-
Notifications
You must be signed in to change notification settings - Fork 0
Closed
Description
This issue tracks the implementation of the azdo security permission delete command.
Command Description
Delete every explicit allow/deny permission that a user or group has on a securable resource (identified by a security token). This removes the access control entry altogether so that only inherited permissions remain. The Azure CLI az devops security permission reset-all command issues the same deletion via RemoveAccessControlEntries (source); azdo should expose that behavior with an explicit delete verb to reflect its destructive effect.
azdo Command Signature
azdo security permission delete <TARGET>
Accepted <TARGET> formats (consistent with other security permission commands):
ORGANIZATION/SUBJECT– operate at the organization scope.ORGANIZATION/PROJECT/SUBJECT– scope the subject to a specific project.
Rules:
- The organization segment is mandatory. If a project segment is present, resolve it via
util.ResolveScopeDescriptorbefore invoking API calls. SUBJECTmust resolve to an Azure DevOps identity descriptor (UPN, descriptor string, group descriptor, etc.).
Flags:
--namespace-id,-n(required): GUID of the security namespace that owns the token.--token(required): Security token string to delete. Preserve the token verbatim apart from trimming surrounding whitespace.--yes,-y: Skip the confirmation prompt.
Behavior
- Parse
<TARGET>usingshared.ParseSubjectTarget; fail if the subject segment is missing. - Resolve IO streams, start the progress indicator immediately, and stop it before emitting output.
- Validate
--namespace-id; parse into auuid.UUIDor return a flag error. - When a project is specified, call
util.ResolveScopeDescriptorto ensure it exists and prime the cache. - Resolve the subject via
extensionsClient.ResolveIdentity; raise a wrapped error if the descriptor is empty or the lookup fails. - Unless
--yesis set, prompt viactx.Prompter()(e.g.,Delete permissions for <subject> on <token>?). Returnutil.ErrCancelwhen the user declines. - Call
securityClient.RemoveAccessControlEntrieswith:SecurityNamespaceId: pointer to the namespace UUID.Token: pointer to the trimmed token string.Descriptors: pointer to the resolved identity descriptor.
- Treat a nil or
falseresponse as a failure and surface a descriptive error message. - Afterwards, call
securityClient.QueryAccessControlListswithIncludeExtendedInfo=true,Descriptors=<descriptor>,Token=<token>to confirm the entry is gone. Usetypes.GetValuehelpers for pointer safety and to detect any remaining inherited data. - Stop the progress indicator.
- Output: print
Permissions deleted.toios.Out. Or an error otherwise. - Add debug logging with
zap.L().Debugstatements covering parsed scope, descriptor resolution, API inputs, and deletion outcomes.
Wiring & Docs
- Implement the command in
internal/cmd/security/permission/delete/delete.gousing the standardNewCmd+runCommandpattern. - Register it inside
internal/cmd/security/permission/permission.goviacmd.AddCommand(deletecmd.NewCmd(ctx))(choose an appropriate package alias such asdeletecmd). - Update help text and
Examplestrings to demonstrate confirmation,--yes, and project-scoped usage. - Run
make docsafter implementation to regenerate CLI documentation.
Testing
- Add table-driven unit tests in
internal/cmd/security/permission/delete/delete_test.gousing mocks frominternal/mocks. Cover at minimum:- Successful deletion (assert
RemoveAccessControlEntriesreceives the descriptor/token pair and the follow-up ACL query is invoked). - Input validation failures (missing subject, empty namespace ID, invalid GUID, empty token).
- Project-scoped targets ensuring
util.ResolveScopeDescriptoris called. - Confirmation flow (
--yesbypass vs prompt decline returningutil.ErrCancel). ResolveIdentityreturning an empty descriptor (should error).- JSON export path ensuring serialized output matches expectations.
- Successful deletion (assert
- Add an acceptance-style integration test (similar to
update_acc_test.go) if possible to verify end-to-end behavior against the mock harness.
References
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels