2020-04-02 12:51:51 -07:00
// This file is part of MinIO Console Server
2021-01-19 17:04:13 -06:00
// Copyright (c) 2021 MinIO, Inc.
2020-04-01 18:18:57 -07:00
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package restapi
import (
"context"
Multiple fixes for sub path and objects filename encoding (#1086)
- fix: objects with special characters (ie: /,&,%,*) won't open
- fix: create subdolders with special characters won't work, ie: /,&,%,*
- fix: view subfolders with special characters (ie: /,&,%,*) won't work
- refactor: browser breadcrumb
- fix: rewind enable/disable toggle button not working
- fix: undefined style for add bucket button in buckets page
- Added: validation for folder path naming
- refactor: encode prefix parameter using base64 to avoid url encode
issues
- fix: share link for versioned object won't work because of wrong
version_id
Signed-off-by: Lenin Alevski <alevsk.8772@gmail.com>
2021-09-28 12:25:28 -07:00
"encoding/base64"
2020-04-01 18:18:57 -07:00
"encoding/json"
"fmt"
"strings"
"time"
2021-06-23 01:10:54 -05:00
"github.com/minio/mc/cmd"
2020-12-15 19:25:43 -06:00
"github.com/minio/mc/pkg/probe"
2020-12-03 13:45:45 -06:00
"github.com/minio/minio-go/v7"
2020-10-25 12:56:23 -07:00
"github.com/minio/minio-go/v7/pkg/sse"
2021-11-11 18:36:18 -08:00
"github.com/minio/minio-go/v7/pkg/tags"
2020-09-28 12:46:08 -05:00
2020-12-03 13:45:45 -06:00
"errors"
2020-04-01 18:18:57 -07:00
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/swag"
2020-07-26 00:34:17 -07:00
"github.com/minio/console/models"
"github.com/minio/console/restapi/operations"
"github.com/minio/console/restapi/operations/user_api"
2020-07-25 14:38:16 -07:00
"github.com/minio/minio-go/v7/pkg/policy"
2022-01-20 00:29:57 -07:00
"github.com/minio/minio-go/v7/pkg/replication"
2021-06-01 11:34:55 -07:00
minioIAMPolicy "github.com/minio/pkg/iam/policy"
2020-04-01 18:18:57 -07:00
)
2020-07-26 00:34:17 -07:00
func registerBucketsHandlers ( api * operations . ConsoleAPI ) {
2020-04-01 18:18:57 -07:00
// list buckets
2020-07-10 19:14:28 -07:00
api . UserAPIListBucketsHandler = user_api . ListBucketsHandlerFunc ( func ( params user_api . ListBucketsParams , session * models . Principal ) middleware . Responder {
listBucketsResponse , err := getListBucketsResponse ( session )
2020-04-01 18:18:57 -07:00
if err != nil {
2020-09-04 20:32:57 -07:00
return user_api . NewListBucketsDefault ( int ( err . Code ) ) . WithPayload ( err )
2020-04-01 18:18:57 -07:00
}
return user_api . NewListBucketsOK ( ) . WithPayload ( listBucketsResponse )
} )
// make bucket
2020-07-10 19:14:28 -07:00
api . UserAPIMakeBucketHandler = user_api . MakeBucketHandlerFunc ( func ( params user_api . MakeBucketParams , session * models . Principal ) middleware . Responder {
if err := getMakeBucketResponse ( session , params . Body ) ; err != nil {
2020-09-04 20:32:57 -07:00
return user_api . NewMakeBucketDefault ( int ( err . Code ) ) . WithPayload ( err )
2020-04-01 18:18:57 -07:00
}
return user_api . NewMakeBucketCreated ( )
} )
// delete bucket
2020-07-10 19:14:28 -07:00
api . UserAPIDeleteBucketHandler = user_api . DeleteBucketHandlerFunc ( func ( params user_api . DeleteBucketParams , session * models . Principal ) middleware . Responder {
if err := getDeleteBucketResponse ( session , params ) ; err != nil {
2020-09-04 20:32:57 -07:00
return user_api . NewMakeBucketDefault ( int ( err . Code ) ) . WithPayload ( err )
2020-04-01 18:18:57 -07:00
}
return user_api . NewDeleteBucketNoContent ( )
} )
// get bucket info
2020-07-10 19:14:28 -07:00
api . UserAPIBucketInfoHandler = user_api . BucketInfoHandlerFunc ( func ( params user_api . BucketInfoParams , session * models . Principal ) middleware . Responder {
bucketInfoResp , err := getBucketInfoResponse ( session , params )
2020-04-01 18:18:57 -07:00
if err != nil {
2020-09-04 20:32:57 -07:00
return user_api . NewBucketInfoDefault ( int ( err . Code ) ) . WithPayload ( err )
2020-04-01 18:18:57 -07:00
}
return user_api . NewBucketInfoOK ( ) . WithPayload ( bucketInfoResp )
} )
// set bucket policy
2020-07-10 19:14:28 -07:00
api . UserAPIBucketSetPolicyHandler = user_api . BucketSetPolicyHandlerFunc ( func ( params user_api . BucketSetPolicyParams , session * models . Principal ) middleware . Responder {
bucketSetPolicyResp , err := getBucketSetPolicyResponse ( session , params . Name , params . Body )
2020-04-01 18:18:57 -07:00
if err != nil {
2020-09-04 20:32:57 -07:00
return user_api . NewBucketSetPolicyDefault ( int ( err . Code ) ) . WithPayload ( err )
2020-04-01 18:18:57 -07:00
}
return user_api . NewBucketSetPolicyOK ( ) . WithPayload ( bucketSetPolicyResp )
} )
2021-11-11 18:36:18 -08:00
// set bucket tags
api . UserAPIPutBucketTagsHandler = user_api . PutBucketTagsHandlerFunc ( func ( params user_api . PutBucketTagsParams , session * models . Principal ) middleware . Responder {
err := getPutBucketTagsResponse ( session , params . BucketName , params . Body )
if err != nil {
return user_api . NewPutBucketTagsDefault ( int ( err . Code ) ) . WithPayload ( err )
}
return user_api . NewPutBucketTagsOK ( )
} )
2020-09-28 12:46:08 -05:00
// get bucket versioning
api . UserAPIGetBucketVersioningHandler = user_api . GetBucketVersioningHandlerFunc ( func ( params user_api . GetBucketVersioningParams , session * models . Principal ) middleware . Responder {
getBucketVersioning , err := getBucketVersionedResponse ( session , params . BucketName )
if err != nil {
return user_api . NewGetBucketVersioningDefault ( 500 ) . WithPayload ( & models . Error { Code : 500 , Message : swag . String ( err . Error ( ) ) } )
}
return user_api . NewGetBucketVersioningOK ( ) . WithPayload ( getBucketVersioning )
} )
2021-03-19 18:48:58 -06:00
// update bucket versioning
api . UserAPISetBucketVersioningHandler = user_api . SetBucketVersioningHandlerFunc ( func ( params user_api . SetBucketVersioningParams , session * models . Principal ) middleware . Responder {
err := setBucketVersioningResponse ( session , params . BucketName , & params )
if err != nil {
return user_api . NewSetBucketVersioningDefault ( 500 ) . WithPayload ( err )
}
return user_api . NewSetBucketVersioningCreated ( )
} )
2020-09-28 12:46:08 -05:00
// get bucket replication
api . UserAPIGetBucketReplicationHandler = user_api . GetBucketReplicationHandlerFunc ( func ( params user_api . GetBucketReplicationParams , session * models . Principal ) middleware . Responder {
2021-07-19 12:24:35 -07:00
getBucketReplication , err := getBucketReplicationResponse ( session , params . BucketName )
2020-09-28 12:46:08 -05:00
if err != nil {
return user_api . NewGetBucketReplicationDefault ( 500 ) . WithPayload ( & models . Error { Code : 500 , Message : swag . String ( err . Error ( ) ) } )
}
return user_api . NewGetBucketReplicationOK ( ) . WithPayload ( getBucketReplication )
} )
2022-01-20 00:29:57 -07:00
// get single bucket replication rule
api . UserAPIGetBucketReplicationRuleHandler = user_api . GetBucketReplicationRuleHandlerFunc ( func ( params user_api . GetBucketReplicationRuleParams , session * models . Principal ) middleware . Responder {
getBucketReplicationRule , err := getBucketReplicationRuleResponse ( session , params . BucketName , params . RuleID )
if err != nil {
return user_api . NewGetBucketReplicationRuleDefault ( 500 ) . WithPayload ( & models . Error { Code : 500 , Message : swag . String ( err . Error ( ) ) } )
}
return user_api . NewGetBucketReplicationRuleOK ( ) . WithPayload ( getBucketReplicationRule )
} )
2020-10-25 12:56:23 -07:00
// enable bucket encryption
api . UserAPIEnableBucketEncryptionHandler = user_api . EnableBucketEncryptionHandlerFunc ( func ( params user_api . EnableBucketEncryptionParams , session * models . Principal ) middleware . Responder {
if err := enableBucketEncryptionResponse ( session , params ) ; err != nil {
return user_api . NewEnableBucketEncryptionDefault ( int ( err . Code ) ) . WithPayload ( err )
}
return user_api . NewEnableBucketEncryptionOK ( )
} )
// disable bucket encryption
api . UserAPIDisableBucketEncryptionHandler = user_api . DisableBucketEncryptionHandlerFunc ( func ( params user_api . DisableBucketEncryptionParams , session * models . Principal ) middleware . Responder {
if err := disableBucketEncryptionResponse ( session , params ) ; err != nil {
return user_api . NewDisableBucketEncryptionDefault ( int ( err . Code ) ) . WithPayload ( err )
}
return user_api . NewDisableBucketEncryptionOK ( )
} )
// get bucket encryption info
api . UserAPIGetBucketEncryptionInfoHandler = user_api . GetBucketEncryptionInfoHandlerFunc ( func ( params user_api . GetBucketEncryptionInfoParams , session * models . Principal ) middleware . Responder {
response , err := getBucketEncryptionInfoResponse ( session , params )
if err != nil {
return user_api . NewGetBucketEncryptionInfoDefault ( int ( err . Code ) ) . WithPayload ( err )
}
return user_api . NewGetBucketEncryptionInfoOK ( ) . WithPayload ( response )
} )
2020-12-03 13:45:45 -06:00
// set bucket retention config
api . UserAPISetBucketRetentionConfigHandler = user_api . SetBucketRetentionConfigHandlerFunc ( func ( params user_api . SetBucketRetentionConfigParams , session * models . Principal ) middleware . Responder {
if err := getSetBucketRetentionConfigResponse ( session , params ) ; err != nil {
return user_api . NewSetBucketRetentionConfigDefault ( int ( err . Code ) ) . WithPayload ( err )
}
return user_api . NewSetBucketRetentionConfigOK ( )
} )
2020-12-15 19:25:43 -06:00
// get bucket retention config
api . UserAPIGetBucketRetentionConfigHandler = user_api . GetBucketRetentionConfigHandlerFunc ( func ( params user_api . GetBucketRetentionConfigParams , session * models . Principal ) middleware . Responder {
response , err := getBucketRetentionConfigResponse ( session , params . BucketName )
if err != nil {
return user_api . NewGetBucketRetentionConfigDefault ( int ( err . Code ) ) . WithPayload ( err )
}
return user_api . NewGetBucketRetentionConfigOK ( ) . WithPayload ( response )
} )
2021-03-22 16:28:07 -07:00
// get bucket object locking status
api . UserAPIGetBucketObjectLockingStatusHandler = user_api . GetBucketObjectLockingStatusHandlerFunc ( func ( params user_api . GetBucketObjectLockingStatusParams , session * models . Principal ) middleware . Responder {
2021-08-09 21:23:40 -07:00
getBucketObjectLockingStatus , err := getBucketObjectLockingResponse ( session , params . BucketName )
2021-03-22 16:28:07 -07:00
if err != nil {
return user_api . NewGetBucketObjectLockingStatusDefault ( 500 ) . WithPayload ( & models . Error { Code : 500 , Message : swag . String ( err . Error ( ) ) } )
}
return user_api . NewGetBucketObjectLockingStatusOK ( ) . WithPayload ( getBucketObjectLockingStatus )
} )
2021-06-23 01:10:54 -05:00
// get objects rewind for a bucket
api . UserAPIGetBucketRewindHandler = user_api . GetBucketRewindHandlerFunc ( func ( params user_api . GetBucketRewindParams , session * models . Principal ) middleware . Responder {
getBucketRewind , err := getBucketRewindResponse ( session , params )
if err != nil {
return user_api . NewGetBucketRewindDefault ( 500 ) . WithPayload ( err )
}
return user_api . NewGetBucketRewindOK ( ) . WithPayload ( getBucketRewind )
} )
2020-09-28 12:46:08 -05:00
}
2021-03-19 18:48:58 -06:00
type VersionState string
const (
VersionEnable VersionState = "enable"
VersionSuspend = "suspend"
)
// removeBucket deletes a bucket
func doSetVersioning ( client MCClient , state VersionState ) error {
err := client . setVersioning ( context . Background ( ) , string ( state ) )
if err != nil {
2021-06-04 11:35:55 -07:00
LogError ( "error setting versioning for bucket: %s" , err . Cause )
2021-03-19 18:48:58 -06:00
return err . Cause
}
return nil
}
func setBucketVersioningResponse ( session * models . Principal , bucketName string , params * user_api . SetBucketVersioningParams ) * models . Error {
s3Client , err := newS3BucketClient ( session , bucketName , "" )
if err != nil {
2021-07-19 17:17:56 -07:00
return prepareError ( err )
2021-03-19 18:48:58 -06:00
}
// create a mc S3Client interface implementation
// defining the client to be used
amcClient := mcClient { client : s3Client }
var versioningState VersionState = VersionSuspend
if params . Body . Versioning {
versioningState = VersionEnable
}
2021-03-22 16:28:07 -07:00
if err := doSetVersioning ( amcClient , versioningState ) ; err != nil {
2021-07-19 17:17:56 -07:00
return prepareError ( err )
2021-03-19 18:48:58 -06:00
}
return nil
}
2021-07-19 12:24:35 -07:00
func getBucketReplicationResponse ( session * models . Principal , bucketName string ) ( * models . BucketReplicationResponse , error ) {
2020-09-28 12:46:08 -05:00
ctx , cancel := context . WithTimeout ( context . Background ( ) , time . Second * 20 )
defer cancel ( )
mClient , err := newMinioClient ( session )
if err != nil {
2021-06-04 11:35:55 -07:00
LogError ( "error creating MinIO Client: %v" , err )
2020-09-28 12:46:08 -05:00
return nil , err
}
// create a minioClient interface implementation
// defining the client to be used
minioClient := minioClient { client : mClient }
// we will tolerate this call failing
res , err := minioClient . getBucketReplication ( ctx , bucketName )
if err != nil {
2021-06-04 11:35:55 -07:00
LogError ( "error versioning bucket: %v" , err )
2020-09-28 12:46:08 -05:00
}
var rules [ ] * models . BucketReplicationRule
for _ , rule := range res . Rules {
2021-05-27 16:25:00 -07:00
repDelMarkerStatus := false
if rule . DeleteMarkerReplication . Status == "enable" {
repDelMarkerStatus = true
}
repDelStatus := false
if rule . DeleteReplication . Status == "enable" {
repDelMarkerStatus = true
}
2020-09-28 12:46:08 -05:00
rules = append ( rules , & models . BucketReplicationRule {
2021-05-27 16:25:00 -07:00
DeleteMarkerReplication : repDelMarkerStatus ,
DeletesReplication : repDelStatus ,
2020-09-28 12:46:08 -05:00
Destination : & models . BucketReplicationDestination { Bucket : rule . Destination . Bucket } ,
2021-05-27 16:25:00 -07:00
Tags : rule . Tags ( ) ,
Prefix : rule . Prefix ( ) ,
2020-09-28 12:46:08 -05:00
ID : rule . ID ,
Priority : int32 ( rule . Priority ) ,
Status : string ( rule . Status ) ,
2022-01-20 00:29:57 -07:00
StorageClass : rule . Destination . StorageClass ,
2020-09-28 12:46:08 -05:00
} )
}
// serialize output
2021-07-19 12:24:35 -07:00
bucketRResponse := & models . BucketReplicationResponse {
2020-09-28 12:46:08 -05:00
Rules : rules ,
}
2021-07-19 12:24:35 -07:00
return bucketRResponse , nil
2020-09-28 12:46:08 -05:00
}
2022-01-20 00:29:57 -07:00
func getBucketReplicationRuleResponse ( session * models . Principal , bucketName , ruleID string ) ( * models . BucketReplicationRule , error ) {
ctx , cancel := context . WithTimeout ( context . Background ( ) , time . Second * 20 )
defer cancel ( )
mClient , err := newMinioClient ( session )
if err != nil {
LogError ( "error creating MinIO Client: %v" , err )
return nil , err
}
// create a minioClient interface implementation
// defining the client to be used
minioClient := minioClient { client : mClient }
replicationRules , err := minioClient . getBucketReplication ( ctx , bucketName )
if err != nil {
return nil , err
}
var foundRule replication . Rule
found := false
for i := range replicationRules . Rules {
if replicationRules . Rules [ i ] . ID == ruleID {
foundRule = replicationRules . Rules [ i ]
found = true
break
}
}
if ! found {
return nil , errors . New ( "no rule is set with this ID" )
}
repDelMarkerStatus := false
if foundRule . DeleteMarkerReplication . Status == "Enabled" {
repDelMarkerStatus = true
}
repDelStatus := false
if foundRule . DeleteReplication . Status == "Enabled" {
repDelStatus = true
}
existingObjects := false
if foundRule . ExistingObjectReplication . Status == "Enabled" {
existingObjects = true
}
metadataModifications := false
if foundRule . SourceSelectionCriteria . ReplicaModifications . Status == "Enabled" {
metadataModifications = true
}
returnRule := & models . BucketReplicationRule {
DeleteMarkerReplication : repDelMarkerStatus ,
DeletesReplication : repDelStatus ,
Destination : & models . BucketReplicationDestination { Bucket : foundRule . Destination . Bucket } ,
Tags : foundRule . Tags ( ) ,
Prefix : foundRule . Prefix ( ) ,
ID : foundRule . ID ,
Priority : int32 ( foundRule . Priority ) ,
Status : string ( foundRule . Status ) ,
StorageClass : foundRule . Destination . StorageClass ,
ExistingObjects : existingObjects ,
MetadataReplication : metadataModifications ,
}
return returnRule , nil
}
2020-09-28 12:46:08 -05:00
func getBucketVersionedResponse ( session * models . Principal , bucketName string ) ( * models . BucketVersioningResponse , error ) {
ctx , cancel := context . WithTimeout ( context . Background ( ) , time . Second * 20 )
defer cancel ( )
mClient , err := newMinioClient ( session )
if err != nil {
2021-06-04 11:35:55 -07:00
LogError ( "error creating MinIO Client: %v" , err )
2020-09-28 12:46:08 -05:00
return nil , err
}
2021-07-19 12:24:35 -07:00
2020-09-28 12:46:08 -05:00
// create a minioClient interface implementation
// defining the client to be used
minioClient := minioClient { client : mClient }
// we will tolerate this call failing
res , err := minioClient . getBucketVersioning ( ctx , bucketName )
if err != nil {
2021-06-04 11:35:55 -07:00
LogError ( "error versioning bucket: %v" , err )
2020-09-28 12:46:08 -05:00
}
// serialize output
2021-07-19 12:24:35 -07:00
bucketVResponse := & models . BucketVersioningResponse {
2020-09-28 12:46:08 -05:00
IsVersioned : res . Status == "Enabled" ,
}
2021-07-19 12:24:35 -07:00
return bucketVResponse , nil
}
2021-11-15 12:24:37 -08:00
// getAccountBuckets fetches a list of all buckets allowed to that particular client from MinIO Servers
2021-11-18 08:25:01 -08:00
func getAccountBuckets ( ctx context . Context , client MinioAdmin ) ( [ ] * models . Bucket , error ) {
2021-07-19 11:48:50 -07:00
info , err := client . AccountInfo ( ctx )
2020-04-01 18:18:57 -07:00
if err != nil {
return [ ] * models . Bucket { } , err
}
var bucketInfos [ ] * models . Bucket
2020-05-18 13:36:18 -07:00
for _ , bucket := range info . Buckets {
2021-07-19 12:24:35 -07:00
bucketElem := & models . Bucket {
CreationDate : bucket . Created . Format ( time . RFC3339 ) ,
2021-09-20 11:13:34 -07:00
Details : & models . BucketDetails {
Quota : nil ,
} ,
RwAccess : & models . BucketRwAccess {
Read : bucket . Access . Read ,
Write : bucket . Access . Write ,
} ,
Name : swag . String ( bucket . Name ) ,
Objects : int64 ( bucket . Objects ) ,
Size : int64 ( bucket . Size ) ,
}
if bucket . Details != nil {
if bucket . Details . Tagging != nil {
bucketElem . Details . Tags = bucket . Details . Tagging . ToMap ( )
}
bucketElem . Details . Locking = bucket . Details . Locking
bucketElem . Details . Replication = bucket . Details . Replication
bucketElem . Details . Versioning = bucket . Details . Versioning
bucketElem . Details . VersioningSuspended = bucket . Details . VersioningSuspended
if bucket . Details . Quota != nil {
bucketElem . Details . Quota = & models . BucketDetailsQuota {
Quota : int64 ( bucket . Details . Quota . Quota ) ,
Type : string ( bucket . Details . Quota . Type ) ,
}
}
2021-07-19 12:24:35 -07:00
}
2021-09-20 11:13:34 -07:00
2020-04-01 18:18:57 -07:00
bucketInfos = append ( bucketInfos , bucketElem )
}
return bucketInfos , nil
}
// getListBucketsResponse performs listBuckets() and serializes it to the handler's output
2020-09-04 20:32:57 -07:00
func getListBucketsResponse ( session * models . Principal ) ( * models . ListBucketsResponse , * models . Error ) {
2020-04-01 18:18:57 -07:00
ctx , cancel := context . WithTimeout ( context . Background ( ) , time . Second * 20 )
defer cancel ( )
2020-05-18 13:36:18 -07:00
2021-07-19 11:48:50 -07:00
mAdmin , err := NewMinioAdminClient ( session )
2020-04-01 18:18:57 -07:00
if err != nil {
2021-07-19 17:17:56 -07:00
return nil , prepareError ( err )
2020-04-01 18:18:57 -07:00
}
// create a minioClient interface implementation
// defining the client to be used
2021-07-19 11:48:50 -07:00
adminClient := AdminClient { Client : mAdmin }
2021-11-18 08:25:01 -08:00
buckets , err := getAccountBuckets ( ctx , adminClient )
2020-04-01 18:18:57 -07:00
if err != nil {
2021-07-19 17:17:56 -07:00
return nil , prepareError ( err )
2020-04-01 18:18:57 -07:00
}
2020-05-18 13:36:18 -07:00
2020-04-01 18:18:57 -07:00
// serialize output
listBucketsResponse := & models . ListBucketsResponse {
Buckets : buckets ,
Total : int64 ( len ( buckets ) ) ,
}
return listBucketsResponse , nil
}
// makeBucket creates a bucket for an specific minio client
2020-11-25 12:40:39 -06:00
func makeBucket ( ctx context . Context , client MinioClient , bucketName string , objectLocking bool ) error {
2020-04-01 18:18:57 -07:00
// creates a new bucket with bucketName with a context to control cancellations and timeouts.
2021-06-07 20:53:03 -07:00
return client . makeBucketWithContext ( ctx , bucketName , "" , objectLocking )
2020-04-06 09:59:19 -07:00
}
// getMakeBucketResponse performs makeBucket() to create a bucket with its access policy
2020-09-04 20:32:57 -07:00
func getMakeBucketResponse ( session * models . Principal , br * models . MakeBucketRequest ) * models . Error {
2020-04-06 09:59:19 -07:00
ctx , cancel := context . WithTimeout ( context . Background ( ) , time . Second * 20 )
defer cancel ( )
// bucket request needed to proceed
if br == nil {
2021-07-19 17:17:56 -07:00
return prepareError ( errBucketBodyNotInRequest )
2020-04-06 09:59:19 -07:00
}
2020-07-10 19:14:28 -07:00
mClient , err := newMinioClient ( session )
2020-04-06 09:59:19 -07:00
if err != nil {
2021-07-19 17:17:56 -07:00
return prepareError ( err )
2020-04-06 09:59:19 -07:00
}
// create a minioClient interface implementation
// defining the client to be used
minioClient := minioClient { client : mClient }
2021-03-22 16:28:07 -07:00
// if we need retention, then object locking needs to be enabled
if br . Retention != nil {
br . Locking = true
}
if err := makeBucket ( ctx , minioClient , * br . Name , br . Locking ) ; err != nil {
2021-07-19 17:17:56 -07:00
return prepareError ( err )
2020-04-01 18:18:57 -07:00
}
2020-11-25 12:40:39 -06:00
2020-12-11 10:22:25 -06:00
// make sure to delete bucket if an error occurs after bucket was created
defer func ( ) {
if err != nil {
2021-06-04 11:35:55 -07:00
LogError ( "error creating bucket: %v" , err )
2020-12-11 10:22:25 -06:00
if err := removeBucket ( minioClient , * br . Name ) ; err != nil {
2021-06-04 11:35:55 -07:00
LogError ( "error removing bucket: %v" , err )
2020-12-11 10:22:25 -06:00
}
}
} ( )
2021-03-22 16:28:07 -07:00
// enable versioning if indicated or retention enabled
if br . Versioning || br . Retention != nil {
s3Client , err := newS3BucketClient ( session , * br . Name , "" )
if err != nil {
2021-07-19 17:17:56 -07:00
return prepareError ( err )
2021-03-22 16:28:07 -07:00
}
// create a mc S3Client interface implementation
// defining the client to be used
amcClient := mcClient { client : s3Client }
if err = doSetVersioning ( amcClient , VersionEnable ) ; err != nil {
2021-07-19 17:17:56 -07:00
return prepareError ( err )
2021-03-22 16:28:07 -07:00
}
}
2020-10-01 18:59:20 -07:00
// if it has support for
if br . Quota != nil && br . Quota . Enabled != nil && * br . Quota . Enabled {
2021-07-19 11:48:50 -07:00
mAdmin , err := NewMinioAdminClient ( session )
2020-10-01 18:59:20 -07:00
if err != nil {
2021-07-19 17:17:56 -07:00
return prepareError ( err )
2020-10-01 18:59:20 -07:00
}
// create a minioClient interface implementation
// defining the client to be used
2021-07-19 11:48:50 -07:00
adminClient := AdminClient { Client : mAdmin }
2020-10-01 18:59:20 -07:00
// we will tolerate this call failing
if err := setBucketQuota ( ctx , & adminClient , br . Name , br . Quota ) ; err != nil {
2021-06-04 11:35:55 -07:00
LogError ( "error versioning bucket:" , err )
2020-10-01 18:59:20 -07:00
}
}
2020-12-11 10:22:25 -06:00
// Set Bucket Retention Configuration if defined
if br . Retention != nil {
2021-06-08 12:35:39 -07:00
err = setBucketRetentionConfig ( ctx , minioClient , * br . Name , * br . Retention . Mode , * br . Retention . Unit , br . Retention . Validity )
2020-12-11 10:22:25 -06:00
if err != nil {
2021-07-19 17:17:56 -07:00
return prepareError ( err )
2020-12-11 10:22:25 -06:00
}
}
2020-04-01 18:18:57 -07:00
return nil
}
// setBucketAccessPolicy set the access permissions on an existing bucket.
2021-12-28 18:21:29 -08:00
func setBucketAccessPolicy ( ctx context . Context , client MinioClient , bucketName string , access models . BucketAccess , policyDefinition string ) error {
2020-04-01 18:18:57 -07:00
if strings . TrimSpace ( bucketName ) == "" {
return fmt . Errorf ( "error: bucket name not present" )
}
if strings . TrimSpace ( string ( access ) ) == "" {
return fmt . Errorf ( "error: bucket access not present" )
}
// Prepare policyJSON corresponding to the access type
2021-12-28 18:21:29 -08:00
if access != models . BucketAccessPRIVATE && access != models . BucketAccessPUBLIC && access != models . BucketAccessCUSTOM {
2020-04-01 18:18:57 -07:00
return fmt . Errorf ( "access: `%s` not supported" , access )
}
bucketAccessPolicy := policy . BucketAccessPolicy { Version : minioIAMPolicy . DefaultVersion }
2021-12-28 18:21:29 -08:00
if access == models . BucketAccessCUSTOM {
err := client . setBucketPolicyWithContext ( ctx , bucketName , policyDefinition )
if err != nil {
return err
}
return nil
}
bucketPolicy := consoleAccess2policyAccess ( access )
2020-04-01 18:18:57 -07:00
bucketAccessPolicy . Statements = policy . SetPolicy ( bucketAccessPolicy . Statements ,
2021-11-15 17:48:25 -08:00
bucketPolicy , bucketName , "" )
2020-04-01 18:18:57 -07:00
policyJSON , err := json . Marshal ( bucketAccessPolicy )
if err != nil {
return err
}
return client . setBucketPolicyWithContext ( ctx , bucketName , string ( policyJSON ) )
}
// getBucketSetPolicyResponse calls setBucketAccessPolicy() to set a access policy to a bucket
// and returns the serialized output.
2020-09-04 20:32:57 -07:00
func getBucketSetPolicyResponse ( session * models . Principal , bucketName string , req * models . SetBucketPolicyRequest ) ( * models . Bucket , * models . Error ) {
2020-04-01 18:18:57 -07:00
ctx , cancel := context . WithTimeout ( context . Background ( ) , time . Second * 20 )
defer cancel ( )
2021-12-28 18:21:29 -08:00
// get updated bucket details and return it
2020-07-10 19:14:28 -07:00
mClient , err := newMinioClient ( session )
2020-04-01 18:18:57 -07:00
if err != nil {
2021-07-19 17:17:56 -07:00
return nil , prepareError ( err )
2020-04-01 18:18:57 -07:00
}
// create a minioClient interface implementation
// defining the client to be used
minioClient := minioClient { client : mClient }
2021-12-28 18:21:29 -08:00
if err := setBucketAccessPolicy ( ctx , minioClient , bucketName , * req . Access , req . Definition ) ; err != nil {
2021-07-19 17:17:56 -07:00
return nil , prepareError ( err )
2020-04-01 18:18:57 -07:00
}
2021-12-28 18:21:29 -08:00
// set bucket access policy
2021-11-18 08:25:01 -08:00
bucket , err := getBucketInfo ( ctx , minioClient , bucketName )
2020-04-01 18:18:57 -07:00
if err != nil {
2021-07-19 17:17:56 -07:00
return nil , prepareError ( err )
2020-04-01 18:18:57 -07:00
}
return bucket , nil
}
2021-11-11 18:36:18 -08:00
// putBucketTags sets tags for a bucket
func getPutBucketTagsResponse ( session * models . Principal , bucketName string , req * models . PutBucketTagsRequest ) * models . Error {
ctx , cancel := context . WithTimeout ( context . Background ( ) , time . Second * 20 )
defer cancel ( )
mClient , err := newMinioClient ( session )
if err != nil {
return prepareError ( err )
}
// create a minioClient interface implementation
// defining the client to be used
minioClient := minioClient { client : mClient }
newTagSet , err := tags . NewTags ( req . Tags , true )
if err != nil {
return prepareError ( err )
}
err = minioClient . SetBucketTagging ( ctx , bucketName , newTagSet )
if err != nil {
return prepareError ( err )
}
return nil
}
2020-04-01 18:18:57 -07:00
// removeBucket deletes a bucket
func removeBucket ( client MinioClient , bucketName string ) error {
2020-07-25 14:38:16 -07:00
return client . removeBucket ( context . Background ( ) , bucketName )
2020-04-01 18:18:57 -07:00
}
// getDeleteBucketResponse performs removeBucket() to delete a bucket
2020-09-04 20:32:57 -07:00
func getDeleteBucketResponse ( session * models . Principal , params user_api . DeleteBucketParams ) * models . Error {
2020-04-01 18:18:57 -07:00
if params . Name == "" {
2021-07-19 17:17:56 -07:00
return prepareError ( errBucketNameNotInRequest )
2020-04-01 18:18:57 -07:00
}
bucketName := params . Name
2020-07-10 19:14:28 -07:00
mClient , err := newMinioClient ( session )
2020-04-01 18:18:57 -07:00
if err != nil {
2021-07-19 17:17:56 -07:00
return prepareError ( err )
2020-04-01 18:18:57 -07:00
}
// create a minioClient interface implementation
// defining the client to be used
minioClient := minioClient { client : mClient }
2020-09-04 20:32:57 -07:00
if err := removeBucket ( minioClient , bucketName ) ; err != nil {
2021-07-19 17:17:56 -07:00
return prepareError ( err )
2020-09-04 20:32:57 -07:00
}
return nil
2020-04-01 18:18:57 -07:00
}
// getBucketInfo return bucket information including name, policy access, size and creation date
2021-11-18 08:25:01 -08:00
func getBucketInfo ( ctx context . Context , client MinioClient , bucketName string ) ( * models . Bucket , error ) {
2021-11-02 17:34:39 -07:00
var bucketAccess models . BucketAccess
policyStr , err := client . getBucketPolicy ( context . Background ( ) , bucketName )
if err != nil {
// we can tolerate this error
LogError ( "error getting bucket policy: %v" , err )
}
2020-04-01 18:18:57 -07:00
if policyStr == "" {
2021-12-28 18:21:29 -08:00
bucketAccess = models . BucketAccessPRIVATE
2020-04-01 18:18:57 -07:00
} else {
var p policy . BucketAccessPolicy
if err = json . Unmarshal ( [ ] byte ( policyStr ) , & p ) ; err != nil {
return nil , err
}
2021-12-28 18:21:29 -08:00
policyAccess := policy . GetPolicy ( p . Statements , bucketName , "" )
if len ( p . Statements ) > 0 && policyAccess == policy . BucketPolicyNone {
bucketAccess = models . BucketAccessCUSTOM
} else {
bucketAccess = policyAccess2consoleAccess ( policyAccess )
}
2020-04-01 18:18:57 -07:00
}
2021-11-11 18:36:18 -08:00
bucketTags , err := client . GetBucketTagging ( ctx , bucketName )
2021-11-18 08:25:01 -08:00
if err != nil {
// we can tolerate this error
LogError ( "error getting bucket tags: %v" , err )
}
bucketDetails := & models . BucketDetails { }
if bucketTags != nil {
bucketDetails . Tags = bucketTags . ToMap ( )
}
return & models . Bucket {
Name : & bucketName ,
Access : & bucketAccess ,
2021-12-28 18:21:29 -08:00
Definition : policyStr ,
2021-11-18 08:25:01 -08:00
CreationDate : "" , // to be implemented
Size : 0 , // to be implemented
Details : bucketDetails ,
} , nil
2020-04-01 18:18:57 -07:00
}
// getBucketInfoResponse calls getBucketInfo() to get the bucket's info
2020-09-04 20:32:57 -07:00
func getBucketInfoResponse ( session * models . Principal , params user_api . BucketInfoParams ) ( * models . Bucket , * models . Error ) {
2021-11-02 17:34:39 -07:00
ctx , cancel := context . WithTimeout ( context . Background ( ) , time . Second * 20 )
defer cancel ( )
2020-07-10 19:14:28 -07:00
mClient , err := newMinioClient ( session )
2020-04-01 18:18:57 -07:00
if err != nil {
2021-07-19 17:17:56 -07:00
return nil , prepareError ( err )
2020-04-01 18:18:57 -07:00
}
// create a minioClient interface implementation
// defining the client to be used
minioClient := minioClient { client : mClient }
2021-11-18 08:25:01 -08:00
bucket , err := getBucketInfo ( ctx , minioClient , params . Name )
2020-04-01 18:18:57 -07:00
if err != nil {
2021-07-19 17:17:56 -07:00
return nil , prepareError ( err )
2020-04-01 18:18:57 -07:00
}
return bucket , nil
}
2020-07-26 00:34:17 -07:00
// policyAccess2consoleAccess gets the equivalent of policy.BucketPolicy to models.BucketAccess
func policyAccess2consoleAccess ( bucketPolicy policy . BucketPolicy ) ( bucketAccess models . BucketAccess ) {
2020-04-01 18:18:57 -07:00
switch bucketPolicy {
case policy . BucketPolicyReadWrite :
bucketAccess = models . BucketAccessPUBLIC
case policy . BucketPolicyNone :
bucketAccess = models . BucketAccessPRIVATE
default :
bucketAccess = models . BucketAccessCUSTOM
}
return bucketAccess
}
2020-07-26 00:34:17 -07:00
// consoleAccess2policyAccess gets the equivalent of models.BucketAccess to policy.BucketPolicy
func consoleAccess2policyAccess ( bucketAccess models . BucketAccess ) ( bucketPolicy policy . BucketPolicy ) {
2020-04-01 18:18:57 -07:00
switch bucketAccess {
case models . BucketAccessPUBLIC :
bucketPolicy = policy . BucketPolicyReadWrite
case models . BucketAccessPRIVATE :
bucketPolicy = policy . BucketPolicyNone
}
return bucketPolicy
}
2020-10-25 12:56:23 -07:00
// enableBucketEncryption will enable bucket encryption based on two encryption algorithms, sse-s3 (server side encryption with external KMS) or sse-kms (aws s3 kms key)
func enableBucketEncryption ( ctx context . Context , client MinioClient , bucketName string , encryptionType models . BucketEncryptionType , kmsKeyID string ) error {
var config * sse . Configuration
switch encryptionType {
2021-06-08 12:35:39 -07:00
case models . BucketEncryptionTypeSseDashKms :
2020-10-25 12:56:23 -07:00
config = sse . NewConfigurationSSEKMS ( kmsKeyID )
2021-06-08 12:35:39 -07:00
case models . BucketEncryptionTypeSseDashS3 :
2020-10-25 12:56:23 -07:00
config = sse . NewConfigurationSSES3 ( )
default :
return errInvalidEncryptionAlgorithm
}
return client . setBucketEncryption ( ctx , bucketName , config )
}
// enableBucketEncryptionResponse calls enableBucketEncryption() to create new encryption configuration for provided bucket name
func enableBucketEncryptionResponse ( session * models . Principal , params user_api . EnableBucketEncryptionParams ) * models . Error {
ctx , cancel := context . WithTimeout ( context . Background ( ) , time . Second * 20 )
defer cancel ( )
mClient , err := newMinioClient ( session )
if err != nil {
2021-07-19 17:17:56 -07:00
return prepareError ( err )
2020-10-25 12:56:23 -07:00
}
// create a minioClient interface implementation
// defining the client to be used
minioClient := minioClient { client : mClient }
2021-06-08 12:35:39 -07:00
if err := enableBucketEncryption ( ctx , minioClient , params . BucketName , * params . Body . EncType , params . Body . KmsKeyID ) ; err != nil {
2021-07-19 17:17:56 -07:00
return prepareError ( err )
2020-10-25 12:56:23 -07:00
}
return nil
}
// disableBucketEncryption will disable bucket for the provided bucket name
func disableBucketEncryption ( ctx context . Context , client MinioClient , bucketName string ) error {
return client . removeBucketEncryption ( ctx , bucketName )
}
// disableBucketEncryptionResponse calls disableBucketEncryption()
func disableBucketEncryptionResponse ( session * models . Principal , params user_api . DisableBucketEncryptionParams ) * models . Error {
ctx , cancel := context . WithTimeout ( context . Background ( ) , time . Second * 20 )
defer cancel ( )
mClient , err := newMinioClient ( session )
if err != nil {
2021-07-19 17:17:56 -07:00
return prepareError ( err )
2020-10-25 12:56:23 -07:00
}
// create a minioClient interface implementation
// defining the client to be used
minioClient := minioClient { client : mClient }
if err := disableBucketEncryption ( ctx , minioClient , params . BucketName ) ; err != nil {
2021-07-19 17:17:56 -07:00
return prepareError ( err )
2020-10-25 12:56:23 -07:00
}
return nil
}
func getBucketEncryptionInfo ( ctx context . Context , client MinioClient , bucketName string ) ( * models . BucketEncryptionInfo , error ) {
bucketInfo , err := client . getBucketEncryption ( ctx , bucketName )
if err != nil {
return nil , err
}
if len ( bucketInfo . Rules ) == 0 {
2021-07-19 11:48:50 -07:00
return nil , ErrorGeneric
2020-10-25 12:56:23 -07:00
}
return & models . BucketEncryptionInfo { Algorithm : bucketInfo . Rules [ 0 ] . Apply . SSEAlgorithm , KmsMasterKeyID : bucketInfo . Rules [ 0 ] . Apply . KmsMasterKeyID } , nil
}
func getBucketEncryptionInfoResponse ( session * models . Principal , params user_api . GetBucketEncryptionInfoParams ) ( * models . BucketEncryptionInfo , * models . Error ) {
ctx , cancel := context . WithTimeout ( context . Background ( ) , time . Second * 20 )
defer cancel ( )
mClient , err := newMinioClient ( session )
if err != nil {
2021-07-19 17:17:56 -07:00
return nil , prepareError ( err )
2020-10-25 12:56:23 -07:00
}
// create a minioClient interface implementation
// defining the client to be used
minioClient := minioClient { client : mClient }
bucketInfo , err := getBucketEncryptionInfo ( ctx , minioClient , params . BucketName )
if err != nil {
2021-07-19 17:17:56 -07:00
return nil , prepareError ( errSSENotConfigured , err )
2020-10-25 12:56:23 -07:00
}
return bucketInfo , nil
}
2020-12-03 13:45:45 -06:00
// setBucketRetentionConfig sets object lock configuration on a bucket
func setBucketRetentionConfig ( ctx context . Context , client MinioClient , bucketName string , mode models . ObjectRetentionMode , unit models . ObjectRetentionUnit , validity * int32 ) error {
if validity == nil {
return errors . New ( "retention validity can't be nil" )
}
var retentionMode minio . RetentionMode
switch mode {
case models . ObjectRetentionModeGovernance :
retentionMode = minio . Governance
case models . ObjectRetentionModeCompliance :
retentionMode = minio . Compliance
default :
return errors . New ( "invalid retention mode" )
}
var retentionUnit minio . ValidityUnit
switch unit {
case models . ObjectRetentionUnitDays :
retentionUnit = minio . Days
case models . ObjectRetentionUnitYears :
retentionUnit = minio . Years
default :
return errors . New ( "invalid retention unit" )
}
retentionValidity := uint ( * validity )
return client . setObjectLockConfig ( ctx , bucketName , & retentionMode , & retentionValidity , & retentionUnit )
}
func getSetBucketRetentionConfigResponse ( session * models . Principal , params user_api . SetBucketRetentionConfigParams ) * models . Error {
ctx , cancel := context . WithTimeout ( context . Background ( ) , time . Second * 20 )
defer cancel ( )
mClient , err := newMinioClient ( session )
if err != nil {
2021-07-19 17:17:56 -07:00
return prepareError ( err )
2020-12-03 13:45:45 -06:00
}
// create a minioClient interface implementation
// defining the client to be used
minioClient := minioClient { client : mClient }
2021-06-08 12:35:39 -07:00
err = setBucketRetentionConfig ( ctx , minioClient , params . BucketName , * params . Body . Mode , * params . Body . Unit , params . Body . Validity )
2020-12-03 13:45:45 -06:00
if err != nil {
2021-07-19 17:17:56 -07:00
return prepareError ( err )
2020-12-03 13:45:45 -06:00
}
return nil
}
2020-12-15 19:25:43 -06:00
func getBucketRetentionConfig ( ctx context . Context , client MinioClient , bucketName string ) ( * models . GetBucketRetentionConfig , error ) {
m , v , u , err := client . getBucketObjectLockConfig ( ctx , bucketName )
if err != nil {
errResp := minio . ToErrorResponse ( probe . NewError ( err ) . ToGoError ( ) )
if errResp . Code == "ObjectLockConfigurationNotFoundError" {
return & models . GetBucketRetentionConfig { } , nil
}
return nil , err
}
2021-08-09 21:23:40 -07:00
// These values can be empty when all are empty, it means
// object was created with object locking enabled but
// does not have any default object locking configuration.
if m == nil && v == nil && u == nil {
return & models . GetBucketRetentionConfig { } , nil
}
2020-12-15 19:25:43 -06:00
var mode models . ObjectRetentionMode
var unit models . ObjectRetentionUnit
2021-08-09 21:23:40 -07:00
if m != nil {
switch * m {
case minio . Governance :
mode = models . ObjectRetentionModeGovernance
case minio . Compliance :
mode = models . ObjectRetentionModeCompliance
default :
return nil , errors . New ( "invalid retention mode" )
}
2020-12-15 19:25:43 -06:00
}
2021-08-09 21:23:40 -07:00
if u != nil {
switch * u {
case minio . Days :
unit = models . ObjectRetentionUnitDays
case minio . Years :
unit = models . ObjectRetentionUnitYears
default :
return nil , errors . New ( "invalid retention unit" )
}
}
var validity int32
if v != nil {
validity = int32 ( * v )
2020-12-15 19:25:43 -06:00
}
config := & models . GetBucketRetentionConfig {
Mode : mode ,
Unit : unit ,
2021-08-09 21:23:40 -07:00
Validity : validity ,
2020-12-15 19:25:43 -06:00
}
return config , nil
}
func getBucketRetentionConfigResponse ( session * models . Principal , bucketName string ) ( * models . GetBucketRetentionConfig , * models . Error ) {
ctx , cancel := context . WithTimeout ( context . Background ( ) , time . Second * 20 )
defer cancel ( )
mClient , err := newMinioClient ( session )
if err != nil {
2021-07-19 17:17:56 -07:00
return nil , prepareError ( err )
2020-12-15 19:25:43 -06:00
}
2021-08-09 21:23:40 -07:00
2020-12-15 19:25:43 -06:00
// create a minioClient interface implementation
// defining the client to be used
minioClient := minioClient { client : mClient }
config , err := getBucketRetentionConfig ( ctx , minioClient , bucketName )
if err != nil {
2021-07-19 17:17:56 -07:00
return nil , prepareError ( err )
2020-12-15 19:25:43 -06:00
}
return config , nil
}
2021-03-22 16:28:07 -07:00
2021-08-09 21:23:40 -07:00
func getBucketObjectLockingResponse ( session * models . Principal , bucketName string ) ( * models . BucketObLockingResponse , error ) {
2021-03-22 16:28:07 -07:00
ctx , cancel := context . WithTimeout ( context . Background ( ) , time . Second * 20 )
defer cancel ( )
mClient , err := newMinioClient ( session )
if err != nil {
2021-06-04 11:35:55 -07:00
LogError ( "error creating MinIO Client: %v" , err )
2021-03-22 16:28:07 -07:00
return nil , err
}
// create a minioClient interface implementation
// defining the client to be used
minioClient := minioClient { client : mClient }
// we will tolerate this call failing
_ , _ , _ , _ , err = minioClient . getObjectLockConfig ( ctx , bucketName )
if err != nil {
2021-08-09 21:23:40 -07:00
if minio . ToErrorResponse ( err ) . Code == "ObjectLockConfigurationNotFoundError" {
2021-03-22 16:28:07 -07:00
return & models . BucketObLockingResponse {
ObjectLockingEnabled : false ,
} , nil
}
2021-08-09 21:23:40 -07:00
return nil , err
2021-03-22 16:28:07 -07:00
}
// serialize output
2021-08-09 21:23:40 -07:00
return & models . BucketObLockingResponse {
2021-03-22 16:28:07 -07:00
ObjectLockingEnabled : true ,
2021-08-09 21:23:40 -07:00
} , nil
2021-03-22 16:28:07 -07:00
}
2021-06-23 01:10:54 -05:00
func getBucketRewindResponse ( session * models . Principal , params user_api . GetBucketRewindParams ) ( * models . RewindResponse , * models . Error ) {
ctx , cancel := context . WithTimeout ( context . Background ( ) , time . Second * 20 )
defer cancel ( )
var prefix = ""
if params . Prefix != nil {
2021-10-19 13:00:13 -07:00
encodedPrefix := SanitizeEncodedPrefix ( * params . Prefix )
Multiple fixes for sub path and objects filename encoding (#1086)
- fix: objects with special characters (ie: /,&,%,*) won't open
- fix: create subdolders with special characters won't work, ie: /,&,%,*
- fix: view subfolders with special characters (ie: /,&,%,*) won't work
- refactor: browser breadcrumb
- fix: rewind enable/disable toggle button not working
- fix: undefined style for add bucket button in buckets page
- Added: validation for folder path naming
- refactor: encode prefix parameter using base64 to avoid url encode
issues
- fix: share link for versioned object won't work because of wrong
version_id
Signed-off-by: Lenin Alevski <alevsk.8772@gmail.com>
2021-09-28 12:25:28 -07:00
decodedPrefix , err := base64 . StdEncoding . DecodeString ( encodedPrefix )
if err != nil {
return nil , prepareError ( err )
}
prefix = string ( decodedPrefix )
2021-06-23 01:10:54 -05:00
}
s3Client , err := newS3BucketClient ( session , params . BucketName , prefix )
if err != nil {
LogError ( "error creating S3Client: %v" , err )
2021-07-19 17:17:56 -07:00
return nil , prepareError ( err )
2021-06-23 01:10:54 -05:00
}
// create a mc S3Client interface implementation
// defining the client to be used
mcClient := mcClient { client : s3Client }
parsedDate , errDate := time . Parse ( time . RFC3339 , params . Date )
if errDate != nil {
2021-07-19 17:17:56 -07:00
return nil , prepareError ( errDate )
2021-06-23 01:10:54 -05:00
}
var rewindItems [ ] * models . RewindItem
for content := range mcClient . client . List ( ctx , cmd . ListOptions { TimeRef : parsedDate , WithDeleteMarkers : true } ) {
// build object name
name := strings . Replace ( content . URL . Path , fmt . Sprintf ( "/%s/" , params . BucketName ) , "" , - 1 )
listElement := & models . RewindItem {
LastModified : content . Time . Format ( time . RFC3339 ) ,
Size : content . Size ,
VersionID : content . VersionID ,
DeleteFlag : content . IsDeleteMarker ,
Action : "" ,
Name : name ,
}
rewindItems = append ( rewindItems , listElement )
}
return & models . RewindResponse {
Objects : rewindItems ,
} , nil
}