mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-24 15:00:43 +02:00
iam: GetUserPolicy returns NoSuchEntity for a policy name the user does not have (#11944)
* iam: GetUserPolicy returns NoSuchEntity for a policy name the user does not have When the user has stored inline policies, an unknown name fell through to the policy rebuilt from the user's actions, so a deleted policy still read back. The standalone IAM server already returns NoSuchEntity here. * iam: return service failure when listing inline policies fails A ListUserInlinePolicies error in GetUserPolicy fell through to action-based reconstruction, masking a store failure as a policy document. Propagate it as ServiceFailureException instead, matching the standalone iam server and the other callers in this file. * iam: return service failure when the inline policy store read fails --------- Co-authored-by: chrislusf <chrislusf@users.noreply.github.com> Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
2 files changed
+60
-2
No files matched your search
@@ -1291,9 +1291,9 @@ func (e *EmbeddedIamApi) GetUserPolicy(s3cfg *iam_pb.S3ApiConfiguration, values
|
||||
ctx := context.Background()
|
||||
storedDoc, storeErr := e.credentialManager.GetUserInlinePolicy(ctx, userName, policyName)
|
||||
if storeErr != nil {
|
||||
glog.Warningf("GetUserPolicy: failed to read stored inline policy %q for user %s: %v; falling back to reconstruction", policyName, userName, storeErr)
|
||||
return resp, &iamError{Code: iam.ErrCodeServiceFailureException, Error: fmt.Errorf("get inline policy %s for %s: %w", policyName, userName, storeErr)}
|
||||
}
|
||||
if storeErr == nil && storedDoc != nil {
|
||||
if storedDoc != nil {
|
||||
policyDocumentJSON, err := json.Marshal(storedDoc)
|
||||
if err != nil {
|
||||
return resp, &iamError{Code: iam.ErrCodeServiceFailureException, Error: err}
|
||||
@@ -1301,6 +1301,14 @@ func (e *EmbeddedIamApi) GetUserPolicy(s3cfg *iam_pb.S3ApiConfiguration, values
|
||||
resp.GetUserPolicyResult.PolicyDocument = string(policyDocumentJSON)
|
||||
return resp, nil
|
||||
}
|
||||
// The user has stored inline policies, but none by this name
|
||||
policyNames, err := e.credentialManager.ListUserInlinePolicies(ctx, userName)
|
||||
if err != nil {
|
||||
return resp, &iamError{Code: iam.ErrCodeServiceFailureException, Error: fmt.Errorf("list inline policies for %s: %w", userName, err)}
|
||||
}
|
||||
if len(policyNames) > 0 {
|
||||
return resp, &iamError{Code: iam.ErrCodeNoSuchEntityException, Error: fmt.Errorf("the user policy with name %s cannot be found", policyName)}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: reconstruct from ident.Actions (lossy - fine-grained actions
|
||||
|
||||
@@ -1979,6 +1979,56 @@ func TestEmbeddedIamGetUserPolicyFallback(t *testing.T) {
|
||||
assert.ElementsMatch(t, []string{"arn:aws:s3:::b-le*", "arn:aws:s3:::b-le*/*"}, stmt.Resource.Strings())
|
||||
}
|
||||
|
||||
// TestEmbeddedIamGetUserPolicyMissingName checks that a policy name the user does not have
|
||||
// is NoSuchEntity, not a policy rebuilt from the user's other inline policies.
|
||||
func TestEmbeddedIamGetUserPolicyMissingName(t *testing.T) {
|
||||
api := NewEmbeddedIamApiForTest()
|
||||
s3cfg := &iam_pb.S3ApiConfiguration{
|
||||
Identities: []*iam_pb.Identity{{Name: "steward"}},
|
||||
}
|
||||
api.mockConfig = s3cfg
|
||||
|
||||
_, iamErr := api.PutUserPolicy(s3cfg, url.Values{
|
||||
"UserName": []string{"steward"},
|
||||
"PolicyName": []string{"read"},
|
||||
"PolicyDocument": []string{`{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"s3:GetObject","Resource":"arn:aws:s3:::b/*"}]}`},
|
||||
})
|
||||
require.Nil(t, iamErr)
|
||||
|
||||
_, iamErr = api.GetUserPolicy(s3cfg, url.Values{
|
||||
"UserName": []string{"steward"},
|
||||
"PolicyName": []string{"write"},
|
||||
})
|
||||
require.NotNil(t, iamErr)
|
||||
assert.Equal(t, iam.ErrCodeNoSuchEntityException, iamErr.Code)
|
||||
}
|
||||
|
||||
// TestEmbeddedIamGetUserPolicyStoreError checks that a store failure surfaces as
|
||||
// ServiceFailure instead of rebuilding a policy from the identity's actions.
|
||||
func TestEmbeddedIamGetUserPolicyStoreError(t *testing.T) {
|
||||
api := NewEmbeddedIamApiForTest()
|
||||
s3cfg := &iam_pb.S3ApiConfiguration{
|
||||
Identities: []*iam_pb.Identity{{Name: "steward"}},
|
||||
}
|
||||
api.mockConfig = s3cfg
|
||||
|
||||
_, iamErr := api.PutUserPolicy(s3cfg, url.Values{
|
||||
"UserName": []string{"steward"},
|
||||
"PolicyName": []string{"read"},
|
||||
"PolicyDocument": []string{`{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"s3:GetObject","Resource":"arn:aws:s3:::b/*"}]}`},
|
||||
})
|
||||
require.Nil(t, iamErr)
|
||||
|
||||
api.credentialManager = &credential.CredentialManager{Store: &memory.MemoryStore{}}
|
||||
|
||||
_, iamErr = api.GetUserPolicy(s3cfg, url.Values{
|
||||
"UserName": []string{"steward"},
|
||||
"PolicyName": []string{"read"},
|
||||
})
|
||||
require.NotNil(t, iamErr)
|
||||
assert.Equal(t, iam.ErrCodeServiceFailureException, iamErr.Code)
|
||||
}
|
||||
|
||||
// TestEmbeddedIamGetUserPolicyUserNotFound tests GetUserPolicy with non-existent user
|
||||
func TestEmbeddedIamGetUserPolicyUserNotFound(t *testing.T) {
|
||||
api := NewEmbeddedIamApiForTest()
|
||||
|
||||
Reference in new issue
Block a user