diff --git a/pkg/api/controller.go b/pkg/api/controller.go index 4e69d6603b0..839b2735972 100644 --- a/pkg/api/controller.go +++ b/pkg/api/controller.go @@ -614,12 +614,7 @@ func (c *Controller) CompletePresignMultipartUpload(w http.ResponseWriter, r *ht } func (c *Controller) PrepareGarbageCollectionUncommitted(w http.ResponseWriter, r *http.Request, body apigen.PrepareGarbageCollectionUncommittedJSONRequestBody, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.PrepareGarbageCollectionUncommittedAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "PrepareGarbageCollectionUncommitted", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -2384,12 +2379,7 @@ func (c *Controller) ensureStorageNamespace(ctx context.Context, storageID, stor } func (c *Controller) DeleteRepository(w http.ResponseWriter, r *http.Request, repository string, params apigen.DeleteRepositoryParams) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.DeleteRepositoryAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "DeleteRepository", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -2402,12 +2392,7 @@ func (c *Controller) DeleteRepository(w http.ResponseWriter, r *http.Request, re } func (c *Controller) GetRepository(w http.ResponseWriter, r *http.Request, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ReadRepositoryAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "GetRepository", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -2437,12 +2422,7 @@ func (c *Controller) GetRepository(w http.ResponseWriter, r *http.Request, repos } func (c *Controller) GetRepositoryMetadata(w http.ResponseWriter, r *http.Request, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ReadRepositoryAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "GetRepositoryMetadata", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -2455,12 +2435,7 @@ func (c *Controller) GetRepositoryMetadata(w http.ResponseWriter, r *http.Reques } func (c *Controller) SetRepositoryMetadata(w http.ResponseWriter, r *http.Request, body apigen.SetRepositoryMetadataJSONRequestBody, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.UpdateRepositoryAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "SetRepositoryMetadata", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -2473,12 +2448,7 @@ func (c *Controller) SetRepositoryMetadata(w http.ResponseWriter, r *http.Reques } func (c *Controller) DeleteRepositoryMetadata(w http.ResponseWriter, r *http.Request, body apigen.DeleteRepositoryMetadataJSONRequestBody, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.UpdateRepositoryAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "DeleteRepositoryMetadata", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -2491,12 +2461,7 @@ func (c *Controller) DeleteRepositoryMetadata(w http.ResponseWriter, r *http.Req } func (c *Controller) GetBranchProtectionRules(w http.ResponseWriter, r *http.Request, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.GetBranchProtectionRulesAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "GetBranchProtectionRules", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -2515,12 +2480,7 @@ func (c *Controller) GetBranchProtectionRules(w http.ResponseWriter, r *http.Req } func (c *Controller) SetBranchProtectionRules(w http.ResponseWriter, r *http.Request, body apigen.SetBranchProtectionRulesJSONRequestBody, repository string, params apigen.SetBranchProtectionRulesParams) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.SetBranchProtectionRulesAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "SetBranchProtectionRules", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -2545,12 +2505,7 @@ func (c *Controller) SetBranchProtectionRules(w http.ResponseWriter, r *http.Req } func (c *Controller) DeleteGCRules(w http.ResponseWriter, r *http.Request, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.SetGarbageCollectionRulesAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "DeleteGCRules", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -2562,12 +2517,7 @@ func (c *Controller) DeleteGCRules(w http.ResponseWriter, r *http.Request, repos } func (c *Controller) GetGCRules(w http.ResponseWriter, r *http.Request, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.GetGarbageCollectionRulesAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "GetGCRules", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -2584,12 +2534,7 @@ func (c *Controller) GetGCRules(w http.ResponseWriter, r *http.Request, reposito } func (c *Controller) SetGCRules(w http.ResponseWriter, r *http.Request, body apigen.SetGCRulesJSONRequestBody, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.SetGarbageCollectionRulesAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "SetGCRules", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -2608,12 +2553,7 @@ func (c *Controller) SetGCRules(w http.ResponseWriter, r *http.Request, body api } func (c *Controller) ListRepositoryRuns(w http.ResponseWriter, r *http.Request, repository string, params apigen.ListRepositoryRunsParams) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ReadActionsAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "ListRepositoryRuns", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -2676,12 +2616,7 @@ func runResultToActionRun(val *actions.RunResult) apigen.ActionRun { } func (c *Controller) GetRun(w http.ResponseWriter, r *http.Request, repository, runID string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ReadActionsAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "GetRun", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -2715,12 +2650,7 @@ func (c *Controller) GetRun(w http.ResponseWriter, r *http.Request, repository, } func (c *Controller) ListRunHooks(w http.ResponseWriter, r *http.Request, repository, runID string, params apigen.ListRunHooksParams) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ReadActionsAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "ListRunHooks", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -2780,12 +2710,7 @@ func (c *Controller) ListRunHooks(w http.ResponseWriter, r *http.Request, reposi } func (c *Controller) GetRunHookOutput(w http.ResponseWriter, r *http.Request, repository, runID, hookRunID string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ReadActionsAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "GetRunHookOutput", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -2830,12 +2755,7 @@ func (c *Controller) GetRunHookOutput(w http.ResponseWriter, r *http.Request, re } func (c *Controller) ListBranches(w http.ResponseWriter, r *http.Request, repository string, params apigen.ListBranchesParams) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ListBranchesAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "ListBranches", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -3237,12 +3157,7 @@ func (c *Controller) Commit(w http.ResponseWriter, r *http.Request, body apigen. } func (c *Controller) CreateCommitRecord(w http.ResponseWriter, r *http.Request, body apigen.CreateCommitRecordJSONRequestBody, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.CreateCommitAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "CreateCommitRecord", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -3276,12 +3191,7 @@ func commitResponse(w http.ResponseWriter, r *http.Request, newCommit *catalog.C } func (c *Controller) DiffBranch(w http.ResponseWriter, r *http.Request, repository, branch string, params apigen.DiffBranchParams) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ListObjectsAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "DiffBranch", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -3751,12 +3661,7 @@ func getCommitOverrides(commitOverrides *apigen.CommitOverrides) *graveler.Commi } func (c *Controller) GetCommit(w http.ResponseWriter, r *http.Request, repository, commitID string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ReadCommitAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "GetCommit", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -3793,12 +3698,7 @@ func (c *Controller) InternalGetGarbageCollectionRules(w http.ResponseWriter, r } func (c *Controller) SetGarbageCollectionRulesPreflight(w http.ResponseWriter, r *http.Request, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.SetGarbageCollectionRulesAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "SetGarbageCollectionRulesPreflight", permissions.PermissionParams{Repository: &repository}, nil) { return } @@ -3817,12 +3717,7 @@ func (c *Controller) InternalDeleteGarbageCollectionRules(w http.ResponseWriter, } func (c *Controller) PrepareGarbageCollectionCommits(w http.ResponseWriter, r *http.Request, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.PrepareGarbageCollectionCommitsAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "PrepareGarbageCollectionCommits", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -3857,12 +3752,7 @@ func (c *Controller) InternalGetBranchProtectionRules(w http.ResponseWriter, r * } func (c *Controller) InternalDeleteBranchProtectionRule(w http.ResponseWriter, r *http.Request, body apigen.InternalDeleteBranchProtectionRuleJSONRequestBody, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.SetBranchProtectionRulesAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "InternalDeleteBranchProtectionRule", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -3887,12 +3777,7 @@ func (c *Controller) InternalDeleteBranchProtectionRule(w http.ResponseWriter, r } func (c *Controller) CreateBranchProtectionRulePreflight(w http.ResponseWriter, r *http.Request, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.SetBranchProtectionRulesAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "CreateBranchProtectionRulePreflight", permissions.PermissionParams{Repository: &repository}, nil) { return } @@ -3903,12 +3788,7 @@ func (c *Controller) CreateBranchProtectionRulePreflight(w http.ResponseWriter, } func (c *Controller) InternalCreateBranchProtectionRule(w http.ResponseWriter, r *http.Request, body apigen.InternalCreateBranchProtectionRuleJSONRequestBody, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.SetBranchProtectionRulesAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "InternalCreateBranchProtectionRule", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -4412,12 +4292,7 @@ func writeSymlink(ctx context.Context, repo *catalog.Repository, branch, path st } func (c *Controller) DiffRefs(w http.ResponseWriter, r *http.Request, repository, leftRef, rightRef string, params apigen.DiffRefsParams) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ListObjectsAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "DiffRefs", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -4764,12 +4639,7 @@ func (c *Controller) GetObject(w http.ResponseWriter, r *http.Request, repositor } func (c *Controller) ListObjects(w http.ResponseWriter, r *http.Request, repository, ref string, params apigen.ListObjectsParams) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ListObjectsAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "ListObjects", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -5029,12 +4899,7 @@ func (c *Controller) MergeIntoBranch(w http.ResponseWriter, r *http.Request, bod } func (c *Controller) FindMergeBase(w http.ResponseWriter, r *http.Request, repository string, sourceRef string, destinationRef string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ListCommitsAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "FindMergeBase", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -5052,12 +4917,7 @@ func (c *Controller) FindMergeBase(w http.ResponseWriter, r *http.Request, repos } func (c *Controller) ListTags(w http.ResponseWriter, r *http.Request, repository string, params apigen.ListTagsParams) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ListTagsAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "ListTags", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -5461,12 +5321,7 @@ func (c *Controller) PostStatsEvents(w http.ResponseWriter, r *http.Request, bod } func (c *Controller) ListPullRequests(w http.ResponseWriter, r *http.Request, repository string, params apigen.ListPullRequestsParams) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ListPullRequestsAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "ListPullRequests", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -5503,12 +5358,7 @@ func (c *Controller) ListPullRequests(w http.ResponseWriter, r *http.Request, re } func (c *Controller) CreatePullRequest(w http.ResponseWriter, r *http.Request, body apigen.CreatePullRequestJSONRequestBody, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.WritePullRequestAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "CreatePullRequest", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -5539,12 +5389,7 @@ func (c *Controller) CreatePullRequest(w http.ResponseWriter, r *http.Request, b } func (c *Controller) GetPullRequest(w http.ResponseWriter, r *http.Request, repository string, pullRequestID string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ReadPullRequestAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "GetPullRequest", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -5571,12 +5416,7 @@ func (c *Controller) GetPullRequest(w http.ResponseWriter, r *http.Request, repo } func (c *Controller) UpdatePullRequest(w http.ResponseWriter, r *http.Request, body apigen.UpdatePullRequestJSONRequestBody, repository string, pullRequestID string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.WritePullRequestAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "UpdatePullRequest", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() diff --git a/pkg/permissions/permission.go b/pkg/permissions/permission.go index 14e9217cab8..44409e4941f 100644 --- a/pkg/permissions/permission.go +++ b/pkg/permissions/permission.go @@ -1,135 +1,199 @@ -package permissions - -const ( - fsArnPrefix = "arn:lakefs:fs:::" - authArnPrefix = "arn:lakefs:auth:::" - - All = "*" -) - -type Permission struct { - Action string - Resource string -} - -type NodeType int - -const ( - NodeTypeNode NodeType = iota - NodeTypeOr - NodeTypeAnd -) - -type Node struct { - Type NodeType - Permission Permission - Nodes []Node -} - -func RepoArn(repoID string) string { - return fsArnPrefix + "repository/" + repoID -} - -func StorageNamespace(namespace string) string { - return fsArnPrefix + "namespace/" + namespace -} - -func ObjectArn(repoID, key string) string { - return fsArnPrefix + "repository/" + repoID + "/object/" + key -} - -func BranchArn(repoID, branchID string) string { - return fsArnPrefix + "repository/" + repoID + "/branch/" + branchID -} - -func TagArn(repoID, tagID string) string { - return fsArnPrefix + "repository/" + repoID + "/tag/" + tagID -} - -func UserArn(userID string) string { - return authArnPrefix + "user/" + userID -} - -func GroupArn(groupID string) string { - return authArnPrefix + "group/" + groupID -} - -func PolicyArn(policyID string) string { - return authArnPrefix + "policy/" + policyID -} - -func ExternalPrincipalArn(principalID string) string { - return authArnPrefix + "externalPrincipal/" + principalID -} - -type PermissionParams struct { - Repository *string - Path *string - Branch *string -} - -type PermissionDescriptor interface { - Permission(PermissionParams) Node -} - -type ObjectPermission struct { - Action string -} - -func (o *ObjectPermission) Permission(params PermissionParams) Node { - return Node{ - Permission: Permission{ - Action: o.Action, - Resource: ObjectArn(*params.Repository, *params.Path), - }, - } -} - -type BranchPermission struct { - Action string -} - -func (o *BranchPermission) Permission(params PermissionParams) Node { - return Node{ - Permission: Permission{ - Action: o.Action, - Resource: ObjectArn(*params.Repository, *params.Branch), - }, - } -} - -var readObjectPermission = ObjectPermission{Action: ReadObjectAction} -var writeObjectPermission = ObjectPermission{Action: WriteObjectAction} -var createBranchPermission = BranchPermission{Action: CreateBranchAction} -var deleteBranchPermission = BranchPermission{Action: DeleteBranchAction} -var readBranchPermission = BranchPermission{Action: ReadBranchAction} -var revertBranchPermission = BranchPermission{Action: RevertBranchAction} -var createCommitPermission = BranchPermission{Action: CreateCommitAction} -var importCancelPermission = BranchPermission{Action: ImportCancelAction} - -var permissionByOp = map[string]PermissionDescriptor{ - "HeadObject": &readObjectPermission, - "GetObject": &readObjectPermission, - "StatObject": &readObjectPermission, - "GetUnderlyingProperties": &readObjectPermission, - "StageObject": &writeObjectPermission, - "CreateSymlinkFile": &writeObjectPermission, - "UpdateObjectUserMetadata": &writeObjectPermission, - "UploadObject": &writeObjectPermission, - "UploadObjectPreflight": &writeObjectPermission, - "CreateBranch": &createBranchPermission, - "DeleteBranch": &deleteBranchPermission, - "GetBranch": &readBranchPermission, - "RevertBranch": &revertBranchPermission, - "LogCommits": &readBranchPermission, - "ResetBranch": &revertBranchPermission, - "MergeIntoBranch": &createCommitPermission, - "HardResetBranch": &revertBranchPermission, - "ImportStatus": &readBranchPermission, - "Commit": &createCommitPermission, - "ImportCancel": &importCancelPermission, -} - -func GetPermissionDescriptor(operationId string) PermissionDescriptor { - return permissionByOp[operationId] -} +package permissions + +const ( + fsArnPrefix = "arn:lakefs:fs:::" + authArnPrefix = "arn:lakefs:auth:::" + + All = "*" +) + +type Permission struct { + Action string + Resource string +} + +type NodeType int + +const ( + NodeTypeNode NodeType = iota + NodeTypeOr + NodeTypeAnd +) + +type Node struct { + Type NodeType + Permission Permission + Nodes []Node +} + +func RepoArn(repoID string) string { + return fsArnPrefix + "repository/" + repoID +} + +func StorageNamespace(namespace string) string { + return fsArnPrefix + "namespace/" + namespace +} + +func ObjectArn(repoID, key string) string { + return fsArnPrefix + "repository/" + repoID + "/object/" + key +} + +func BranchArn(repoID, branchID string) string { + return fsArnPrefix + "repository/" + repoID + "/branch/" + branchID +} + +func TagArn(repoID, tagID string) string { + return fsArnPrefix + "repository/" + repoID + "/tag/" + tagID +} + +func UserArn(userID string) string { + return authArnPrefix + "user/" + userID +} + +func GroupArn(groupID string) string { + return authArnPrefix + "group/" + groupID +} + +func PolicyArn(policyID string) string { + return authArnPrefix + "policy/" + policyID +} + +func ExternalPrincipalArn(principalID string) string { + return authArnPrefix + "externalPrincipal/" + principalID +} + +type PermissionParams struct { + Repository *string + Path *string + Branch *string +} + +type PermissionDescriptor interface { + Permission(PermissionParams) Node +} + +type ObjectPermission struct { + Action string +} + +func (o *ObjectPermission) Permission(params PermissionParams) Node { + return Node{ + Permission: Permission{ + Action: o.Action, + Resource: ObjectArn(*params.Repository, *params.Path), + }, + } +} + +type BranchPermission struct { + Action string +} + +func (o *BranchPermission) Permission(params PermissionParams) Node { + return Node{ + Permission: Permission{ + Action: o.Action, + Resource: ObjectArn(*params.Repository, *params.Branch), + }, + } +} + +type RepoPermission struct { + Action string +} + +func (r *RepoPermission) Permission(params PermissionParams) Node { + return Node{ + Permission: Permission{ + Action: r.Action, + Resource: RepoArn(*params.Repository), + }, + } +} + +var readObjectPermission = ObjectPermission{Action: ReadObjectAction} +var writeObjectPermission = ObjectPermission{Action: WriteObjectAction} +var createBranchPermission = BranchPermission{Action: CreateBranchAction} +var deleteBranchPermission = BranchPermission{Action: DeleteBranchAction} +var readBranchPermission = BranchPermission{Action: ReadBranchAction} +var revertBranchPermission = BranchPermission{Action: RevertBranchAction} +var createCommitPermission = BranchPermission{Action: CreateCommitAction} +var importCancelPermission = BranchPermission{Action: ImportCancelAction} +var prepareGCUncommittedPermission = RepoPermission{Action: PrepareGarbageCollectionUncommittedAction} +var getGCRulesPermission = RepoPermission{Action: GetGarbageCollectionRulesAction} +var setGCRulesPermission = RepoPermission{Action: SetGarbageCollectionRulesAction} +var prepareGCCommitsPermission = RepoPermission{Action: PrepareGarbageCollectionCommitsAction} +var readRepositoryPermission = RepoPermission{Action: ReadRepositoryAction} +var updateRepositoryPermission = RepoPermission{Action: UpdateRepositoryAction} +var deleteRepositoryPermission = RepoPermission{Action: DeleteRepositoryAction} +var writePullRequestPermission = RepoPermission{Action: WritePullRequestAction} +var listPullRequestsPermission = RepoPermission{Action: ListPullRequestsAction} +var readPullRequestPermission = RepoPermission{Action: ReadPullRequestAction} +var listBranchesPermission = RepoPermission{Action: ListBranchesAction} +var listTagsPermission = RepoPermission{Action: ListTagsAction} +var listObjectsPermission = RepoPermission{Action: ListObjectsAction} +var readCommitPermission = RepoPermission{Action: ReadCommitAction} +var listCommitsPermission = RepoPermission{Action: ListCommitsAction} +var createCommitRepoPermission = RepoPermission{Action: CreateCommitAction} +var getBranchProtectionRulesPermission = RepoPermission{Action: GetBranchProtectionRulesAction} +var setBranchProtectionRulesPermission = RepoPermission{Action: SetBranchProtectionRulesAction} +var readActionsPermission = RepoPermission{Action: ReadActionsAction} + +var permissionByOp = map[string]PermissionDescriptor{ + "HeadObject": &readObjectPermission, + "GetObject": &readObjectPermission, + "StatObject": &readObjectPermission, + "GetUnderlyingProperties": &readObjectPermission, + "StageObject": &writeObjectPermission, + "CreateSymlinkFile": &writeObjectPermission, + "UpdateObjectUserMetadata": &writeObjectPermission, + "UploadObject": &writeObjectPermission, + "UploadObjectPreflight": &writeObjectPermission, + "CreateBranch": &createBranchPermission, + "DeleteBranch": &deleteBranchPermission, + "GetBranch": &readBranchPermission, + "RevertBranch": &revertBranchPermission, + "LogCommits": &readBranchPermission, + "ResetBranch": &revertBranchPermission, + "MergeIntoBranch": &createCommitPermission, + "HardResetBranch": &revertBranchPermission, + "ImportStatus": &readBranchPermission, + "Commit": &createCommitPermission, + "ImportCancel": &importCancelPermission, + "PrepareGarbageCollectionUncommitted": &prepareGCUncommittedPermission, + "GetGCRules": &getGCRulesPermission, + "SetGCRules": &setGCRulesPermission, + "DeleteGCRules": &setGCRulesPermission, + "SetGarbageCollectionRulesPreflight": &setGCRulesPermission, + "PrepareGarbageCollectionCommits": &prepareGCCommitsPermission, + "GetRepository": &readRepositoryPermission, + "GetRepositoryMetadata": &readRepositoryPermission, + "SetRepositoryMetadata": &updateRepositoryPermission, + "DeleteRepositoryMetadata": &updateRepositoryPermission, + "DeleteRepository": &deleteRepositoryPermission, + "UpdatePullRequest": &writePullRequestPermission, + "CreatePullRequest": &writePullRequestPermission, + "ListPullRequests": &listPullRequestsPermission, + "GetPullRequest": &readPullRequestPermission, + "ListBranches": &listBranchesPermission, + "ListTags": &listTagsPermission, + "ListObjects": &listObjectsPermission, + "GetCommit": &readCommitPermission, + "FindMergeBase": &listCommitsPermission, + "CreateCommitRecord": &createCommitRepoPermission, + "DiffBranch": &listObjectsPermission, + "DiffRefs": &listObjectsPermission, + "GetBranchProtectionRules": &getBranchProtectionRulesPermission, + "SetBranchProtectionRules": &setBranchProtectionRulesPermission, + "InternalCreateBranchProtectionRule": &setBranchProtectionRulesPermission, + "CreateBranchProtectionRulePreflight": &setBranchProtectionRulesPermission, + "InternalDeleteBranchProtectionRule": &setBranchProtectionRulesPermission, + "ListRepositoryRuns": &readActionsPermission, + "GetRun": &readActionsPermission, + "ListRunHooks": &readActionsPermission, + "GetRunHookOutput": &readActionsPermission, +} + +func GetPermissionDescriptor(operationId string) PermissionDescriptor { + return permissionByOp[operationId] +}