api-object-legal-hold.go (4831B)
1 /* 2 * MinIO Go Library for Amazon S3 Compatible Cloud Storage 3 * Copyright 2020 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 28 "github.com/minio/minio-go/v7/pkg/s3utils" 29 ) 30 31 // objectLegalHold - object legal hold specified in 32 // https://docs.aws.amazon.com/AmazonS3/latest/API/archive-RESTObjectPUTLegalHold.html 33 type objectLegalHold struct { 34 XMLNS string `xml:"xmlns,attr,omitempty"` 35 XMLName xml.Name `xml:"LegalHold"` 36 Status LegalHoldStatus `xml:"Status,omitempty"` 37 } 38 39 // PutObjectLegalHoldOptions represents options specified by user for PutObjectLegalHold call 40 type PutObjectLegalHoldOptions struct { 41 VersionID string 42 Status *LegalHoldStatus 43 } 44 45 // GetObjectLegalHoldOptions represents options specified by user for GetObjectLegalHold call 46 type GetObjectLegalHoldOptions struct { 47 VersionID string 48 } 49 50 // LegalHoldStatus - object legal hold status. 51 type LegalHoldStatus string 52 53 const ( 54 // LegalHoldEnabled indicates legal hold is enabled 55 LegalHoldEnabled LegalHoldStatus = "ON" 56 57 // LegalHoldDisabled indicates legal hold is disabled 58 LegalHoldDisabled LegalHoldStatus = "OFF" 59 ) 60 61 func (r LegalHoldStatus) String() string { 62 return string(r) 63 } 64 65 // IsValid - check whether this legal hold status is valid or not. 66 func (r LegalHoldStatus) IsValid() bool { 67 return r == LegalHoldEnabled || r == LegalHoldDisabled 68 } 69 70 func newObjectLegalHold(status *LegalHoldStatus) (*objectLegalHold, error) { 71 if status == nil { 72 return nil, fmt.Errorf("Status not set") 73 } 74 if !status.IsValid() { 75 return nil, fmt.Errorf("invalid legal hold status `%v`", status) 76 } 77 legalHold := &objectLegalHold{ 78 Status: *status, 79 } 80 return legalHold, nil 81 } 82 83 // PutObjectLegalHold : sets object legal hold for a given object and versionID. 84 func (c *Client) PutObjectLegalHold(ctx context.Context, bucketName, objectName string, opts PutObjectLegalHoldOptions) error { 85 // Input validation. 86 if err := s3utils.CheckValidBucketName(bucketName); err != nil { 87 return err 88 } 89 90 if err := s3utils.CheckValidObjectName(objectName); err != nil { 91 return err 92 } 93 94 // Get resources properly escaped and lined up before 95 // using them in http request. 96 urlValues := make(url.Values) 97 urlValues.Set("legal-hold", "") 98 99 if opts.VersionID != "" { 100 urlValues.Set("versionId", opts.VersionID) 101 } 102 103 lh, err := newObjectLegalHold(opts.Status) 104 if err != nil { 105 return err 106 } 107 108 lhData, err := xml.Marshal(lh) 109 if err != nil { 110 return err 111 } 112 113 reqMetadata := requestMetadata{ 114 bucketName: bucketName, 115 objectName: objectName, 116 queryValues: urlValues, 117 contentBody: bytes.NewReader(lhData), 118 contentLength: int64(len(lhData)), 119 contentMD5Base64: sumMD5Base64(lhData), 120 contentSHA256Hex: sum256Hex(lhData), 121 } 122 123 // Execute PUT Object Legal Hold. 124 resp, err := c.executeMethod(ctx, http.MethodPut, reqMetadata) 125 defer closeResponse(resp) 126 if err != nil { 127 return err 128 } 129 if resp != nil { 130 if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusNoContent { 131 return httpRespToErrorResponse(resp, bucketName, objectName) 132 } 133 } 134 return nil 135 } 136 137 // GetObjectLegalHold gets legal-hold status of given object. 138 func (c *Client) GetObjectLegalHold(ctx context.Context, bucketName, objectName string, opts GetObjectLegalHoldOptions) (status *LegalHoldStatus, err error) { 139 // Input validation. 140 if err := s3utils.CheckValidBucketName(bucketName); err != nil { 141 return nil, err 142 } 143 144 if err := s3utils.CheckValidObjectName(objectName); err != nil { 145 return nil, err 146 } 147 urlValues := make(url.Values) 148 urlValues.Set("legal-hold", "") 149 150 if opts.VersionID != "" { 151 urlValues.Set("versionId", opts.VersionID) 152 } 153 154 // Execute GET on bucket to list objects. 155 resp, err := c.executeMethod(ctx, http.MethodGet, requestMetadata{ 156 bucketName: bucketName, 157 objectName: objectName, 158 queryValues: urlValues, 159 contentSHA256Hex: emptySHA256Hex, 160 }) 161 defer closeResponse(resp) 162 if err != nil { 163 return nil, err 164 } 165 if resp != nil { 166 if resp.StatusCode != http.StatusOK { 167 return nil, httpRespToErrorResponse(resp, bucketName, objectName) 168 } 169 } 170 lh := &objectLegalHold{} 171 if err = xml.NewDecoder(resp.Body).Decode(lh); err != nil { 172 return nil, err 173 } 174 175 return &lh.Status, nil 176 }