|
|
|
|
@@ -19,6 +19,7 @@ import (
|
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/pb/iam_pb"
|
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/s3api/policy_engine"
|
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/s3api/s3err"
|
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/util/request_id"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Constants from shared package
|
|
|
|
|
@@ -162,14 +163,16 @@ func validateAccessKeyStatus(status string) error {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (iama *IamApiServer) ListUsers(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp ListUsersResponse) {
|
|
|
|
|
func (iama *IamApiServer) ListUsers(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp *ListUsersResponse) {
|
|
|
|
|
resp = &ListUsersResponse{}
|
|
|
|
|
for _, ident := range s3cfg.Identities {
|
|
|
|
|
resp.ListUsersResult.Users = append(resp.ListUsersResult.Users, &iam.User{UserName: &ident.Name})
|
|
|
|
|
}
|
|
|
|
|
return resp
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (iama *IamApiServer) ListAccessKeys(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp ListAccessKeysResponse) {
|
|
|
|
|
func (iama *IamApiServer) ListAccessKeys(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp *ListAccessKeysResponse) {
|
|
|
|
|
resp = &ListAccessKeysResponse{}
|
|
|
|
|
userName := values.Get("UserName")
|
|
|
|
|
for _, ident := range s3cfg.Identities {
|
|
|
|
|
if userName != "" && userName != ident.Name {
|
|
|
|
|
@@ -190,16 +193,31 @@ func (iama *IamApiServer) ListAccessKeys(s3cfg *iam_pb.S3ApiConfiguration, value
|
|
|
|
|
return resp
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (iama *IamApiServer) CreateUser(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp CreateUserResponse) {
|
|
|
|
|
func (iama *IamApiServer) CreateUser(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp *CreateUserResponse) {
|
|
|
|
|
resp = &CreateUserResponse{}
|
|
|
|
|
userName := values.Get("UserName")
|
|
|
|
|
resp.CreateUserResult.User.UserName = &userName
|
|
|
|
|
s3cfg.Identities = append(s3cfg.Identities, &iam_pb.Identity{Name: userName})
|
|
|
|
|
return resp
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (iama *IamApiServer) DeleteUser(s3cfg *iam_pb.S3ApiConfiguration, userName string) (resp DeleteUserResponse, err *IamError) {
|
|
|
|
|
func (iama *IamApiServer) DeleteUser(s3cfg *iam_pb.S3ApiConfiguration, userName string) (resp *DeleteUserResponse, err *IamError) {
|
|
|
|
|
resp = &DeleteUserResponse{}
|
|
|
|
|
for i, ident := range s3cfg.Identities {
|
|
|
|
|
if userName == ident.Name {
|
|
|
|
|
// Clean up any inline policies stored for this user
|
|
|
|
|
policies := Policies{}
|
|
|
|
|
if pErr := iama.s3ApiConfig.GetPolicies(&policies); pErr != nil && !errors.Is(pErr, filer_pb.ErrNotFound) {
|
|
|
|
|
return resp, &IamError{Code: iam.ErrCodeServiceFailureException, Error: pErr}
|
|
|
|
|
}
|
|
|
|
|
if policies.InlinePolicies != nil {
|
|
|
|
|
if _, exists := policies.InlinePolicies[userName]; exists {
|
|
|
|
|
delete(policies.InlinePolicies, userName)
|
|
|
|
|
if pErr := iama.s3ApiConfig.PutPolicies(&policies); pErr != nil {
|
|
|
|
|
return resp, &IamError{Code: iam.ErrCodeServiceFailureException, Error: pErr}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
s3cfg.Identities = append(s3cfg.Identities[:i], s3cfg.Identities[i+1:]...)
|
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
@@ -207,7 +225,8 @@ func (iama *IamApiServer) DeleteUser(s3cfg *iam_pb.S3ApiConfiguration, userName
|
|
|
|
|
return resp, &IamError{Code: iam.ErrCodeNoSuchEntityException, Error: fmt.Errorf(USER_DOES_NOT_EXIST, userName)}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (iama *IamApiServer) GetUser(s3cfg *iam_pb.S3ApiConfiguration, userName string) (resp GetUserResponse, err *IamError) {
|
|
|
|
|
func (iama *IamApiServer) GetUser(s3cfg *iam_pb.S3ApiConfiguration, userName string) (resp *GetUserResponse, err *IamError) {
|
|
|
|
|
resp = &GetUserResponse{}
|
|
|
|
|
for _, ident := range s3cfg.Identities {
|
|
|
|
|
if userName == ident.Name {
|
|
|
|
|
resp.GetUserResult.User = iam.User{UserName: &ident.Name}
|
|
|
|
|
@@ -217,13 +236,28 @@ func (iama *IamApiServer) GetUser(s3cfg *iam_pb.S3ApiConfiguration, userName str
|
|
|
|
|
return resp, &IamError{Code: iam.ErrCodeNoSuchEntityException, Error: fmt.Errorf(USER_DOES_NOT_EXIST, userName)}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (iama *IamApiServer) UpdateUser(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp UpdateUserResponse, err *IamError) {
|
|
|
|
|
func (iama *IamApiServer) UpdateUser(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp *UpdateUserResponse, err *IamError) {
|
|
|
|
|
resp = &UpdateUserResponse{}
|
|
|
|
|
userName := values.Get("UserName")
|
|
|
|
|
newUserName := values.Get("NewUserName")
|
|
|
|
|
if newUserName != "" {
|
|
|
|
|
for _, ident := range s3cfg.Identities {
|
|
|
|
|
if userName == ident.Name {
|
|
|
|
|
ident.Name = newUserName
|
|
|
|
|
// Move any inline policies from old username to new username
|
|
|
|
|
policies := Policies{}
|
|
|
|
|
if pErr := iama.s3ApiConfig.GetPolicies(&policies); pErr != nil && !errors.Is(pErr, filer_pb.ErrNotFound) {
|
|
|
|
|
return resp, &IamError{Code: iam.ErrCodeServiceFailureException, Error: pErr}
|
|
|
|
|
}
|
|
|
|
|
if policies.InlinePolicies != nil {
|
|
|
|
|
if userPolicies, exists := policies.InlinePolicies[userName]; exists {
|
|
|
|
|
delete(policies.InlinePolicies, userName)
|
|
|
|
|
policies.InlinePolicies[newUserName] = userPolicies
|
|
|
|
|
if pErr := iama.s3ApiConfig.PutPolicies(&policies); pErr != nil {
|
|
|
|
|
return resp, &IamError{Code: iam.ErrCodeServiceFailureException, Error: pErr}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -241,12 +275,13 @@ func GetPolicyDocument(policy *string) (policy_engine.PolicyDocument, error) {
|
|
|
|
|
return policyDocument, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (iama *IamApiServer) CreatePolicy(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp CreatePolicyResponse, iamError *IamError) {
|
|
|
|
|
func (iama *IamApiServer) CreatePolicy(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp *CreatePolicyResponse, iamError *IamError) {
|
|
|
|
|
resp = &CreatePolicyResponse{}
|
|
|
|
|
policyName := values.Get("PolicyName")
|
|
|
|
|
policyDocumentString := values.Get("PolicyDocument")
|
|
|
|
|
policyDocument, err := GetPolicyDocument(&policyDocumentString)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return CreatePolicyResponse{}, &IamError{Code: iam.ErrCodeMalformedPolicyDocumentException, Error: err}
|
|
|
|
|
return resp, &IamError{Code: iam.ErrCodeMalformedPolicyDocumentException, Error: err}
|
|
|
|
|
}
|
|
|
|
|
policyId := Hash(&policyName)
|
|
|
|
|
arn := fmt.Sprintf("arn:aws:iam:::policy/%s", policyName)
|
|
|
|
|
@@ -274,16 +309,17 @@ type IamError struct {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// https://docs.aws.amazon.com/IAM/latest/APIReference/API_PutUserPolicy.html
|
|
|
|
|
func (iama *IamApiServer) PutUserPolicy(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp PutUserPolicyResponse, iamError *IamError) {
|
|
|
|
|
func (iama *IamApiServer) PutUserPolicy(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp *PutUserPolicyResponse, iamError *IamError) {
|
|
|
|
|
resp = &PutUserPolicyResponse{}
|
|
|
|
|
userName := values.Get("UserName")
|
|
|
|
|
policyName := values.Get("PolicyName")
|
|
|
|
|
policyDocumentString := values.Get("PolicyDocument")
|
|
|
|
|
policyDocument, err := GetPolicyDocument(&policyDocumentString)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return PutUserPolicyResponse{}, &IamError{Code: iam.ErrCodeMalformedPolicyDocumentException, Error: err}
|
|
|
|
|
return resp, &IamError{Code: iam.ErrCodeMalformedPolicyDocumentException, Error: err}
|
|
|
|
|
}
|
|
|
|
|
if _, err := GetActions(&policyDocument); err != nil {
|
|
|
|
|
return PutUserPolicyResponse{}, &IamError{Code: iam.ErrCodeMalformedPolicyDocumentException, Error: err}
|
|
|
|
|
return resp, &IamError{Code: iam.ErrCodeMalformedPolicyDocumentException, Error: err}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Verify the user exists before persisting the policy
|
|
|
|
|
@@ -295,20 +331,20 @@ func (iama *IamApiServer) PutUserPolicy(s3cfg *iam_pb.S3ApiConfiguration, values
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if targetIdent == nil {
|
|
|
|
|
return PutUserPolicyResponse{}, &IamError{Code: iam.ErrCodeNoSuchEntityException, Error: fmt.Errorf("the user with name %s cannot be found", userName)}
|
|
|
|
|
return resp, &IamError{Code: iam.ErrCodeNoSuchEntityException, Error: fmt.Errorf("the user with name %s cannot be found", userName)}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Persist inline policy to storage using per-user indexed structure
|
|
|
|
|
policies := Policies{}
|
|
|
|
|
if err = iama.s3ApiConfig.GetPolicies(&policies); err != nil && !errors.Is(err, filer_pb.ErrNotFound) {
|
|
|
|
|
return PutUserPolicyResponse{}, &IamError{Code: iam.ErrCodeServiceFailureException, Error: err}
|
|
|
|
|
return resp, &IamError{Code: iam.ErrCodeServiceFailureException, Error: err}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
userPolicies := policies.getOrCreateUserPolicies(userName)
|
|
|
|
|
userPolicies[policyName] = policyDocument
|
|
|
|
|
|
|
|
|
|
if err = iama.s3ApiConfig.PutPolicies(&policies); err != nil {
|
|
|
|
|
return PutUserPolicyResponse{}, &IamError{Code: iam.ErrCodeServiceFailureException, Error: err}
|
|
|
|
|
return resp, &IamError{Code: iam.ErrCodeServiceFailureException, Error: err}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Recompute aggregated actions (inline + managed)
|
|
|
|
|
@@ -321,7 +357,8 @@ func (iama *IamApiServer) PutUserPolicy(s3cfg *iam_pb.S3ApiConfiguration, values
|
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (iama *IamApiServer) GetUserPolicy(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp GetUserPolicyResponse, err *IamError) {
|
|
|
|
|
func (iama *IamApiServer) GetUserPolicy(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp *GetUserPolicyResponse, err *IamError) {
|
|
|
|
|
resp = &GetUserPolicyResponse{}
|
|
|
|
|
userName := values.Get("UserName")
|
|
|
|
|
policyName := values.Get("PolicyName")
|
|
|
|
|
for _, ident := range s3cfg.Identities {
|
|
|
|
|
@@ -404,7 +441,8 @@ func (iama *IamApiServer) GetUserPolicy(s3cfg *iam_pb.S3ApiConfiguration, values
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DeleteUserPolicy removes the inline policy from a user (clears their actions).
|
|
|
|
|
func (iama *IamApiServer) DeleteUserPolicy(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp DeleteUserPolicyResponse, err *IamError) {
|
|
|
|
|
func (iama *IamApiServer) DeleteUserPolicy(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp *DeleteUserPolicyResponse, err *IamError) {
|
|
|
|
|
resp = &DeleteUserPolicyResponse{}
|
|
|
|
|
userName := values.Get("UserName")
|
|
|
|
|
policyName := values.Get("PolicyName")
|
|
|
|
|
|
|
|
|
|
@@ -447,7 +485,8 @@ func (iama *IamApiServer) DeleteUserPolicy(s3cfg *iam_pb.S3ApiConfiguration, val
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetPolicy retrieves a managed policy by ARN.
|
|
|
|
|
func (iama *IamApiServer) GetPolicy(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp GetPolicyResponse, iamError *IamError) {
|
|
|
|
|
func (iama *IamApiServer) GetPolicy(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp *GetPolicyResponse, iamError *IamError) {
|
|
|
|
|
resp = &GetPolicyResponse{}
|
|
|
|
|
policyArn := values.Get("PolicyArn")
|
|
|
|
|
policyName, iamError := parsePolicyArn(policyArn)
|
|
|
|
|
if iamError != nil {
|
|
|
|
|
@@ -472,7 +511,8 @@ func (iama *IamApiServer) GetPolicy(s3cfg *iam_pb.S3ApiConfiguration, values url
|
|
|
|
|
|
|
|
|
|
// DeletePolicy removes a managed policy. Rejects deletion if the policy is still attached to any user
|
|
|
|
|
// (matching AWS IAM behavior: must detach before deleting).
|
|
|
|
|
func (iama *IamApiServer) DeletePolicy(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp DeletePolicyResponse, iamError *IamError) {
|
|
|
|
|
func (iama *IamApiServer) DeletePolicy(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp *DeletePolicyResponse, iamError *IamError) {
|
|
|
|
|
resp = &DeletePolicyResponse{}
|
|
|
|
|
policyArn := values.Get("PolicyArn")
|
|
|
|
|
policyName, iamError := parsePolicyArn(policyArn)
|
|
|
|
|
if iamError != nil {
|
|
|
|
|
@@ -509,7 +549,8 @@ func (iama *IamApiServer) DeletePolicy(s3cfg *iam_pb.S3ApiConfiguration, values
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ListPolicies lists all managed policies.
|
|
|
|
|
func (iama *IamApiServer) ListPolicies(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp ListPoliciesResponse, iamError *IamError) {
|
|
|
|
|
func (iama *IamApiServer) ListPolicies(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp *ListPoliciesResponse, iamError *IamError) {
|
|
|
|
|
resp = &ListPoliciesResponse{}
|
|
|
|
|
policies := Policies{}
|
|
|
|
|
if err := iama.s3ApiConfig.GetPolicies(&policies); err != nil && !errors.Is(err, filer_pb.ErrNotFound) {
|
|
|
|
|
return resp, &IamError{Code: iam.ErrCodeServiceFailureException, Error: err}
|
|
|
|
|
@@ -529,7 +570,8 @@ func (iama *IamApiServer) ListPolicies(s3cfg *iam_pb.S3ApiConfiguration, values
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// AttachUserPolicy attaches a managed policy to a user.
|
|
|
|
|
func (iama *IamApiServer) AttachUserPolicy(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp AttachUserPolicyResponse, iamError *IamError) {
|
|
|
|
|
func (iama *IamApiServer) AttachUserPolicy(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp *AttachUserPolicyResponse, iamError *IamError) {
|
|
|
|
|
resp = &AttachUserPolicyResponse{}
|
|
|
|
|
userName := values.Get("UserName")
|
|
|
|
|
policyArn := values.Get("PolicyArn")
|
|
|
|
|
policyName, iamError := parsePolicyArn(policyArn)
|
|
|
|
|
@@ -574,7 +616,8 @@ func (iama *IamApiServer) AttachUserPolicy(s3cfg *iam_pb.S3ApiConfiguration, val
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DetachUserPolicy detaches a managed policy from a user.
|
|
|
|
|
func (iama *IamApiServer) DetachUserPolicy(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp DetachUserPolicyResponse, iamError *IamError) {
|
|
|
|
|
func (iama *IamApiServer) DetachUserPolicy(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp *DetachUserPolicyResponse, iamError *IamError) {
|
|
|
|
|
resp = &DetachUserPolicyResponse{}
|
|
|
|
|
userName := values.Get("UserName")
|
|
|
|
|
policyArn := values.Get("PolicyArn")
|
|
|
|
|
policyName, iamError := parsePolicyArn(policyArn)
|
|
|
|
|
@@ -622,7 +665,8 @@ func (iama *IamApiServer) DetachUserPolicy(s3cfg *iam_pb.S3ApiConfiguration, val
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ListAttachedUserPolicies lists the managed policies attached to a user.
|
|
|
|
|
func (iama *IamApiServer) ListAttachedUserPolicies(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp ListAttachedUserPoliciesResponse, iamError *IamError) {
|
|
|
|
|
func (iama *IamApiServer) ListAttachedUserPolicies(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp *ListAttachedUserPoliciesResponse, iamError *IamError) {
|
|
|
|
|
resp = &ListAttachedUserPoliciesResponse{}
|
|
|
|
|
userName := values.Get("UserName")
|
|
|
|
|
for _, ident := range s3cfg.Identities {
|
|
|
|
|
if ident.Name != userName {
|
|
|
|
|
@@ -714,7 +758,8 @@ func GetActions(policy *policy_engine.PolicyDocument) ([]string, error) {
|
|
|
|
|
return actions, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (iama *IamApiServer) CreateAccessKey(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp CreateAccessKeyResponse, iamErr *IamError) {
|
|
|
|
|
func (iama *IamApiServer) CreateAccessKey(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp *CreateAccessKeyResponse, iamErr *IamError) {
|
|
|
|
|
resp = &CreateAccessKeyResponse{}
|
|
|
|
|
userName := values.Get("UserName")
|
|
|
|
|
status := iam.StatusTypeActive
|
|
|
|
|
|
|
|
|
|
@@ -758,7 +803,8 @@ func (iama *IamApiServer) CreateAccessKey(s3cfg *iam_pb.S3ApiConfiguration, valu
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UpdateAccessKey updates the status of an access key (Active or Inactive).
|
|
|
|
|
func (iama *IamApiServer) UpdateAccessKey(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp UpdateAccessKeyResponse, err *IamError) {
|
|
|
|
|
func (iama *IamApiServer) UpdateAccessKey(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp *UpdateAccessKeyResponse, err *IamError) {
|
|
|
|
|
resp = &UpdateAccessKeyResponse{}
|
|
|
|
|
userName := values.Get("UserName")
|
|
|
|
|
accessKeyId := values.Get("AccessKeyId")
|
|
|
|
|
status := values.Get("Status")
|
|
|
|
|
@@ -788,7 +834,8 @@ func (iama *IamApiServer) UpdateAccessKey(s3cfg *iam_pb.S3ApiConfiguration, valu
|
|
|
|
|
return resp, &IamError{Code: iam.ErrCodeNoSuchEntityException, Error: fmt.Errorf(USER_DOES_NOT_EXIST, userName)}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (iama *IamApiServer) DeleteAccessKey(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp DeleteAccessKeyResponse) {
|
|
|
|
|
func (iama *IamApiServer) DeleteAccessKey(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp *DeleteAccessKeyResponse) {
|
|
|
|
|
resp = &DeleteAccessKeyResponse{}
|
|
|
|
|
userName := values.Get("UserName")
|
|
|
|
|
accessKeyId := values.Get("AccessKeyId")
|
|
|
|
|
for _, ident := range s3cfg.Identities {
|
|
|
|
|
@@ -859,6 +906,8 @@ func (iama *IamApiServer) DoActions(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
policyLock.Lock()
|
|
|
|
|
defer policyLock.Unlock()
|
|
|
|
|
|
|
|
|
|
r, reqID := request_id.Ensure(r)
|
|
|
|
|
|
|
|
|
|
if err := r.ParseForm(); err != nil {
|
|
|
|
|
s3err.WriteErrorResponse(w, r, s3err.ErrInvalidRequest)
|
|
|
|
|
return
|
|
|
|
|
@@ -871,8 +920,7 @@ func (iama *IamApiServer) DoActions(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glog.V(4).Infof("DoActions: %+v", values)
|
|
|
|
|
var response interface{}
|
|
|
|
|
var iamError *IamError
|
|
|
|
|
var response iamlib.RequestIDSetter
|
|
|
|
|
changed := true
|
|
|
|
|
switch r.Form.Get("Action") {
|
|
|
|
|
case "ListUsers":
|
|
|
|
|
@@ -886,32 +934,35 @@ func (iama *IamApiServer) DoActions(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
response = iama.CreateUser(s3cfg, values)
|
|
|
|
|
case "GetUser":
|
|
|
|
|
userName := values.Get("UserName")
|
|
|
|
|
response, iamError = iama.GetUser(s3cfg, userName)
|
|
|
|
|
if iamError != nil {
|
|
|
|
|
writeIamErrorResponse(w, r, iamError)
|
|
|
|
|
var err *IamError
|
|
|
|
|
response, err = iama.GetUser(s3cfg, userName)
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeIamErrorResponse(w, r, reqID, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
changed = false
|
|
|
|
|
case "UpdateUser":
|
|
|
|
|
response, iamError = iama.UpdateUser(s3cfg, values)
|
|
|
|
|
if iamError != nil {
|
|
|
|
|
glog.Errorf("UpdateUser: %+v", iamError.Error)
|
|
|
|
|
s3err.WriteErrorResponse(w, r, s3err.ErrInvalidRequest)
|
|
|
|
|
var err *IamError
|
|
|
|
|
response, err = iama.UpdateUser(s3cfg, values)
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeIamErrorResponse(w, r, reqID, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
case "DeleteUser":
|
|
|
|
|
userName := values.Get("UserName")
|
|
|
|
|
response, iamError = iama.DeleteUser(s3cfg, userName)
|
|
|
|
|
if iamError != nil {
|
|
|
|
|
writeIamErrorResponse(w, r, iamError)
|
|
|
|
|
var err *IamError
|
|
|
|
|
response, err = iama.DeleteUser(s3cfg, userName)
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeIamErrorResponse(w, r, reqID, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
case "CreateAccessKey":
|
|
|
|
|
iama.handleImplicitUsername(r, values)
|
|
|
|
|
response, iamError = iama.CreateAccessKey(s3cfg, values)
|
|
|
|
|
if iamError != nil {
|
|
|
|
|
glog.Errorf("CreateAccessKey: %+v", iamError.Error)
|
|
|
|
|
writeIamErrorResponse(w, r, iamError)
|
|
|
|
|
var err *IamError
|
|
|
|
|
response, err = iama.CreateAccessKey(s3cfg, values)
|
|
|
|
|
if err != nil {
|
|
|
|
|
glog.Errorf("CreateAccessKey: %+v", err.Error)
|
|
|
|
|
writeIamErrorResponse(w, r, reqID, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
case "DeleteAccessKey":
|
|
|
|
|
@@ -919,85 +970,94 @@ func (iama *IamApiServer) DoActions(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
response = iama.DeleteAccessKey(s3cfg, values)
|
|
|
|
|
case "UpdateAccessKey":
|
|
|
|
|
iama.handleImplicitUsername(r, values)
|
|
|
|
|
response, iamError = iama.UpdateAccessKey(s3cfg, values)
|
|
|
|
|
if iamError != nil {
|
|
|
|
|
writeIamErrorResponse(w, r, iamError)
|
|
|
|
|
var err *IamError
|
|
|
|
|
response, err = iama.UpdateAccessKey(s3cfg, values)
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeIamErrorResponse(w, r, reqID, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
case "CreatePolicy":
|
|
|
|
|
response, iamError = iama.CreatePolicy(s3cfg, values)
|
|
|
|
|
if iamError != nil {
|
|
|
|
|
glog.Errorf("CreatePolicy: %+v", iamError.Error)
|
|
|
|
|
s3err.WriteErrorResponse(w, r, s3err.ErrInvalidRequest)
|
|
|
|
|
var err *IamError
|
|
|
|
|
response, err = iama.CreatePolicy(s3cfg, values)
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeIamErrorResponse(w, r, reqID, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
// CreatePolicy persists the policy document via iama.s3ApiConfig.PutPolicies().
|
|
|
|
|
// The `changed` flag is false because this does not modify the main s3cfg.Identities configuration.
|
|
|
|
|
changed = false
|
|
|
|
|
case "PutUserPolicy":
|
|
|
|
|
var iamError *IamError
|
|
|
|
|
response, iamError = iama.PutUserPolicy(s3cfg, values)
|
|
|
|
|
if iamError != nil {
|
|
|
|
|
glog.Errorf("PutUserPolicy: %+v", iamError.Error)
|
|
|
|
|
|
|
|
|
|
writeIamErrorResponse(w, r, iamError)
|
|
|
|
|
var err *IamError
|
|
|
|
|
response, err = iama.PutUserPolicy(s3cfg, values)
|
|
|
|
|
if err != nil {
|
|
|
|
|
glog.Errorf("PutUserPolicy: %+v", err.Error)
|
|
|
|
|
writeIamErrorResponse(w, r, reqID, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
case "GetUserPolicy":
|
|
|
|
|
response, iamError = iama.GetUserPolicy(s3cfg, values)
|
|
|
|
|
if iamError != nil {
|
|
|
|
|
writeIamErrorResponse(w, r, iamError)
|
|
|
|
|
var err *IamError
|
|
|
|
|
response, err = iama.GetUserPolicy(s3cfg, values)
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeIamErrorResponse(w, r, reqID, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
changed = false
|
|
|
|
|
case "DeleteUserPolicy":
|
|
|
|
|
if response, iamError = iama.DeleteUserPolicy(s3cfg, values); iamError != nil {
|
|
|
|
|
writeIamErrorResponse(w, r, iamError)
|
|
|
|
|
var err *IamError
|
|
|
|
|
response, err = iama.DeleteUserPolicy(s3cfg, values)
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeIamErrorResponse(w, r, reqID, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
case "GetPolicy":
|
|
|
|
|
response, iamError = iama.GetPolicy(s3cfg, values)
|
|
|
|
|
if iamError != nil {
|
|
|
|
|
writeIamErrorResponse(w, r, iamError)
|
|
|
|
|
var err *IamError
|
|
|
|
|
response, err = iama.GetPolicy(s3cfg, values)
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeIamErrorResponse(w, r, reqID, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
changed = false
|
|
|
|
|
case "DeletePolicy":
|
|
|
|
|
response, iamError = iama.DeletePolicy(s3cfg, values)
|
|
|
|
|
if iamError != nil {
|
|
|
|
|
writeIamErrorResponse(w, r, iamError)
|
|
|
|
|
var err *IamError
|
|
|
|
|
response, err = iama.DeletePolicy(s3cfg, values)
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeIamErrorResponse(w, r, reqID, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
changed = false
|
|
|
|
|
case "ListPolicies":
|
|
|
|
|
response, iamError = iama.ListPolicies(s3cfg, values)
|
|
|
|
|
if iamError != nil {
|
|
|
|
|
writeIamErrorResponse(w, r, iamError)
|
|
|
|
|
var err *IamError
|
|
|
|
|
response, err = iama.ListPolicies(s3cfg, values)
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeIamErrorResponse(w, r, reqID, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
changed = false
|
|
|
|
|
case "AttachUserPolicy":
|
|
|
|
|
response, iamError = iama.AttachUserPolicy(s3cfg, values)
|
|
|
|
|
if iamError != nil {
|
|
|
|
|
writeIamErrorResponse(w, r, iamError)
|
|
|
|
|
var err *IamError
|
|
|
|
|
response, err = iama.AttachUserPolicy(s3cfg, values)
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeIamErrorResponse(w, r, reqID, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
case "DetachUserPolicy":
|
|
|
|
|
response, iamError = iama.DetachUserPolicy(s3cfg, values)
|
|
|
|
|
if iamError != nil {
|
|
|
|
|
writeIamErrorResponse(w, r, iamError)
|
|
|
|
|
var err *IamError
|
|
|
|
|
response, err = iama.DetachUserPolicy(s3cfg, values)
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeIamErrorResponse(w, r, reqID, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
case "ListAttachedUserPolicies":
|
|
|
|
|
response, iamError = iama.ListAttachedUserPolicies(s3cfg, values)
|
|
|
|
|
if iamError != nil {
|
|
|
|
|
writeIamErrorResponse(w, r, iamError)
|
|
|
|
|
var err *IamError
|
|
|
|
|
response, err = iama.ListAttachedUserPolicies(s3cfg, values)
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeIamErrorResponse(w, r, reqID, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
changed = false
|
|
|
|
|
default:
|
|
|
|
|
errNotImplemented := s3err.GetAPIError(s3err.ErrNotImplemented)
|
|
|
|
|
errorResponse := newErrorResponse(errNotImplemented.Code, errNotImplemented.Description)
|
|
|
|
|
errorResponse := newErrorResponse(errNotImplemented.Code, errNotImplemented.Description, reqID)
|
|
|
|
|
s3err.WriteXMLResponse(w, r, errNotImplemented.HTTPStatusCode, errorResponse)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@@ -1005,7 +1065,7 @@ func (iama *IamApiServer) DoActions(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
err := iama.s3ApiConfig.PutS3ApiConfiguration(s3cfg)
|
|
|
|
|
if err != nil {
|
|
|
|
|
var iamError = IamError{Code: iam.ErrCodeServiceFailureException, Error: err}
|
|
|
|
|
writeIamErrorResponse(w, r, &iamError)
|
|
|
|
|
writeIamErrorResponse(w, r, reqID, &iamError)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
// Reload in-memory identity maps so subsequent LookupByAccessKey calls
|
|
|
|
|
@@ -1017,5 +1077,6 @@ func (iama *IamApiServer) DoActions(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
response.SetRequestId(reqID)
|
|
|
|
|
s3err.WriteXMLResponse(w, r, http.StatusOK, response)
|
|
|
|
|
}
|
|
|
|
|
|