[bugfix] Fix existing perm adoption

This commit is contained in:
tobi 2025-01-18 13:10:08 +01:00
commit 288cc3dbe5
6 changed files with 91 additions and 17 deletions

View file

@ -104,3 +104,7 @@ func (d *DomainAllow) SetSubscriptionID(i string) {
func (d *DomainAllow) GetType() DomainPermissionType { func (d *DomainAllow) GetType() DomainPermissionType {
return DomainPermissionAllow return DomainPermissionAllow
} }
func (d *DomainAllow) IsOrphan() bool {
return d.SubscriptionID == ""
}

View file

@ -104,3 +104,7 @@ func (d *DomainBlock) SetSubscriptionID(i string) {
func (d *DomainBlock) GetType() DomainPermissionType { func (d *DomainBlock) GetType() DomainPermissionType {
return DomainPermissionBlock return DomainPermissionBlock
} }
func (d *DomainBlock) IsOrphan() bool {
return d.SubscriptionID == ""
}

View file

@ -43,6 +43,10 @@ type DomainPermission interface {
GetSubscriptionID() string GetSubscriptionID() string
SetSubscriptionID(i string) SetSubscriptionID(i string)
GetType() DomainPermissionType GetType() DomainPermissionType
// Return true if this DomainPermission
// does not have a subscription id set.
IsOrphan() bool
} }
// Domain permission type. // Domain permission type.

View file

@ -104,3 +104,7 @@ func (d *DomainPermissionDraft) SetSubscriptionID(i string) {
func (d *DomainPermissionDraft) GetType() DomainPermissionType { func (d *DomainPermissionDraft) GetType() DomainPermissionType {
return d.PermissionType return d.PermissionType
} }
func (d *DomainPermissionDraft) IsOrphan() bool {
return d.SubscriptionID == ""
}

View file

@ -90,3 +90,4 @@ func (d *DomainPermissionExclude) SetObfuscate(_ *bool) {}
func (d *DomainPermissionExclude) GetSubscriptionID() string { return "" } func (d *DomainPermissionExclude) GetSubscriptionID() string { return "" }
func (d *DomainPermissionExclude) SetSubscriptionID(_ string) {} func (d *DomainPermissionExclude) SetSubscriptionID(_ string) {}
func (d *DomainPermissionExclude) GetType() DomainPermissionType { return DomainPermissionUnknown } func (d *DomainPermissionExclude) GetType() DomainPermissionType { return DomainPermissionUnknown }
func (d *DomainPermissionExclude) IsOrphan() bool { return true }

View file

@ -486,26 +486,52 @@ func (s *Subscriptions) processDomainPermission(
// side effects of permission. // side effects of permission.
err = s.state.AdminActions.Run(ctx, action, actionF) err = s.state.AdminActions.Run(ctx, action, actionF)
case existingPerm.GetSubscriptionID() != "" || *permSub.AdoptOrphans: case existingPerm.IsOrphan():
// Perm exists but we should adopt/take // Perm already exists, but it's not managed
// it by copying over desired fields. // by a subscription, ie., it's an orphan.
existingPerm.SetCreatedByAccountID(wantedPerm.GetCreatedByAccountID()) if !*permSub.AdoptOrphans {
existingPerm.SetCreatedByAccount(wantedPerm.GetCreatedByAccount()) l.Debug("permission exists as an orphan that we shouldn't adopt, skipping")
existingPerm.SetSubscriptionID(permSub.ID) return false, nil
existingPerm.SetObfuscate(wantedPerm.GetObfuscate())
existingPerm.SetPrivateComment(wantedPerm.GetPrivateComment())
existingPerm.SetPublicComment(wantedPerm.GetPublicComment())
switch p := existingPerm.(type) {
case *gtsmodel.DomainBlock:
err = s.state.DB.UpdateDomainBlock(ctx, p)
case *gtsmodel.DomainAllow:
err = s.state.DB.UpdateDomainAllow(ctx, p)
} }
// Orphan is adoptable, so adopt
// it by rewriting some fields.
//
// TODO: preserve previous private
// + public comment in some way.
l.Debug("adopting orphan permission")
err = s.adoptPerm(
ctx,
existingPerm,
permSub,
wantedPerm.GetObfuscate(),
permSub.URI,
wantedPerm.GetPublicComment(),
)
case existingPerm.GetSubscriptionID() != permSub.ID:
// Perm already exists, and is managed
// by a lower-priority subscription.
// Take it for ourselves.
//
// TODO: preserve previous private
// + public comment in some way.
l.Debug("taking over permission from lower-priority subscription")
err = s.adoptPerm(
ctx,
existingPerm,
permSub,
wantedPerm.GetObfuscate(),
permSub.URI,
wantedPerm.GetPublicComment(),
)
default: default:
// Perm exists but we should leave it alone. // Perm exists and is managed by us.
l.Debug("domain is covered by a higher-priority subscription, skipping") //
// TODO: update public/private comment
// from latest version if it's changed.
l.Debug("permission already exists and is managed by this subscription, skipping")
} }
if err != nil && !errors.Is(err, db.ErrAlreadyExists) { if err != nil && !errors.Is(err, db.ErrAlreadyExists) {
@ -829,3 +855,34 @@ func (s *Subscriptions) existingCovered(
return return
} }
func (s *Subscriptions) adoptPerm(
ctx context.Context,
perm gtsmodel.DomainPermission,
permSub *gtsmodel.DomainPermissionSubscription,
obfuscate *bool,
privateComment string,
publicComment string,
) error {
// Set to our sub ID + this subs's
// account as we're managing it now.
perm.SetSubscriptionID(permSub.ID)
perm.SetCreatedByAccountID(permSub.CreatedByAccount.ID)
perm.SetCreatedByAccount(permSub.CreatedByAccount)
// Set new metadata on the perm.
perm.SetObfuscate(obfuscate)
perm.SetPrivateComment(privateComment)
perm.SetPublicComment(publicComment)
// Update the perm in the db.
var err error
switch p := perm.(type) {
case *gtsmodel.DomainBlock:
err = s.state.DB.UpdateDomainBlock(ctx, p)
case *gtsmodel.DomainAllow:
err = s.state.DB.UpdateDomainAllow(ctx, p)
}
return err
}