mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-29 00:10:42 +01:00
feat(iam): implement group inline policy actions (#8992)
* feat(iam): implement group inline policy actions Add PutGroupPolicy, GetGroupPolicy, DeleteGroupPolicy, and ListGroupPolicies to both embedded and standalone IAM servers. The standalone IAM stores group inline policies in a new GroupInlinePolicies field in the Policies JSON, mirroring the existing user inline policy pattern. DeleteGroup now also checks for inline policies before allowing deletion. * fix: address review feedback for group inline policies - Embedded IAM: return NotImplemented for group inline policies instead of silently succeeding as no-ops (Gemini + CodeRabbit) - Standalone IAM: recompute member actions after PutGroupPolicy and DeleteGroupPolicy (Gemini) - Add parameter validation for GroupName/PolicyName/PolicyDocument on PutGroupPolicy, DeleteGroupPolicy, ListGroupPolicies (Gemini) - Add UserName validation for ListUserPolicies in standalone IAM - Call cleanupGroupInlinePolicies from DeleteGroup (Gemini) - Migrate GroupInlinePolicies on group rename in UpdateGroup (CodeRabbit) - Fix integration test cleanup order (CodeRabbit) * fix: persist recomputed actions and improve error handling - Set changed=true for PutGroupPolicy/DeleteGroupPolicy in standalone IAM DoActions so recomputed member actions are persisted (Gemini critical) - Make cleanupGroupInlinePolicies accept policies parameter to avoid redundant I/O, return error (Gemini) - Make migrateGroupInlinePolicies return error, handle in caller (Gemini) * fix: include group policies in action recomputation Extend computeAllActionsForUser to also aggregate group inline policies and group managed policies when s3cfg is provided. Previously, group inline policies were stored but never reflected in member Identity.Actions. (CodeRabbit critical) * perf: use identity index in recomputeActionsForGroupMembers for O(N+M) * fix: skip group inline policy integration test on embedded IAM The embedded IAM returns NotImplemented for group inline policies. Skip TestIAMGroupInlinePolicy when running against embedded mode to avoid CI failures in the group integration test matrix.
This commit is contained in:
1 parent
3af571a5f3
commit
e21d7602c3
7 files changed
+573
-10
No files matched your search
@@ -125,6 +125,10 @@ type (
|
||||
iamAttachGroupPolicyResponse = iamlib.AttachGroupPolicyResponse
|
||||
iamDetachGroupPolicyResponse = iamlib.DetachGroupPolicyResponse
|
||||
iamListAttachedGroupPoliciesResponse = iamlib.ListAttachedGroupPoliciesResponse
|
||||
iamPutGroupPolicyResponse = iamlib.PutGroupPolicyResponse
|
||||
iamGetGroupPolicyResponse = iamlib.GetGroupPolicyResponse
|
||||
iamDeleteGroupPolicyResponse = iamlib.DeleteGroupPolicyResponse
|
||||
iamListGroupPoliciesResponse = iamlib.ListGroupPoliciesResponse
|
||||
iamListGroupsForUserResponse = iamlib.ListGroupsForUserResponse
|
||||
)
|
||||
|
||||
@@ -1771,6 +1775,31 @@ func (e *EmbeddedIamApi) ListGroupsForUser(s3cfg *iam_pb.S3ApiConfiguration, val
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// notImplementedError returns a NotImplemented IAM error for the embedded server.
|
||||
func notImplementedGroupInlineError() *iamError {
|
||||
return &iamError{Code: s3err.GetAPIError(s3err.ErrNotImplemented).Code, Error: fmt.Errorf("group inline policies are not supported in embedded IAM mode; use the standalone IAM server or managed policies (AttachGroupPolicy)")}
|
||||
}
|
||||
|
||||
// PutGroupPolicy is not supported in embedded IAM mode.
|
||||
func (e *EmbeddedIamApi) PutGroupPolicy(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (*iamPutGroupPolicyResponse, *iamError) {
|
||||
return &iamPutGroupPolicyResponse{}, notImplementedGroupInlineError()
|
||||
}
|
||||
|
||||
// GetGroupPolicy is not supported in embedded IAM mode.
|
||||
func (e *EmbeddedIamApi) GetGroupPolicy(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (*iamGetGroupPolicyResponse, *iamError) {
|
||||
return &iamGetGroupPolicyResponse{}, notImplementedGroupInlineError()
|
||||
}
|
||||
|
||||
// DeleteGroupPolicy is not supported in embedded IAM mode.
|
||||
func (e *EmbeddedIamApi) DeleteGroupPolicy(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (*iamDeleteGroupPolicyResponse, *iamError) {
|
||||
return &iamDeleteGroupPolicyResponse{}, notImplementedGroupInlineError()
|
||||
}
|
||||
|
||||
// ListGroupPolicies is not supported in embedded IAM mode.
|
||||
func (e *EmbeddedIamApi) ListGroupPolicies(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (*iamListGroupPoliciesResponse, *iamError) {
|
||||
return &iamListGroupPoliciesResponse{}, notImplementedGroupInlineError()
|
||||
}
|
||||
|
||||
// handleImplicitUsername adds username who signs the request to values if 'username' is not specified.
|
||||
// According to AWS documentation: "If you do not specify a user name, IAM determines the user name
|
||||
// implicitly based on the Amazon Web Services access key ID signing the request."
|
||||
@@ -1925,7 +1954,7 @@ func (e *EmbeddedIamApi) ExecuteAction(ctx context.Context, values url.Values, s
|
||||
if e.readOnly {
|
||||
switch action {
|
||||
case "ListUsers", "ListAccessKeys", "GetUser", "GetUserPolicy", "ListUserPolicies", "ListAttachedUserPolicies", "ListPolicies", "GetPolicy", "ListPolicyVersions", "GetPolicyVersion", "ListServiceAccounts", "GetServiceAccount",
|
||||
"GetGroup", "ListGroups", "ListAttachedGroupPolicies", "ListGroupsForUser":
|
||||
"GetGroup", "ListGroups", "ListAttachedGroupPolicies", "GetGroupPolicy", "ListGroupPolicies", "ListGroupsForUser":
|
||||
// Allowed read-only actions
|
||||
default:
|
||||
return nil, &iamError{Code: s3err.GetAPIError(s3err.ErrAccessDenied).Code, Error: fmt.Errorf("IAM write operations are disabled on this server")}
|
||||
@@ -2179,6 +2208,34 @@ func (e *EmbeddedIamApi) ExecuteAction(ctx context.Context, values url.Values, s
|
||||
return nil, iamErr
|
||||
}
|
||||
changed = false
|
||||
case "PutGroupPolicy":
|
||||
var iamErr *iamError
|
||||
response, iamErr = e.PutGroupPolicy(s3cfg, values)
|
||||
if iamErr != nil {
|
||||
return nil, iamErr
|
||||
}
|
||||
changed = false
|
||||
case "GetGroupPolicy":
|
||||
var iamErr *iamError
|
||||
response, iamErr = e.GetGroupPolicy(s3cfg, values)
|
||||
if iamErr != nil {
|
||||
return nil, iamErr
|
||||
}
|
||||
changed = false
|
||||
case "DeleteGroupPolicy":
|
||||
var iamErr *iamError
|
||||
response, iamErr = e.DeleteGroupPolicy(s3cfg, values)
|
||||
if iamErr != nil {
|
||||
return nil, iamErr
|
||||
}
|
||||
changed = false
|
||||
case "ListGroupPolicies":
|
||||
var iamErr *iamError
|
||||
response, iamErr = e.ListGroupPolicies(s3cfg, values)
|
||||
if iamErr != nil {
|
||||
return nil, iamErr
|
||||
}
|
||||
changed = false
|
||||
case "ListGroupsForUser":
|
||||
var iamErr *iamError
|
||||
response, iamErr = e.ListGroupsForUser(s3cfg, values)
|
||||
|
||||
Reference in new issue
Block a user