Custom Policies for Buckets (#1332)
* custom policies * fixing error * add formatting
This commit is contained in:
@@ -3735,6 +3735,9 @@ func init() {
|
||||
"creation_date": {
|
||||
"type": "string"
|
||||
},
|
||||
"definition": {
|
||||
"type": "string"
|
||||
},
|
||||
"details": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -5294,6 +5297,9 @@ func init() {
|
||||
"properties": {
|
||||
"access": {
|
||||
"$ref": "#/definitions/bucketAccess"
|
||||
},
|
||||
"definition": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -9626,6 +9632,9 @@ func init() {
|
||||
"creation_date": {
|
||||
"type": "string"
|
||||
},
|
||||
"definition": {
|
||||
"type": "string"
|
||||
},
|
||||
"details": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -11185,6 +11194,9 @@ func init() {
|
||||
"properties": {
|
||||
"access": {
|
||||
"$ref": "#/definitions/bucketAccess"
|
||||
},
|
||||
"definition": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -436,7 +436,7 @@ func getMakeBucketResponse(session *models.Principal, br *models.MakeBucketReque
|
||||
}
|
||||
|
||||
// setBucketAccessPolicy set the access permissions on an existing bucket.
|
||||
func setBucketAccessPolicy(ctx context.Context, client MinioClient, bucketName string, access models.BucketAccess) error {
|
||||
func setBucketAccessPolicy(ctx context.Context, client MinioClient, bucketName string, access models.BucketAccess, policyDefinition string) error {
|
||||
if strings.TrimSpace(bucketName) == "" {
|
||||
return fmt.Errorf("error: bucket name not present")
|
||||
}
|
||||
@@ -444,18 +444,21 @@ func setBucketAccessPolicy(ctx context.Context, client MinioClient, bucketName s
|
||||
return fmt.Errorf("error: bucket access not present")
|
||||
}
|
||||
// Prepare policyJSON corresponding to the access type
|
||||
if access != models.BucketAccessPRIVATE && access != models.BucketAccessPUBLIC {
|
||||
if access != models.BucketAccessPRIVATE && access != models.BucketAccessPUBLIC && access != models.BucketAccessCUSTOM {
|
||||
return fmt.Errorf("access: `%s` not supported", access)
|
||||
}
|
||||
bucketPolicy := consoleAccess2policyAccess(access)
|
||||
|
||||
bucketAccessPolicy := policy.BucketAccessPolicy{Version: minioIAMPolicy.DefaultVersion}
|
||||
if access == models.BucketAccessCUSTOM {
|
||||
err := client.setBucketPolicyWithContext(ctx, bucketName, policyDefinition)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
bucketPolicy := consoleAccess2policyAccess(access)
|
||||
bucketAccessPolicy.Statements = policy.SetPolicy(bucketAccessPolicy.Statements,
|
||||
bucketPolicy, bucketName, "")
|
||||
// implemented like minio/mc/ s3Client.SetAccess()
|
||||
if len(bucketAccessPolicy.Statements) == 0 {
|
||||
return client.setBucketPolicyWithContext(ctx, bucketName, "")
|
||||
}
|
||||
policyJSON, err := json.Marshal(bucketAccessPolicy)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -469,6 +472,7 @@ func getBucketSetPolicyResponse(session *models.Principal, bucketName string, re
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
|
||||
defer cancel()
|
||||
|
||||
// get updated bucket details and return it
|
||||
mClient, err := newMinioClient(session)
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
@@ -476,11 +480,11 @@ func getBucketSetPolicyResponse(session *models.Principal, bucketName string, re
|
||||
// create a minioClient interface implementation
|
||||
// defining the client to be used
|
||||
minioClient := minioClient{client: mClient}
|
||||
// set bucket access policy
|
||||
if err := setBucketAccessPolicy(ctx, minioClient, bucketName, *req.Access); err != nil {
|
||||
|
||||
if err := setBucketAccessPolicy(ctx, minioClient, bucketName, *req.Access, req.Definition); err != nil {
|
||||
return nil, prepareError(err)
|
||||
}
|
||||
// get updated bucket details and return it
|
||||
// set bucket access policy
|
||||
bucket, err := getBucketInfo(ctx, minioClient, bucketName)
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
@@ -548,19 +552,19 @@ func getBucketInfo(ctx context.Context, client MinioClient, bucketName string) (
|
||||
LogError("error getting bucket policy: %v", err)
|
||||
}
|
||||
|
||||
var policyAccess policy.BucketPolicy
|
||||
if policyStr == "" {
|
||||
policyAccess = policy.BucketPolicyNone
|
||||
bucketAccess = models.BucketAccessPRIVATE
|
||||
} else {
|
||||
var p policy.BucketAccessPolicy
|
||||
if err = json.Unmarshal([]byte(policyStr), &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
policyAccess = policy.GetPolicy(p.Statements, bucketName, "")
|
||||
}
|
||||
bucketAccess = policyAccess2consoleAccess(policyAccess)
|
||||
if bucketAccess == models.BucketAccessPRIVATE && policyStr != "" {
|
||||
bucketAccess = models.BucketAccessCUSTOM
|
||||
policyAccess := policy.GetPolicy(p.Statements, bucketName, "")
|
||||
if len(p.Statements) > 0 && policyAccess == policy.BucketPolicyNone {
|
||||
bucketAccess = models.BucketAccessCUSTOM
|
||||
} else {
|
||||
bucketAccess = policyAccess2consoleAccess(policyAccess)
|
||||
}
|
||||
}
|
||||
bucketTags, err := client.GetBucketTagging(ctx, bucketName)
|
||||
if err != nil {
|
||||
@@ -574,6 +578,7 @@ func getBucketInfo(ctx context.Context, client MinioClient, bucketName string) (
|
||||
return &models.Bucket{
|
||||
Name: &bucketName,
|
||||
Access: &bucketAccess,
|
||||
Definition: policyStr,
|
||||
CreationDate: "", // to be implemented
|
||||
Size: 0, // to be implemented
|
||||
Details: bucketDetails,
|
||||
|
||||
@@ -338,8 +338,8 @@ func TestBucketInfo(t *testing.T) {
|
||||
assert.Equal(outputExpected.CreationDate, bucketInfo.CreationDate)
|
||||
assert.Equal(outputExpected.Size, bucketInfo.Size)
|
||||
|
||||
// Test-3: getBucketInfo() get a bucket with CUSTOM access
|
||||
// if bucket has a custom policy set it should return CUSTOM
|
||||
// Test-3: getBucketInfo() get a bucket with PRIVATE access
|
||||
// if bucket has a null statement, the the bucket is PRIVATE
|
||||
mockPolicy = "{\"Version\":\"2012-10-17\",\"Statement\":[]}"
|
||||
minioGetBucketPolicyMock = func(bucketName string) (string, error) {
|
||||
return mockPolicy, nil
|
||||
@@ -347,7 +347,7 @@ func TestBucketInfo(t *testing.T) {
|
||||
bucketToSet = "csbucket"
|
||||
outputExpected = &models.Bucket{
|
||||
Name: swag.String(bucketToSet),
|
||||
Access: models.NewBucketAccess(models.BucketAccessCUSTOM),
|
||||
Access: models.NewBucketAccess(models.BucketAccessPRIVATE),
|
||||
CreationDate: "", // to be implemented
|
||||
Size: 0, // to be implemented
|
||||
}
|
||||
@@ -393,27 +393,27 @@ func TestSetBucketAccess(t *testing.T) {
|
||||
minioSetBucketPolicyWithContextMock = func(ctx context.Context, bucketName, policy string) error {
|
||||
return nil
|
||||
}
|
||||
if err := setBucketAccessPolicy(ctx, minClient, "bucktest1", models.BucketAccessPUBLIC); err != nil {
|
||||
if err := setBucketAccessPolicy(ctx, minClient, "bucktest1", models.BucketAccessPUBLIC, ""); err != nil {
|
||||
t.Errorf("Failed on %s:, error occurred: %s", function, err.Error())
|
||||
}
|
||||
|
||||
// Test-2: setBucketAccessPolicy() set private access
|
||||
if err := setBucketAccessPolicy(ctx, minClient, "bucktest1", models.BucketAccessPRIVATE); err != nil {
|
||||
if err := setBucketAccessPolicy(ctx, minClient, "bucktest1", models.BucketAccessPRIVATE, ""); err != nil {
|
||||
t.Errorf("Failed on %s:, error occurred: %s", function, err.Error())
|
||||
}
|
||||
|
||||
// Test-3: setBucketAccessPolicy() set invalid access, expected error
|
||||
if err := setBucketAccessPolicy(ctx, minClient, "bucktest1", "other"); assert.Error(err) {
|
||||
if err := setBucketAccessPolicy(ctx, minClient, "bucktest1", "other", ""); assert.Error(err) {
|
||||
assert.Equal("access: `other` not supported", err.Error())
|
||||
}
|
||||
|
||||
// Test-4: setBucketAccessPolicy() set access on empty bucket name, expected error
|
||||
if err := setBucketAccessPolicy(ctx, minClient, "", models.BucketAccessPRIVATE); assert.Error(err) {
|
||||
if err := setBucketAccessPolicy(ctx, minClient, "", models.BucketAccessPRIVATE, ""); assert.Error(err) {
|
||||
assert.Equal("error: bucket name not present", err.Error())
|
||||
}
|
||||
|
||||
// Test-5: setBucketAccessPolicy() set empty access on bucket, expected error
|
||||
if err := setBucketAccessPolicy(ctx, minClient, "bucktest1", ""); assert.Error(err) {
|
||||
if err := setBucketAccessPolicy(ctx, minClient, "bucktest1", "", ""); assert.Error(err) {
|
||||
assert.Equal("error: bucket access not present", err.Error())
|
||||
}
|
||||
|
||||
@@ -421,7 +421,7 @@ func TestSetBucketAccess(t *testing.T) {
|
||||
minioSetBucketPolicyWithContextMock = func(ctx context.Context, bucketName, policy string) error {
|
||||
return errors.New("error")
|
||||
}
|
||||
if err := setBucketAccessPolicy(ctx, minClient, "bucktest1", models.BucketAccessPUBLIC); assert.Error(err) {
|
||||
if err := setBucketAccessPolicy(ctx, minClient, "bucktest1", models.BucketAccessPUBLIC, ""); assert.Error(err) {
|
||||
assert.Equal("error", err.Error())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user