package issue import ( "context" "github.com/bluesky-social/indigo/atproto/syntax" "tangled.org/core/appview/db" "tangled.org/core/appview/models" "tangled.org/core/appview/pages/repoinfo" "tangled.org/core/appview/session" "tangled.org/core/orm" ) func (s *Service) CloseIssue(ctx context.Context, issue *models.Issue) error { l := s.logger.With("method", "CloseIssue") sess := session.FromContext(ctx) if sess == nil { l.Error("user session is missing in context") return ErrUnAuthenticated } sessDid := sess.Data.AccountDID l = l.With("did", sessDid) // TODO: make this more granular roles := repoinfo.RolesInRepo{Roles: s.enforcer.GetPermissionsInRepo(sessDid.String(), issue.Repo.Knot, issue.Repo.DidSlashRepo())} isRepoOwner := roles.IsOwner() isCollaborator := roles.IsCollaborator() isIssueOwner := sessDid == syntax.DID(issue.Did) if !(isRepoOwner || isCollaborator || isIssueOwner) { l.Error("user is not authorized") return ErrForbidden } err := db.CloseIssues( s.db, orm.FilterEq("id", issue.Id), ) if err != nil { l.Error("db.CloseIssues failed", "err", err) return ErrDatabaseFail } // change the issue state (this will pass down to the notifiers) issue.Open = false s.notifier.NewIssueState(ctx, sessDid, issue) return nil } func (s *Service) ReopenIssue(ctx context.Context, issue *models.Issue) error { l := s.logger.With("method", "ReopenIssue") sess := session.FromContext(ctx) if sess == nil { l.Error("user session is missing in context") return ErrUnAuthenticated } sessDid := sess.Data.AccountDID l = l.With("did", sessDid) // TODO: make this more granular roles := repoinfo.RolesInRepo{Roles: s.enforcer.GetPermissionsInRepo(sessDid.String(), issue.Repo.Knot, issue.Repo.DidSlashRepo())} isRepoOwner := roles.IsOwner() isCollaborator := roles.IsCollaborator() isIssueOwner := sessDid == syntax.DID(issue.Did) if !(isRepoOwner || isCollaborator || isIssueOwner) { l.Error("user is not authorized") return ErrForbidden } err := db.ReopenIssues( s.db, orm.FilterEq("id", issue.Id), ) if err != nil { l.Error("db.ReopenIssues failed", "err", err) return ErrDatabaseFail } // change the issue state (this will pass down to the notifiers) issue.Open = true s.notifier.NewIssueState(ctx, sessDid, issue) return nil }