aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Lebedev <lebedev_k@tochka.com>2021-03-29 12:01:44 +0500
committerKonstantin Lebedev <lebedev_k@tochka.com>2021-03-29 12:01:44 +0500
commit8a95f9c10c3d4c9e1f6761f5620da3e5253398f5 (patch)
tree7dc0d395515c7ab925ef8c8c89f182abff9c8fd0
parent40938d6a47136a47f612d7a4c93862ff5e17ec45 (diff)
downloadseaweedfs-8a95f9c10c3d4c9e1f6761f5620da3e5253398f5.tar.xz
seaweedfs-8a95f9c10c3d4c9e1f6761f5620da3e5253398f5.zip
iam GetUser
-rw-r--r--weed/command/filer.go25
-rw-r--r--weed/iamapi/iamapi_handlers.go18
-rw-r--r--weed/iamapi/iamapi_management_handlers.go119
-rw-r--r--weed/iamapi/iamapi_response.go93
4 files changed, 167 insertions, 88 deletions
diff --git a/weed/command/filer.go b/weed/command/filer.go
index 534bd9e04..b256e385f 100644
--- a/weed/command/filer.go
+++ b/weed/command/filer.go
@@ -25,6 +25,8 @@ var (
filerS3Options S3Options
filerStartWebDav *bool
filerWebDavOptions WebDavOption
+ filerStartIam *bool
+ filerIamOptions IamOptions
)
type FilerOptions struct {
@@ -89,6 +91,10 @@ func init() {
filerWebDavOptions.tlsCertificate = cmdFiler.Flag.String("webdav.cert.file", "", "path to the TLS certificate file")
filerWebDavOptions.cacheDir = cmdFiler.Flag.String("webdav.cacheDir", os.TempDir(), "local cache directory for file chunks")
filerWebDavOptions.cacheSizeMB = cmdFiler.Flag.Int64("webdav.cacheCapacityMB", 1000, "local cache capacity in MB")
+
+ // start iam on filer
+ filerStartIam = cmdFiler.Flag.Bool("iam", false, "whether to start IAM service")
+ filerIamOptions.port = cmdFiler.Flag.Int("iam.port", 8111, "iam server http listen port")
}
var cmdFiler = &Command{
@@ -119,22 +125,33 @@ func runFiler(cmd *Command, args []string) bool {
go stats_collect.StartMetricsServer(*f.metricsHttpPort)
+ filerAddress := fmt.Sprintf("%s:%d", *f.ip, *f.port)
+ startDelay := time.Duration(2)
if *filerStartS3 {
- filerAddress := fmt.Sprintf("%s:%d", *f.ip, *f.port)
filerS3Options.filer = &filerAddress
go func() {
- time.Sleep(2 * time.Second)
+ time.Sleep(startDelay * time.Second)
filerS3Options.startS3Server()
}()
+ startDelay++
}
if *filerStartWebDav {
- filerAddress := fmt.Sprintf("%s:%d", *f.ip, *f.port)
filerWebDavOptions.filer = &filerAddress
go func() {
- time.Sleep(2 * time.Second)
+ time.Sleep(startDelay * time.Second)
filerWebDavOptions.startWebDav()
}()
+ startDelay++
+ }
+
+ if *filerStartIam {
+ filerIamOptions.filer = &filerAddress
+ filerIamOptions.masters = f.masters
+ go func() {
+ time.Sleep(startDelay * time.Second)
+ filerIamOptions.startIamServer()
+ }()
}
f.startFiler()
diff --git a/weed/iamapi/iamapi_handlers.go b/weed/iamapi/iamapi_handlers.go
index c436ba998..962717ad9 100644
--- a/weed/iamapi/iamapi_handlers.go
+++ b/weed/iamapi/iamapi_handlers.go
@@ -12,6 +12,8 @@ import (
"github.com/chrislusf/seaweedfs/weed/glog"
"github.com/chrislusf/seaweedfs/weed/s3api/s3err"
+
+ "github.com/aws/aws-sdk-go/service/iam"
)
type mimeType string
@@ -48,6 +50,22 @@ func writeErrorResponse(w http.ResponseWriter, errorCode s3err.ErrorCode, reqURL
writeResponse(w, apiError.HTTPStatusCode, encodedErrorResponse, mimeXML)
}
+func writeIamErrorResponse(w http.ResponseWriter, err error, object string, value string) {
+ errCode := err.Error()
+ errorResp := ErrorResponse{}
+ errorResp.Error.Type = "Sender"
+ errorResp.Error.Code = &errCode
+ switch errCode {
+ case iam.ErrCodeNoSuchEntityException:
+ msg := fmt.Sprintf("The %s with name %s cannot be found.", object, value)
+ errorResp.Error.Message = &msg
+ writeResponse(w, http.StatusNotFound, encodeResponse(errorResp), mimeXML)
+ default:
+ writeResponse(w, http.StatusInternalServerError, encodeResponse(errorResp), mimeXML)
+
+ }
+}
+
func getRESTErrorResponse(err s3err.APIError, resource string) s3err.RESTErrorResponse {
return s3err.RESTErrorResponse{
Code: err.Code,
diff --git a/weed/iamapi/iamapi_management_handlers.go b/weed/iamapi/iamapi_management_handlers.go
index 322c16d73..e4daa081f 100644
--- a/weed/iamapi/iamapi_management_handlers.go
+++ b/weed/iamapi/iamapi_management_handlers.go
@@ -4,7 +4,6 @@ import (
"bytes"
"crypto/sha1"
"encoding/json"
- "encoding/xml"
"fmt"
"github.com/chrislusf/seaweedfs/weed/filer"
"github.com/chrislusf/seaweedfs/weed/glog"
@@ -19,12 +18,10 @@ import (
"strings"
"time"
- // "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/iam"
)
const (
- version = "2010-05-08"
charsetUpper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
charset = charsetUpper + "abcdefghijklmnopqrstuvwxyz/"
)
@@ -44,73 +41,6 @@ type PolicyDocument struct {
} `json:"Statement"`
}
-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"`
-}
-
-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 CreatePolicyResponse struct {
- CommonResponse
- XMLName xml.Name `xml:"https://iam.amazonaws.com/doc/2010-05-08/ CreatePolicyResponse"`
- CreatePolicyResult struct {
- Policy iam.Policy `xml:"Policy"`
- } `xml:"CreatePolicyResult"`
-}
-
-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"`
-}
-
-type PutUserPolicyResponse struct {
- CommonResponse
- XMLName xml.Name `xml:"https://iam.amazonaws.com/doc/2010-05-08/ PutUserPolicyResponse"`
-}
-
-func (r *CommonResponse) SetRequestId() {
- r.ResponseMetadata.RequestId = fmt.Sprintf("%d", time.Now().UnixNano())
-}
-
func Hash(s *string) string {
h := sha1.New()
h.Write([]byte(*s))
@@ -150,6 +80,27 @@ func (iama *IamApiServer) CreateUser(s3cfg *iam_pb.S3ApiConfiguration, values ur
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 error) {
+ for i, ident := range s3cfg.Identities {
+ if userName == ident.Name {
+ ident.Credentials = append(ident.Credentials[:i], ident.Credentials[i+1:]...)
+ return resp, nil
+ }
+ }
+ return resp, fmt.Errorf(iam.ErrCodeNoSuchEntityException)
+}
+
+func (iama *IamApiServer) GetUser(s3cfg *iam_pb.S3ApiConfiguration, userName string) (resp GetUserResponse, err error) {
+ for _, ident := range s3cfg.Identities {
+ if userName == ident.Name {
+ resp.GetUserResult.User = iam.User{UserName: &ident.Name}
+ return resp, nil
+ }
+ }
+ return resp, fmt.Errorf(iam.ErrCodeNoSuchEntityException)
+}
+
func GetPolicyDocument(policy *string) (policyDocument PolicyDocument, err error) {
if err = json.Unmarshal([]byte(*policy), &policyDocument); err != nil {
return PolicyDocument{}, err
@@ -245,17 +196,6 @@ func GetActions(policy *PolicyDocument) (actions []string) {
return actions
}
-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
@@ -320,6 +260,7 @@ func (iama *IamApiServer) DoActions(w http.ResponseWriter, r *http.Request) {
glog.Info("values ", values)
var response interface{}
+ var err error
changed := true
switch r.Form.Get("Action") {
case "ListUsers":
@@ -330,21 +271,31 @@ func (iama *IamApiServer) DoActions(w http.ResponseWriter, r *http.Request) {
changed = false
case "CreateUser":
response = iama.CreateUser(s3cfg, values)
+ case "GetUser":
+ userName := values.Get("UserName")
+ response, err = iama.GetUser(s3cfg, userName)
+ if err != nil {
+ writeIamErrorResponse(w, err, "user", userName)
+ return
+ }
case "DeleteUser":
- response = iama.DeleteUser(s3cfg, values)
+ userName := values.Get("UserName")
+ response, err = iama.DeleteUser(s3cfg, userName)
+ if err != nil {
+ writeIamErrorResponse(w, err, "user", userName)
+ return
+ }
case "CreateAccessKey":
response = iama.CreateAccessKey(s3cfg, values)
case "DeleteAccessKey":
response = iama.DeleteAccessKey(s3cfg, values)
case "CreatePolicy":
- var err error
response, err = iama.CreatePolicy(s3cfg, values)
if err != nil {
writeErrorResponse(w, s3err.ErrInvalidRequest, r.URL)
return
}
case "PutUserPolicy":
- var err error
response, err = iama.PutUserPolicy(s3cfg, values)
if err != nil {
writeErrorResponse(w, s3err.ErrInvalidRequest, r.URL)
diff --git a/weed/iamapi/iamapi_response.go b/weed/iamapi/iamapi_response.go
new file mode 100644
index 000000000..26dd0f263
--- /dev/null
+++ b/weed/iamapi/iamapi_response.go
@@ -0,0 +1,93 @@
+package iamapi
+
+import (
+ "encoding/xml"
+ "fmt"
+ "time"
+
+ "github.com/aws/aws-sdk-go/service/iam"
+)
+
+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"`
+}
+
+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 DeleteAccessKeyResponse struct {
+ CommonResponse
+ XMLName xml.Name `xml:"https://iam.amazonaws.com/doc/2010-05-08/ DeleteAccessKeyResponse"`
+}
+
+type CreatePolicyResponse struct {
+ CommonResponse
+ XMLName xml.Name `xml:"https://iam.amazonaws.com/doc/2010-05-08/ CreatePolicyResponse"`
+ CreatePolicyResult struct {
+ Policy iam.Policy `xml:"Policy"`
+ } `xml:"CreatePolicyResult"`
+}
+
+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 DeleteUserResponse struct {
+ CommonResponse
+ XMLName xml.Name `xml:"https://iam.amazonaws.com/doc/2010-05-08/ DeleteUserResponse"`
+}
+
+type GetUserResponse struct {
+ CommonResponse
+ XMLName xml.Name `xml:"https://iam.amazonaws.com/doc/2010-05-08/ GetUserResponse"`
+ GetUserResult struct {
+ User iam.User `xml:"User"`
+ } `xml:"GetUserResult"`
+}
+
+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"`
+}
+
+type PutUserPolicyResponse struct {
+ CommonResponse
+ XMLName xml.Name `xml:"https://iam.amazonaws.com/doc/2010-05-08/ PutUserPolicyResponse"`
+}
+
+type ErrorResponse struct {
+ CommonResponse
+ XMLName xml.Name `xml:"https://iam.amazonaws.com/doc/2010-05-08/ ErrorResponse"`
+ Error struct {
+ iam.ErrorDetails
+ Type string `xml:"Type"`
+ } `xml:"Error"`
+}
+
+func (r *CommonResponse) SetRequestId() {
+ r.ResponseMetadata.RequestId = fmt.Sprintf("%d", time.Now().UnixNano())
+}