api-bucket-policy.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. * MinIO Go Library for Amazon S3 Compatible Cloud Storage
  3. * Copyright 2020 MinIO, Inc.
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package minio
  17. import (
  18. "context"
  19. "io/ioutil"
  20. "net/http"
  21. "net/url"
  22. "strings"
  23. "github.com/minio/minio-go/v7/pkg/s3utils"
  24. )
  25. // SetBucketPolicy sets the access permissions on an existing bucket.
  26. func (c Client) SetBucketPolicy(ctx context.Context, bucketName, policy string) error {
  27. // Input validation.
  28. if err := s3utils.CheckValidBucketName(bucketName); err != nil {
  29. return err
  30. }
  31. // If policy is empty then delete the bucket policy.
  32. if policy == "" {
  33. return c.removeBucketPolicy(ctx, bucketName)
  34. }
  35. // Save the updated policies.
  36. return c.putBucketPolicy(ctx, bucketName, policy)
  37. }
  38. // Saves a new bucket policy.
  39. func (c Client) putBucketPolicy(ctx context.Context, bucketName, policy string) error {
  40. // Get resources properly escaped and lined up before
  41. // using them in http request.
  42. urlValues := make(url.Values)
  43. urlValues.Set("policy", "")
  44. reqMetadata := requestMetadata{
  45. bucketName: bucketName,
  46. queryValues: urlValues,
  47. contentBody: strings.NewReader(policy),
  48. contentLength: int64(len(policy)),
  49. }
  50. // Execute PUT to upload a new bucket policy.
  51. resp, err := c.executeMethod(ctx, http.MethodPut, reqMetadata)
  52. defer closeResponse(resp)
  53. if err != nil {
  54. return err
  55. }
  56. if resp != nil {
  57. if resp.StatusCode != http.StatusNoContent && resp.StatusCode != http.StatusOK {
  58. return httpRespToErrorResponse(resp, bucketName, "")
  59. }
  60. }
  61. return nil
  62. }
  63. // Removes all policies on a bucket.
  64. func (c Client) removeBucketPolicy(ctx context.Context, bucketName string) error {
  65. // Get resources properly escaped and lined up before
  66. // using them in http request.
  67. urlValues := make(url.Values)
  68. urlValues.Set("policy", "")
  69. // Execute DELETE on objectName.
  70. resp, err := c.executeMethod(ctx, http.MethodDelete, requestMetadata{
  71. bucketName: bucketName,
  72. queryValues: urlValues,
  73. contentSHA256Hex: emptySHA256Hex,
  74. })
  75. defer closeResponse(resp)
  76. if err != nil {
  77. return err
  78. }
  79. return nil
  80. }
  81. // GetBucketPolicy returns the current policy
  82. func (c Client) GetBucketPolicy(ctx context.Context, bucketName string) (string, error) {
  83. // Input validation.
  84. if err := s3utils.CheckValidBucketName(bucketName); err != nil {
  85. return "", err
  86. }
  87. bucketPolicy, err := c.getBucketPolicy(ctx, bucketName)
  88. if err != nil {
  89. errResponse := ToErrorResponse(err)
  90. if errResponse.Code == "NoSuchBucketPolicy" {
  91. return "", nil
  92. }
  93. return "", err
  94. }
  95. return bucketPolicy, nil
  96. }
  97. // Request server for current bucket policy.
  98. func (c Client) getBucketPolicy(ctx context.Context, bucketName string) (string, error) {
  99. // Get resources properly escaped and lined up before
  100. // using them in http request.
  101. urlValues := make(url.Values)
  102. urlValues.Set("policy", "")
  103. // Execute GET on bucket to list objects.
  104. resp, err := c.executeMethod(ctx, http.MethodGet, requestMetadata{
  105. bucketName: bucketName,
  106. queryValues: urlValues,
  107. contentSHA256Hex: emptySHA256Hex,
  108. })
  109. defer closeResponse(resp)
  110. if err != nil {
  111. return "", err
  112. }
  113. if resp != nil {
  114. if resp.StatusCode != http.StatusOK {
  115. return "", httpRespToErrorResponse(resp, bucketName, "")
  116. }
  117. }
  118. bucketPolicyBuf, err := ioutil.ReadAll(resp.Body)
  119. if err != nil {
  120. return "", err
  121. }
  122. policy := string(bucketPolicyBuf)
  123. return policy, err
  124. }