mirror of
https://github.com/minio/minio.git
synced 2025-11-07 04:42:56 -05:00
@@ -116,9 +116,9 @@ func getOldBucketsConfigPath() (string, error) {
|
||||
return path.Join(configPath, "buckets"), nil
|
||||
}
|
||||
|
||||
// readBucketPolicy - reads bucket policy for an input bucket, returns BucketPolicyNotFound
|
||||
// if bucket policy is not found. This function also parses the bucket policy into an object.
|
||||
func readBucketPolicy(bucket string, objAPI ObjectLayer) (*bucketPolicy, error) {
|
||||
// readBucketPolicyJSON - reads bucket policy for an input bucket, returns BucketPolicyNotFound
|
||||
// if bucket policy is not found.
|
||||
func readBucketPolicyJSON(bucket string, objAPI ObjectLayer) (bucketPolicyReader io.Reader, err error) {
|
||||
// Verify bucket is valid.
|
||||
if !IsValidBucketName(bucket) {
|
||||
return nil, BucketNameInvalid{Bucket: bucket}
|
||||
@@ -139,9 +139,22 @@ func readBucketPolicy(bucket string, objAPI ObjectLayer) (*bucketPolicy, error)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &buffer, nil
|
||||
}
|
||||
|
||||
// readBucketPolicy - reads bucket policy for an input bucket, returns BucketPolicyNotFound
|
||||
// if bucket policy is not found. This function also parses the bucket policy into an object.
|
||||
func readBucketPolicy(bucket string, objAPI ObjectLayer) (*bucketPolicy, error) {
|
||||
// Read bucket policy JSON.
|
||||
bucketPolicyReader, err := readBucketPolicyJSON(bucket, objAPI)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Parse the saved policy.
|
||||
var policy = &bucketPolicy{}
|
||||
err = parseBucketPolicy(&buffer, policy)
|
||||
err = parseBucketPolicy(bucketPolicyReader, policy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
|
||||
@@ -17,7 +17,10 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
@@ -30,6 +33,7 @@ import (
|
||||
"github.com/dustin/go-humanize"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/gorilla/rpc/v2/json2"
|
||||
"github.com/minio/minio-go/pkg/policy"
|
||||
"github.com/minio/miniobrowser"
|
||||
)
|
||||
|
||||
@@ -482,3 +486,98 @@ func writeWebErrorResponse(w http.ResponseWriter, err error) {
|
||||
w.WriteHeader(apiErr.HTTPStatusCode)
|
||||
w.Write([]byte(apiErr.Description))
|
||||
}
|
||||
|
||||
// GetBucketPolicyArgs - get bucket policy args.
|
||||
type GetBucketPolicyArgs struct {
|
||||
BucketName string `json:"bucketName"`
|
||||
Prefix string `json:"prefix"`
|
||||
}
|
||||
|
||||
// GetBucketPolicyRep - get bucket policy reply.
|
||||
type GetBucketPolicyRep struct {
|
||||
UIVersion string `json:"uiVersion"`
|
||||
Policy policy.BucketPolicy `json:"policy"`
|
||||
}
|
||||
|
||||
func readBucketAccessPolicy(objAPI ObjectLayer, bucketName string) (policy.BucketAccessPolicy, error) {
|
||||
bucketPolicyReader, err := readBucketPolicyJSON(bucketName, objAPI)
|
||||
if err != nil {
|
||||
if _, ok := err.(BucketPolicyNotFound); ok {
|
||||
return policy.BucketAccessPolicy{}, nil
|
||||
}
|
||||
return policy.BucketAccessPolicy{}, err
|
||||
}
|
||||
|
||||
bucketPolicyBuf, err := ioutil.ReadAll(bucketPolicyReader)
|
||||
if err != nil {
|
||||
return policy.BucketAccessPolicy{}, err
|
||||
}
|
||||
|
||||
policyInfo := policy.BucketAccessPolicy{}
|
||||
err = json.Unmarshal(bucketPolicyBuf, &policyInfo)
|
||||
if err != nil {
|
||||
return policy.BucketAccessPolicy{}, err
|
||||
}
|
||||
|
||||
return policyInfo, nil
|
||||
|
||||
}
|
||||
|
||||
// GetBucketPolicy - get bucket policy.
|
||||
func (web *webAPIHandlers) GetBucketPolicy(r *http.Request, args *GetBucketPolicyArgs, reply *GetBucketPolicyRep) error {
|
||||
if !isJWTReqAuthenticated(r) {
|
||||
return &json2.Error{Message: "Unauthorized request"}
|
||||
}
|
||||
|
||||
policyInfo, err := readBucketAccessPolicy(web.ObjectAPI, args.BucketName)
|
||||
if err != nil {
|
||||
return &json2.Error{Message: err.Error()}
|
||||
}
|
||||
|
||||
bucketPolicy := policy.GetPolicy(policyInfo.Statements, args.BucketName, args.Prefix)
|
||||
|
||||
reply.UIVersion = miniobrowser.UIVersion
|
||||
reply.Policy = bucketPolicy
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetBucketPolicyArgs - set bucket policy args.
|
||||
type SetBucketPolicyArgs struct {
|
||||
BucketName string `json:"bucketName"`
|
||||
Prefix string `json:"prefix"`
|
||||
Policy string `json:"policy"`
|
||||
}
|
||||
|
||||
// SetBucketPolicy - set bucket policy.
|
||||
func (web *webAPIHandlers) SetBucketPolicy(r *http.Request, args *SetBucketPolicyArgs, reply *WebGenericRep) error {
|
||||
if !isJWTReqAuthenticated(r) {
|
||||
return &json2.Error{Message: "Unauthorized request"}
|
||||
}
|
||||
|
||||
bucketPolicy := policy.BucketPolicy(args.Policy)
|
||||
if !bucketPolicy.IsValidBucketPolicy() {
|
||||
return &json2.Error{Message: "Invalid policy " + args.Policy}
|
||||
}
|
||||
|
||||
policyInfo, err := readBucketAccessPolicy(web.ObjectAPI, args.BucketName)
|
||||
if err != nil {
|
||||
return &json2.Error{Message: err.Error()}
|
||||
}
|
||||
|
||||
policyInfo.Statements = policy.SetPolicy(policyInfo.Statements, bucketPolicy, args.BucketName, args.Prefix)
|
||||
|
||||
data, err := json.Marshal(policyInfo)
|
||||
if err != nil {
|
||||
return &json2.Error{Message: err.Error()}
|
||||
}
|
||||
|
||||
// TODO: update policy statements according to bucket name, prefix and policy arguments.
|
||||
if err := writeBucketPolicy(args.BucketName, web.ObjectAPI, bytes.NewReader(data), int64(len(data))); err != nil {
|
||||
return &json2.Error{Message: err.Error()}
|
||||
}
|
||||
|
||||
reply.UIVersion = miniobrowser.UIVersion
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ import (
|
||||
"net/http/httptest"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/minio/minio-go/pkg/policy"
|
||||
)
|
||||
|
||||
// Authenticate and get JWT token - will be called before every webrpc handler invocation
|
||||
@@ -711,3 +713,60 @@ func testDownloadWebHandler(obj ObjectLayer, instanceType string, t TestErrHandl
|
||||
t.Fatalf("The downloaded file is corrupted")
|
||||
}
|
||||
}
|
||||
|
||||
// Wrapper for calling GetBucketPolicy Handler
|
||||
func TestWebHandlerGetBucketPolicyHandler(t *testing.T) {
|
||||
ExecObjectLayerTest(t, testWebGetBucketPolicyHandler)
|
||||
}
|
||||
|
||||
// testWebGetBucketPolicyHandler - Test GetBucketPolicy web handler
|
||||
func testWebGetBucketPolicyHandler(obj ObjectLayer, instanceType string, t TestErrHandler) {
|
||||
// Register the API end points with XL/FS object layer.
|
||||
apiRouter := initTestWebRPCEndPoint(obj)
|
||||
// initialize the server and obtain the credentials and root.
|
||||
// credentials are necessary to sign the HTTP request.
|
||||
rootPath, err := newTestConfig("us-east-1")
|
||||
if err != nil {
|
||||
t.Fatalf("Init Test config failed")
|
||||
}
|
||||
// remove the root folder after the test ends.
|
||||
defer removeAll(rootPath)
|
||||
|
||||
credentials := serverConfig.GetCredential()
|
||||
|
||||
authorization, err := getWebRPCToken(apiRouter, credentials.AccessKeyID, credentials.SecretAccessKey)
|
||||
if err != nil {
|
||||
t.Fatal("Cannot authenticate")
|
||||
}
|
||||
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
bucketName := getRandomBucketName()
|
||||
|
||||
testCases := []struct {
|
||||
bucketName string
|
||||
prefix string
|
||||
expectedResult policy.BucketPolicy
|
||||
}{
|
||||
{bucketName, "", policy.BucketPolicyNone},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
args := &GetBucketPolicyArgs{BucketName: testCase.bucketName, Prefix: testCase.prefix}
|
||||
reply := &GetBucketPolicyRep{}
|
||||
req, err := newTestWebRPCRequest("Web.GetBucketPolicy", authorization, args)
|
||||
if err != nil {
|
||||
t.Fatalf("Test %d: Failed to create HTTP request: <ERROR> %v", i+1, err)
|
||||
}
|
||||
apiRouter.ServeHTTP(rec, req)
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("Test %d: Expected the response status to be 200, but instead found `%d`", i+1, rec.Code)
|
||||
}
|
||||
if err = getTestWebRPCResponse(rec, &reply); err != nil {
|
||||
t.Fatalf("Test %d: Should succeed but it didn't, %v", i+1, err)
|
||||
}
|
||||
if testCase.expectedResult != reply.Policy {
|
||||
t.Fatalf("Test %d: expected: %v, got: %v", i+1, testCase.expectedResult, reply.Policy)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user