gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

api-object-lock.go (6985B)


      1 /*
      2  * MinIO Go Library for Amazon S3 Compatible Cloud Storage
      3  * Copyright 2019 MinIO, Inc.
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 package minio
     19 
     20 import (
     21 	"bytes"
     22 	"context"
     23 	"encoding/xml"
     24 	"fmt"
     25 	"net/http"
     26 	"net/url"
     27 	"time"
     28 
     29 	"github.com/minio/minio-go/v7/pkg/s3utils"
     30 )
     31 
     32 // RetentionMode - object retention mode.
     33 type RetentionMode string
     34 
     35 const (
     36 	// Governance - governance mode.
     37 	Governance RetentionMode = "GOVERNANCE"
     38 
     39 	// Compliance - compliance mode.
     40 	Compliance RetentionMode = "COMPLIANCE"
     41 )
     42 
     43 func (r RetentionMode) String() string {
     44 	return string(r)
     45 }
     46 
     47 // IsValid - check whether this retention mode is valid or not.
     48 func (r RetentionMode) IsValid() bool {
     49 	return r == Governance || r == Compliance
     50 }
     51 
     52 // ValidityUnit - retention validity unit.
     53 type ValidityUnit string
     54 
     55 const (
     56 	// Days - denotes no. of days.
     57 	Days ValidityUnit = "DAYS"
     58 
     59 	// Years - denotes no. of years.
     60 	Years ValidityUnit = "YEARS"
     61 )
     62 
     63 func (unit ValidityUnit) String() string {
     64 	return string(unit)
     65 }
     66 
     67 // IsValid - check whether this validity unit is valid or not.
     68 func (unit ValidityUnit) isValid() bool {
     69 	return unit == Days || unit == Years
     70 }
     71 
     72 // Retention - bucket level retention configuration.
     73 type Retention struct {
     74 	Mode     RetentionMode
     75 	Validity time.Duration
     76 }
     77 
     78 func (r Retention) String() string {
     79 	return fmt.Sprintf("{Mode:%v, Validity:%v}", r.Mode, r.Validity)
     80 }
     81 
     82 // IsEmpty - returns whether retention is empty or not.
     83 func (r Retention) IsEmpty() bool {
     84 	return r.Mode == "" || r.Validity == 0
     85 }
     86 
     87 // objectLockConfig - object lock configuration specified in
     88 // https://docs.aws.amazon.com/AmazonS3/latest/API/Type_API_ObjectLockConfiguration.html
     89 type objectLockConfig struct {
     90 	XMLNS             string   `xml:"xmlns,attr,omitempty"`
     91 	XMLName           xml.Name `xml:"ObjectLockConfiguration"`
     92 	ObjectLockEnabled string   `xml:"ObjectLockEnabled"`
     93 	Rule              *struct {
     94 		DefaultRetention struct {
     95 			Mode  RetentionMode `xml:"Mode"`
     96 			Days  *uint         `xml:"Days"`
     97 			Years *uint         `xml:"Years"`
     98 		} `xml:"DefaultRetention"`
     99 	} `xml:"Rule,omitempty"`
    100 }
    101 
    102 func newObjectLockConfig(mode *RetentionMode, validity *uint, unit *ValidityUnit) (*objectLockConfig, error) {
    103 	config := &objectLockConfig{
    104 		ObjectLockEnabled: "Enabled",
    105 	}
    106 
    107 	if mode != nil && validity != nil && unit != nil {
    108 		if !mode.IsValid() {
    109 			return nil, fmt.Errorf("invalid retention mode `%v`", mode)
    110 		}
    111 
    112 		if !unit.isValid() {
    113 			return nil, fmt.Errorf("invalid validity unit `%v`", unit)
    114 		}
    115 
    116 		config.Rule = &struct {
    117 			DefaultRetention struct {
    118 				Mode  RetentionMode `xml:"Mode"`
    119 				Days  *uint         `xml:"Days"`
    120 				Years *uint         `xml:"Years"`
    121 			} `xml:"DefaultRetention"`
    122 		}{}
    123 
    124 		config.Rule.DefaultRetention.Mode = *mode
    125 		if *unit == Days {
    126 			config.Rule.DefaultRetention.Days = validity
    127 		} else {
    128 			config.Rule.DefaultRetention.Years = validity
    129 		}
    130 
    131 		return config, nil
    132 	}
    133 
    134 	if mode == nil && validity == nil && unit == nil {
    135 		return config, nil
    136 	}
    137 
    138 	return nil, fmt.Errorf("all of retention mode, validity and validity unit must be passed")
    139 }
    140 
    141 // SetBucketObjectLockConfig sets object lock configuration in given bucket. mode, validity and unit are either all set or all nil.
    142 func (c *Client) SetBucketObjectLockConfig(ctx context.Context, bucketName string, mode *RetentionMode, validity *uint, unit *ValidityUnit) error {
    143 	// Input validation.
    144 	if err := s3utils.CheckValidBucketName(bucketName); err != nil {
    145 		return err
    146 	}
    147 
    148 	// Get resources properly escaped and lined up before
    149 	// using them in http request.
    150 	urlValues := make(url.Values)
    151 	urlValues.Set("object-lock", "")
    152 
    153 	config, err := newObjectLockConfig(mode, validity, unit)
    154 	if err != nil {
    155 		return err
    156 	}
    157 
    158 	configData, err := xml.Marshal(config)
    159 	if err != nil {
    160 		return err
    161 	}
    162 
    163 	reqMetadata := requestMetadata{
    164 		bucketName:       bucketName,
    165 		queryValues:      urlValues,
    166 		contentBody:      bytes.NewReader(configData),
    167 		contentLength:    int64(len(configData)),
    168 		contentMD5Base64: sumMD5Base64(configData),
    169 		contentSHA256Hex: sum256Hex(configData),
    170 	}
    171 
    172 	// Execute PUT bucket object lock configuration.
    173 	resp, err := c.executeMethod(ctx, http.MethodPut, reqMetadata)
    174 	defer closeResponse(resp)
    175 	if err != nil {
    176 		return err
    177 	}
    178 	if resp != nil {
    179 		if resp.StatusCode != http.StatusOK {
    180 			return httpRespToErrorResponse(resp, bucketName, "")
    181 		}
    182 	}
    183 	return nil
    184 }
    185 
    186 // GetObjectLockConfig gets object lock configuration of given bucket.
    187 func (c *Client) GetObjectLockConfig(ctx context.Context, bucketName string) (objectLock string, mode *RetentionMode, validity *uint, unit *ValidityUnit, err error) {
    188 	// Input validation.
    189 	if err := s3utils.CheckValidBucketName(bucketName); err != nil {
    190 		return "", nil, nil, nil, err
    191 	}
    192 
    193 	urlValues := make(url.Values)
    194 	urlValues.Set("object-lock", "")
    195 
    196 	// Execute GET on bucket to list objects.
    197 	resp, err := c.executeMethod(ctx, http.MethodGet, requestMetadata{
    198 		bucketName:       bucketName,
    199 		queryValues:      urlValues,
    200 		contentSHA256Hex: emptySHA256Hex,
    201 	})
    202 	defer closeResponse(resp)
    203 	if err != nil {
    204 		return "", nil, nil, nil, err
    205 	}
    206 	if resp != nil {
    207 		if resp.StatusCode != http.StatusOK {
    208 			return "", nil, nil, nil, httpRespToErrorResponse(resp, bucketName, "")
    209 		}
    210 	}
    211 	config := &objectLockConfig{}
    212 	if err = xml.NewDecoder(resp.Body).Decode(config); err != nil {
    213 		return "", nil, nil, nil, err
    214 	}
    215 
    216 	if config.Rule != nil {
    217 		mode = &config.Rule.DefaultRetention.Mode
    218 		if config.Rule.DefaultRetention.Days != nil {
    219 			validity = config.Rule.DefaultRetention.Days
    220 			days := Days
    221 			unit = &days
    222 		} else {
    223 			validity = config.Rule.DefaultRetention.Years
    224 			years := Years
    225 			unit = &years
    226 		}
    227 		return config.ObjectLockEnabled, mode, validity, unit, nil
    228 	}
    229 	return config.ObjectLockEnabled, nil, nil, nil, nil
    230 }
    231 
    232 // GetBucketObjectLockConfig gets object lock configuration of given bucket.
    233 func (c *Client) GetBucketObjectLockConfig(ctx context.Context, bucketName string) (mode *RetentionMode, validity *uint, unit *ValidityUnit, err error) {
    234 	_, mode, validity, unit, err = c.GetObjectLockConfig(ctx, bucketName)
    235 	return mode, validity, unit, err
    236 }
    237 
    238 // SetObjectLockConfig sets object lock configuration in given bucket. mode, validity and unit are either all set or all nil.
    239 func (c *Client) SetObjectLockConfig(ctx context.Context, bucketName string, mode *RetentionMode, validity *uint, unit *ValidityUnit) error {
    240 	return c.SetBucketObjectLockConfig(ctx, bucketName, mode, validity, unit)
    241 }