mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2024-01-19 02:48:24 +00:00
iam GetUser
This commit is contained in:
parent
40938d6a47
commit
8a95f9c10c
|
@ -25,6 +25,8 @@ var (
|
||||||
filerS3Options S3Options
|
filerS3Options S3Options
|
||||||
filerStartWebDav *bool
|
filerStartWebDav *bool
|
||||||
filerWebDavOptions WebDavOption
|
filerWebDavOptions WebDavOption
|
||||||
|
filerStartIam *bool
|
||||||
|
filerIamOptions IamOptions
|
||||||
)
|
)
|
||||||
|
|
||||||
type FilerOptions struct {
|
type FilerOptions struct {
|
||||||
|
@ -89,6 +91,10 @@ func init() {
|
||||||
filerWebDavOptions.tlsCertificate = cmdFiler.Flag.String("webdav.cert.file", "", "path to the TLS certificate file")
|
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.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")
|
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{
|
var cmdFiler = &Command{
|
||||||
|
@ -119,22 +125,33 @@ func runFiler(cmd *Command, args []string) bool {
|
||||||
|
|
||||||
go stats_collect.StartMetricsServer(*f.metricsHttpPort)
|
go stats_collect.StartMetricsServer(*f.metricsHttpPort)
|
||||||
|
|
||||||
if *filerStartS3 {
|
|
||||||
filerAddress := fmt.Sprintf("%s:%d", *f.ip, *f.port)
|
filerAddress := fmt.Sprintf("%s:%d", *f.ip, *f.port)
|
||||||
|
startDelay := time.Duration(2)
|
||||||
|
if *filerStartS3 {
|
||||||
filerS3Options.filer = &filerAddress
|
filerS3Options.filer = &filerAddress
|
||||||
go func() {
|
go func() {
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(startDelay * time.Second)
|
||||||
filerS3Options.startS3Server()
|
filerS3Options.startS3Server()
|
||||||
}()
|
}()
|
||||||
|
startDelay++
|
||||||
}
|
}
|
||||||
|
|
||||||
if *filerStartWebDav {
|
if *filerStartWebDav {
|
||||||
filerAddress := fmt.Sprintf("%s:%d", *f.ip, *f.port)
|
|
||||||
filerWebDavOptions.filer = &filerAddress
|
filerWebDavOptions.filer = &filerAddress
|
||||||
go func() {
|
go func() {
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(startDelay * time.Second)
|
||||||
filerWebDavOptions.startWebDav()
|
filerWebDavOptions.startWebDav()
|
||||||
}()
|
}()
|
||||||
|
startDelay++
|
||||||
|
}
|
||||||
|
|
||||||
|
if *filerStartIam {
|
||||||
|
filerIamOptions.filer = &filerAddress
|
||||||
|
filerIamOptions.masters = f.masters
|
||||||
|
go func() {
|
||||||
|
time.Sleep(startDelay * time.Second)
|
||||||
|
filerIamOptions.startIamServer()
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
f.startFiler()
|
f.startFiler()
|
||||||
|
|
|
@ -12,6 +12,8 @@ import (
|
||||||
|
|
||||||
"github.com/chrislusf/seaweedfs/weed/glog"
|
"github.com/chrislusf/seaweedfs/weed/glog"
|
||||||
"github.com/chrislusf/seaweedfs/weed/s3api/s3err"
|
"github.com/chrislusf/seaweedfs/weed/s3api/s3err"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/service/iam"
|
||||||
)
|
)
|
||||||
|
|
||||||
type mimeType string
|
type mimeType string
|
||||||
|
@ -48,6 +50,22 @@ func writeErrorResponse(w http.ResponseWriter, errorCode s3err.ErrorCode, reqURL
|
||||||
writeResponse(w, apiError.HTTPStatusCode, encodedErrorResponse, mimeXML)
|
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 {
|
func getRESTErrorResponse(err s3err.APIError, resource string) s3err.RESTErrorResponse {
|
||||||
return s3err.RESTErrorResponse{
|
return s3err.RESTErrorResponse{
|
||||||
Code: err.Code,
|
Code: err.Code,
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"encoding/xml"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/chrislusf/seaweedfs/weed/filer"
|
"github.com/chrislusf/seaweedfs/weed/filer"
|
||||||
"github.com/chrislusf/seaweedfs/weed/glog"
|
"github.com/chrislusf/seaweedfs/weed/glog"
|
||||||
|
@ -19,12 +18,10 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
// "github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/service/iam"
|
"github.com/aws/aws-sdk-go/service/iam"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
version = "2010-05-08"
|
|
||||||
charsetUpper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
charsetUpper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||||
charset = charsetUpper + "abcdefghijklmnopqrstuvwxyz/"
|
charset = charsetUpper + "abcdefghijklmnopqrstuvwxyz/"
|
||||||
)
|
)
|
||||||
|
@ -44,73 +41,6 @@ type PolicyDocument struct {
|
||||||
} `json:"Statement"`
|
} `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 {
|
func Hash(s *string) string {
|
||||||
h := sha1.New()
|
h := sha1.New()
|
||||||
h.Write([]byte(*s))
|
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})
|
s3cfg.Identities = append(s3cfg.Identities, &iam_pb.Identity{Name: userName})
|
||||||
return resp
|
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) {
|
func GetPolicyDocument(policy *string) (policyDocument PolicyDocument, err error) {
|
||||||
if err = json.Unmarshal([]byte(*policy), &policyDocument); err != nil {
|
if err = json.Unmarshal([]byte(*policy), &policyDocument); err != nil {
|
||||||
return PolicyDocument{}, err
|
return PolicyDocument{}, err
|
||||||
|
@ -245,17 +196,6 @@ func GetActions(policy *PolicyDocument) (actions []string) {
|
||||||
return actions
|
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) {
|
func (iama *IamApiServer) CreateAccessKey(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp CreateAccessKeyResponse) {
|
||||||
userName := values.Get("UserName")
|
userName := values.Get("UserName")
|
||||||
status := iam.StatusTypeActive
|
status := iam.StatusTypeActive
|
||||||
|
@ -320,6 +260,7 @@ func (iama *IamApiServer) DoActions(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
glog.Info("values ", values)
|
glog.Info("values ", values)
|
||||||
var response interface{}
|
var response interface{}
|
||||||
|
var err error
|
||||||
changed := true
|
changed := true
|
||||||
switch r.Form.Get("Action") {
|
switch r.Form.Get("Action") {
|
||||||
case "ListUsers":
|
case "ListUsers":
|
||||||
|
@ -330,21 +271,31 @@ func (iama *IamApiServer) DoActions(w http.ResponseWriter, r *http.Request) {
|
||||||
changed = false
|
changed = false
|
||||||
case "CreateUser":
|
case "CreateUser":
|
||||||
response = iama.CreateUser(s3cfg, values)
|
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":
|
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":
|
case "CreateAccessKey":
|
||||||
response = iama.CreateAccessKey(s3cfg, values)
|
response = iama.CreateAccessKey(s3cfg, values)
|
||||||
case "DeleteAccessKey":
|
case "DeleteAccessKey":
|
||||||
response = iama.DeleteAccessKey(s3cfg, values)
|
response = iama.DeleteAccessKey(s3cfg, values)
|
||||||
case "CreatePolicy":
|
case "CreatePolicy":
|
||||||
var err error
|
|
||||||
response, err = iama.CreatePolicy(s3cfg, values)
|
response, err = iama.CreatePolicy(s3cfg, values)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, s3err.ErrInvalidRequest, r.URL)
|
writeErrorResponse(w, s3err.ErrInvalidRequest, r.URL)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
case "PutUserPolicy":
|
case "PutUserPolicy":
|
||||||
var err error
|
|
||||||
response, err = iama.PutUserPolicy(s3cfg, values)
|
response, err = iama.PutUserPolicy(s3cfg, values)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, s3err.ErrInvalidRequest, r.URL)
|
writeErrorResponse(w, s3err.ErrInvalidRequest, r.URL)
|
||||||
|
|
93
weed/iamapi/iamapi_response.go
Normal file
93
weed/iamapi/iamapi_response.go
Normal file
|
@ -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())
|
||||||
|
}
|
Loading…
Reference in a new issue