[bugfix] Fix existing perm adoption

This commit is contained in:
tobi 2025-01-18 13:10:08 +01:00
parent 81b66ad7e3
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 {
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 {
return DomainPermissionBlock
}
func (d *DomainBlock) IsOrphan() bool {
return d.SubscriptionID == ""
}

View file

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

View file

@ -104,3 +104,7 @@ func (d *DomainPermissionDraft) SetSubscriptionID(i string) {
func (d *DomainPermissionDraft) GetType() DomainPermissionType {
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) SetSubscriptionID(_ string) {}
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.
err = s.state.AdminActions.Run(ctx, action, actionF)
case existingPerm.GetSubscriptionID() != "" || *permSub.AdoptOrphans:
// Perm exists but we should adopt/take
// it by copying over desired fields.
existingPerm.SetCreatedByAccountID(wantedPerm.GetCreatedByAccountID())
existingPerm.SetCreatedByAccount(wantedPerm.GetCreatedByAccount())
existingPerm.SetSubscriptionID(permSub.ID)
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)
case existingPerm.IsOrphan():
// Perm already exists, but it's not managed
// by a subscription, ie., it's an orphan.
if !*permSub.AdoptOrphans {
l.Debug("permission exists as an orphan that we shouldn't adopt, skipping")
return false, nil
}
// 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:
// Perm exists but we should leave it alone.
l.Debug("domain is covered by a higher-priority subscription, skipping")
// Perm exists and is managed by us.
//
// 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) {
@ -829,3 +855,34 @@ func (s *Subscriptions) existingCovered(
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
}