storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/cmd/bucket-encryption-handlers.go (about)

     1  /*
     2   * MinIO Cloud Storage, (C) 2020 MinIO, Inc.
     3   *
     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  
    17  package cmd
    18  
    19  import (
    20  	"encoding/xml"
    21  	"fmt"
    22  	"io"
    23  	"net/http"
    24  
    25  	"github.com/gorilla/mux"
    26  
    27  	"storj.io/minio/cmd/logger"
    28  	"storj.io/minio/pkg/bucket/policy"
    29  )
    30  
    31  const (
    32  	// Bucket Encryption configuration file name.
    33  	bucketSSEConfig = "bucket-encryption.xml"
    34  )
    35  
    36  // PutBucketEncryptionHandler - Stores given bucket encryption configuration
    37  // https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html
    38  func (api ObjectAPIHandlers) PutBucketEncryptionHandler(w http.ResponseWriter, r *http.Request) {
    39  	ctx := NewContext(r, w, "PutBucketEncryption")
    40  
    41  	defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
    42  
    43  	objAPI := api.ObjectAPI()
    44  	if objAPI == nil {
    45  		WriteErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r))
    46  		return
    47  	}
    48  
    49  	if !objAPI.IsEncryptionSupported() {
    50  		WriteErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r))
    51  		return
    52  	}
    53  
    54  	vars := mux.Vars(r)
    55  	bucket := vars["bucket"]
    56  
    57  	if s3Error := checkRequestAuthType(ctx, r, policy.PutBucketEncryptionAction, bucket, ""); s3Error != ErrNone {
    58  		WriteErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r))
    59  		return
    60  	}
    61  
    62  	// Check if bucket exists.
    63  	if _, err := objAPI.GetBucketInfo(ctx, bucket); err != nil {
    64  		WriteErrorResponse(ctx, w, ToAPIError(ctx, err), r.URL, guessIsBrowserReq(r))
    65  		return
    66  	}
    67  
    68  	// Parse bucket encryption xml
    69  	encConfig, err := validateBucketSSEConfig(io.LimitReader(r.Body, maxBucketSSEConfigSize))
    70  	if err != nil {
    71  		apiErr := APIError{
    72  			Code:           "MalformedXML",
    73  			Description:    fmt.Sprintf("%s (%s)", errorCodes[ErrMalformedXML].Description, err),
    74  			HTTPStatusCode: errorCodes[ErrMalformedXML].HTTPStatusCode,
    75  		}
    76  		WriteErrorResponse(ctx, w, apiErr, r.URL, guessIsBrowserReq(r))
    77  		return
    78  	}
    79  
    80  	// Return error if KMS is not initialized
    81  	if GlobalKMS == nil {
    82  		WriteErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrKMSNotConfigured), r.URL, guessIsBrowserReq(r))
    83  		return
    84  	}
    85  
    86  	configData, err := xml.Marshal(encConfig)
    87  	if err != nil {
    88  		WriteErrorResponse(ctx, w, ToAPIError(ctx, err), r.URL, guessIsBrowserReq(r))
    89  		return
    90  	}
    91  
    92  	// Store the bucket encryption configuration in the object layer
    93  	if err = globalBucketMetadataSys.Update(bucket, bucketSSEConfig, configData); err != nil {
    94  		WriteErrorResponse(ctx, w, ToAPIError(ctx, err), r.URL, guessIsBrowserReq(r))
    95  		return
    96  	}
    97  
    98  	writeSuccessResponseHeadersOnly(w)
    99  }
   100  
   101  // GetBucketEncryptionHandler - Returns bucket policy configuration
   102  // https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketEncryption.html
   103  func (api ObjectAPIHandlers) GetBucketEncryptionHandler(w http.ResponseWriter, r *http.Request) {
   104  	ctx := NewContext(r, w, "GetBucketEncryption")
   105  
   106  	defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
   107  
   108  	objAPI := api.ObjectAPI()
   109  	if objAPI == nil {
   110  		WriteErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r))
   111  		return
   112  	}
   113  
   114  	vars := mux.Vars(r)
   115  	bucket := vars["bucket"]
   116  
   117  	if s3Error := checkRequestAuthType(ctx, r, policy.GetBucketEncryptionAction, bucket, ""); s3Error != ErrNone {
   118  		WriteErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r))
   119  		return
   120  	}
   121  
   122  	// Check if bucket exists
   123  	var err error
   124  	if _, err = objAPI.GetBucketInfo(ctx, bucket); err != nil {
   125  		WriteErrorResponse(ctx, w, ToAPIError(ctx, err), r.URL, guessIsBrowserReq(r))
   126  		return
   127  	}
   128  
   129  	config, err := globalBucketMetadataSys.GetSSEConfig(bucket)
   130  	if err != nil {
   131  		WriteErrorResponse(ctx, w, ToAPIError(ctx, err), r.URL, guessIsBrowserReq(r))
   132  		return
   133  	}
   134  
   135  	configData, err := xml.Marshal(config)
   136  	if err != nil {
   137  		WriteErrorResponse(ctx, w, ToAPIError(ctx, err), r.URL, guessIsBrowserReq(r))
   138  		return
   139  	}
   140  
   141  	// Write bucket encryption configuration to client
   142  	WriteSuccessResponseXML(w, configData)
   143  }
   144  
   145  // DeleteBucketEncryptionHandler - Removes bucket encryption configuration
   146  func (api ObjectAPIHandlers) DeleteBucketEncryptionHandler(w http.ResponseWriter, r *http.Request) {
   147  	ctx := NewContext(r, w, "DeleteBucketEncryption")
   148  
   149  	defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
   150  
   151  	objAPI := api.ObjectAPI()
   152  	if objAPI == nil {
   153  		WriteErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r))
   154  		return
   155  	}
   156  
   157  	vars := mux.Vars(r)
   158  	bucket := vars["bucket"]
   159  
   160  	if s3Error := checkRequestAuthType(ctx, r, policy.PutBucketEncryptionAction, bucket, ""); s3Error != ErrNone {
   161  		WriteErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r))
   162  		return
   163  	}
   164  
   165  	// Check if bucket exists
   166  	var err error
   167  	if _, err = objAPI.GetBucketInfo(ctx, bucket); err != nil {
   168  		WriteErrorResponse(ctx, w, ToAPIError(ctx, err), r.URL, guessIsBrowserReq(r))
   169  		return
   170  	}
   171  
   172  	// Delete bucket encryption config from object layer
   173  	if err = globalBucketMetadataSys.Update(bucket, bucketSSEConfig, nil); err != nil {
   174  		WriteErrorResponse(ctx, w, ToAPIError(ctx, err), r.URL, guessIsBrowserReq(r))
   175  		return
   176  	}
   177  
   178  	writeSuccessNoContent(w)
   179  }