wahhh getting there
This commit is contained in:
parent
41e6e8ed10
commit
d4c919d273
|
@ -23,7 +23,6 @@ import (
|
|||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
)
|
||||
|
||||
// UsersGETHandler should be served at https://example.org/users/:username.
|
||||
|
@ -55,60 +54,14 @@ func (m *Module) UsersGETHandler(c *gin.Context) {
|
|||
}
|
||||
l.Tracef("negotiated format: %s", format)
|
||||
|
||||
// get the account the request is referring to
|
||||
requestedAccount := >smodel.Account{}
|
||||
if err := m.db.GetLocalAccountByUsername(requestedUsername, requestedAccount); err != nil {
|
||||
l.Errorf("database error getting account with username %s: %s", requestedUsername, err)
|
||||
// we'll just return not authorized here to avoid giving anything away
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "not authorized"})
|
||||
return
|
||||
}
|
||||
|
||||
// and create a transport for it
|
||||
transport, err := m.federator.TransportController().NewTransport(requestedAccount.PublicKeyURI, requestedAccount.PrivateKey)
|
||||
// make a copy of the context to pass along so we don't break anything
|
||||
cp := c.Copy()
|
||||
user, err := m.processor.GetAPUser(requestedUsername, cp.Request) // GetAPUser handles auth as well
|
||||
if err != nil {
|
||||
l.Errorf("error creating transport for username %s: %s", requestedUsername, err)
|
||||
// we'll just return not authorized here to avoid giving anything away
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "not authorized"})
|
||||
l.Info(err.Error())
|
||||
c.JSON(err.Code(), gin.H{"error": err.Safe()})
|
||||
return
|
||||
}
|
||||
|
||||
// authenticate the request
|
||||
authentication, err := federation.AuthenticateFederatedRequest(transport, c.Request)
|
||||
if err != nil {
|
||||
l.Errorf("error authenticating GET user request: %s", err)
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "not authorized"})
|
||||
return
|
||||
}
|
||||
|
||||
if !authentication.Authenticated {
|
||||
l.Debug("request not authorized")
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "not authorized"})
|
||||
return
|
||||
}
|
||||
|
||||
requestingAccount := >smodel.Account{}
|
||||
if authentication.RequestingPublicKeyID != nil {
|
||||
if err := m.db.GetWhere("public_key_uri", authentication.RequestingPublicKeyID.String(), requestingAccount); err != nil {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
authorization, err := federation.AuthorizeFederatedRequest
|
||||
|
||||
person, err := m.tc.AccountToAS(requestedAccount)
|
||||
if err != nil {
|
||||
l.Errorf("error converting account to ap person: %s", err)
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "not authorized"})
|
||||
return
|
||||
}
|
||||
|
||||
data, err := person.Serialize()
|
||||
if err != nil {
|
||||
l.Errorf("error serializing user: %s", err)
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "not authorized"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, data)
|
||||
c.JSON(http.StatusOK, user)
|
||||
}
|
||||
|
|
|
@ -104,7 +104,30 @@ func (f *federatingDB) Unlock(c context.Context, id *url.URL) error {
|
|||
//
|
||||
// The library makes this call only after acquiring a lock first.
|
||||
func (f *federatingDB) InboxContains(c context.Context, inbox, id *url.URL) (contains bool, err error) {
|
||||
return false, nil
|
||||
|
||||
if !util.IsInboxPath(inbox) {
|
||||
return false, fmt.Errorf("%s is not an inbox URI", inbox.String())
|
||||
}
|
||||
|
||||
if !util.IsStatusesPath(id) {
|
||||
return false, fmt.Errorf("%s is not a status URI", id.String())
|
||||
}
|
||||
_, statusID, err := util.ParseStatusesPath(inbox)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("status URI %s was not parseable: %s", id.String(), err)
|
||||
}
|
||||
|
||||
if err := f.db.GetByID(statusID, >smodel.Status{}); err != nil {
|
||||
if _, ok := err.(ErrNoEntries); ok {
|
||||
// we don't have it
|
||||
return false, nil
|
||||
}
|
||||
// actual error
|
||||
return false, fmt.Errorf("error getting status from db: %s", err)
|
||||
}
|
||||
|
||||
// we must have it
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// GetInbox returns the first ordered collection page of the outbox at
|
||||
|
@ -128,11 +151,6 @@ func (f *federatingDB) SetInbox(c context.Context, inbox vocab.ActivityStreamsOr
|
|||
// the database has an entry for the IRI.
|
||||
// The library makes this call only after acquiring a lock first.
|
||||
func (f *federatingDB) Owns(c context.Context, id *url.URL) (bool, error) {
|
||||
l := f.log.WithFields(logrus.Fields{
|
||||
"func": "Owns",
|
||||
"activityID": id.String(),
|
||||
})
|
||||
|
||||
// if the id host isn't this instance host, we don't own this IRI
|
||||
if id.Host != f.config.Host {
|
||||
return false, nil
|
||||
|
@ -142,27 +160,18 @@ func (f *federatingDB) Owns(c context.Context, id *url.URL) (bool, error) {
|
|||
|
||||
// check if it's a status, eg /users/example_username/statuses/SOME_UUID_OF_A_STATUS
|
||||
if util.IsStatusesPath(id) {
|
||||
username, uid, err := util.ParseStatusesPath(id)
|
||||
_, uid, err := util.ParseStatusesPath(id)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("error parsing statuses path for url %s: %s", id.String(), err)
|
||||
}
|
||||
acct := >smodel.Account{}
|
||||
if err := f.db.GetLocalAccountByUsername(username, acct); err != nil {
|
||||
if _, ok := err.(ErrNoEntries); ok {
|
||||
// there are no entries for this username
|
||||
return false, nil
|
||||
}
|
||||
return false, fmt.Errorf("database error fetching account with username %s: %s", username, err)
|
||||
}
|
||||
status := >smodel.Status{}
|
||||
if err := f.db.GetByID(uid, status); err != nil {
|
||||
if err := f.db.GetWhere("uri", uid, >smodel.Status{}); err != nil {
|
||||
if _, ok := err.(ErrNoEntries); ok {
|
||||
// there are no entries for this status
|
||||
return false, nil
|
||||
}
|
||||
// an actual error happened
|
||||
return false, fmt.Errorf("database error fetching status with id %s: %s", uid, err)
|
||||
}
|
||||
// the user exists, the status exists, we own both, we're good
|
||||
return true, nil
|
||||
}
|
||||
|
||||
|
@ -172,34 +181,52 @@ func (f *federatingDB) Owns(c context.Context, id *url.URL) (bool, error) {
|
|||
if err != nil {
|
||||
return false, fmt.Errorf("error parsing statuses path for url %s: %s", id.String(), err)
|
||||
}
|
||||
acct := >smodel.Account{}
|
||||
if err := f.db.GetLocalAccountByUsername(username, acct); err != nil {
|
||||
if err := f.db.GetLocalAccountByUsername(username, >smodel.Account{}); err != nil {
|
||||
if _, ok := err.(ErrNoEntries); ok {
|
||||
// there are no entries for this username
|
||||
return false, nil
|
||||
}
|
||||
// an actual error happened
|
||||
return false, fmt.Errorf("database error fetching account with username %s: %s", username, err)
|
||||
}
|
||||
// the user exists, we own it, we're good
|
||||
return true, nil
|
||||
}
|
||||
|
||||
l.Info("could not match activityID")
|
||||
return false, nil
|
||||
return false, fmt.Errorf("could not match activityID: %s", id.String())
|
||||
}
|
||||
|
||||
// ActorForOutbox fetches the actor's IRI for the given outbox IRI.
|
||||
//
|
||||
// The library makes this call only after acquiring a lock first.
|
||||
func (f *federatingDB) ActorForOutbox(c context.Context, outboxIRI *url.URL) (actorIRI *url.URL, err error) {
|
||||
return nil, nil
|
||||
if !util.IsOutboxPath(outboxIRI) {
|
||||
return nil, fmt.Errorf("%s is not an outbox URI", outboxIRI.String())
|
||||
}
|
||||
acct := >smodel.Account{}
|
||||
if err := f.db.GetWhere("outbox_uri", outboxIRI.String(), acct); err != nil {
|
||||
if _, ok := err.(ErrNoEntries); ok {
|
||||
return nil, fmt.Errorf("no actor found that corresponds to outbox %s", outboxIRI.String())
|
||||
}
|
||||
return nil, fmt.Errorf("db error searching for actor with outbox %s", outboxIRI.String())
|
||||
}
|
||||
return url.Parse(acct.URI)
|
||||
}
|
||||
|
||||
// ActorForInbox fetches the actor's IRI for the given outbox IRI.
|
||||
//
|
||||
// The library makes this call only after acquiring a lock first.
|
||||
func (f *federatingDB) ActorForInbox(c context.Context, inboxIRI *url.URL) (actorIRI *url.URL, err error) {
|
||||
return nil, nil
|
||||
if !util.IsInboxPath(inboxIRI) {
|
||||
return nil, fmt.Errorf("%s is not an inbox URI", inboxIRI.String())
|
||||
}
|
||||
acct := >smodel.Account{}
|
||||
if err := f.db.GetWhere("inbox_uri", inboxIRI.String(), acct); err != nil {
|
||||
if _, ok := err.(ErrNoEntries); ok {
|
||||
return nil, fmt.Errorf("no actor found that corresponds to inbox %s", inboxIRI.String())
|
||||
}
|
||||
return nil, fmt.Errorf("db error searching for actor with inbox %s", inboxIRI.String())
|
||||
}
|
||||
return url.Parse(acct.URI)
|
||||
}
|
||||
|
||||
// OutboxForInbox fetches the corresponding actor's outbox IRI for the
|
||||
|
@ -207,7 +234,17 @@ func (f *federatingDB) ActorForInbox(c context.Context, inboxIRI *url.URL) (acto
|
|||
//
|
||||
// The library makes this call only after acquiring a lock first.
|
||||
func (f *federatingDB) OutboxForInbox(c context.Context, inboxIRI *url.URL) (outboxIRI *url.URL, err error) {
|
||||
return nil, nil
|
||||
if !util.IsInboxPath(inboxIRI) {
|
||||
return nil, fmt.Errorf("%s is not an inbox URI", inboxIRI.String())
|
||||
}
|
||||
acct := >smodel.Account{}
|
||||
if err := f.db.GetWhere("inbox_uri", inboxIRI.String(), acct); err != nil {
|
||||
if _, ok := err.(ErrNoEntries); ok {
|
||||
return nil, fmt.Errorf("no actor found that corresponds to inbox %s", inboxIRI.String())
|
||||
}
|
||||
return nil, fmt.Errorf("db error searching for actor with inbox %s", inboxIRI.String())
|
||||
}
|
||||
return url.Parse(acct.OutboxURI)
|
||||
}
|
||||
|
||||
// Exists returns true if the database has an entry for the specified
|
||||
|
|
|
@ -578,6 +578,7 @@ func (ps *postgresService) GetAvatarForAccountID(avatar *gtsmodel.MediaAttachmen
|
|||
}
|
||||
|
||||
func (ps *postgresService) Blocked(account1 string, account2 string) (bool, error) {
|
||||
// TODO: check domain blocks as well
|
||||
var blocked bool
|
||||
if err := ps.conn.Model(>smodel.Block{}).
|
||||
Where("account_id = ?", account1).Where("target_account_id = ?", account2).
|
||||
|
|
|
@ -137,7 +137,9 @@ func (f *federator) AuthenticatePostInbox(ctx context.Context, w http.ResponseWr
|
|||
requestingAccount = a
|
||||
}
|
||||
|
||||
return nil, true, nil
|
||||
contextWithRequestingAccount := context.WithValue(ctx, util.APRequestingAccount, requestingAccount)
|
||||
|
||||
return contextWithRequestingAccount, true, nil
|
||||
}
|
||||
|
||||
// Blocked should determine whether to permit a set of actors given by
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"net/url"
|
||||
|
||||
"github.com/go-fed/activity/pub"
|
||||
"github.com/go-fed/activity/streams/vocab"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
|
@ -32,9 +33,17 @@ import (
|
|||
|
||||
// Federator wraps various interfaces and functions to manage activitypub federation from gotosocial
|
||||
type Federator interface {
|
||||
// FederatingActor returns the underlying pub.FederatingActor, which can be used to send activities, and serve actors at inboxes/outboxes.
|
||||
FederatingActor() pub.FederatingActor
|
||||
TransportController() transport.Controller
|
||||
// AuthenticateFederatedRequest can be used to check the authenticity of incoming http-signed requests for federating resources.
|
||||
// The given username will be used to create a transport for making outgoing requests. See the implementation for more detailed comments.
|
||||
AuthenticateFederatedRequest(username string, r *http.Request) (*url.URL, error)
|
||||
// DereferenceRemoteAccount can be used to get the ActivityStreamsPerson representation of a remote account, based on the account ID (which is a URI).
|
||||
// The given username will be used to create a transport for making outgoing requests. See the implementation for more detailed comments.
|
||||
DereferenceRemoteAccount(username string, remoteAccountID *url.URL) (vocab.ActivityStreamsPerson, error)
|
||||
// GetTransportForUser returns a new transport initialized with the key credentials belonging to the given username.
|
||||
// This can be used for making signed http requests.
|
||||
GetTransportForUser(username string) (pub.Transport, error)
|
||||
pub.CommonBehavior
|
||||
pub.FederatingProtocol
|
||||
}
|
||||
|
@ -69,7 +78,3 @@ func NewFederator(db db.DB, transportController transport.Controller, config *co
|
|||
func (f *federator) FederatingActor() pub.FederatingActor {
|
||||
return f.actor
|
||||
}
|
||||
|
||||
func (f *federator) TransportController() transport.Controller {
|
||||
return f.transportController
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ func (suite *ProtocolTestSuite) TestPostInboxRequestBodyHook() {
|
|||
request.Header.Set("Signature", activity.SignatureHeader)
|
||||
|
||||
// trigger the function being tested, and return the new context it creates
|
||||
newContext, err := federator.FederatingProtocol().PostInboxRequestBodyHook(ctx, request, activity.Activity)
|
||||
newContext, err := federator.PostInboxRequestBodyHook(ctx, request, activity.Activity)
|
||||
assert.NoError(suite.T(), err)
|
||||
assert.NotNil(suite.T(), newContext)
|
||||
|
||||
|
@ -173,7 +173,7 @@ func (suite *ProtocolTestSuite) TestAuthenticatePostInbox() {
|
|||
recorder := httptest.NewRecorder()
|
||||
|
||||
// trigger the function being tested, and return the new context it creates
|
||||
newContext, authed, err := federator.FederatingProtocol().AuthenticatePostInbox(ctxWithActivity, recorder, request)
|
||||
newContext, authed, err := federator.AuthenticatePostInbox(ctxWithActivity, recorder, request)
|
||||
assert.NoError(suite.T(), err)
|
||||
assert.True(suite.T(), authed)
|
||||
|
||||
|
|
|
@ -93,13 +93,13 @@ func getPublicKeyFromResponse(c context.Context, b []byte, keyID *url.URL) (voca
|
|||
return pkpFound, nil
|
||||
}
|
||||
|
||||
// AuthenticateFederatedRequest authenticates any kind of federated request from a remote server. This includes things like
|
||||
// GET requests for dereferencing users or statuses etc and POST requests for delivering new Activities.
|
||||
//
|
||||
// Error means the request did not pass authentication. No error means it's authentic.
|
||||
// AuthenticateFederatedRequest authenticates any kind of incoming federated request from a remote server. This includes things like
|
||||
// GET requests for dereferencing our users or statuses etc, and POST requests for delivering new Activities. The function returns
|
||||
// the URL of the owner of the public key used in the http signature.
|
||||
//
|
||||
// Authenticate in this case is defined as just making sure that the http request is actually signed by whoever claims
|
||||
// to have signed it, by fetching the public key from the signature and checking it against the remote public key.
|
||||
// to have signed it, by fetching the public key from the signature and checking it against the remote public key. This function
|
||||
// *does not* check whether the request is authorized, only whether it's authentic.
|
||||
//
|
||||
// The provided username will be used to generate a transport for making remote requests/derefencing the public key ID of the request signature.
|
||||
// Ideally you should pass in the username of the user *being requested*, so that the remote server can decide how to handle the request based on who's making it.
|
||||
|
@ -108,8 +108,8 @@ func getPublicKeyFromResponse(c context.Context, b []byte, keyID *url.URL) (voca
|
|||
//
|
||||
// Note that it is also valid to pass in an empty string here, in which case the keys of the instance account will be used.
|
||||
//
|
||||
// Note that this function *does not* dereference the remote account that the signature key is associated with, but it will
|
||||
// return the owner of the public key, so that other functions can dereference it with that, as required.
|
||||
// Also note that this function *does not* dereference the remote account that the signature key is associated with.
|
||||
// Other functions should use the returned URL to dereference the remote account, if required.
|
||||
func (f *federator) AuthenticateFederatedRequest(username string, r *http.Request) (*url.URL, error) {
|
||||
verifier, err := httpsig.NewVerifier(r)
|
||||
if err != nil {
|
||||
|
@ -225,9 +225,56 @@ func (f *federator) GetTransportForUser(username string) (pub.Transport, error)
|
|||
return nil, fmt.Errorf("error getting account %s from db: %s", username, err)
|
||||
}
|
||||
|
||||
transport, err := f.TransportController().NewTransport(ourAccount.PublicKeyURI, ourAccount.PrivateKey)
|
||||
transport, err := f.transportController.NewTransport(ourAccount.PublicKeyURI, ourAccount.PrivateKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating transport for user %s: %s", username, err)
|
||||
}
|
||||
return transport, nil
|
||||
}
|
||||
|
||||
const (
|
||||
activityStreamsContext = "https://www.w3.org/ns/activitystreams"
|
||||
w3idContext = "https://w3id.org/security/v1"
|
||||
tootContext = "http://joinmastodon.org/ns#"
|
||||
schemaContext = "http://schema.org#"
|
||||
)
|
||||
|
||||
// ActivityStreamsContext returns the url representation of https://www.w3.org/ns/activitystreams
|
||||
func ActivityStreamsContext() *url.URL {
|
||||
u, err := url.Parse(activityStreamsContext)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
||||
// W3IDContext returns the url representation of https://w3id.org/security/v1
|
||||
func W3IDContext() *url.URL {
|
||||
u, err := url.Parse(w3idContext)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
||||
// TootContext returns the url representation of http://joinmastodon.org/ns#
|
||||
func TootContext() *url.URL {
|
||||
u, err := url.Parse(tootContext)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
||||
// SchemaContext returns the url representation of http://schema.org#
|
||||
func SchemaContext() *url.URL {
|
||||
u, err := url.Parse(schemaContext)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
||||
func StandardContexts() vocab.ActivityStreamsContextProperty {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,63 +1,70 @@
|
|||
package message
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-fed/activity/streams"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
)
|
||||
|
||||
func (p *processor) GetAPUser(requestHeaders http.Header, username string) (interface{}, error) {
|
||||
func (p *processor) GetAPUser(requestedUsername string, request *http.Request) (interface{}, ErrorWithCode) {
|
||||
// get the account the request is referring to
|
||||
requestedAccount := >smodel.Account{}
|
||||
if err := p.db.GetLocalAccountByUsername(requestedUsername, requestedAccount); err != nil {
|
||||
return nil, NewErrorNotFound(fmt.Errorf("database error getting account with username %s: %s", requestedUsername, err))
|
||||
}
|
||||
|
||||
// // get the account the request is referring to
|
||||
// requestedAccount := >smodel.Account{}
|
||||
// if err := m.db.GetLocalAccountByUsername(username, requestedAccount); err != nil {
|
||||
// return nil, NewErrorNotAuthorized(fmt.Errorf("database error getting account with username %s: %s", username, err))
|
||||
// }
|
||||
// authenticate the request
|
||||
requestingAccountURI, err := p.federator.AuthenticateFederatedRequest(requestedUsername, request)
|
||||
if err != nil {
|
||||
return nil, NewErrorNotAuthorized(err)
|
||||
}
|
||||
|
||||
// // and create a transport for it
|
||||
// transport, err := p.federator.TransportController().NewTransport(requestedAccount.PublicKeyURI, requestedAccount.PrivateKey)
|
||||
// if err != nil {
|
||||
// l.Errorf("error creating transport for username %s: %s", requestedUsername, err)
|
||||
// // we'll just return not authorized here to avoid giving anything away
|
||||
// c.JSON(http.StatusUnauthorized, gin.H{"error": "not authorized"})
|
||||
// return
|
||||
// }
|
||||
requestingAccount := >smodel.Account{}
|
||||
err = p.db.GetWhere("uri", requestingAccountURI.String(), requestingAccount)
|
||||
if err != nil {
|
||||
if _, ok := err.(db.ErrNoEntries); !ok {
|
||||
// we don't have an entry for this account yet
|
||||
// what we do now should depend on our chosen federation method
|
||||
// for now though, we'll just dereference it
|
||||
// TODO: slow-fed
|
||||
requestingPerson, err := p.federator.DereferenceRemoteAccount(requestedUsername, requestingAccountURI)
|
||||
if err != nil {
|
||||
return nil, NewErrorInternalError(err)
|
||||
}
|
||||
requestedAccount, err = p.tc.ASPersonToAccount(requestingPerson)
|
||||
if err != nil {
|
||||
return nil, NewErrorInternalError(err)
|
||||
}
|
||||
if err := p.db.Put(requestingAccount); err != nil {
|
||||
return nil, NewErrorInternalError(err)
|
||||
}
|
||||
} else {
|
||||
// something has actually gone wrong
|
||||
return nil, NewErrorInternalError(err)
|
||||
}
|
||||
}
|
||||
|
||||
// // authenticate the request
|
||||
// authentication, err := federation.AuthenticateFederatedRequest(transport, c.Request)
|
||||
// if err != nil {
|
||||
// l.Errorf("error authenticating GET user request: %s", err)
|
||||
// c.JSON(http.StatusUnauthorized, gin.H{"error": "not authorized"})
|
||||
// return
|
||||
// }
|
||||
blocked, err := p.db.Blocked(requestedAccount.ID, requestingAccount.ID)
|
||||
if err != nil {
|
||||
return nil, NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
// if !authentication.Authenticated {
|
||||
// l.Debug("request not authorized")
|
||||
// c.JSON(http.StatusUnauthorized, gin.H{"error": "not authorized"})
|
||||
// return
|
||||
// }
|
||||
if blocked {
|
||||
return nil, NewErrorNotAuthorized(fmt.Errorf("block exists between accounts %s and %s", requestedAccount.ID, requestingAccount.ID))
|
||||
}
|
||||
|
||||
// requestingAccount := >smodel.Account{}
|
||||
// if authentication.RequestingPublicKeyID != nil {
|
||||
// if err := m.db.GetWhere("public_key_uri", authentication.RequestingPublicKeyID.String(), requestingAccount); err != nil {
|
||||
requestedPerson, err := p.tc.AccountToAS(requestedAccount)
|
||||
if err != nil {
|
||||
return nil, NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
// }
|
||||
// }
|
||||
data, err := streams.Serialize(requestedPerson)
|
||||
if err != nil {
|
||||
return nil, NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
// authorization, err := federation.AuthorizeFederatedRequest
|
||||
|
||||
// person, err := m.tc.AccountToAS(requestedAccount)
|
||||
// if err != nil {
|
||||
// l.Errorf("error converting account to ap person: %s", err)
|
||||
// c.JSON(http.StatusUnauthorized, gin.H{"error": "not authorized"})
|
||||
// return
|
||||
// }
|
||||
|
||||
// data, err := person.Serialize()
|
||||
// if err != nil {
|
||||
// l.Errorf("error serializing user: %s", err)
|
||||
// c.JSON(http.StatusUnauthorized, gin.H{"error": "not authorized"})
|
||||
// return
|
||||
// }
|
||||
|
||||
// c.JSON(http.StatusOK, data)
|
||||
return nil, nil
|
||||
return data, nil
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
package message
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
|
@ -48,7 +50,7 @@ type Processor interface {
|
|||
FromFederator() chan FromFederator
|
||||
|
||||
/*
|
||||
API-FACING PROCESSING FUNCTIONS
|
||||
CLIENT API-FACING PROCESSING FUNCTIONS
|
||||
These functions are intended to be called when the API client needs an immediate (ie., synchronous) reply
|
||||
to an HTTP request. As such, they will only do the bare-minimum of work necessary to give a properly
|
||||
formed reply. For more intensive (and time-consuming) calls, where you don't require an immediate
|
||||
|
@ -82,6 +84,16 @@ type Processor interface {
|
|||
// AdminEmojiCreate handles the creation of a new instance emoji by an admin, using the given form.
|
||||
AdminEmojiCreate(authed *oauth.Auth, form *apimodel.EmojiCreateRequest) (*apimodel.Emoji, error)
|
||||
|
||||
/*
|
||||
FEDERATION API-FACING PROCESSING FUNCTIONS
|
||||
These functions are intended to be called when the federating client needs an immediate (ie., synchronous) reply
|
||||
to an HTTP request. As such, they will only do the bare-minimum of work necessary to give a properly
|
||||
formed reply. For more intensive (and time-consuming) calls, where you don't require an immediate
|
||||
response, pass work to the processor using a channel instead.
|
||||
*/
|
||||
|
||||
GetAPUser(requestedUsername string, request *http.Request) (interface{}, ErrorWithCode)
|
||||
|
||||
// Start starts the Processor, reading from its channels and passing messages back and forth.
|
||||
Start() error
|
||||
// Stop stops the processor cleanly, finishing handling any remaining messages before closing down.
|
||||
|
|
|
@ -82,11 +82,7 @@ func (p *processor) StatusCreate(auth *oauth.Auth, form *apimodel.AdvancedStatus
|
|||
}
|
||||
|
||||
// return the frontend representation of the new status to the submitter
|
||||
mastoStatus, err := p.tc.StatusToMasto(newStatus, auth.Account, auth.Account, nil, newStatus.GTSReplyToAccount, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return mastoStatus, nil
|
||||
return p.tc.StatusToMasto(newStatus, auth.Account, auth.Account, nil, newStatus.GTSReplyToAccount, nil)
|
||||
}
|
||||
|
||||
func (p *processor) StatusDelete(authed *oauth.Auth, targetStatusID string) (*apimodel.Status, error) {
|
||||
|
|
|
@ -28,6 +28,8 @@ import (
|
|||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
)
|
||||
|
||||
|
||||
|
||||
// Converts a gts model account into an Activity Streams person type, following
|
||||
// the spec laid out for mastodon here: https://docs.joinmastodon.org/spec/activitypub/
|
||||
func (c *converter) AccountToAS(a *gtsmodel.Account) (vocab.ActivityStreamsPerson, error) {
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/go-fed/activity/streams"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
@ -69,7 +70,7 @@ func (suite *InternalToASTestSuite) TestPostAccountToAS() {
|
|||
asPerson, err := suite.typeconverter.AccountToAS(testAccount)
|
||||
assert.NoError(suite.T(), err)
|
||||
|
||||
ser, err := asPerson.Serialize()
|
||||
ser, err := streams.Serialize(asPerson)
|
||||
assert.NoError(suite.T(), err)
|
||||
|
||||
bytes, err := json.Marshal(ser)
|
||||
|
|
Loading…
Reference in New Issue