Refactor: reorganize permission and actions

Signed-off-by: Mofei Zhang <mofei2816@gmail.com>
This commit is contained in:
Mofei Zhang 2020-03-17 00:08:40 +08:00
parent ecce5dc45f
commit 11d0a4ddf0
No known key found for this signature in database
GPG Key ID: 7C19725C197AE672
15 changed files with 415 additions and 250 deletions

View File

@ -37,6 +37,7 @@ func newUserCmd(client *master.MasterClient) *cobra.Command {
cmd.AddCommand(
newUserCreateCmd(client),
newUserInfoCmd(client),
newUserPermCmd(client),
)
return cmd
}
@ -146,6 +147,74 @@ func newUserInfoCmd(client *master.MasterClient) *cobra.Command {
return cmd
}
const (
cmdUserPermUse = "perm [USER ID] [VOLUME] [PERM]"
cmdUserPermShort = "Setup volume permission for a user"
)
func newUserPermCmd(client *master.MasterClient) *cobra.Command {
var cmd = &cobra.Command{
Use: cmdUserPermUse,
Short: cmdUserPermShort,
Args: cobra.MinimumNArgs(3),
Run: func(cmd *cobra.Command, args []string) {
var userID = args[0]
var volume = args[1]
var perm proto.Permission
switch args[2] {
case "ro":
perm = proto.BuiltinPermissionReadOnly
case "rw":
perm = proto.BuiltinPermissionWritable
case "none":
perm = proto.NonePermission
default:
stdout("Permission must be on of ro, rw, none")
return
}
stdout("Setup volume permission\n")
stdout(" User ID : %v\n", userID)
stdout(" Volume : %v\n", volume)
stdout(" Permission: %v\n", perm.ReadableString())
// ask user for confirm
stdout("\nConfirm (yes/no)[yes]: ")
var userConfirm string
_, _ = fmt.Scanln(&userConfirm)
if userConfirm != "yes" && len(userConfirm) != 0 {
stdout("Abort by user.\n")
return
}
var err error
defer func() {
if err != nil {
errout("Setup permission failed:\n%v\n", err)
os.Exit(1)
}
}()
var akp *proto.AKPolicy
if akp, err = client.UserAPI().GetUserInfo(userID); err != nil {
return
}
if _, err = client.AdminAPI().GetVolumeSimpleInfo(volume); err != nil {
return
}
var newUserPolicy = proto.NewUserPolicy()
newUserPolicy.SetPerm(volume, perm)
if perm.IsNone() {
akp, err = client.UserAPI().DeletePolicy(akp.AccessKey, newUserPolicy)
} else {
akp, err = client.UserAPI().AddPolicy(akp.AccessKey, newUserPolicy)
}
if err != nil {
return
}
printUserInfo(akp)
},
}
return cmd
}
func printUserInfo(akp *proto.AKPolicy) {
stdout("\n[Summary]\n")
stdout(" User ID : %v\n", akp.UserID)
@ -165,9 +234,11 @@ func printUserInfo(akp *proto.AKPolicy) {
stdout(" None\n")
}
stdout("\n[Authorized volumes]\n")
if len(akp.Policy.AuthorizedVols) != 0 {
for vol := range akp.Policy.AuthorizedVols {
stdout(" %s\n", vol)
stdout(" %10v\t%10v\n", "VOLUME", "PERMISSION")
for vol, perms := range akp.Policy.AuthorizedVols {
stdout(" %10v\t%10v\n", vol, perms)
}
} else {
stdout(" None\n")

View File

@ -1812,10 +1812,10 @@ func genRespMessage(data []byte, req *proto.APIAccessReq, ts int64, key []byte)
func (m *Server) associateVolWithUser(userID, volName string) error {
var err error
var akPolicy *proto.AKPolicy
if akPolicy, err = m.user.getUserInfo(userID); err != nil && err != proto.ErrOSSUserNotExists {
if akPolicy, err = m.user.getUserInfo(userID); err != nil && err != proto.ErrUserNotExists {
return err
}
if err == proto.ErrOSSUserNotExists {
if err == proto.ErrUserNotExists {
var param = proto.UserCreateParam{
ID: userID,
Password: DefaultUserPassword,

View File

@ -106,7 +106,7 @@ func (u *User) deleteKey(userID string) (err error) {
akPolicy *proto.AKPolicy
)
if value, exist := u.userAk.Load(userID); !exist {
err = proto.ErrOSSUserNotExists
err = proto.ErrUserNotExists
return
} else {
userAK = value.(*proto.UserAK)
@ -151,7 +151,7 @@ func (u *User) getUserInfo(userID string) (akPolicy *proto.AKPolicy, err error)
if value, exist := u.userAk.Load(userID); exist {
ak = value.(*proto.UserAK).AccessKey
} else {
err = proto.ErrOSSUserNotExists
err = proto.ErrUserNotExists
return
}
if akPolicy, err = u.loadAKInfo(ak); err != nil {

View File

@ -42,24 +42,24 @@ const (
// https://docs.aws.amazon.com/zh_cn/AmazonS3/latest/dev/acl-overview.html
var (
aclBucketPermissionActions = map[Permission]proto.Actions{
ReadPermission: {proto.ListBucketAction, proto.ListBucketVersionsAction, proto.ListBucketMultipartUploadsAction},
WritePermission: {proto.PutObjectAction, proto.DeleteObjectAction, proto.DeleteBucketAction},
ReadACPPermission: {proto.GetBucketAclAction},
WriteACPPermission: {proto.PutBucketAclAction},
ReadPermission: {proto.OSSListBucketAction, proto.OSSListBucketVersionsAction, proto.OSSListBucketMultipartUploadsAction},
WritePermission: {proto.OSSPutObjectAction, proto.OSSDeleteObjectAction, proto.OSSDeleteBucketAction},
ReadACPPermission: {proto.OSSGetBucketAclAction},
WriteACPPermission: {proto.OSSPutBucketAclAction},
FullControlPermission: {
proto.ListBucketAction, proto.ListBucketVersionsAction, proto.ListBucketMultipartUploadsAction,
proto.PutObjectAction, proto.DeleteObjectAction, proto.DeleteBucketAction,
proto.GetBucketAclAction, proto.PutBucketAclAction},
proto.OSSListBucketAction, proto.OSSListBucketVersionsAction, proto.OSSListBucketMultipartUploadsAction,
proto.OSSPutObjectAction, proto.OSSDeleteObjectAction, proto.OSSDeleteBucketAction,
proto.OSSGetBucketAclAction, proto.OSSPutBucketAclAction},
}
aclObjectPermissionActions = map[Permission]proto.Actions{
ReadPermission: {proto.GetObjectAction, proto.GetObjectVersionAction, proto.GetObjectTorrentAction},
ReadPermission: {proto.OSSGetObjectAction, proto.OSSGetObjectVersionAction, proto.OSSGetObjectTorrentAction},
WritePermission: {},
ReadACPPermission: {proto.GetObjectAclAction, proto.GetObjectVersionAclAction},
WriteACPPermission: {proto.PutObjectAclAction, proto.PutObjectVersionAclAction},
ReadACPPermission: {proto.OSSGetObjectAclAction, proto.OSSGetObjectVersionAclAction},
WriteACPPermission: {proto.OSSPutObjectAclAction, proto.OSSPutObjectVersionAclAction},
FullControlPermission: {
proto.GetObjectAction, proto.GetObjectVersionAction, proto.GetObjectTorrentAction,
proto.GetObjectAclAction, proto.GetObjectVersionAclAction,
proto.PutObjectAclAction, proto.PutObjectVersionAclAction},
proto.OSSGetObjectAction, proto.OSSGetObjectVersionAction, proto.OSSGetObjectTorrentAction,
proto.OSSGetObjectAclAction, proto.OSSGetObjectVersionAclAction,
proto.OSSPutObjectAclAction, proto.OSSPutObjectVersionAclAction},
}
)

View File

@ -83,7 +83,7 @@ func ParseRequestParam(r *http.Request) *RequestParam {
p.accessKey = auth.accessKey
}
p.action = GetActionFromContext(r)
if !p.action.IsKnown() {
if p.action.IsNone() {
p.action = ActionFromRouteName(mux.CurrentRoute(r).GetName())
}

View File

@ -61,7 +61,7 @@ func (o *ObjectNode) createBucketHandler(w http.ResponseWriter, r *http.Request)
}
auth := parseRequestAuthInfo(r)
var akPolicy *proto.AKPolicy
if akPolicy, err = o.getAkInfo(auth.accessKey); err != nil {
if akPolicy, err = o.getUserInfoByAccessKey(auth.accessKey); err != nil {
log.LogErrorf("get user info from master error: accessKey(%v), err(%v)", auth.accessKey, err)
_ = InternalError.ServeResponse(w, r)
return
@ -102,7 +102,7 @@ func (o *ObjectNode) deleteBucketHandler(w http.ResponseWriter, r *http.Request)
}
auth := parseRequestAuthInfo(r)
var akPolicy *proto.AKPolicy
if akPolicy, err = o.getAkInfo(auth.accessKey); err != nil {
if akPolicy, err = o.getUserInfoByAccessKey(auth.accessKey); err != nil {
log.LogErrorf("get user info from master error: accessKey(%v), err(%v)", auth.accessKey, err)
_ = InternalError.ServeResponse(w, r)
return
@ -147,7 +147,7 @@ func (o *ObjectNode) listBucketsHandler(w http.ResponseWriter, r *http.Request)
var err error
auth := parseRequestAuthInfo(r)
var akPolicy *proto.AKPolicy
if akPolicy, err = o.getAkInfo(auth.accessKey); err != nil {
if akPolicy, err = o.getUserInfoByAccessKey(auth.accessKey); err != nil {
log.LogErrorf("get user info from master error: accessKey(%v), err(%v)", auth.accessKey, err)
_ = InternalError.ServeResponse(w, r)
return
@ -342,7 +342,7 @@ func calculateAuthKey(key string) (authKey string, err error) {
return strings.ToLower(hex.EncodeToString(cipherStr)), nil
}
func (o *ObjectNode) getAkInfo(accessKey string) (*proto.AKPolicy, error) {
func (o *ObjectNode) getUserInfoByAccessKey(accessKey string) (*proto.AKPolicy, error) {
var err error
akPolicy, exist := o.userStore.Get(accessKey)
if !exist {

View File

@ -102,7 +102,7 @@ func (o *ObjectNode) authMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
var currentAction = ActionFromRouteName(mux.CurrentRoute(r).GetName())
if currentAction.IsKnown() && o.signatureIgnoredActions.Constant(currentAction) {
if !currentAction.IsNone() && o.signatureIgnoredActions.Contains(currentAction) {
next.ServeHTTP(w, r)
return
}
@ -160,7 +160,7 @@ func (o *ObjectNode) policyCheckMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
action := ActionFromRouteName(mux.CurrentRoute(r).GetName())
if action.IsKnown() && o.signatureIgnoredActions.Constant(action) {
if !action.IsNone() && o.signatureIgnoredActions.Contains(action) {
next.ServeHTTP(w, r)
return
}

View File

@ -175,7 +175,7 @@ func (o *ObjectNode) validateHeaderBySignatureAlgorithmV2(r *http.Request) (bool
}
var akPolicy *proto.AKPolicy
if akPolicy, err = o.getAkInfo(authInfo.accessKeyId); err != nil {
if akPolicy, err = o.getUserInfoByAccessKey(authInfo.accessKeyId); err != nil {
log.LogInfof("get secretKey from master error: accessKey(%v), err(%v)", authInfo.accessKeyId, err)
return false, err
}
@ -272,7 +272,7 @@ func (o *ObjectNode) validateUrlBySignatureAlgorithmV2(r *http.Request) (bool, e
//check access key
var akPolicy *proto.AKPolicy
if akPolicy, err = o.getAkInfo(accessKey); err != nil {
if akPolicy, err = o.getUserInfoByAccessKey(accessKey); err != nil {
log.LogInfof("get secretKey from master error: accessKey(%v), err(%v)", accessKey, err)
return false, err
}

View File

@ -98,7 +98,7 @@ func (o *ObjectNode) validateHeaderBySignatureAlgorithmV4(r *http.Request) (bool
return false, err
}
var akPolicy *proto.AKPolicy
if akPolicy, err = o.getAkInfo(req.Credential.AccessKey); err != nil {
if akPolicy, err = o.getUserInfoByAccessKey(req.Credential.AccessKey); err != nil {
log.LogInfof("validateHeaderBySignatureAlgorithmV4: get secretKey from master fail: err(%v)", err)
return false, err
}
@ -138,7 +138,7 @@ func (o *ObjectNode) validateUrlBySignatureAlgorithmV4(r *http.Request) (pass bo
// check accessKey valid
var akPolicy *proto.AKPolicy
if akPolicy, err = o.getAkInfo(req.Credential.AccessKey); err != nil {
if akPolicy, err = o.getUserInfoByAccessKey(req.Credential.AccessKey); err != nil {
log.LogInfof("get secretKey from master error: accessKey(%v), err(%v)", req.Credential.AccessKey, err)
return false, err
}

View File

@ -48,7 +48,6 @@ func (p *Policy) IsEmpty() bool {
return len(p.Statements) == 0
}
//
// arn:partition:service:region:account-id:resource-id
// arn:partition:service:region:account-id:resource-type/resource-id
// arn:partition:service:region:account-id:resource-type:resource-id
@ -220,7 +219,7 @@ func (o *ObjectNode) policyCheck(f http.HandlerFunc) http.HandlerFunc {
return
}
switch param.action {
case proto.CreateBucketAction:
case proto.OSSCreateBucketAction:
default:
if err = loadBucketMeta(param.Bucket()); err != nil {
log.LogErrorf("policyCheck: load bucket metadata fail: requestID(%v) err(%v)", GetRequestID(r), err)
@ -247,33 +246,27 @@ func (o *ObjectNode) policyCheck(f http.HandlerFunc) http.HandlerFunc {
}
//check user policy
var akPolicy *proto.AKPolicy
if akPolicy, err = o.getAkInfo(param.accessKey); err != nil {
if akPolicy, err = o.getUserInfoByAccessKey(param.accessKey); err != nil {
log.LogErrorf("policyCheck: load user policy from master fail: requestID(%v) accessKey(%v) err(%v)",
GetRequestID(r), param.AccessKey(), err)
allowed = false
return
}
if param.action == proto.CreateBucketAction {
if param.action == proto.OSSCreateBucketAction {
allowed = true
return
}
if contains(akPolicy.Policy.OwnVols, param.bucket) {
var userPolicy = akPolicy.Policy
if userPolicy.IsOwn(param.Bucket()) {
allowed = true
return
}
if apis, exit := akPolicy.Policy.AuthorizedVols[param.bucket]; exit {
if !contains(apis, param.Action().String()) {
allowed = false
log.LogWarnf("policyCheck: user policy not allowed: requestID(%v) accessKey(%v) action(%v)",
GetRequestID(r), param.AccessKey(), param.Action())
return
}
if userPolicy.IsAuthorized(param.Bucket(), param.Action()) {
allowed = true
} else {
allowed = false
log.LogWarnf("policyCheck: user policy not allowed: requestID(%v) accessKey(%v) action(%v)",
GetRequestID(r), param.AccessKey(), param.Action())
return
}
allowed = false
log.LogWarnf("policyCheck: user policy not allowed: requestID(%v) accessKey(%v) action(%v)",
GetRequestID(r), param.AccessKey(), param.Action())
}
}

View File

@ -36,14 +36,14 @@ func (o *ObjectNode) registerApiRouters(router *mux.Router) {
var registerBucketHttpHeadRouters = func(r *mux.Router) {
// Head object
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.HeadObjectAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSHeadObjectAction)).
Methods(http.MethodHead).
Path("/{object:.+}").
HandlerFunc(o.headObjectHandler)
// Head bucket
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadBucket.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.HeadBucketAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSHeadBucketAction)).
Methods(http.MethodHead).
HandlerFunc(o.headBucketHandler)
}
@ -51,7 +51,7 @@ func (o *ObjectNode) registerApiRouters(router *mux.Router) {
var registerBucketHttpGetRouters = func(r *mux.Router) {
// Get object with pre-signed auth signature v2
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.GetObjectAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSGetObjectAction)).
Methods(http.MethodGet).
Path("/{object:.+}").
Queries("AWSAccessKeyId", "{accessKey:.+}",
@ -60,7 +60,7 @@ func (o *ObjectNode) registerApiRouters(router *mux.Router) {
// Get object with pre-signed auth signature v4
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.GetObjectAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSGetObjectAction)).
Methods(http.MethodGet).
Path("/{object:.+}").
Queries("X-Amz-Credential", "{creadential:.+}",
@ -71,7 +71,7 @@ func (o *ObjectNode) registerApiRouters(router *mux.Router) {
// Get object tagging
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.GetObjectTaggingAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSGetObjectTaggingAction)).
Methods(http.MethodGet).
Path("/{object:.+}").
Queries("tagging", "").
@ -79,14 +79,14 @@ func (o *ObjectNode) registerApiRouters(router *mux.Router) {
// Get object XAttr
// Notes: ChubaoFS owned API for XAttr operation
r.NewRoute().Name(ActionToUniqueRouteName(proto.GetObjectXAttrAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSGetObjectXAttrAction)).
Methods(http.MethodGet).
Path("/{object:.+}").
Queries("xattr", "", "key", "{key:.+}").
HandlerFunc(o.getObjectXAttrHandler)
// List object XAttrs
r.NewRoute().Name(ActionToUniqueRouteName(proto.ListObjectXAttrsAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSListObjectXAttrsAction)).
Methods(http.MethodGet).
Path("/{object:.+}").
Queries("xattr", "").
@ -94,7 +94,7 @@ func (o *ObjectNode) registerApiRouters(router *mux.Router) {
// Get object acl
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAcl.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.GetObjectAclAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSGetObjectAclAction)).
Methods(http.MethodGet).
Path("/{objject:.+}").
Queries("acl", "").
@ -102,63 +102,63 @@ func (o *ObjectNode) registerApiRouters(router *mux.Router) {
// Get object
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.GetObjectAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSGetObjectAction)).
Methods(http.MethodGet).
Path("/{object:.+}").
HandlerFunc(o.getObjectHandler)
// List objects version 2
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.ListObjectsAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSListObjectsAction)).
Methods(http.MethodGet).
Queries("list-type", "2").
HandlerFunc(o.getBucketV2Handler)
// List multipart uploads
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.ListMultipartUploadsAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSListMultipartUploadsAction)).
Methods(http.MethodGet).
Queries("uploads", "").
HandlerFunc(o.listMultipartUploadsHandler)
// List parts
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.ListPartsAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSListPartsAction)).
Methods(http.MethodGet).
Queries("uploadId", "{uploadId:.*}").
HandlerFunc(o.listPartsHandler)
// Get bucket location
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLocation.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.GetBucketLocationAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSGetBucketLocationAction)).
Methods(http.MethodGet).
Queries("location", "").
HandlerFunc(o.getBucketLocation)
// Get bucket policy
// https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketPolicy.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.GetBucketPolicyAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSGetBucketPolicyAction)).
Methods(http.MethodGet).
Queries("policy", "").
HandlerFunc(o.getBucketPolicyHandler)
// Get bucket acl
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketAcl.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.GetBucketAclAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSGetBucketAclAction)).
Methods(http.MethodGet).
Queries("acl", "").
HandlerFunc(o.getBucketACLHandler)
// Get bucket tagging
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketTagging.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.GetBucketTaggingAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSGetBucketTaggingAction)).
Methods(http.MethodGet).
Queries("tagging", "").
HandlerFunc(o.getBucketTaggingHandler)
// List objects version 1
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.ListObjectsAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSListObjectsAction)).
Methods(http.MethodGet).
HandlerFunc(o.getBucketV1Handler)
}
@ -166,7 +166,7 @@ func (o *ObjectNode) registerApiRouters(router *mux.Router) {
var registerBucketHttpPostRouters = func(r *mux.Router) {
// Create multipart upload
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.CreateMultipartUploadAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSCreateMultipartUploadAction)).
Methods(http.MethodPost).
Path("/{object:.+}").
Queries("uploads", "").
@ -174,7 +174,7 @@ func (o *ObjectNode) registerApiRouters(router *mux.Router) {
// Complete multipart
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.CompleteMultipartUploadAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSCompleteMultipartUploadAction)).
Methods(http.MethodPost).
Path("/{object:.+}").
Queries("uploadId", "{uploadId:.*}").
@ -182,7 +182,7 @@ func (o *ObjectNode) registerApiRouters(router *mux.Router) {
// Delete objects (multiple objects)
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjects.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.DeleteObjectsAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSDeleteObjectsAction)).
Methods(http.MethodPost).
Queries("delete", "").
HandlerFunc(o.deleteObjectsHandler)
@ -191,7 +191,7 @@ func (o *ObjectNode) registerApiRouters(router *mux.Router) {
var registerBucketHttpPutRouters = func(r *mux.Router) {
// Upload part
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html .
r.NewRoute().Name(ActionToUniqueRouteName(proto.UploadPartAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSUploadPartAction)).
Methods(http.MethodPut).
Path("/{object:.+}").
Queries("partNumber", "{partNumber:[0-9]+}", "uploadId", "{uploadId:.*}").
@ -199,7 +199,7 @@ func (o *ObjectNode) registerApiRouters(router *mux.Router) {
// Copy object
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html .
r.NewRoute().Name(ActionToUniqueRouteName(proto.CopyObjectAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSCopyObjectAction)).
Methods(http.MethodPut).
Path("/{object:.+}").
HeadersRegexp(HeaderNameCopySource, ".*?(\\/|%2F).*?").
@ -207,7 +207,7 @@ func (o *ObjectNode) registerApiRouters(router *mux.Router) {
// Put object tagging
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectTagging.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.PutObjectTaggingAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSPutObjectTaggingAction)).
Methods(http.MethodPut).
Path("/{object:.+}").
Queries("tagging", "").
@ -215,7 +215,7 @@ func (o *ObjectNode) registerApiRouters(router *mux.Router) {
// Put object xattrs
// Notes: ChubaoFS owned API for XAttr operation
r.NewRoute().Name(ActionToUniqueRouteName(proto.PutObjectXAttrAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSPutObjectXAttrAction)).
Methods(http.MethodPut).
Path("/{object:.+}").
Queries("xattr", "").
@ -223,7 +223,7 @@ func (o *ObjectNode) registerApiRouters(router *mux.Router) {
// Put object acl
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAcl.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.PutObjectAclAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSPutObjectAclAction)).
Methods(http.MethodPut).
Path("/{object:.+}").
Queries("acl", "").
@ -231,35 +231,35 @@ func (o *ObjectNode) registerApiRouters(router *mux.Router) {
// Put object
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.PutObjectAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSPutObjectAction)).
Methods(http.MethodPut).
Path("/{object:.+}").
HandlerFunc(o.putObjectHandler)
// Put bucket acl
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAcl.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.PutBucketAclAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSPutBucketAclAction)).
Methods(http.MethodPut).
Queries("acl", "").
HandlerFunc(o.putBucketACLHandler)
// Put bucket policy
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketPolicy.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.PutBucketPolicyAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSPutBucketPolicyAction)).
Methods(http.MethodPut).
Queries("policy", "").
HandlerFunc(o.putBucketPolicyHandler)
// Put bucket tagging
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketTagging.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.PutBucketTaggingAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSPutBucketTaggingAction)).
Methods(http.MethodPut).
Queries("tagging", "").
HandlerFunc(o.putBucketTaggingHandler)
// Create bucket
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.CreateBucketAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSCreateBucketAction)).
Methods(http.MethodPut).
HandlerFunc(o.createBucketHandler)
}
@ -267,7 +267,7 @@ func (o *ObjectNode) registerApiRouters(router *mux.Router) {
var registerBucketHttpDeleteRouters = func(r *mux.Router) {
// Abort multipart upload
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html .
r.NewRoute().Name(ActionToUniqueRouteName(proto.AbortMultipartUploadAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSAbortMultipartUploadAction)).
Methods(http.MethodDelete).
Path("/{object:.+}").
Queries("uploadId", "{uploadId:.*}").
@ -275,7 +275,7 @@ func (o *ObjectNode) registerApiRouters(router *mux.Router) {
// Delete object tagging
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjectTagging.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.DeleteObjectTaggingAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSDeleteObjectTaggingAction)).
Methods(http.MethodDelete).
Path("/{object:.+").
Queries("tagging", "").
@ -283,7 +283,7 @@ func (o *ObjectNode) registerApiRouters(router *mux.Router) {
// Delete object xattrs
// Notes: ChubaoFS owned API for XAttr operation
r.NewRoute().Name(ActionToUniqueRouteName(proto.DeleteObjectXAttrAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSDeleteObjectXAttrAction)).
Methods(http.MethodDelete).
Path("/{object:.+}").
Queries("xattr", "", "key", "{key:.+}").
@ -291,28 +291,28 @@ func (o *ObjectNode) registerApiRouters(router *mux.Router) {
// Delete object
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html .
r.NewRoute().Name(ActionToUniqueRouteName(proto.DeleteObjectAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSDeleteObjectAction)).
Methods(http.MethodDelete).
Path("/{object:.+}").
HandlerFunc(o.deleteObjectHandler)
// Delete bucket policy
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketPolicy.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.DeleteBucketPolicyAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSDeleteBucketPolicyAction)).
Methods(http.MethodDelete).
Queries("policy", "").
HandlerFunc(o.deleteBucketPolicyHandler)
// Delete bucket tagging
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketTagging.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.DeleteBucketTaggingAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSDeleteBucketTaggingAction)).
Methods(http.MethodDelete).
Queries("tagging", "").
HandlerFunc(o.deleteBucketTaggingHandler)
// Delete bucket
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucket.html
r.NewRoute().Name(ActionToUniqueRouteName(proto.DeleteBucketAction)).
r.NewRoute().Name(ActionToUniqueRouteName(proto.OSSDeleteBucketAction)).
Methods(http.MethodDelete).
HandlerFunc(o.deleteBucketHandler)
@ -328,7 +328,7 @@ func (o *ObjectNode) registerApiRouters(router *mux.Router) {
// List buckets
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html
router.NewRoute().Name(ActionToUniqueRouteName(proto.ListBucketAction)).
router.NewRoute().Name(ActionToUniqueRouteName(proto.OSSListBucketAction)).
Methods(http.MethodGet).
HandlerFunc(o.listBucketsHandler)

View File

@ -109,7 +109,7 @@ func (o *ObjectNode) loadConfig(cfg *config.Config) (err error) {
signatureIgnoredActionNames := cfg.GetStringSlice(configSignatureIgnoredActions)
for _, actionName := range signatureIgnoredActionNames {
action := proto.ParseAction(actionName)
if action.IsKnown() {
if !action.IsNone() {
o.signatureIgnoredActions = append(o.signatureIgnoredActions, action)
log.LogInfof("loadConfig: signature ignored action: %v", action)
}

View File

@ -66,7 +66,7 @@ var (
ErrExpiredTicket = errors.New("expired ticket")
ErrMasterAPIGenRespError = errors.New("master API generate response error")
ErrDuplicateUserID = errors.New("duplicate user id")
ErrOSSUserNotExists = errors.New("oss user not exists")
ErrUserNotExists = errors.New("user not exists")
ErrReadBodyError = errors.New("read request body failed")
ErrVolPolicyNotExists = errors.New("vol policy not exists")
ErrDuplicateAccessKey = errors.New("duplicate access key")
@ -124,7 +124,7 @@ const (
ErrCodeExpiredTicket
ErrCodeMasterAPIGenRespError
ErrCodeDuplicateUserID
ErrCodeOSSUserNotExists
ErrCodeUserNotExists
ErrCodeReadBodyError
ErrCodeVolPolicyNotExists
ErrCodeDuplicateAccessKey
@ -181,7 +181,7 @@ var Err2CodeMap = map[error]int32{
ErrExpiredTicket: ErrCodeExpiredTicket,
ErrMasterAPIGenRespError: ErrCodeMasterAPIGenRespError,
ErrDuplicateUserID: ErrCodeDuplicateUserID,
ErrOSSUserNotExists: ErrCodeOSSUserNotExists,
ErrUserNotExists: ErrCodeUserNotExists,
ErrReadBodyError: ErrCodeReadBodyError,
ErrVolPolicyNotExists: ErrCodeVolPolicyNotExists,
ErrDuplicateAccessKey: ErrCodeDuplicateAccessKey,

View File

@ -24,125 +24,138 @@ func (a Action) String() string {
return string(a)
}
func (a Action) IsKnown() bool {
return len(a) != 0 && a != UnknownAction
func (a Action) IsNone() bool {
return len(a) == 0 || a == NoneAction
}
const (
ActionPrefix = "action:"
OSSActionPrefix = ActionPrefix + "oss:"
GetObjectAction Action = OSSActionPrefix + "GetObject"
PutObjectAction Action = OSSActionPrefix + "PutObject"
CopyObjectAction Action = OSSActionPrefix + "CopyObject"
ListObjectsAction Action = OSSActionPrefix + "ListObjects"
DeleteObjectAction Action = OSSActionPrefix + "DeleteObject"
DeleteObjectsAction Action = OSSActionPrefix + "DeleteObjects"
HeadObjectAction Action = OSSActionPrefix + "HeadObject"
CreateBucketAction Action = OSSActionPrefix + "CreateBucket"
DeleteBucketAction Action = OSSActionPrefix + "DeleteBucket"
HeadBucketAction Action = OSSActionPrefix + "HeadBucket"
ListBucketAction Action = OSSActionPrefix + "ListBucket"
ListBucketVersionsAction Action = OSSActionPrefix + "ListBucketVersions"
ListBucketMultipartUploadsAction Action = OSSActionPrefix + "ListBucketMultipartUploads"
GetBucketPolicyAction Action = OSSActionPrefix + "GetBucketPolicy"
PutBucketPolicyAction Action = OSSActionPrefix + "PutBucketPolicy"
GetBucketAclAction Action = OSSActionPrefix + "GetBucketAcl"
PutBucketAclAction Action = OSSActionPrefix + "PutBucketAcl"
GetObjectAclAction Action = OSSActionPrefix + "GetObjectAcl"
GetObjectVersionAction Action = OSSActionPrefix + "GetObjectVersion"
PutObjectVersionAction Action = OSSActionPrefix + "PutObjectVersion"
GetObjectTorrentAction Action = OSSActionPrefix + "GetObjectTorrent"
PutObjectTorrentAction Action = OSSActionPrefix + "PutObjectTorrent"
PutObjectAclAction Action = OSSActionPrefix + "PutObjectAcl"
GetObjectVersionAclAction Action = OSSActionPrefix + "GetObjectVersionAcl"
PutObjectVersionAclAction Action = OSSActionPrefix + "PutObjectVersionAcl"
DeleteBucketPolicyAction Action = OSSActionPrefix + "DeleteBucketPolicy"
CreateMultipartUploadAction Action = OSSActionPrefix + "CreateMultipartUpload"
ListMultipartUploadsAction Action = OSSActionPrefix + "ListMultipartUploads"
UploadPartAction Action = OSSActionPrefix + "UploadPart"
ListPartsAction Action = OSSActionPrefix + "ListParts"
CompleteMultipartUploadAction Action = OSSActionPrefix + "CompleteMultipartUpload"
AbortMultipartUploadAction Action = OSSActionPrefix + "AbortMultipartUpload"
GetBucketLocationAction Action = OSSActionPrefix + "GetBucketLocation"
GetObjectXAttrAction Action = OSSActionPrefix + "GetObjectXAttr"
PutObjectXAttrAction Action = OSSActionPrefix + "PutObjectXAttr"
ListObjectXAttrsAction Action = OSSActionPrefix + "ListObjectXAttrs"
DeleteObjectXAttrAction Action = OSSActionPrefix + "DeleteObjectXAttr"
GetObjectTaggingAction Action = OSSActionPrefix + "GetObjectTagging"
PutObjectTaggingAction Action = OSSActionPrefix + "PutObjectTagging"
DeleteObjectTaggingAction Action = OSSActionPrefix + "DeleteObjectTagging"
GetBucketTaggingAction Action = OSSActionPrefix + "GetBucketTagging"
PutBucketTaggingAction Action = OSSActionPrefix + "PutBucketTagging"
DeleteBucketTaggingAction Action = OSSActionPrefix + "DeleteBucketTagging"
ActionPrefix = "action:"
OSSActionPrefix = ActionPrefix + "oss:"
POSIXActionPrefix = ActionPrefix + "posix:"
UnknownAction Action = ""
// constants for object storage interfaces
OSSGetObjectAction Action = OSSActionPrefix + "GetObject"
OSSPutObjectAction Action = OSSActionPrefix + "PutObject"
OSSCopyObjectAction Action = OSSActionPrefix + "CopyObject"
OSSListObjectsAction Action = OSSActionPrefix + "ListObjects"
OSSDeleteObjectAction Action = OSSActionPrefix + "DeleteObject"
OSSDeleteObjectsAction Action = OSSActionPrefix + "DeleteObjects"
OSSHeadObjectAction Action = OSSActionPrefix + "HeadObject"
OSSCreateBucketAction Action = OSSActionPrefix + "CreateBucket"
OSSDeleteBucketAction Action = OSSActionPrefix + "DeleteBucket"
OSSHeadBucketAction Action = OSSActionPrefix + "HeadBucket"
OSSListBucketAction Action = OSSActionPrefix + "ListBucket"
OSSListBucketVersionsAction Action = OSSActionPrefix + "ListBucketVersions"
OSSListBucketMultipartUploadsAction Action = OSSActionPrefix + "ListBucketMultipartUploads"
OSSGetBucketPolicyAction Action = OSSActionPrefix + "GetBucketPolicy"
OSSPutBucketPolicyAction Action = OSSActionPrefix + "PutBucketPolicy"
OSSGetBucketAclAction Action = OSSActionPrefix + "GetBucketAcl"
OSSPutBucketAclAction Action = OSSActionPrefix + "PutBucketAcl"
OSSGetObjectAclAction Action = OSSActionPrefix + "GetObjectAcl"
OSSGetObjectVersionAction Action = OSSActionPrefix + "GetObjectVersion"
OSSPutObjectVersionAction Action = OSSActionPrefix + "PutObjectVersion"
OSSGetObjectTorrentAction Action = OSSActionPrefix + "GetObjectTorrent"
OSSPutObjectTorrentAction Action = OSSActionPrefix + "PutObjectTorrent"
OSSPutObjectAclAction Action = OSSActionPrefix + "PutObjectAcl"
OSSGetObjectVersionAclAction Action = OSSActionPrefix + "GetObjectVersionAcl"
OSSPutObjectVersionAclAction Action = OSSActionPrefix + "PutObjectVersionAcl"
OSSDeleteBucketPolicyAction Action = OSSActionPrefix + "DeleteBucketPolicy"
OSSCreateMultipartUploadAction Action = OSSActionPrefix + "CreateMultipartUpload"
OSSListMultipartUploadsAction Action = OSSActionPrefix + "ListMultipartUploads"
OSSUploadPartAction Action = OSSActionPrefix + "UploadPart"
OSSListPartsAction Action = OSSActionPrefix + "ListParts"
OSSCompleteMultipartUploadAction Action = OSSActionPrefix + "CompleteMultipartUpload"
OSSAbortMultipartUploadAction Action = OSSActionPrefix + "AbortMultipartUpload"
OSSGetBucketLocationAction Action = OSSActionPrefix + "GetBucketLocation"
OSSGetObjectXAttrAction Action = OSSActionPrefix + "GetObjectXAttr"
OSSPutObjectXAttrAction Action = OSSActionPrefix + "PutObjectXAttr"
OSSListObjectXAttrsAction Action = OSSActionPrefix + "ListObjectXAttrs"
OSSDeleteObjectXAttrAction Action = OSSActionPrefix + "DeleteObjectXAttr"
OSSGetObjectTaggingAction Action = OSSActionPrefix + "GetObjectTagging"
OSSPutObjectTaggingAction Action = OSSActionPrefix + "PutObjectTagging"
OSSDeleteObjectTaggingAction Action = OSSActionPrefix + "DeleteObjectTagging"
OSSGetBucketTaggingAction Action = OSSActionPrefix + "GetBucketTagging"
OSSPutBucketTaggingAction Action = OSSActionPrefix + "PutBucketTagging"
OSSDeleteBucketTaggingAction Action = OSSActionPrefix + "DeleteBucketTagging"
// constants for POSIX file system interface
POSIXReadAction Action = POSIXActionPrefix + "Read"
POSIXWriteAction Action = POSIXActionPrefix + "Write"
NoneAction Action = ""
)
var (
AllActions = []Action{
GetObjectAction,
PutObjectAction,
CopyObjectAction,
ListObjectsAction,
DeleteObjectAction,
HeadObjectAction,
CreateBucketAction,
DeleteBucketAction,
HeadBucketAction,
ListBucketAction,
ListBucketVersionsAction,
ListBucketMultipartUploadsAction,
GetBucketPolicyAction,
PutBucketPolicyAction,
GetBucketAclAction,
PutBucketAclAction,
GetObjectAclAction,
GetObjectVersionAction,
PutObjectVersionAction,
GetObjectTorrentAction,
PutObjectTorrentAction,
PutObjectAclAction,
GetObjectVersionAclAction,
PutObjectVersionAclAction,
DeleteBucketPolicyAction,
CreateMultipartUploadAction,
ListMultipartUploadsAction,
UploadPartAction,
ListPartsAction,
CompleteMultipartUploadAction,
AbortMultipartUploadAction,
GetBucketLocationAction,
GetObjectXAttrAction,
PutObjectXAttrAction,
ListObjectXAttrsAction,
DeleteObjectXAttrAction,
GetObjectTaggingAction,
PutObjectTaggingAction,
DeleteObjectTaggingAction,
GetBucketTaggingAction,
PutBucketTaggingAction,
DeleteBucketTaggingAction,
// object storage interface actions
OSSGetObjectAction,
OSSPutObjectAction,
OSSCopyObjectAction,
OSSListObjectsAction,
OSSDeleteObjectAction,
OSSHeadObjectAction,
OSSCreateBucketAction,
OSSDeleteBucketAction,
OSSHeadBucketAction,
OSSListBucketAction,
OSSListBucketVersionsAction,
OSSListBucketMultipartUploadsAction,
OSSGetBucketPolicyAction,
OSSPutBucketPolicyAction,
OSSGetBucketAclAction,
OSSPutBucketAclAction,
OSSGetObjectAclAction,
OSSGetObjectVersionAction,
OSSPutObjectVersionAction,
OSSGetObjectTorrentAction,
OSSPutObjectTorrentAction,
OSSPutObjectAclAction,
OSSGetObjectVersionAclAction,
OSSPutObjectVersionAclAction,
OSSDeleteBucketPolicyAction,
OSSCreateMultipartUploadAction,
OSSListMultipartUploadsAction,
OSSUploadPartAction,
OSSListPartsAction,
OSSCompleteMultipartUploadAction,
OSSAbortMultipartUploadAction,
OSSGetBucketLocationAction,
OSSGetObjectXAttrAction,
OSSPutObjectXAttrAction,
OSSListObjectXAttrsAction,
OSSDeleteObjectXAttrAction,
OSSGetObjectTaggingAction,
OSSPutObjectTaggingAction,
OSSDeleteObjectTaggingAction,
OSSGetBucketTaggingAction,
OSSPutBucketTaggingAction,
OSSDeleteBucketTaggingAction,
// posix file system interface actions
POSIXReadAction,
POSIXWriteAction,
}
)
var (
actionRegexp = regexp.MustCompile("^perm:((oss:(\\w+))|(posix:(\\w)+))$")
)
func ParseAction(str string) Action {
if len(str) == 0 {
return UnknownAction
if len(str) == 0 || !actionRegexp.MatchString(str) {
return NoneAction
}
for _, act := range AllActions {
if act.String() == str {
return act
}
}
return UnknownAction
return NoneAction
}
type Actions []Action
func (actions Actions) Constant(action Action) bool {
func (actions Actions) Contains(action Action) bool {
if len(actions) == 0 {
return false
}
@ -154,12 +167,29 @@ func (actions Actions) Constant(action Action) bool {
return false
}
func (actions Actions) Len() int {
return len(actions)
}
type Permission string
func (p Permission) String() string {
return string(p)
}
func (p Permission) ReadableString() string {
if p.Valid() {
if p.IsBuiltin() {
return p.String()[len(BuiltinPermissionPrefix.String()):] + "(builtin)"
}
if p.IsCustom() {
return p.String()[len(CustomPermissionPrefix.String()):] + "(custom)"
}
return p.String()
}
return "None"
}
func (p Permission) IsBuiltin() bool {
return builtinPermRegexp.MatchString(string(p))
}
@ -168,6 +198,14 @@ func (p Permission) IsCustom() bool {
return customPermRegexp.MatchString(string(p))
}
func (p Permission) Valid() bool {
return permRegexp.MatchString(string(p))
}
func (p Permission) IsNone() bool {
return p == NonePermission
}
const (
// prefixes for value organization
PermissionPrefix Permission = "perm:"
@ -179,7 +217,7 @@ const (
BuiltinPermissionWritable Permission = BuiltinPermissionPrefix + "Writable"
// constants for unknown permission
UnknownPermission Permission = ""
NonePermission Permission = ""
)
var (
@ -192,7 +230,7 @@ func ParsePermission(value string) Permission {
if permRegexp.MatchString(value) {
return Permission(value)
}
return UnknownPermission
return NonePermission
}
func NewCustomPermission(name string) Permission {
@ -202,65 +240,74 @@ func NewCustomPermission(name string) Permission {
var (
builtinPermissionActionsMap = map[Permission]Actions{
BuiltinPermissionReadOnly: {
GetObjectAction,
ListObjectsAction,
HeadObjectAction,
HeadBucketAction,
ListBucketAction,
ListBucketVersionsAction,
ListBucketMultipartUploadsAction,
GetBucketPolicyAction,
GetBucketAclAction,
PutBucketAclAction,
GetObjectAclAction,
GetObjectVersionAction,
PutObjectVersionAction,
GetObjectTorrentAction,
GetObjectVersionAclAction,
ListMultipartUploadsAction,
ListPartsAction,
GetBucketLocationAction,
GetObjectXAttrAction,
ListObjectXAttrsAction,
GetObjectTaggingAction,
GetBucketTaggingAction,
// object storage interface
OSSGetObjectAction,
OSSListObjectsAction,
OSSHeadObjectAction,
OSSHeadBucketAction,
OSSListBucketAction,
OSSListBucketVersionsAction,
OSSListBucketMultipartUploadsAction,
OSSGetBucketPolicyAction,
OSSGetBucketAclAction,
OSSPutBucketAclAction,
OSSGetObjectAclAction,
OSSGetObjectVersionAction,
OSSPutObjectVersionAction,
OSSGetObjectTorrentAction,
OSSGetObjectVersionAclAction,
OSSListMultipartUploadsAction,
OSSListPartsAction,
OSSGetBucketLocationAction,
OSSGetObjectXAttrAction,
OSSListObjectXAttrsAction,
OSSGetObjectTaggingAction,
OSSGetBucketTaggingAction,
// file system interface
POSIXReadAction,
},
BuiltinPermissionWritable: {
GetObjectAction,
PutObjectAction,
CopyObjectAction,
ListObjectsAction,
DeleteObjectAction,
HeadObjectAction,
HeadBucketAction,
ListBucketAction,
ListBucketVersionsAction,
ListBucketMultipartUploadsAction,
GetBucketPolicyAction,
GetBucketAclAction,
GetObjectAclAction,
GetObjectVersionAction,
PutObjectVersionAction,
GetObjectTorrentAction,
PutObjectTorrentAction,
PutObjectAclAction,
GetObjectVersionAclAction,
PutObjectVersionAclAction,
CreateMultipartUploadAction,
ListMultipartUploadsAction,
UploadPartAction,
ListPartsAction,
CompleteMultipartUploadAction,
AbortMultipartUploadAction,
GetBucketLocationAction,
GetObjectXAttrAction,
PutObjectXAttrAction,
ListObjectXAttrsAction,
DeleteObjectXAttrAction,
GetObjectTaggingAction,
PutObjectTaggingAction,
DeleteObjectTaggingAction,
GetBucketTaggingAction,
// object storage interface
OSSGetObjectAction,
OSSPutObjectAction,
OSSCopyObjectAction,
OSSListObjectsAction,
OSSDeleteObjectAction,
OSSHeadObjectAction,
OSSHeadBucketAction,
OSSListBucketAction,
OSSListBucketVersionsAction,
OSSListBucketMultipartUploadsAction,
OSSGetBucketPolicyAction,
OSSGetBucketAclAction,
OSSGetObjectAclAction,
OSSGetObjectVersionAction,
OSSPutObjectVersionAction,
OSSGetObjectTorrentAction,
OSSPutObjectTorrentAction,
OSSPutObjectAclAction,
OSSGetObjectVersionAclAction,
OSSPutObjectVersionAclAction,
OSSCreateMultipartUploadAction,
OSSListMultipartUploadsAction,
OSSUploadPartAction,
OSSListPartsAction,
OSSCompleteMultipartUploadAction,
OSSAbortMultipartUploadAction,
OSSGetBucketLocationAction,
OSSGetObjectXAttrAction,
OSSPutObjectXAttrAction,
OSSListObjectXAttrsAction,
OSSDeleteObjectXAttrAction,
OSSGetObjectTaggingAction,
OSSPutObjectTaggingAction,
OSSDeleteObjectTaggingAction,
OSSGetBucketTaggingAction,
// file system interface
POSIXReadAction,
POSIXWriteAction,
},
}
)

View File

@ -77,6 +77,16 @@ type AKPolicy struct {
CreateTime string `json:"create_time"`
}
func NewAkPolicy() *AKPolicy {
return &AKPolicy{Policy: NewUserPolicy()}
}
type VolAK struct {
Vol string `json:"vol"`
AKAndActions map[string][]string // k: ak, v: actions or permissions
sync.RWMutex
}
type UserPolicy struct {
OwnVols []string `json:"own_vols"`
AuthorizedVols map[string][]string `json:"authorized_vols"` // mapping: volume -> actions
@ -90,14 +100,33 @@ func NewUserPolicy() *UserPolicy {
}
}
func NewAkPolicy() *AKPolicy {
return &AKPolicy{Policy: NewUserPolicy()}
func (policy *UserPolicy) IsOwn(volume string) bool {
policy.mu.RLock()
defer policy.mu.RUnlock()
for _, vol := range policy.OwnVols {
if vol == volume {
return true
}
}
return false
}
type VolAK struct {
Vol string `json:"vol"`
AKAndActions map[string][]string // k: ak, v: actions
sync.RWMutex
func (policy *UserPolicy) IsAuthorized(volume string, action Action) bool {
policy.mu.RLock()
defer policy.mu.RUnlock()
values, exist := policy.AuthorizedVols[volume]
if !exist {
return false
}
for _, value := range values {
if perm := ParsePermission(value); !perm.IsNone() && perm.IsBuiltin() && BuiltinPermissionActions(perm).Contains(action) {
return true
}
if action := ParseAction(value); action == action {
return true
}
}
return false
}
func (policy *UserPolicy) AddOwnVol(volume string) {
@ -126,6 +155,22 @@ func (policy *UserPolicy) RemoveOwnVol(volume string) {
}
}
func (policy *UserPolicy) SetPerm(volume string, perm Permission) {
policy.mu.Lock()
defer policy.mu.Unlock()
policy.AuthorizedVols[volume] = []string{perm.String()}
}
func (policy *UserPolicy) SetActions(volume string, actions Actions) {
policy.mu.Lock()
defer policy.mu.Unlock()
var values = make([]string, actions.Len())
for i, action := range actions {
values[i] = action.String()
}
policy.AuthorizedVols[volume] = values
}
func (policy *UserPolicy) Add(addPolicy *UserPolicy) {
policy.mu.Lock()
defer policy.mu.Unlock()
@ -198,4 +243,13 @@ type UserCreateParam struct {
Type UserType
}
type UserUpdateParam = UserCreateParam
type UserPermUpdateParam struct {
UserID string `json:"user_id"`
Volume string `json:"volume"`
Perm Permission `json:"perm"`
}
type UserPermRemoveParam struct {
UserID string `json:"user_id"`
Volume string `json:"volume"`
}