aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--weed/s3api/auth_credentials.go12
-rw-r--r--weed/s3api/auth_credentials_test.go49
-rw-r--r--weed/s3api/chunked_reader_v4.go5
-rw-r--r--weed/s3api/s3api_bucket_handlers.go2
4 files changed, 58 insertions, 10 deletions
diff --git a/weed/s3api/auth_credentials.go b/weed/s3api/auth_credentials.go
index 87d478136..3c27b7d35 100644
--- a/weed/s3api/auth_credentials.go
+++ b/weed/s3api/auth_credentials.go
@@ -247,9 +247,9 @@ func (iam *IdentityAccessManagement) authRequest(r *http.Request, action Action)
glog.V(3).Infof("user name: %v actions: %v, action: %v", identity.Name, identity.Actions, action)
- bucket, _ := xhttp.GetBucketAndObject(r)
+ bucket, object := xhttp.GetBucketAndObject(r)
- if !identity.canDo(action, bucket) {
+ if !identity.canDo(action, bucket, object) {
return identity, s3err.ErrAccessDenied
}
@@ -307,7 +307,7 @@ func (iam *IdentityAccessManagement) authUser(r *http.Request) (*Identity, s3err
return identity, s3err.ErrNone
}
-func (identity *Identity) canDo(action Action, bucket string) bool {
+func (identity *Identity) canDo(action Action, bucket string, objectKey string) bool {
if identity.isAdmin() {
return true
}
@@ -319,15 +319,13 @@ func (identity *Identity) canDo(action Action, bucket string) bool {
if bucket == "" {
return false
}
+ target := string(action) + ":" + bucket + "/" + objectKey
limitedByBucket := string(action) + ":" + bucket
adminLimitedByBucket := s3_constants.ACTION_ADMIN + ":" + bucket
for _, a := range identity.Actions {
act := string(a)
if strings.HasSuffix(act, "*") {
- if strings.HasPrefix(limitedByBucket, act[:len(act)-1]) {
- return true
- }
- if strings.HasPrefix(adminLimitedByBucket, act[:len(act)-1]) {
+ if strings.HasPrefix(target, act[:len(act)-1]) {
return true
}
} else {
diff --git a/weed/s3api/auth_credentials_test.go b/weed/s3api/auth_credentials_test.go
index 0383ddbcd..b674557fa 100644
--- a/weed/s3api/auth_credentials_test.go
+++ b/weed/s3api/auth_credentials_test.go
@@ -2,6 +2,7 @@ package s3api
import (
. "github.com/chrislusf/seaweedfs/weed/s3api/s3_constants"
+ "github.com/stretchr/testify/assert"
"testing"
"github.com/golang/protobuf/jsonpb"
@@ -67,3 +68,51 @@ func TestIdentityListFileFormat(t *testing.T) {
println(text)
}
+
+func TestCanDo(t *testing.T) {
+ ident1 := &Identity{
+ Name: "anything",
+ Actions: []Action{
+ "Write:bucket1/a/b/c/*",
+ "Write:bucket1/a/b/other",
+ },
+ }
+ // object specific
+ assert.Equal(t, true, ident1.canDo(ACTION_WRITE, "bucket1", "a/b/c/d.txt"))
+ assert.Equal(t, false, ident1.canDo(ACTION_WRITE, "bucket1", "a/b/other/some"), "action without *")
+
+ // bucket specific
+ ident2 := &Identity{
+ Name: "anything",
+ Actions: []Action{
+ "Read:bucket1",
+ "Write:bucket1/*",
+ },
+ }
+ assert.Equal(t, true, ident2.canDo(ACTION_READ, "bucket1", "a/b/c/d.txt"))
+ assert.Equal(t, true, ident2.canDo(ACTION_WRITE, "bucket1", "a/b/c/d.txt"))
+ assert.Equal(t, false, ident2.canDo(ACTION_LIST, "bucket1", "a/b/c/d.txt"))
+
+ // across buckets
+ ident3 := &Identity{
+ Name: "anything",
+ Actions: []Action{
+ "Read",
+ "Write",
+ },
+ }
+ assert.Equal(t, true, ident3.canDo(ACTION_READ, "bucket1", "a/b/c/d.txt"))
+ assert.Equal(t, true, ident3.canDo(ACTION_WRITE, "bucket1", "a/b/c/d.txt"))
+ assert.Equal(t, false, ident3.canDo(ACTION_LIST, "bucket1", "a/b/other/some"))
+
+ // partial buckets
+ ident4 := &Identity{
+ Name: "anything",
+ Actions: []Action{
+ "Read:special_*",
+ },
+ }
+ assert.Equal(t, true, ident4.canDo(ACTION_READ, "special_bucket", "a/b/c/d.txt"))
+ assert.Equal(t, false, ident4.canDo(ACTION_READ, "bucket1", "a/b/c/d.txt"))
+
+}
diff --git a/weed/s3api/chunked_reader_v4.go b/weed/s3api/chunked_reader_v4.go
index 5dd0648c6..e683faf22 100644
--- a/weed/s3api/chunked_reader_v4.go
+++ b/weed/s3api/chunked_reader_v4.go
@@ -25,6 +25,7 @@ import (
"encoding/hex"
"errors"
xhttp "github.com/chrislusf/seaweedfs/weed/s3api/http"
+ "github.com/chrislusf/seaweedfs/weed/s3api/s3_constants"
"github.com/chrislusf/seaweedfs/weed/s3api/s3err"
"hash"
"io"
@@ -91,8 +92,8 @@ func (iam *IdentityAccessManagement) calculateSeedSignature(r *http.Request) (cr
return nil, "", "", time.Time{}, s3err.ErrInvalidAccessKeyID
}
- bucket, _ := xhttp.GetBucketAndObject(r)
- if !identity.canDo("Write", bucket) {
+ bucket, object := xhttp.GetBucketAndObject(r)
+ if !identity.canDo(s3_constants.ACTION_WRITE, bucket, object) {
errCode = s3err.ErrAccessDenied
return
}
diff --git a/weed/s3api/s3api_bucket_handlers.go b/weed/s3api/s3api_bucket_handlers.go
index c3e50ec44..3233f4006 100644
--- a/weed/s3api/s3api_bucket_handlers.go
+++ b/weed/s3api/s3api_bucket_handlers.go
@@ -55,7 +55,7 @@ func (s3a *S3ApiServer) ListBucketsHandler(w http.ResponseWriter, r *http.Reques
var buckets []*s3.Bucket
for _, entry := range entries {
if entry.IsDirectory {
- if identity != nil && !identity.canDo(s3_constants.ACTION_LIST, entry.Name) {
+ if identity != nil && !identity.canDo(s3_constants.ACTION_LIST, entry.Name, "") {
continue
}
buckets = append(buckets, &s3.Bucket{