diff options
Diffstat (limited to 'internal/processing')
| -rw-r--r-- | internal/processing/admin/domainallow.go | 50 | ||||
| -rw-r--r-- | internal/processing/admin/domainblock.go | 50 | ||||
| -rw-r--r-- | internal/processing/admin/domainpermission.go | 163 | ||||
| -rw-r--r-- | internal/processing/instance.go | 6 |
4 files changed, 228 insertions, 41 deletions
diff --git a/internal/processing/admin/domainallow.go b/internal/processing/admin/domainallow.go index 02101ccff..134351ad5 100644 --- a/internal/processing/admin/domainallow.go +++ b/internal/processing/admin/domainallow.go @@ -60,7 +60,7 @@ func (p *Processor) createDomainAllow( } // Insert the new allow into the database. - if err := p.state.DB.CreateDomainAllow(ctx, domainAllow); err != nil { + if err := p.state.DB.PutDomainAllow(ctx, domainAllow); err != nil { err = gtserror.Newf("db error putting domain allow %s: %w", domain, err) return nil, "", gtserror.NewErrorInternalError(err) } @@ -92,6 +92,54 @@ func (p *Processor) createDomainAllow( return apiDomainAllow, action.ID, nil } +func (p *Processor) updateDomainAllow( + ctx context.Context, + domainAllowID string, + obfuscate *bool, + publicComment *string, + privateComment *string, + subscriptionID *string, +) (*apimodel.DomainPermission, gtserror.WithCode) { + domainAllow, err := p.state.DB.GetDomainAllowByID(ctx, domainAllowID) + if err != nil { + if !errors.Is(err, db.ErrNoEntries) { + // Real error. + err = gtserror.Newf("db error getting domain allow: %w", err) + return nil, gtserror.NewErrorInternalError(err) + } + + // There are just no entries for this ID. + err = fmt.Errorf("no domain allow entry exists with ID %s", domainAllowID) + return nil, gtserror.NewErrorNotFound(err, err.Error()) + } + + var columns []string + if obfuscate != nil { + domainAllow.Obfuscate = obfuscate + columns = append(columns, "obfuscate") + } + if publicComment != nil { + domainAllow.PublicComment = *publicComment + columns = append(columns, "public_comment") + } + if privateComment != nil { + domainAllow.PrivateComment = *privateComment + columns = append(columns, "private_comment") + } + if subscriptionID != nil { + domainAllow.SubscriptionID = *subscriptionID + columns = append(columns, "subscription_id") + } + + // Update the domain allow. + if err := p.state.DB.UpdateDomainAllow(ctx, domainAllow, columns...); err != nil { + err = gtserror.Newf("db error updating domain allow: %w", err) + return nil, gtserror.NewErrorInternalError(err) + } + + return p.apiDomainPerm(ctx, domainAllow, false) +} + func (p *Processor) deleteDomainAllow( ctx context.Context, adminAcct *gtsmodel.Account, diff --git a/internal/processing/admin/domainblock.go b/internal/processing/admin/domainblock.go index 249df744c..3dd5a256f 100644 --- a/internal/processing/admin/domainblock.go +++ b/internal/processing/admin/domainblock.go @@ -60,7 +60,7 @@ func (p *Processor) createDomainBlock( } // Insert the new block into the database. - if err := p.state.DB.CreateDomainBlock(ctx, domainBlock); err != nil { + if err := p.state.DB.PutDomainBlock(ctx, domainBlock); err != nil { err = gtserror.Newf("db error putting domain block %s: %w", domain, err) return nil, "", gtserror.NewErrorInternalError(err) } @@ -93,6 +93,54 @@ func (p *Processor) createDomainBlock( return apiDomainBlock, action.ID, nil } +func (p *Processor) updateDomainBlock( + ctx context.Context, + domainBlockID string, + obfuscate *bool, + publicComment *string, + privateComment *string, + subscriptionID *string, +) (*apimodel.DomainPermission, gtserror.WithCode) { + domainBlock, err := p.state.DB.GetDomainBlockByID(ctx, domainBlockID) + if err != nil { + if !errors.Is(err, db.ErrNoEntries) { + // Real error. + err = gtserror.Newf("db error getting domain block: %w", err) + return nil, gtserror.NewErrorInternalError(err) + } + + // There are just no entries for this ID. + err = fmt.Errorf("no domain block entry exists with ID %s", domainBlockID) + return nil, gtserror.NewErrorNotFound(err, err.Error()) + } + + var columns []string + if obfuscate != nil { + domainBlock.Obfuscate = obfuscate + columns = append(columns, "obfuscate") + } + if publicComment != nil { + domainBlock.PublicComment = *publicComment + columns = append(columns, "public_comment") + } + if privateComment != nil { + domainBlock.PrivateComment = *privateComment + columns = append(columns, "private_comment") + } + if subscriptionID != nil { + domainBlock.SubscriptionID = *subscriptionID + columns = append(columns, "subscription_id") + } + + // Update the domain block. + if err := p.state.DB.UpdateDomainBlock(ctx, domainBlock, columns...); err != nil { + err = gtserror.Newf("db error updating domain block: %w", err) + return nil, gtserror.NewErrorInternalError(err) + } + + return p.apiDomainPerm(ctx, domainBlock, false) +} + func (p *Processor) deleteDomainBlock( ctx context.Context, adminAcct *gtsmodel.Account, diff --git a/internal/processing/admin/domainpermission.go b/internal/processing/admin/domainpermission.go index 55800f458..04ee2ab26 100644 --- a/internal/processing/admin/domainpermission.go +++ b/internal/processing/admin/domainpermission.go @@ -18,6 +18,7 @@ package admin import ( + "cmp" "context" "encoding/json" "errors" @@ -29,6 +30,7 @@ import ( "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/gtserror" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" + "github.com/superseriousbusiness/gotosocial/internal/util" ) // DomainPermissionCreate creates an instance-level permission @@ -84,6 +86,50 @@ func (p *Processor) DomainPermissionCreate( } } +// DomainPermissionUpdate updates a domain permission +// of the given permissionType, with the given ID. +func (p *Processor) DomainPermissionUpdate( + ctx context.Context, + permissionType gtsmodel.DomainPermissionType, + permID string, + obfuscate *bool, + publicComment *string, + privateComment *string, + subscriptionID *string, +) (*apimodel.DomainPermission, gtserror.WithCode) { + switch permissionType { + + // Explicitly block a domain. + case gtsmodel.DomainPermissionBlock: + return p.updateDomainBlock( + ctx, + permID, + obfuscate, + publicComment, + privateComment, + subscriptionID, + ) + + // Explicitly allow a domain. + case gtsmodel.DomainPermissionAllow: + return p.updateDomainAllow( + ctx, + permID, + obfuscate, + publicComment, + privateComment, + subscriptionID, + ) + + // 🎵 Why don't we all strap bombs to our chests, + // and ride our bikes to the next G7 picnic? + // Seems easier with every clock-tick. 🎵 + default: + err := gtserror.Newf("unrecognized permission type %d", permissionType) + return nil, gtserror.NewErrorInternalError(err) + } +} + // DomainPermissionDelete removes one domain block with the given ID, // and processes side effects of removing the block asynchronously. // @@ -153,14 +199,14 @@ func (p *Processor) DomainPermissionsImport( } defer file.Close() - // Parse file as slice of domain blocks. - domainPerms := make([]*apimodel.DomainPermission, 0) - if err := json.NewDecoder(file).Decode(&domainPerms); err != nil { + // Parse file as slice of domain permissions. + apiDomainPerms := make([]*apimodel.DomainPermission, 0) + if err := json.NewDecoder(file).Decode(&apiDomainPerms); err != nil { err = gtserror.Newf("error parsing attachment as domain permissions: %w", err) return nil, gtserror.NewErrorBadRequest(err, err.Error()) } - count := len(domainPerms) + count := len(apiDomainPerms) if count == 0 { err = gtserror.New("error importing domain permissions: 0 entries provided") return nil, gtserror.NewErrorBadRequest(err, err.Error()) @@ -170,50 +216,95 @@ func (p *Processor) DomainPermissionsImport( // between successes and errors so that the caller can // try failed imports again if desired. multiStatusEntries := make([]apimodel.MultiStatusEntry, 0, count) - - for _, domainPerm := range domainPerms { - var ( - domain = domainPerm.Domain.Domain - obfuscate = domainPerm.Obfuscate - publicComment = domainPerm.PublicComment - privateComment = domainPerm.PrivateComment - subscriptionID = "" // No sub ID for imports. - errWithCode gtserror.WithCode + for _, apiDomainPerm := range apiDomainPerms { + multiStatusEntries = append( + multiStatusEntries, + p.importOrUpdateDomainPerm( + ctx, + permissionType, + account, + apiDomainPerm, + ), ) + } + + return apimodel.NewMultiStatus(multiStatusEntries), nil +} + +func (p *Processor) importOrUpdateDomainPerm( + ctx context.Context, + permType gtsmodel.DomainPermissionType, + account *gtsmodel.Account, + apiDomainPerm *apimodel.DomainPermission, +) apimodel.MultiStatusEntry { + var ( + domain = apiDomainPerm.Domain.Domain + obfuscate = apiDomainPerm.Obfuscate + publicComment = cmp.Or(apiDomainPerm.PublicComment, apiDomainPerm.Comment) + privateComment = apiDomainPerm.PrivateComment + subscriptionID = "" // No sub ID for imports. + ) + + // Check if this domain + // perm already exists. + var ( + domainPerm gtsmodel.DomainPermission + err error + ) + if permType == gtsmodel.DomainPermissionBlock { + domainPerm, err = p.state.DB.GetDomainBlock(ctx, domain) + } else { + domainPerm, err = p.state.DB.GetDomainAllow(ctx, domain) + } - domainPerm, _, errWithCode = p.DomainPermissionCreate( + if err != nil && !errors.Is(err, db.ErrNoEntries) { + // Real db error. + return apimodel.MultiStatusEntry{ + Resource: domain, + Message: "db error checking for existence of domain permission", + Status: http.StatusInternalServerError, + } + } + + var errWithCode gtserror.WithCode + if domainPerm != nil { + // Permission already exists, update it. + apiDomainPerm, errWithCode = p.DomainPermissionUpdate( ctx, - permissionType, - account, - domain, + permType, + domainPerm.GetID(), obfuscate, publicComment, privateComment, + nil, + ) + } else { + // Permission didn't exist yet, create it. + apiDomainPerm, _, errWithCode = p.DomainPermissionCreate( + ctx, + permType, + account, + domain, + util.PtrOrZero(obfuscate), + util.PtrOrZero(publicComment), + util.PtrOrZero(privateComment), subscriptionID, ) + } - var entry *apimodel.MultiStatusEntry - - if errWithCode != nil { - entry = &apimodel.MultiStatusEntry{ - // Use the failed domain entry as the resource value. - Resource: domain, - Message: errWithCode.Safe(), - Status: errWithCode.Code(), - } - } else { - entry = &apimodel.MultiStatusEntry{ - // Use successfully created API model domain block as the resource value. - Resource: domainPerm, - Message: http.StatusText(http.StatusOK), - Status: http.StatusOK, - } + if errWithCode != nil { + return apimodel.MultiStatusEntry{ + Resource: domain, + Message: errWithCode.Safe(), + Status: errWithCode.Code(), } - - multiStatusEntries = append(multiStatusEntries, *entry) } - return apimodel.NewMultiStatus(multiStatusEntries), nil + return apimodel.MultiStatusEntry{ + Resource: apiDomainPerm, + Message: http.StatusText(http.StatusOK), + Status: http.StatusOK, + } } // DomainPermissionsGet returns all existing domain diff --git a/internal/processing/instance.go b/internal/processing/instance.go index 4cbbb742a..e723c751e 100644 --- a/internal/processing/instance.go +++ b/internal/processing/instance.go @@ -106,9 +106,9 @@ func (p *Processor) InstancePeersGet(ctx context.Context, includeSuspended bool, } domains = append(domains, &apimodel.Domain{ - Domain: d, - SuspendedAt: util.FormatISO8601(domainBlock.CreatedAt), - PublicComment: domainBlock.PublicComment, + Domain: d, + SuspendedAt: util.FormatISO8601(domainBlock.CreatedAt), + Comment: &domainBlock.PublicComment, }) } } |
