mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-09-20 23:14:21 +00:00
perf(s3.iam.GetUser): Make the API default to the request username if not specified (#9746)
* perf(s3.iam.GetUser): Make the API default to the request username if not specified This makes the Embedded S3 IAM API align with the documented behavior of the AWS IAM API as per AWS Docs: https://docs.aws.amazon.com/IAM/latest/APIReference/API_GetUser.html BREAKING CHANGE: This changes the default behavior of the Embedded IAM API to use the username of the user holding the accesskey used to make the request in the GetUsername request handler. * test: cover GetUser implicit username default --------- Co-authored-by: Chris Lu <chris.lu@gmail.com>
This commit is contained in:
@@ -2854,7 +2854,7 @@ func (e *EmbeddedIamApi) DoActions(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// Handle implicit username for HTTP requests
|
||||
switch r.Form.Get("Action") {
|
||||
case "ListAccessKeys", "CreateAccessKey", "DeleteAccessKey", "UpdateAccessKey", "ListUserPolicies":
|
||||
case "ListAccessKeys", "CreateAccessKey", "DeleteAccessKey", "UpdateAccessKey", "ListUserPolicies", "GetUser":
|
||||
e.handleImplicitUsername(r, values)
|
||||
case "CreateServiceAccount":
|
||||
createdBy := s3_constants.GetIdentityNameFromContext(r)
|
||||
|
||||
@@ -339,6 +339,46 @@ func TestEmbeddedIamGetUser(t *testing.T) {
|
||||
assert.Equal(t, "TestUser", *out.GetUserResult.User.UserName)
|
||||
}
|
||||
|
||||
// TestEmbeddedIamGetUserImplicitUsername verifies GetUser without a UserName defaults
|
||||
// to the user that signed the request rather than returning NoSuchEntity for an empty
|
||||
// username, matching documented AWS IAM behavior.
|
||||
func TestEmbeddedIamGetUserImplicitUsername(t *testing.T) {
|
||||
const accessKey = UserAccessKeyPrefix + "TESTFAKEKEY000001"
|
||||
|
||||
api := NewEmbeddedIamApiForTest()
|
||||
api.mockConfig = &iam_pb.S3ApiConfiguration{
|
||||
Identities: []*iam_pb.Identity{
|
||||
{
|
||||
Name: "TestUser",
|
||||
Credentials: []*iam_pb.Credential{
|
||||
{AccessKey: accessKey, SecretKey: "testsecretfake"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
// handleImplicitUsername resolves the username via iam.LookupByAccessKey,
|
||||
// so the iam state must know about the credential.
|
||||
if err := api.iam.LoadS3ApiConfigurationFromBytes(mustMarshalJSON(api.mockConfig)); err != nil {
|
||||
t.Fatalf("failed to load iam config: %v", err)
|
||||
}
|
||||
|
||||
// GetUser request with NO UserName, but signed by accessKey.
|
||||
form := url.Values{}
|
||||
form.Set("Action", "GetUser")
|
||||
req, _ := http.NewRequest(http.MethodPost, "/", strings.NewReader(form.Encode()))
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
req.Header.Set("Authorization", "AWS4-HMAC-SHA256 Credential="+accessKey+
|
||||
"/20220420/us-east-1/iam/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=fakesig")
|
||||
|
||||
out := iamGetUserResponse{}
|
||||
rr, err := executeEmbeddedIamRequest(api, req, &out)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusOK, rr.Code, "body=%s", rr.Body.String())
|
||||
|
||||
require.NotNil(t, out.GetUserResult.User.UserName)
|
||||
assert.Equal(t, "TestUser", *out.GetUserResult.User.UserName)
|
||||
}
|
||||
|
||||
// TestEmbeddedIamCreatePolicy tests creating a policy via the embedded IAM API
|
||||
func TestEmbeddedIamCreatePolicy(t *testing.T) {
|
||||
api := NewEmbeddedIamApiForTest()
|
||||
|
||||
Reference in New Issue
Block a user