From 87a44bfab6d5bd7ba88ae3d56c77e449fef5e1c6 Mon Sep 17 00:00:00 2001 From: Konstantin Lebedev Date: Tue, 8 Dec 2020 15:44:08 +0500 Subject: [PATCH] init Iam Api Server --- weed/command/iam.go | 5 +- weed/iamapi/iamapi_handlers.go | 4 ++ weed/iamapi/iamapi_management_handlers.go | 68 +++++++++++++++++++++++ weed/iamapi/iamapi_server.go | 7 ++- 4 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 weed/iamapi/iamapi_management_handlers.go diff --git a/weed/command/iam.go b/weed/command/iam.go index b985318ef..e7dc0d2a4 100644 --- a/weed/command/iam.go +++ b/weed/command/iam.go @@ -48,6 +48,7 @@ func (iamopt *IamOptions) startIamServer() bool { } grpcDialOption := security.LoadClientTLS(util.GetViper(), "grpc.client") + ifs := &iamapi.IAMFilerStore{} for { err = pb.WithGrpcFilerClient(filerGrpcAddress, grpcDialOption, func(client filer_pb.SeaweedFilerClient) error { resp, err := client.GetFilerConfiguration(context.Background(), &filer_pb.GetFilerConfigurationRequest{}) @@ -55,6 +56,7 @@ func (iamopt *IamOptions) startIamServer() bool { return fmt.Errorf("get filer %s configuration: %v", filerGrpcAddress, err) } glog.V(0).Infof("IAM read filer configuration: %s", resp) + ifs = iamapi.NewIAMFilerStore(&client) return nil }) if err != nil { @@ -72,8 +74,7 @@ func (iamopt *IamOptions) startIamServer() bool { Port: *iamopt.port, FilerGrpcAddress: filerGrpcAddress, GrpcDialOption: grpcDialOption, - }) - glog.V(0).Info("NewIamApiServer created") + }, ifs) if iamApiServer_err != nil { glog.Fatalf("IAM API Server startup error: %v", iamApiServer_err) } diff --git a/weed/iamapi/iamapi_handlers.go b/weed/iamapi/iamapi_handlers.go index 2a4a9f009..c436ba998 100644 --- a/weed/iamapi/iamapi_handlers.go +++ b/weed/iamapi/iamapi_handlers.go @@ -75,3 +75,7 @@ func writeResponse(w http.ResponseWriter, statusCode int, response []byte, mType w.(http.Flusher).Flush() } } + +func writeSuccessResponseXML(w http.ResponseWriter, response []byte) { + writeResponse(w, http.StatusOK, response, mimeXML) +} diff --git a/weed/iamapi/iamapi_management_handlers.go b/weed/iamapi/iamapi_management_handlers.go new file mode 100644 index 000000000..85504316c --- /dev/null +++ b/weed/iamapi/iamapi_management_handlers.go @@ -0,0 +1,68 @@ +package iamapi + +import ( + "encoding/xml" + "github.com/chrislusf/seaweedfs/weed/glog" + "github.com/chrislusf/seaweedfs/weed/pb/iam_pb" + "github.com/chrislusf/seaweedfs/weed/s3api/s3err" + "net/http" + "net/url" + + // "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/iam" +) + +const ( + version = "2010-05-08" +) + +type ListUsersResponse struct { + 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{} + 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) DoActions(w http.ResponseWriter, r *http.Request) { + if err := r.ParseForm(); err != nil { + writeErrorResponse(w, s3err.ErrInvalidRequest, r.URL) + return + } + values := r.PostForm + s3cfg := &iam_pb.S3ApiConfiguration{} + if err := iama.ifs.LoadIAMConfig(s3cfg); err != nil { + writeErrorResponse(w, s3err.ErrInternalError, r.URL) + return + } + glog.Info("values ", values) + var response interface{} + switch r.Form.Get("Action") { + case "ListUsers": + response = iama.ListUsers(s3cfg, values) + case "ListAccessKeys": + response = iama.ListAccessKeys(values) + default: + writeErrorResponse(w, s3err.ErrNotImplemented, r.URL) + return + } + writeSuccessResponseXML(w, encodeResponse(response)) +} diff --git a/weed/iamapi/iamapi_server.go b/weed/iamapi/iamapi_server.go index 748ed078c..30b356548 100644 --- a/weed/iamapi/iamapi_server.go +++ b/weed/iamapi/iamapi_server.go @@ -18,11 +18,13 @@ type IamServerOption struct { type IamApiServer struct { option *IamServerOption + ifs *IAMFilerStore } -func NewIamApiServer(router *mux.Router, option *IamServerOption) (iamApiServer *IamApiServer, err error) { +func NewIamApiServer(router *mux.Router, option *IamServerOption, ifs *IAMFilerStore) (iamApiServer *IamApiServer, err error) { iamApiServer = &IamApiServer{ option: option, + ifs: ifs, } iamApiServer.registerRouter(router) @@ -34,8 +36,9 @@ func (iama *IamApiServer) registerRouter(router *mux.Router) { // API Router apiRouter := router.PathPrefix("/").Subrouter() // ListBuckets - //apiRouter.Methods("GET").Path("/").HandlerFunc(track(s3a.iam.Auth(s3a.ListBucketsHandler, ACTION_ADMIN), "LIST")) + // apiRouter.Methods("GET").Path("/").HandlerFunc(track(s3a.iam.Auth(s3a.ListBucketsHandler, ACTION_ADMIN), "LIST")) + apiRouter.Path("/").Methods("POST").HandlerFunc(iama.DoActions) // NotFound apiRouter.NotFoundHandler = http.HandlerFunc(notFoundHandler) }