mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-12-17 10:33:01 -06:00
domain blocking more work
This commit is contained in:
parent
d27791bc73
commit
99eb3bf564
11 changed files with 160 additions and 58 deletions
|
|
@ -1,6 +1,7 @@
|
|||
package admin
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
|
|
@ -59,6 +60,10 @@ func (m *Module) DomainBlocksPOSTHandler(c *gin.Context) {
|
|||
}
|
||||
|
||||
func validateCreateDomainBlock(form *model.DomainBlockCreateRequest) error {
|
||||
// TODO: add some validation here later if necessary
|
||||
// add some more validation here later if necessary
|
||||
if form.Domain == "" {
|
||||
return errors.New("empty domain provided")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ func getPublicKeyFromResponse(c context.Context, b []byte, keyID *url.URL) (voca
|
|||
//
|
||||
// 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(requestedUsername string, r *http.Request) (*url.URL, error) {
|
||||
func (f *federator) AuthenticateFederatedRequest(requestedUsername string, r *http.Request) (*url.URL, bool, error) {
|
||||
|
||||
var publicKey interface{}
|
||||
var pkOwnerURI *url.URL
|
||||
|
|
@ -126,23 +126,24 @@ func (f *federator) AuthenticateFederatedRequest(requestedUsername string, r *ht
|
|||
|
||||
verifier, err := httpsig.NewVerifier(r)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not create http sig verifier: %s", err)
|
||||
return nil, false, fmt.Errorf("could not create http sig verifier: %s", err)
|
||||
}
|
||||
|
||||
// The key ID should be given in the signature so that we know where to fetch it from the remote server.
|
||||
// This will be something like https://example.org/users/whatever_requesting_user#main-key
|
||||
requestingPublicKeyID, err := url.Parse(verifier.KeyId())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse key id into a url: %s", err)
|
||||
return nil, false, fmt.Errorf("could not parse key id into a url: %s", err)
|
||||
}
|
||||
|
||||
// if the domain is blocked we want to make as few calls towards it as possible, so already bail here if that's the case!
|
||||
blockedDomain, err := f.blockedDomain(requestingPublicKeyID.Host)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not tell if domain %s was blocked or not: %s", requestingPublicKeyID.Host, err)
|
||||
return nil, false, fmt.Errorf("could not tell if domain %s was blocked or not: %s", requestingPublicKeyID.Host, err)
|
||||
}
|
||||
if blockedDomain {
|
||||
return nil, fmt.Errorf("host %s was domain blocked, aborting auth", requestingPublicKeyID.Host)
|
||||
f.log.Infof("domain %s is blocked", requestingPublicKeyID.Host)
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
requestingRemoteAccount := >smodel.Account{}
|
||||
|
|
@ -152,12 +153,12 @@ func (f *federator) AuthenticateFederatedRequest(requestedUsername string, r *ht
|
|||
// LOCAL ACCOUNT REQUEST
|
||||
// the request is coming from INSIDE THE HOUSE so skip the remote dereferencing
|
||||
if err := f.db.GetWhere([]db.Where{{Key: "public_key_uri", Value: requestingPublicKeyID.String()}}, requestingLocalAccount); err != nil {
|
||||
return nil, fmt.Errorf("couldn't get local account with public key uri %s from the database: %s", requestingPublicKeyID.String(), err)
|
||||
return nil, false, fmt.Errorf("couldn't get local account with public key uri %s from the database: %s", requestingPublicKeyID.String(), err)
|
||||
}
|
||||
publicKey = requestingLocalAccount.PublicKey
|
||||
pkOwnerURI, err = url.Parse(requestingLocalAccount.URI)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing url %s: %s", requestingLocalAccount.URI, err)
|
||||
return nil, false, fmt.Errorf("error parsing url %s: %s", requestingLocalAccount.URI, err)
|
||||
}
|
||||
} else if err := f.db.GetWhere([]db.Where{{Key: "public_key_uri", Value: requestingPublicKeyID.String()}}, requestingRemoteAccount); err == nil {
|
||||
// REMOTE ACCOUNT REQUEST WITH KEY CACHED LOCALLY
|
||||
|
|
@ -165,7 +166,7 @@ func (f *federator) AuthenticateFederatedRequest(requestedUsername string, r *ht
|
|||
publicKey = requestingRemoteAccount.PublicKey
|
||||
pkOwnerURI, err = url.Parse(requestingRemoteAccount.URI)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing url %s: %s", requestingRemoteAccount.URI, err)
|
||||
return nil, false, fmt.Errorf("error parsing url %s: %s", requestingRemoteAccount.URI, err)
|
||||
}
|
||||
} else {
|
||||
// REMOTE ACCOUNT REQUEST WITHOUT KEY CACHED LOCALLY
|
||||
|
|
@ -173,72 +174,55 @@ func (f *federator) AuthenticateFederatedRequest(requestedUsername string, r *ht
|
|||
// so we need to authenticate the request properly by dereferencing the remote key
|
||||
transport, err := f.GetTransportForUser(requestedUsername)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("transport err: %s", err)
|
||||
return nil, false, fmt.Errorf("transport err: %s", err)
|
||||
}
|
||||
|
||||
// The actual http call to the remote server is made right here in the Dereference function.
|
||||
b, err := transport.Dereference(context.Background(), requestingPublicKeyID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error deferencing key %s: %s", requestingPublicKeyID.String(), err)
|
||||
return nil, false, fmt.Errorf("error deferencing key %s: %s", requestingPublicKeyID.String(), err)
|
||||
}
|
||||
|
||||
// if the key isn't in the response, we can't authenticate the request
|
||||
requestingPublicKey, err := getPublicKeyFromResponse(context.Background(), b, requestingPublicKeyID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting key %s from response %s: %s", requestingPublicKeyID.String(), string(b), err)
|
||||
return nil, false, fmt.Errorf("error getting key %s from response %s: %s", requestingPublicKeyID.String(), string(b), err)
|
||||
}
|
||||
|
||||
// we should be able to get the actual key embedded in the vocab.W3IDSecurityV1PublicKey
|
||||
pkPemProp := requestingPublicKey.GetW3IDSecurityV1PublicKeyPem()
|
||||
if pkPemProp == nil || !pkPemProp.IsXMLSchemaString() {
|
||||
return nil, errors.New("publicKeyPem property is not provided or it is not embedded as a value")
|
||||
return nil, false, errors.New("publicKeyPem property is not provided or it is not embedded as a value")
|
||||
}
|
||||
|
||||
// and decode the PEM so that we can parse it as a golang public key
|
||||
pubKeyPem := pkPemProp.Get()
|
||||
block, _ := pem.Decode([]byte(pubKeyPem))
|
||||
if block == nil || block.Type != "PUBLIC KEY" {
|
||||
return nil, errors.New("could not decode publicKeyPem to PUBLIC KEY pem block type")
|
||||
return nil, false, errors.New("could not decode publicKeyPem to PUBLIC KEY pem block type")
|
||||
}
|
||||
|
||||
publicKey, err = x509.ParsePKIXPublicKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse public key from block bytes: %s", err)
|
||||
return nil, false, fmt.Errorf("could not parse public key from block bytes: %s", err)
|
||||
}
|
||||
|
||||
// all good! we just need the URI of the key owner to return
|
||||
pkOwnerProp := requestingPublicKey.GetW3IDSecurityV1Owner()
|
||||
if pkOwnerProp == nil || !pkOwnerProp.IsIRI() {
|
||||
return nil, errors.New("publicKeyOwner property is not provided or it is not embedded as a value")
|
||||
return nil, false, errors.New("publicKeyOwner property is not provided or it is not embedded as a value")
|
||||
}
|
||||
pkOwnerURI = pkOwnerProp.GetIRI()
|
||||
}
|
||||
if publicKey == nil {
|
||||
return nil, errors.New("returned public key was empty")
|
||||
return nil, false, errors.New("returned public key was empty")
|
||||
}
|
||||
|
||||
// do the actual authentication here!
|
||||
algo := httpsig.RSA_SHA256 // TODO: make this more robust
|
||||
if err := verifier.Verify(publicKey, algo); err != nil {
|
||||
return nil, fmt.Errorf("error verifying key %s: %s", requestingPublicKeyID.String(), err)
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
return pkOwnerURI, nil
|
||||
}
|
||||
|
||||
func (f *federator) blockedDomain(host string) (bool, error) {
|
||||
b := >smodel.DomainBlock{}
|
||||
err := f.db.GetWhere([]db.Where{{Key: "domain", Value: host, CaseInsensitive: true}}, b)
|
||||
if err == nil {
|
||||
// block exists
|
||||
return true, nil
|
||||
}
|
||||
|
||||
if _, ok := err.(db.ErrNoEntries); ok {
|
||||
// there are no entries so there's no block
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// there's an actual error
|
||||
return false, err
|
||||
return pkOwnerURI, true, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,10 @@ func (f *federator) DereferenceRemoteAccount(username string, remoteAccountID *u
|
|||
f.startHandshake(username, remoteAccountID)
|
||||
defer f.stopHandshake(username, remoteAccountID)
|
||||
|
||||
if blocked, err := f.blockedDomain(remoteAccountID.Host); blocked || err != nil {
|
||||
return nil, fmt.Errorf("DereferenceRemoteAccount: domain %s is blocked", remoteAccountID.Host)
|
||||
}
|
||||
|
||||
transport, err := f.GetTransportForUser(username)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("transport err: %s", err)
|
||||
|
|
@ -66,6 +70,10 @@ func (f *federator) DereferenceRemoteAccount(username string, remoteAccountID *u
|
|||
}
|
||||
|
||||
func (f *federator) DereferenceRemoteStatus(username string, remoteStatusID *url.URL) (typeutils.Statusable, error) {
|
||||
if blocked, err := f.blockedDomain(remoteStatusID.Host); blocked || err != nil {
|
||||
return nil, fmt.Errorf("DereferenceRemoteStatus: domain %s is blocked", remoteStatusID.Host)
|
||||
}
|
||||
|
||||
transport, err := f.GetTransportForUser(username)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("transport err: %s", err)
|
||||
|
|
@ -148,6 +156,10 @@ func (f *federator) DereferenceRemoteStatus(username string, remoteStatusID *url
|
|||
}
|
||||
|
||||
func (f *federator) DereferenceRemoteInstance(username string, remoteInstanceURI *url.URL) (*gtsmodel.Instance, error) {
|
||||
if blocked, err := f.blockedDomain(remoteInstanceURI.Host); blocked || err != nil {
|
||||
return nil, fmt.Errorf("DereferenceRemoteInstance: domain %s is blocked", remoteInstanceURI.Host)
|
||||
}
|
||||
|
||||
transport, err := f.GetTransportForUser(username)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("transport err: %s", err)
|
||||
|
|
@ -186,6 +198,14 @@ func (f *federator) DereferenceStatusFields(status *gtsmodel.Status, requestingU
|
|||
})
|
||||
l.Debug("entering function")
|
||||
|
||||
statusURI, err := url.Parse(status.URI)
|
||||
if err != nil {
|
||||
return fmt.Errorf("DereferenceStatusFields: couldn't parse status URI %s: %s", status.URI, err)
|
||||
}
|
||||
if blocked, err := f.blockedDomain(statusURI.Host); blocked || err != nil {
|
||||
return fmt.Errorf("DereferenceStatusFields: domain %s is blocked", statusURI.Host)
|
||||
}
|
||||
|
||||
t, err := f.GetTransportForUser(requestingUsername)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating transport: %s", err)
|
||||
|
|
@ -321,6 +341,14 @@ func (f *federator) DereferenceAccountFields(account *gtsmodel.Account, requesti
|
|||
"requestingUsername": requestingUsername,
|
||||
})
|
||||
|
||||
accountURI, err := url.Parse(account.URI)
|
||||
if err != nil {
|
||||
return fmt.Errorf("DereferenceAccountFields: couldn't parse account URI %s: %s", account.URI, err)
|
||||
}
|
||||
if blocked, err := f.blockedDomain(accountURI.Host); blocked || err != nil {
|
||||
return fmt.Errorf("DereferenceAccountFields: domain %s is blocked", accountURI.Host)
|
||||
}
|
||||
|
||||
t, err := f.GetTransportForUser(requestingUsername)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error getting transport for user: %s", err)
|
||||
|
|
@ -342,12 +370,20 @@ func (f *federator) DereferenceAccountFields(account *gtsmodel.Account, requesti
|
|||
func (f *federator) DereferenceAnnounce(announce *gtsmodel.Status, requestingUsername string) error {
|
||||
if announce.GTSBoostedStatus == nil || announce.GTSBoostedStatus.URI == "" {
|
||||
// we can't do anything unfortunately
|
||||
return errors.New("dereferenceAnnounce: no URI to dereference")
|
||||
return errors.New("DereferenceAnnounce: no URI to dereference")
|
||||
}
|
||||
|
||||
boostedStatusURI, err := url.Parse(announce.GTSBoostedStatus.URI)
|
||||
if err != nil {
|
||||
return fmt.Errorf("DereferenceAnnounce: couldn't parse boosted status URI %s: %s", announce.GTSBoostedStatus.URI, err)
|
||||
}
|
||||
if blocked, err := f.blockedDomain(boostedStatusURI.Host); blocked || err != nil {
|
||||
return fmt.Errorf("DereferenceAnnounce: domain %s is blocked", boostedStatusURI.Host)
|
||||
}
|
||||
|
||||
// check if we already have the boosted status in the database
|
||||
boostedStatus := >smodel.Status{}
|
||||
err := f.db.GetWhere([]db.Where{{Key: "uri", Value: announce.GTSBoostedStatus.URI}}, boostedStatus)
|
||||
err = f.db.GetWhere([]db.Where{{Key: "uri", Value: announce.GTSBoostedStatus.URI}}, boostedStatus)
|
||||
if err == nil {
|
||||
// nice, we already have it so we don't actually need to dereference it from remote
|
||||
announce.Content = boostedStatus.Content
|
||||
|
|
@ -364,12 +400,7 @@ func (f *federator) DereferenceAnnounce(announce *gtsmodel.Status, requestingUse
|
|||
}
|
||||
|
||||
// we don't have it so we need to dereference it
|
||||
remoteStatusURI, err := url.Parse(announce.GTSBoostedStatus.URI)
|
||||
if err != nil {
|
||||
return fmt.Errorf("dereferenceAnnounce: error parsing url %s: %s", announce.GTSBoostedStatus.URI, err)
|
||||
}
|
||||
|
||||
statusable, err := f.DereferenceRemoteStatus(requestingUsername, remoteStatusURI)
|
||||
statusable, err := f.DereferenceRemoteStatus(requestingUsername, boostedStatusURI)
|
||||
if err != nil {
|
||||
return fmt.Errorf("dereferenceAnnounce: error dereferencing remote status with id %s: %s", announce.GTSBoostedStatus.URI, err)
|
||||
}
|
||||
|
|
@ -460,6 +491,14 @@ func (f *federator) DereferenceAnnounce(announce *gtsmodel.Status, requestingUse
|
|||
// SIDE EFFECTS: remote header and avatar will be stored in local storage, and the database will be updated
|
||||
// to reflect the creation of these new attachments.
|
||||
func (f *federator) fetchHeaderAndAviForAccount(targetAccount *gtsmodel.Account, t transport.Transport, refresh bool) error {
|
||||
accountURI, err := url.Parse(targetAccount.URI)
|
||||
if err != nil {
|
||||
return fmt.Errorf("fetchHeaderAndAviForAccount: couldn't parse account URI %s: %s", targetAccount.URI, err)
|
||||
}
|
||||
if blocked, err := f.blockedDomain(accountURI.Host); blocked || err != nil {
|
||||
return fmt.Errorf("fetchHeaderAndAviForAccount: domain %s is blocked", accountURI.Host)
|
||||
}
|
||||
|
||||
if targetAccount.AvatarRemoteURL != "" && (targetAccount.AvatarMediaAttachmentID == "" || refresh) {
|
||||
a, err := f.mediaHandler.ProcessRemoteHeaderOrAvatar(t, >smodel.MediaAttachment{
|
||||
RemoteURL: targetAccount.AvatarRemoteURL,
|
||||
|
|
|
|||
|
|
@ -119,10 +119,15 @@ func (f *federator) AuthenticatePostInbox(ctx context.Context, w http.ResponseWr
|
|||
return nil, false, fmt.Errorf("could not fetch requested account with username %s: %s", username, err)
|
||||
}
|
||||
|
||||
publicKeyOwnerURI, err := f.AuthenticateFederatedRequest(requestedAccount.Username, r)
|
||||
publicKeyOwnerURI, authenticated, err := f.AuthenticateFederatedRequest(requestedAccount.Username, r)
|
||||
if err != nil {
|
||||
l.Debugf("request not authenticated: %s", err)
|
||||
return ctx, false, fmt.Errorf("not authenticated: %s", err)
|
||||
return ctx, false, err
|
||||
}
|
||||
|
||||
if !authenticated {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
return ctx, false, nil
|
||||
}
|
||||
|
||||
// authentication has passed, so add an instance entry for this instance if it hasn't been done already
|
||||
|
|
@ -230,6 +235,14 @@ func (f *federator) Blocked(ctx context.Context, actorIRIs []*url.URL) (bool, er
|
|||
}
|
||||
|
||||
for _, uri := range actorIRIs {
|
||||
blockedDomain, err := f.blockedDomain(uri.Host);
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("error checking domain block: %s", err)
|
||||
}
|
||||
if blockedDomain {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
a := >smodel.Account{}
|
||||
if err := f.db.GetWhere([]db.Where{{Key: "uri", Value: uri.String()}}, a); err != nil {
|
||||
_, ok := err.(db.ErrNoEntries)
|
||||
|
|
|
|||
|
|
@ -42,7 +42,13 @@ type Federator interface {
|
|||
FederatingDB() federatingdb.DB
|
||||
// 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)
|
||||
//
|
||||
// If the request is valid and passes authentication, the URL of the key owner ID will be returned, as well as true, and nil.
|
||||
//
|
||||
// If the request does not pass authentication, or there's a domain block, nil, false, nil will be returned.
|
||||
//
|
||||
// If something goes wrong during authentication, nil, false, and an error will be returned.
|
||||
AuthenticateFederatedRequest(username string, r *http.Request) (*url.URL, bool, error)
|
||||
// FingerRemoteAccount performs a webfinger lookup for a remote account, using the .well-known path. It will return the ActivityPub URI for that
|
||||
// account, or an error if it doesn't exist or can't be retrieved.
|
||||
FingerRemoteAccount(requestingUsername string, targetUsername string, targetDomain string) (*url.URL, error)
|
||||
|
|
@ -97,6 +103,7 @@ func NewFederator(db db.DB, federatingDB federatingdb.DB, transportController tr
|
|||
clock: &Clock{},
|
||||
typeConverter: typeConverter,
|
||||
transportController: transportController,
|
||||
mediaHandler: mediaHandler,
|
||||
log: log,
|
||||
handshakeSync: &sync.Mutex{},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@ import (
|
|||
)
|
||||
|
||||
func (f *federator) FingerRemoteAccount(requestingUsername string, targetUsername string, targetDomain string) (*url.URL, error) {
|
||||
if blocked, err := f.blockedDomain(targetDomain); blocked || err != nil {
|
||||
return nil, fmt.Errorf("FingerRemoteAccount: domain %s is blocked", targetDomain)
|
||||
}
|
||||
|
||||
t, err := f.GetTransportForUser(requestingUsername)
|
||||
if err != nil {
|
||||
|
|
|
|||
23
internal/federation/util.go
Normal file
23
internal/federation/util.go
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
package federation
|
||||
|
||||
import (
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
)
|
||||
|
||||
func (f *federator) blockedDomain(host string) (bool, error) {
|
||||
b := >smodel.DomainBlock{}
|
||||
err := f.db.GetWhere([]db.Where{{Key: "domain", Value: host, CaseInsensitive: true}}, b)
|
||||
if err == nil {
|
||||
// block exists
|
||||
return true, nil
|
||||
}
|
||||
|
||||
if _, ok := err.(db.ErrNoEntries); ok {
|
||||
// there are no entries so there's no block
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// there's an actual error
|
||||
return false, err
|
||||
}
|
||||
|
|
@ -35,7 +35,7 @@ func (p *processor) DomainBlockCreate(account *gtsmodel.Account, form *apimodel.
|
|||
domainBlock := >smodel.DomainBlock{}
|
||||
err := p.db.GetWhere([]db.Where{{Key: "domain", Value: form.Domain, CaseInsensitive: true}}, domainBlock)
|
||||
if err != nil {
|
||||
if _, ok := err.(db.ErrNoEntries); ok {
|
||||
if _, ok := err.(db.ErrNoEntries); !ok {
|
||||
// something went wrong in the DB
|
||||
return nil, gtserror.NewErrorInternalError(fmt.Errorf("DomainBlockCreate: db error checking for existence of domain block %s: %s", form.Domain, err))
|
||||
}
|
||||
|
|
@ -130,6 +130,7 @@ selectAccountsLoop:
|
|||
}
|
||||
// an actual error has occurred
|
||||
l.Errorf("domainBlockProcessSideEffects: db error selecting accounts for domain %s: %s", block.Domain, err)
|
||||
break selectAccountsLoop
|
||||
}
|
||||
|
||||
for i, a := range accounts {
|
||||
|
|
|
|||
|
|
@ -106,8 +106,8 @@ func (p *processor) GetFediUser(requestedUsername string, request *http.Request)
|
|||
}
|
||||
} else if util.IsUserPath(request.URL) {
|
||||
// if it's a user path, we want to fully authenticate the request before we serve any data, and then we can serve a more complete profile
|
||||
requestingAccountURI, err := p.federator.AuthenticateFederatedRequest(requestedUsername, request)
|
||||
if err != nil {
|
||||
requestingAccountURI, authenticated, err := p.federator.AuthenticateFederatedRequest(requestedUsername, request)
|
||||
if err != nil || !authenticated {
|
||||
return nil, gtserror.NewErrorNotAuthorized(err)
|
||||
}
|
||||
|
||||
|
|
@ -152,8 +152,8 @@ func (p *processor) GetFediFollowers(requestedUsername string, request *http.Req
|
|||
}
|
||||
|
||||
// authenticate the request
|
||||
requestingAccountURI, err := p.federator.AuthenticateFederatedRequest(requestedUsername, request)
|
||||
if err != nil {
|
||||
requestingAccountURI, authenticated, err := p.federator.AuthenticateFederatedRequest(requestedUsername, request)
|
||||
if err != nil || !authenticated {
|
||||
return nil, gtserror.NewErrorNotAuthorized(err)
|
||||
}
|
||||
|
||||
|
|
@ -197,8 +197,8 @@ func (p *processor) GetFediFollowing(requestedUsername string, request *http.Req
|
|||
}
|
||||
|
||||
// authenticate the request
|
||||
requestingAccountURI, err := p.federator.AuthenticateFederatedRequest(requestedUsername, request)
|
||||
if err != nil {
|
||||
requestingAccountURI, authenticated, err := p.federator.AuthenticateFederatedRequest(requestedUsername, request)
|
||||
if err != nil || !authenticated {
|
||||
return nil, gtserror.NewErrorNotAuthorized(err)
|
||||
}
|
||||
|
||||
|
|
@ -242,8 +242,8 @@ func (p *processor) GetFediStatus(requestedUsername string, requestedStatusID st
|
|||
}
|
||||
|
||||
// authenticate the request
|
||||
requestingAccountURI, err := p.federator.AuthenticateFederatedRequest(requestedUsername, request)
|
||||
if err != nil {
|
||||
requestingAccountURI, authenticated, err := p.federator.AuthenticateFederatedRequest(requestedUsername, request)
|
||||
if err != nil || !authenticated {
|
||||
return nil, gtserror.NewErrorNotAuthorized(err)
|
||||
}
|
||||
|
||||
|
|
@ -356,6 +356,5 @@ func (p *processor) GetNodeInfo(request *http.Request) (*apimodel.Nodeinfo, gtse
|
|||
|
||||
func (p *processor) InboxPost(ctx context.Context, w http.ResponseWriter, r *http.Request) (bool, error) {
|
||||
contextWithChannel := context.WithValue(ctx, util.APFromFederatorChanKey, p.fromFederator)
|
||||
posted, err := p.federator.FederatingActor().PostInbox(contextWithChannel, w, r)
|
||||
return posted, err
|
||||
return p.federator.FederatingActor().PostInbox(contextWithChannel, w, r)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package visibility
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"net/url"
|
||||
|
||||
"fmt"
|
||||
|
||||
|
|
@ -16,6 +17,15 @@ func (f *filter) StatusVisible(targetStatus *gtsmodel.Status, requestingAccount
|
|||
"statusID": targetStatus.ID,
|
||||
})
|
||||
|
||||
uri, err := url.Parse(targetStatus.URI)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("StatusVisible: error parsing uri: %s", targetStatus.URI)
|
||||
}
|
||||
if blocked, err := f.blockedDomain(uri.Host); blocked || err != nil {
|
||||
l.Debugf("domain %s is blocked", uri.Host)
|
||||
return blocked, err
|
||||
}
|
||||
aaaaaaaaaa
|
||||
relevantAccounts, err := f.pullRelevantAccountsFromStatus(targetStatus)
|
||||
if err != nil {
|
||||
l.Debugf("error pulling relevant accounts for status %s: %s", targetStatus.ID, err)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package visibility
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
)
|
||||
|
||||
|
|
@ -79,3 +80,20 @@ type relevantAccounts struct {
|
|||
BoostedReplyToAccount *gtsmodel.Account
|
||||
MentionedAccounts []*gtsmodel.Account
|
||||
}
|
||||
|
||||
func (f *filter) blockedDomain(host string) (bool, error) {
|
||||
b := >smodel.DomainBlock{}
|
||||
err := f.db.GetWhere([]db.Where{{Key: "domain", Value: host, CaseInsensitive: true}}, b)
|
||||
if err == nil {
|
||||
// block exists
|
||||
return true, nil
|
||||
}
|
||||
|
||||
if _, ok := err.(db.ErrNoEntries); ok {
|
||||
// there are no entries so there's no block
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// there's an actual error
|
||||
return false, err
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue