feat(supervisor): support revoke binding and tighten access

This commit is contained in:
nepiedg
2026-04-16 11:55:00 +08:00
parent 0eaf3a206a
commit 55d84576f3
4 changed files with 103 additions and 5 deletions
+31 -5
View File
@@ -40,11 +40,12 @@ type SupervisorStatusResult struct {
}
var (
ErrInviteNotFound = errors.New("邀请不存在")
ErrInviteExpired = errors.New("邀请已过期")
ErrInviteUsed = errors.New("邀请已被使用")
ErrCannotBindSelf = errors.New("不能绑定自己为监督人")
ErrBindingExists = errors.New("监督关系已存在")
ErrInviteNotFound = errors.New("邀请不存在")
ErrInviteExpired = errors.New("邀请已过期")
ErrInviteUsed = errors.New("邀请已被使用")
ErrCannotBindSelf = errors.New("不能绑定自己为监督人")
ErrBindingExists = errors.New("监督关系已存在")
ErrBindingNotFound = errors.New("监督关系不存在")
)
func (s *Service) CreateSupervisorInvite(ctx context.Context, ownerUID int, now time.Time, days int) (SupervisorInviteResult, error) {
@@ -221,6 +222,31 @@ func (s *Service) GetSupervisorStatus(ctx context.Context, ownerUID int) (Superv
return SupervisorStatusResult{Items: items}, nil
}
// RevokeSupervisorBinding 解除监督关系(owner 或 supervisor 任一方均可解除)。
func (s *Service) RevokeSupervisorBinding(ctx context.Context, actorUID int, ownerUID int, supervisorUID int, now time.Time) error {
if ownerUID <= 0 || supervisorUID <= 0 {
return ErrBindingNotFound
}
if actorUID != ownerUID && actorUID != supervisorUID {
return ErrBindingNotFound
}
result := s.db.WithContext(ctx).
Model(&quitmodel.SupervisorBinding{}).
Where("owner_uid = ? AND supervisor_uid = ? AND status = ?", ownerUID, supervisorUID, "active").
Updates(map[string]interface{}{
"status": "revoked",
"updated_at": now,
})
if result.Error != nil {
return result.Error
}
if result.RowsAffected == 0 {
return ErrBindingNotFound
}
return nil
}
func newInviteToken() string {
// 80-bit random -> base32 -> ~16 chars, URL safe-ish, upper-case; unify to lower for nicer display.
buf := make([]byte, 10)