aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--weed/iamapi/iamapi_management_handlers.go167
1 files changed, 155 insertions, 12 deletions
diff --git a/weed/iamapi/iamapi_management_handlers.go b/weed/iamapi/iamapi_management_handlers.go
index a46a506f1..2347c9a80 100644
--- a/weed/iamapi/iamapi_management_handlers.go
+++ b/weed/iamapi/iamapi_management_handlers.go
@@ -2,44 +2,179 @@ package iamapi
import (
"encoding/xml"
+ "fmt"
"github.com/chrislusf/seaweedfs/weed/glog"
"github.com/chrislusf/seaweedfs/weed/pb/iam_pb"
"github.com/chrislusf/seaweedfs/weed/s3api/s3err"
+ "math/rand"
"net/http"
"net/url"
+ "time"
// "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/iam"
)
const (
- version = "2010-05-08"
+ version = "2010-05-08"
+ charsetUpper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
+ charset = charsetUpper + "abcdefghijklmnopqrstuvwxyz/"
)
+var seededRand *rand.Rand = rand.New(
+ rand.NewSource(time.Now().UnixNano()))
+
+type Response interface {
+ SetRequestId()
+}
+
+type CommonResponse struct {
+ ResponseMetadata struct {
+ RequestId string `xml:"RequestId"`
+ } `xml:"ResponseMetadata"`
+}
+
type ListUsersResponse struct {
+ CommonResponse
XMLName xml.Name `xml:"https://iam.amazonaws.com/doc/2010-05-08/ ListUsersResponse"`
ListUsersResult struct {
Users []*iam.User `xml:"Users>member"`
IsTruncated bool `xml:"IsTruncated"`
} `xml:"ListUsersResult"`
- ResponseMetadata struct {
- RequestId string `xml:"RequestId"`
- } `xml:"ResponseMetadata"`
}
-// {'Action': 'CreateUser', 'Version': '2010-05-08', 'UserName': 'Bob'}
-// {'Action': 'ListUsers', 'Version': '2010-05-08'}
-func (iama *IamApiServer) ListUsers(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) ListUsersResponse {
- glog.Info("Do ListUsers")
- resp := ListUsersResponse{}
+type ListAccessKeysResponse struct {
+ CommonResponse
+ XMLName xml.Name `xml:"https://iam.amazonaws.com/doc/2010-05-08/ ListAccessKeysResponse"`
+ ListAccessKeysResult struct {
+ AccessKeyMetadata []*iam.AccessKeyMetadata `xml:"AccessKeyMetadata>member"`
+ IsTruncated bool `xml:"IsTruncated"`
+ } `xml:"ListAccessKeysResult"`
+}
+
+type DeleteUserResponse struct {
+ CommonResponse
+ XMLName xml.Name `xml:"https://iam.amazonaws.com/doc/2010-05-08/ DeleteUserResponse"`
+}
+
+type DeleteAccessKeyResponse struct {
+ CommonResponse
+ XMLName xml.Name `xml:"https://iam.amazonaws.com/doc/2010-05-08/ DeleteAccessKeyResponse"`
+}
+
+type CreateUserResponse struct {
+ CommonResponse
+ XMLName xml.Name `xml:"https://iam.amazonaws.com/doc/2010-05-08/ CreateUserResponse"`
+ CreateUserResult struct {
+ User iam.User `xml:"User"`
+ } `xml:"CreateUserResult"`
+}
+
+type CreateAccessKeyResponse struct {
+ CommonResponse
+ XMLName xml.Name `xml:"https://iam.amazonaws.com/doc/2010-05-08/ CreateAccessKeyResponse"`
+ CreateAccessKeyResult struct {
+ AccessKey iam.AccessKey `xml:"AccessKey"`
+ } `xml:"CreateAccessKeyResult"`
+}
+
+func (r *CommonResponse) SetRequestId() {
+ r.ResponseMetadata.RequestId = fmt.Sprintf("%d", time.Now().UnixNano())
+}
+
+func StringWithCharset(length int, charset string) string {
+ b := make([]byte, length)
+ for i := range b {
+ b[i] = charset[seededRand.Intn(len(charset))]
+ }
+ return string(b)
+}
+
+func (iama *IamApiServer) ListUsers(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (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(values url.Values) ListUsersResponse {
- return ListUsersResponse{}
+func (iama *IamApiServer) ListAccessKeys(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp ListAccessKeysResponse) {
+ status := iam.StatusTypeActive
+ for _, ident := range s3cfg.Identities {
+ for _, cred := range ident.Credentials {
+ resp.ListAccessKeysResult.AccessKeyMetadata = append(resp.ListAccessKeysResult.AccessKeyMetadata,
+ &iam.AccessKeyMetadata{UserName: &ident.Name, AccessKeyId: &cred.AccessKey, Status: &status},
+ )
+ }
+ }
+ return resp
+}
+
+func (iama *IamApiServer) CreateUser(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (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, values url.Values) (resp DeleteUserResponse) {
+ userName := values.Get("UserName")
+ for i, ident := range s3cfg.Identities {
+ if userName == ident.Name {
+ ident.Credentials = append(ident.Credentials[:i], ident.Credentials[i+1:]...)
+ break
+ }
+ }
+ return resp
+}
+
+func (iama *IamApiServer) CreateAccessKey(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp CreateAccessKeyResponse) {
+ userName := values.Get("UserName")
+ status := iam.StatusTypeActive
+ accessKeyId := StringWithCharset(21, charsetUpper)
+ secretAccessKey := StringWithCharset(42, charset)
+ resp.CreateAccessKeyResult.AccessKey.AccessKeyId = &accessKeyId
+ resp.CreateAccessKeyResult.AccessKey.SecretAccessKey = &secretAccessKey
+ resp.CreateAccessKeyResult.AccessKey.UserName = &userName
+ resp.CreateAccessKeyResult.AccessKey.Status = &status
+ changed := false
+ for _, ident := range s3cfg.Identities {
+ if userName == ident.Name {
+ ident.Credentials = append(ident.Credentials,
+ &iam_pb.Credential{AccessKey: accessKeyId, SecretKey: secretAccessKey})
+ changed = true
+ break
+ }
+ }
+ if !changed {
+ s3cfg.Identities = append(s3cfg.Identities,
+ &iam_pb.Identity{Name: userName,
+ Credentials: []*iam_pb.Credential{
+ {
+ AccessKey: accessKeyId,
+ SecretKey: secretAccessKey,
+ },
+ },
+ },
+ )
+ }
+ return resp
+}
+
+func (iama *IamApiServer) DeleteAccessKey(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp DeleteAccessKeyResponse) {
+ userName := values.Get("UserName")
+ accessKeyId := values.Get("AccessKeyId")
+ for _, ident := range s3cfg.Identities {
+ if userName == ident.Name {
+ for i, cred := range ident.Credentials {
+ if cred.AccessKey == accessKeyId {
+ ident.Credentials = append(ident.Credentials[:i], ident.Credentials[i+1:]...)
+ break
+ }
+ }
+ break
+ }
+ }
+ return resp
}
func (iama *IamApiServer) DoActions(w http.ResponseWriter, r *http.Request) {
@@ -60,7 +195,15 @@ func (iama *IamApiServer) DoActions(w http.ResponseWriter, r *http.Request) {
case "ListUsers":
response = iama.ListUsers(s3cfg, values)
case "ListAccessKeys":
- response = iama.ListAccessKeys(values)
+ response = iama.ListAccessKeys(s3cfg, values)
+ case "CreateUser":
+ response = iama.CreateUser(s3cfg, values)
+ case "DeleteUser":
+ response = iama.DeleteUser(s3cfg, values)
+ case "CreateAccessKey":
+ response = iama.CreateAccessKey(s3cfg, values)
+ case "DeleteAccessKey":
+ response = iama.DeleteAccessKey(s3cfg, values)
default:
writeErrorResponse(w, s3err.ErrNotImplemented, r.URL)
return