github.com/minio/console@v1.4.1/api/user_buckets_test.go (about)

     1  // This file is part of MinIO Console Server
     2  // Copyright (c) 2021 MinIO, Inc.
     3  //
     4  // This program is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Affero General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // This program is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  // GNU Affero General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Affero General Public License
    15  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package api
    18  
    19  import (
    20  	"context"
    21  	"errors"
    22  	"fmt"
    23  	"os"
    24  	"reflect"
    25  	"testing"
    26  	"time"
    27  
    28  	"github.com/minio/console/pkg/auth/token"
    29  	"github.com/minio/console/pkg/utils"
    30  
    31  	"github.com/go-openapi/swag"
    32  	"github.com/minio/console/models"
    33  	"github.com/minio/madmin-go/v3"
    34  	"github.com/minio/mc/pkg/probe"
    35  	"github.com/minio/minio-go/v7"
    36  	"github.com/minio/minio-go/v7/pkg/sse"
    37  	"github.com/minio/minio-go/v7/pkg/tags"
    38  	"github.com/stretchr/testify/assert"
    39  )
    40  
    41  // assigning mock at runtime instead of compile time
    42  var minioListBucketsWithContextMock func(ctx context.Context) ([]minio.BucketInfo, error)
    43  
    44  var (
    45  	minioMakeBucketWithContextMock      func(ctx context.Context, bucketName, location string, objectLock bool) error
    46  	minioSetBucketPolicyWithContextMock func(ctx context.Context, bucketName, policy string) error
    47  	minioRemoveBucketMock               func(bucketName string) error
    48  	minioGetBucketPolicyMock            func(bucketName string) (string, error)
    49  	minioSetBucketEncryptionMock        func(ctx context.Context, bucketName string, config *sse.Configuration) error
    50  	minioRemoveBucketEncryptionMock     func(ctx context.Context, bucketName string) error
    51  	minioGetBucketEncryptionMock        func(ctx context.Context, bucketName string) (*sse.Configuration, error)
    52  	minioSetObjectLockConfigMock        func(ctx context.Context, bucketName string, mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit) error
    53  	minioGetBucketObjectLockConfigMock  func(ctx context.Context, bucketName string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error)
    54  	minioGetObjectLockConfigMock        func(ctx context.Context, bucketName string) (lock string, mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error)
    55  	minioSetVersioningMock              func(ctx context.Context, state string, excludePrefix []string, excludeFolders bool) *probe.Error
    56  	minioCopyObjectMock                 func(ctx context.Context, dst minio.CopyDestOptions, src minio.CopySrcOptions) (minio.UploadInfo, error)
    57  	minioSetBucketTaggingMock           func(ctx context.Context, bucketName string, tags *tags.Tags) error
    58  	minioRemoveBucketTaggingMock        func(ctx context.Context, bucketName string) error
    59  )
    60  
    61  // Define a mock struct of minio Client interface implementation
    62  type minioClientMock struct{}
    63  
    64  // mock function of listBucketsWithContext()
    65  func (mc minioClientMock) listBucketsWithContext(ctx context.Context) ([]minio.BucketInfo, error) {
    66  	return minioListBucketsWithContextMock(ctx)
    67  }
    68  
    69  // mock function of makeBucketsWithContext()
    70  func (mc minioClientMock) makeBucketWithContext(ctx context.Context, bucketName, location string, objectLock bool) error {
    71  	return minioMakeBucketWithContextMock(ctx, bucketName, location, objectLock)
    72  }
    73  
    74  // mock function of setBucketPolicyWithContext()
    75  func (mc minioClientMock) setBucketPolicyWithContext(ctx context.Context, bucketName, policy string) error {
    76  	return minioSetBucketPolicyWithContextMock(ctx, bucketName, policy)
    77  }
    78  
    79  // mock function of removeBucket()
    80  func (mc minioClientMock) removeBucket(_ context.Context, bucketName string) error {
    81  	return minioRemoveBucketMock(bucketName)
    82  }
    83  
    84  // mock function of getBucketPolicy()
    85  func (mc minioClientMock) getBucketPolicy(_ context.Context, bucketName string) (string, error) {
    86  	return minioGetBucketPolicyMock(bucketName)
    87  }
    88  
    89  func (mc minioClientMock) setBucketEncryption(ctx context.Context, bucketName string, config *sse.Configuration) error {
    90  	return minioSetBucketEncryptionMock(ctx, bucketName, config)
    91  }
    92  
    93  func (mc minioClientMock) removeBucketEncryption(ctx context.Context, bucketName string) error {
    94  	return minioRemoveBucketEncryptionMock(ctx, bucketName)
    95  }
    96  
    97  func (mc minioClientMock) getBucketEncryption(ctx context.Context, bucketName string) (*sse.Configuration, error) {
    98  	return minioGetBucketEncryptionMock(ctx, bucketName)
    99  }
   100  
   101  func (mc minioClientMock) setObjectLockConfig(ctx context.Context, bucketName string, mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit) error {
   102  	return minioSetObjectLockConfigMock(ctx, bucketName, mode, validity, unit)
   103  }
   104  
   105  func (mc minioClientMock) getBucketObjectLockConfig(ctx context.Context, bucketName string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) {
   106  	return minioGetBucketObjectLockConfigMock(ctx, bucketName)
   107  }
   108  
   109  func (mc minioClientMock) getObjectLockConfig(ctx context.Context, bucketName string) (lock string, mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) {
   110  	return minioGetObjectLockConfigMock(ctx, bucketName)
   111  }
   112  
   113  func (mc minioClientMock) copyObject(ctx context.Context, dst minio.CopyDestOptions, src minio.CopySrcOptions) (minio.UploadInfo, error) {
   114  	return minioCopyObjectMock(ctx, dst, src)
   115  }
   116  
   117  func (c s3ClientMock) setVersioning(ctx context.Context, state string, excludePrefix []string, excludeFolders bool) *probe.Error {
   118  	return minioSetVersioningMock(ctx, state, excludePrefix, excludeFolders)
   119  }
   120  
   121  func (mc minioClientMock) GetBucketTagging(ctx context.Context, bucketName string) (*tags.Tags, error) {
   122  	return minioGetBucketTaggingMock(ctx, bucketName)
   123  }
   124  
   125  func (mc minioClientMock) SetBucketTagging(ctx context.Context, bucketName string, tags *tags.Tags) error {
   126  	return minioSetBucketTaggingMock(ctx, bucketName, tags)
   127  }
   128  
   129  func (mc minioClientMock) RemoveBucketTagging(ctx context.Context, bucketName string) error {
   130  	return minioRemoveBucketTaggingMock(ctx, bucketName)
   131  }
   132  
   133  func minioGetBucketTaggingMock(ctx context.Context, bucketName string) (*tags.Tags, error) {
   134  	fmt.Println(ctx)
   135  	fmt.Println(bucketName)
   136  	retval, _ := tags.NewTags(map[string]string{}, true)
   137  	return retval, nil
   138  }
   139  
   140  func TestMakeBucket(t *testing.T) {
   141  	assert := assert.New(t)
   142  	// mock minIO client
   143  	minClient := minioClientMock{}
   144  	function := "makeBucket()"
   145  	ctx := context.Background()
   146  	// Test-1: makeBucket() create a bucket
   147  	// mock function response from makeBucketWithContext(ctx)
   148  	minioMakeBucketWithContextMock = func(_ context.Context, _, _ string, _ bool) error {
   149  		return nil
   150  	}
   151  	if err := makeBucket(ctx, minClient, "bucktest1", true); err != nil {
   152  		t.Errorf("Failed on %s:, errors occurred: %s", function, err.Error())
   153  	}
   154  
   155  	// Test-2 makeBucket() make sure errors are handled correctly when errors on MakeBucketWithContext
   156  	minioMakeBucketWithContextMock = func(_ context.Context, _, _ string, _ bool) error {
   157  		return errors.New("error")
   158  	}
   159  	if err := makeBucket(ctx, minClient, "bucktest1", true); assert.Error(err) {
   160  		assert.Equal("error", err.Error())
   161  	}
   162  }
   163  
   164  func TestDeleteBucket(t *testing.T) {
   165  	assert := assert.New(t)
   166  	// mock minIO client
   167  	minClient := minioClientMock{}
   168  	function := "removeBucket()"
   169  
   170  	// Test-1: removeBucket() delete a bucket
   171  	// mock function response from removeBucket(bucketName)
   172  	minioRemoveBucketMock = func(_ string) error {
   173  		return nil
   174  	}
   175  	if err := removeBucket(minClient, "bucktest1"); err != nil {
   176  		t.Errorf("Failed on %s:, errors occurred: %s", function, err.Error())
   177  	}
   178  
   179  	// Test-2: removeBucket() make sure errors are handled correctly when errors on DeleteBucket()
   180  	// mock function response from removeBucket(bucketName)
   181  	minioRemoveBucketMock = func(_ string) error {
   182  		return errors.New("error")
   183  	}
   184  	if err := removeBucket(minClient, "bucktest1"); assert.Error(err) {
   185  		assert.Equal("error", err.Error())
   186  	}
   187  }
   188  
   189  func TestBucketInfo(t *testing.T) {
   190  	assert := assert.New(t)
   191  	// mock minIO client
   192  	minClient := minioClientMock{}
   193  	adminClient := AdminClientMock{}
   194  	ctx := context.Background()
   195  	function := "getBucketInfo()"
   196  
   197  	// Test-1: getBucketInfo() get a bucket with PRIVATE access
   198  	// if not policy set on bucket, access should be PRIVATE
   199  	mockPolicy := ""
   200  	minioGetBucketPolicyMock = func(_ string) (string, error) {
   201  		return mockPolicy, nil
   202  	}
   203  	bucketToSet := "csbucket"
   204  	outputExpected := &models.Bucket{
   205  		Name:         swag.String(bucketToSet),
   206  		Access:       models.NewBucketAccess(models.BucketAccessPRIVATE),
   207  		CreationDate: "0001-01-01T00:00:00Z",
   208  		Size:         0,
   209  		Objects:      0,
   210  	}
   211  	infoPolicy := `
   212  {
   213  	"Version": "2012-10-17",
   214  	"Statement": [{
   215  			"Action": [
   216  				"admin:*"
   217  			],
   218  			"Effect": "Allow",
   219  			"Sid": ""
   220  		},
   221  		{
   222  			"Action": [
   223  				"s3:*"
   224  			],
   225  			"Effect": "Allow",
   226  			"Resource": [
   227  				"arn:aws:s3:::*"
   228  			],
   229  			"Sid": ""
   230  		}
   231  	]
   232  }`
   233  	mockBucketList := madmin.AccountInfo{
   234  		AccountName: "test",
   235  		Buckets: []madmin.BucketAccessInfo{
   236  			{Name: "bucket-1", Created: time.Now(), Size: 1024},
   237  			{Name: "bucket-2", Created: time.Now().Add(time.Hour * 1), Size: 0},
   238  		},
   239  		Policy: []byte(infoPolicy),
   240  	}
   241  	// mock function response from listBucketsWithContext(ctx)
   242  	minioAccountInfoMock = func(_ context.Context) (madmin.AccountInfo, error) {
   243  		return mockBucketList, nil
   244  	}
   245  
   246  	bucketInfo, err := getBucketInfo(ctx, minClient, adminClient, bucketToSet)
   247  	if err != nil {
   248  		t.Errorf("Failed on %s:, errors occurred: %s", function, err.Error())
   249  	}
   250  	assert.Equal(outputExpected.Name, bucketInfo.Name)
   251  	assert.Equal(outputExpected.Access, bucketInfo.Access)
   252  	assert.Equal(outputExpected.CreationDate, bucketInfo.CreationDate)
   253  	assert.Equal(outputExpected.Size, bucketInfo.Size)
   254  	assert.Equal(outputExpected.Objects, bucketInfo.Objects)
   255  
   256  	// Test-2: getBucketInfo() get a bucket with PUBLIC access
   257  	// mock policy for bucket csbucket with readWrite access (should return PUBLIC)
   258  	mockPolicy = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucket\",\"s3:ListBucketMultipartUploads\"],\"Resource\":[\"arn:aws:s3:::csbucket\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetObject\",\"s3:ListMultipartUploadParts\",\"s3:PutObject\",\"s3:AbortMultipartUpload\",\"s3:DeleteObject\"],\"Resource\":[\"arn:aws:s3:::csbucket/*\"]}]}"
   259  	minioGetBucketPolicyMock = func(_ string) (string, error) {
   260  		return mockPolicy, nil
   261  	}
   262  	bucketToSet = "csbucket"
   263  	outputExpected = &models.Bucket{
   264  		Name:         swag.String(bucketToSet),
   265  		Access:       models.NewBucketAccess(models.BucketAccessPUBLIC),
   266  		CreationDate: "0001-01-01T00:00:00Z",
   267  		Size:         0,
   268  		Objects:      0,
   269  	}
   270  	bucketInfo, err = getBucketInfo(ctx, minClient, adminClient, bucketToSet)
   271  	if err != nil {
   272  		t.Errorf("Failed on %s:, errors occurred: %s", function, err.Error())
   273  	}
   274  	assert.Equal(outputExpected.Name, bucketInfo.Name)
   275  	assert.Equal(outputExpected.Access, bucketInfo.Access)
   276  	assert.Equal(outputExpected.CreationDate, bucketInfo.CreationDate)
   277  	assert.Equal(outputExpected.Size, bucketInfo.Size)
   278  	assert.Equal(outputExpected.Objects, bucketInfo.Objects)
   279  
   280  	// Test-3: getBucketInfo() get a bucket with PRIVATE access
   281  	// if bucket has a null statement, the bucket is PRIVATE
   282  	mockPolicy = "{\"Version\":\"2012-10-17\",\"Statement\":[]}"
   283  	minioGetBucketPolicyMock = func(_ string) (string, error) {
   284  		return mockPolicy, nil
   285  	}
   286  	bucketToSet = "csbucket"
   287  	outputExpected = &models.Bucket{
   288  		Name:         swag.String(bucketToSet),
   289  		Access:       models.NewBucketAccess(models.BucketAccessPRIVATE),
   290  		CreationDate: "0001-01-01T00:00:00Z",
   291  		Size:         0,
   292  		Objects:      0,
   293  	}
   294  	bucketInfo, err = getBucketInfo(ctx, minClient, adminClient, bucketToSet)
   295  	if err != nil {
   296  		t.Errorf("Failed on %s:, errors occurred: %s", function, err.Error())
   297  	}
   298  	assert.Equal(outputExpected.Name, bucketInfo.Name)
   299  	assert.Equal(outputExpected.Access, bucketInfo.Access)
   300  	assert.Equal(outputExpected.CreationDate, bucketInfo.CreationDate)
   301  	assert.Equal(outputExpected.Size, bucketInfo.Size)
   302  	assert.Equal(outputExpected.Objects, bucketInfo.Objects)
   303  
   304  	// Test-4: getBucketInfo() returns an errors while parsing invalid policy
   305  	mockPolicy = "policyinvalid"
   306  	minioGetBucketPolicyMock = func(_ string) (string, error) {
   307  		return mockPolicy, nil
   308  	}
   309  	bucketToSet = "csbucket"
   310  	outputExpected = &models.Bucket{
   311  		Name:         swag.String(bucketToSet),
   312  		Access:       models.NewBucketAccess(models.BucketAccessCUSTOM),
   313  		CreationDate: "",
   314  		Size:         0,
   315  	}
   316  	_, err = getBucketInfo(ctx, minClient, adminClient, bucketToSet)
   317  	if assert.Error(err) {
   318  		assert.Equal("invalid character 'p' looking for beginning of value", err.Error())
   319  	}
   320  
   321  	// Test-4: getBucketInfo() handle GetBucketPolicy errors correctly
   322  	// Test removed since we can tolerate this scenario now
   323  }
   324  
   325  func TestSetBucketAccess(t *testing.T) {
   326  	assert := assert.New(t)
   327  	ctx := context.Background()
   328  	// mock minIO client
   329  	minClient := minioClientMock{}
   330  
   331  	function := "setBucketAccessPolicy()"
   332  	// Test-1: setBucketAccessPolicy() set a bucket's access policy
   333  	// mock function response from setBucketPolicyWithContext(ctx)
   334  	minioSetBucketPolicyWithContextMock = func(_ context.Context, _, _ string) error {
   335  		return nil
   336  	}
   337  	if err := setBucketAccessPolicy(ctx, minClient, "bucktest1", models.BucketAccessPUBLIC, ""); err != nil {
   338  		t.Errorf("Failed on %s:, errors occurred: %s", function, err.Error())
   339  	}
   340  
   341  	// Test-2: setBucketAccessPolicy() set private access
   342  	if err := setBucketAccessPolicy(ctx, minClient, "bucktest1", models.BucketAccessPRIVATE, ""); err != nil {
   343  		t.Errorf("Failed on %s:, errors occurred: %s", function, err.Error())
   344  	}
   345  
   346  	// Test-3: setBucketAccessPolicy() set invalid access, expected errors
   347  	if err := setBucketAccessPolicy(ctx, minClient, "bucktest1", "other", ""); assert.Error(err) {
   348  		assert.Equal("access: `other` not supported", err.Error())
   349  	}
   350  
   351  	// Test-4: setBucketAccessPolicy() set access on empty bucket name, expected errors
   352  	if err := setBucketAccessPolicy(ctx, minClient, "", models.BucketAccessPRIVATE, ""); assert.Error(err) {
   353  		assert.Equal("error: bucket name not present", err.Error())
   354  	}
   355  
   356  	// Test-5: setBucketAccessPolicy() set empty access on bucket, expected errors
   357  	if err := setBucketAccessPolicy(ctx, minClient, "bucktest1", "", ""); assert.Error(err) {
   358  		assert.Equal("error: bucket access not present", err.Error())
   359  	}
   360  
   361  	// Test-5: setBucketAccessPolicy() handle errors on SetPolicy call
   362  	minioSetBucketPolicyWithContextMock = func(_ context.Context, _, _ string) error {
   363  		return errors.New("error")
   364  	}
   365  	if err := setBucketAccessPolicy(ctx, minClient, "bucktest1", models.BucketAccessPUBLIC, ""); assert.Error(err) {
   366  		assert.Equal("error", err.Error())
   367  	}
   368  }
   369  
   370  func Test_enableBucketEncryption(t *testing.T) {
   371  	ctx := context.Background()
   372  	minClient := minioClientMock{}
   373  	type args struct {
   374  		ctx                            context.Context
   375  		client                         MinioClient
   376  		bucketName                     string
   377  		encryptionType                 models.BucketEncryptionType
   378  		kmsKeyID                       string
   379  		mockEnableBucketEncryptionFunc func(ctx context.Context, bucketName string, config *sse.Configuration) error
   380  	}
   381  	tests := []struct {
   382  		name    string
   383  		args    args
   384  		wantErr bool
   385  	}{
   386  		{
   387  			name: "Bucket encryption enabled correctly",
   388  			args: args{
   389  				ctx:            ctx,
   390  				client:         minClient,
   391  				bucketName:     "test",
   392  				encryptionType: "sse-s3",
   393  				mockEnableBucketEncryptionFunc: func(_ context.Context, _ string, _ *sse.Configuration) error {
   394  					return nil
   395  				},
   396  			},
   397  			wantErr: false,
   398  		},
   399  		{
   400  			name: "Error when enabling bucket encryption",
   401  			args: args{
   402  				ctx:            ctx,
   403  				client:         minClient,
   404  				bucketName:     "test",
   405  				encryptionType: "sse-s3",
   406  				mockEnableBucketEncryptionFunc: func(_ context.Context, _ string, _ *sse.Configuration) error {
   407  					return ErrInvalidSession
   408  				},
   409  			},
   410  			wantErr: true,
   411  		},
   412  	}
   413  	for _, tt := range tests {
   414  		t.Run(tt.name, func(_ *testing.T) {
   415  			minioSetBucketEncryptionMock = tt.args.mockEnableBucketEncryptionFunc
   416  			if err := enableBucketEncryption(tt.args.ctx, tt.args.client, tt.args.bucketName, tt.args.encryptionType, tt.args.kmsKeyID); (err != nil) != tt.wantErr {
   417  				t.Errorf("enableBucketEncryption() errors = %v, wantErr %v", err, tt.wantErr)
   418  			}
   419  		})
   420  	}
   421  }
   422  
   423  func Test_disableBucketEncryption(t *testing.T) {
   424  	ctx := context.Background()
   425  	minClient := minioClientMock{}
   426  	type args struct {
   427  		ctx                   context.Context
   428  		client                MinioClient
   429  		bucketName            string
   430  		mockBucketDisableFunc func(ctx context.Context, bucketName string) error
   431  	}
   432  	tests := []struct {
   433  		name    string
   434  		args    args
   435  		wantErr bool
   436  	}{
   437  		{
   438  			name: "Bucket encryption disabled correctly",
   439  			args: args{
   440  				ctx:        ctx,
   441  				client:     minClient,
   442  				bucketName: "test",
   443  				mockBucketDisableFunc: func(_ context.Context, _ string) error {
   444  					return nil
   445  				},
   446  			},
   447  			wantErr: false,
   448  		},
   449  		{
   450  			name: "Error when disabling bucket encryption",
   451  			args: args{
   452  				ctx:        ctx,
   453  				client:     minClient,
   454  				bucketName: "test",
   455  				mockBucketDisableFunc: func(_ context.Context, _ string) error {
   456  					return ErrDefault
   457  				},
   458  			},
   459  			wantErr: true,
   460  		},
   461  	}
   462  	for _, tt := range tests {
   463  		t.Run(tt.name, func(_ *testing.T) {
   464  			minioRemoveBucketEncryptionMock = tt.args.mockBucketDisableFunc
   465  			if err := disableBucketEncryption(tt.args.ctx, tt.args.client, tt.args.bucketName); (err != nil) != tt.wantErr {
   466  				t.Errorf("disableBucketEncryption() errors = %v, wantErr %v", err, tt.wantErr)
   467  			}
   468  		})
   469  	}
   470  }
   471  
   472  func Test_getBucketEncryptionInfo(t *testing.T) {
   473  	ctx := context.Background()
   474  	minClient := minioClientMock{}
   475  	type args struct {
   476  		ctx                     context.Context
   477  		client                  MinioClient
   478  		bucketName              string
   479  		mockBucketEncryptionGet func(ctx context.Context, bucketName string) (*sse.Configuration, error)
   480  	}
   481  	tests := []struct {
   482  		name    string
   483  		args    args
   484  		want    *models.BucketEncryptionInfo
   485  		wantErr bool
   486  	}{
   487  		{
   488  			name: "Bucket encryption info returned correctly",
   489  			args: args{
   490  				ctx:        ctx,
   491  				client:     minClient,
   492  				bucketName: "test",
   493  				mockBucketEncryptionGet: func(_ context.Context, _ string) (*sse.Configuration, error) {
   494  					return &sse.Configuration{
   495  						Rules: []sse.Rule{
   496  							{
   497  								Apply: sse.ApplySSEByDefault{SSEAlgorithm: "AES256", KmsMasterKeyID: ""},
   498  							},
   499  						},
   500  					}, nil
   501  				},
   502  			},
   503  			wantErr: false,
   504  			want: &models.BucketEncryptionInfo{
   505  				Algorithm:      "AES256",
   506  				KmsMasterKeyID: "",
   507  			},
   508  		},
   509  		{
   510  			name: "Bucket encryption info with no rules",
   511  			args: args{
   512  				ctx:        ctx,
   513  				client:     minClient,
   514  				bucketName: "test",
   515  				mockBucketEncryptionGet: func(_ context.Context, _ string) (*sse.Configuration, error) {
   516  					return &sse.Configuration{
   517  						Rules: []sse.Rule{},
   518  					}, nil
   519  				},
   520  			},
   521  			wantErr: true,
   522  		},
   523  		{
   524  			name: "Error when obtaining bucket encryption info",
   525  			args: args{
   526  				ctx:        ctx,
   527  				client:     minClient,
   528  				bucketName: "test",
   529  				mockBucketEncryptionGet: func(_ context.Context, _ string) (*sse.Configuration, error) {
   530  					return nil, ErrSSENotConfigured
   531  				},
   532  			},
   533  			wantErr: true,
   534  		},
   535  	}
   536  	for _, tt := range tests {
   537  		t.Run(tt.name, func(_ *testing.T) {
   538  			minioGetBucketEncryptionMock = tt.args.mockBucketEncryptionGet
   539  			got, err := getBucketEncryptionInfo(tt.args.ctx, tt.args.client, tt.args.bucketName)
   540  			if (err != nil) != tt.wantErr {
   541  				t.Errorf("getBucketEncryptionInfo() errors = %v, wantErr %v", err, tt.wantErr)
   542  				return
   543  			}
   544  			if !reflect.DeepEqual(got, tt.want) {
   545  				t.Errorf("getBucketEncryptionInfo() got = %v, want %v", got, tt.want)
   546  			}
   547  		})
   548  	}
   549  }
   550  
   551  func Test_SetBucketRetentionConfig(t *testing.T) {
   552  	assert := assert.New(t)
   553  	ctx := context.Background()
   554  	minClient := minioClientMock{}
   555  	type args struct {
   556  		ctx                     context.Context
   557  		client                  MinioClient
   558  		bucketName              string
   559  		mode                    models.ObjectRetentionMode
   560  		unit                    models.ObjectRetentionUnit
   561  		validity                *int32
   562  		mockBucketRetentionFunc func(ctx context.Context, bucketName string, mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit) error
   563  	}
   564  	tests := []struct {
   565  		name          string
   566  		args          args
   567  		expectedError error
   568  	}{
   569  		{
   570  			name: "Set Bucket Retention Config",
   571  			args: args{
   572  				ctx:        ctx,
   573  				client:     minClient,
   574  				bucketName: "test",
   575  				mode:       models.ObjectRetentionModeCompliance,
   576  				unit:       models.ObjectRetentionUnitDays,
   577  				validity:   swag.Int32(2),
   578  				mockBucketRetentionFunc: func(_ context.Context, _ string, _ *minio.RetentionMode, _ *uint, _ *minio.ValidityUnit) error {
   579  					return nil
   580  				},
   581  			},
   582  			expectedError: nil,
   583  		},
   584  		{
   585  			name: "Set Bucket Retention Config 2",
   586  			args: args{
   587  				ctx:        ctx,
   588  				client:     minClient,
   589  				bucketName: "test",
   590  				mode:       models.ObjectRetentionModeGovernance,
   591  				unit:       models.ObjectRetentionUnitYears,
   592  				validity:   swag.Int32(2),
   593  				mockBucketRetentionFunc: func(_ context.Context, _ string, _ *minio.RetentionMode, _ *uint, _ *minio.ValidityUnit) error {
   594  					return nil
   595  				},
   596  			},
   597  			expectedError: nil,
   598  		},
   599  		{
   600  			name: "Invalid validity",
   601  			args: args{
   602  				ctx:        ctx,
   603  				client:     minClient,
   604  				bucketName: "test",
   605  				mode:       models.ObjectRetentionModeCompliance,
   606  				unit:       models.ObjectRetentionUnitDays,
   607  				validity:   nil,
   608  				mockBucketRetentionFunc: func(_ context.Context, _ string, _ *minio.RetentionMode, _ *uint, _ *minio.ValidityUnit) error {
   609  					return nil
   610  				},
   611  			},
   612  			expectedError: errors.New("retention validity can't be nil"),
   613  		},
   614  		{
   615  			name: "Invalid retention mode",
   616  			args: args{
   617  				ctx:        ctx,
   618  				client:     minClient,
   619  				bucketName: "test",
   620  				mode:       models.ObjectRetentionMode("othermode"),
   621  				unit:       models.ObjectRetentionUnitDays,
   622  				validity:   swag.Int32(2),
   623  				mockBucketRetentionFunc: func(_ context.Context, _ string, _ *minio.RetentionMode, _ *uint, _ *minio.ValidityUnit) error {
   624  					return nil
   625  				},
   626  			},
   627  			expectedError: errors.New("invalid retention mode"),
   628  		},
   629  		{
   630  			name: "Invalid retention unit",
   631  			args: args{
   632  				ctx:        ctx,
   633  				client:     minClient,
   634  				bucketName: "test",
   635  				mode:       models.ObjectRetentionModeCompliance,
   636  				unit:       models.ObjectRetentionUnit("otherunit"),
   637  				validity:   swag.Int32(2),
   638  				mockBucketRetentionFunc: func(_ context.Context, _ string, _ *minio.RetentionMode, _ *uint, _ *minio.ValidityUnit) error {
   639  					return nil
   640  				},
   641  			},
   642  			expectedError: errors.New("invalid retention unit"),
   643  		},
   644  		{
   645  			name: "Handle errors on objec lock function",
   646  			args: args{
   647  				ctx:        ctx,
   648  				client:     minClient,
   649  				bucketName: "test",
   650  				mode:       models.ObjectRetentionModeCompliance,
   651  				unit:       models.ObjectRetentionUnitDays,
   652  				validity:   swag.Int32(2),
   653  				mockBucketRetentionFunc: func(_ context.Context, _ string, _ *minio.RetentionMode, _ *uint, _ *minio.ValidityUnit) error {
   654  					return errors.New("error func")
   655  				},
   656  			},
   657  			expectedError: errors.New("error func"),
   658  		},
   659  	}
   660  	for _, tt := range tests {
   661  		t.Run(tt.name, func(_ *testing.T) {
   662  			minioSetObjectLockConfigMock = tt.args.mockBucketRetentionFunc
   663  			err := setBucketRetentionConfig(tt.args.ctx, tt.args.client, tt.args.bucketName, tt.args.mode, tt.args.unit, tt.args.validity)
   664  			if tt.expectedError != nil {
   665  				fmt.Println(t.Name())
   666  				assert.Equal(tt.expectedError.Error(), err.Error(), fmt.Sprintf("setObjectRetention() errors: `%s`, wantErr: `%s`", err, tt.expectedError))
   667  			} else {
   668  				assert.Nil(err, fmt.Sprintf("setBucketRetentionConfig() errors: %v, wantErr: %v", err, tt.expectedError))
   669  			}
   670  		})
   671  	}
   672  }
   673  
   674  func Test_GetBucketRetentionConfig(t *testing.T) {
   675  	assert := assert.New(t)
   676  	ctx := context.Background()
   677  	minClient := minioClientMock{}
   678  	type args struct {
   679  		ctx              context.Context
   680  		client           MinioClient
   681  		bucketName       string
   682  		getRetentionFunc func(ctx context.Context, bucketName string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error)
   683  	}
   684  	tests := []struct {
   685  		name             string
   686  		args             args
   687  		expectedResponse *models.GetBucketRetentionConfig
   688  		expectedError    error
   689  	}{
   690  		{
   691  			name: "Get Bucket Retention Config",
   692  			args: args{
   693  				ctx:        ctx,
   694  				client:     minClient,
   695  				bucketName: "test",
   696  				getRetentionFunc: func(_ context.Context, _ string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) {
   697  					m := minio.Governance
   698  					u := minio.Days
   699  					return &m, swag.Uint(2), &u, nil
   700  				},
   701  			},
   702  			expectedResponse: &models.GetBucketRetentionConfig{
   703  				Mode:     models.ObjectRetentionModeGovernance,
   704  				Unit:     models.ObjectRetentionUnitDays,
   705  				Validity: int32(2),
   706  			},
   707  			expectedError: nil,
   708  		},
   709  		{
   710  			name: "Get Bucket Retention Config Compliance",
   711  			args: args{
   712  				ctx:        ctx,
   713  				client:     minClient,
   714  				bucketName: "test",
   715  				getRetentionFunc: func(_ context.Context, _ string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) {
   716  					m := minio.Compliance
   717  					u := minio.Days
   718  					return &m, swag.Uint(2), &u, nil
   719  				},
   720  			},
   721  			expectedResponse: &models.GetBucketRetentionConfig{
   722  				Mode:     models.ObjectRetentionModeCompliance,
   723  				Unit:     models.ObjectRetentionUnitDays,
   724  				Validity: int32(2),
   725  			},
   726  			expectedError: nil,
   727  		},
   728  		{
   729  			name: "Handle Error on minio func",
   730  			args: args{
   731  				ctx:        ctx,
   732  				client:     minClient,
   733  				bucketName: "test",
   734  				getRetentionFunc: func(_ context.Context, _ string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) {
   735  					return nil, nil, nil, errors.New("error func")
   736  				},
   737  			},
   738  			expectedResponse: nil,
   739  			expectedError:    errors.New("error func"),
   740  		},
   741  		{
   742  			// Description: if minio return NoSuchObjectLockConfiguration, don't panic
   743  			// and return empty response
   744  			name: "Handle NoLock Config errors",
   745  			args: args{
   746  				ctx:        ctx,
   747  				client:     minClient,
   748  				bucketName: "test",
   749  				getRetentionFunc: func(_ context.Context, _ string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) {
   750  					return nil, nil, nil, minio.ErrorResponse{
   751  						Code:    "ObjectLockConfigurationNotFoundError",
   752  						Message: "Object Lock configuration does not exist for this bucket",
   753  					}
   754  				},
   755  			},
   756  			expectedResponse: &models.GetBucketRetentionConfig{},
   757  			expectedError:    nil,
   758  		},
   759  		{
   760  			name: "Return errors on invalid mode",
   761  			args: args{
   762  				ctx:        ctx,
   763  				client:     minClient,
   764  				bucketName: "test",
   765  				getRetentionFunc: func(_ context.Context, _ string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) {
   766  					m := minio.RetentionMode("other")
   767  					u := minio.Days
   768  					return &m, swag.Uint(2), &u, nil
   769  				},
   770  			},
   771  			expectedResponse: nil,
   772  			expectedError:    errors.New("invalid retention mode"),
   773  		},
   774  		{
   775  			name: "Return errors on invalid unit",
   776  			args: args{
   777  				ctx:        ctx,
   778  				client:     minClient,
   779  				bucketName: "test",
   780  				getRetentionFunc: func(_ context.Context, _ string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) {
   781  					m := minio.Governance
   782  					u := minio.ValidityUnit("otherUnit")
   783  					return &m, swag.Uint(2), &u, nil
   784  				},
   785  			},
   786  			expectedResponse: nil,
   787  			expectedError:    errors.New("invalid retention unit"),
   788  		},
   789  	}
   790  
   791  	for _, tt := range tests {
   792  		t.Run(tt.name, func(_ *testing.T) {
   793  			minioGetBucketObjectLockConfigMock = tt.args.getRetentionFunc
   794  			resp, err := getBucketRetentionConfig(tt.args.ctx, tt.args.client, tt.args.bucketName)
   795  
   796  			if tt.expectedError != nil {
   797  				fmt.Println(t.Name())
   798  				assert.Equal(tt.expectedError.Error(), err.Error(), fmt.Sprintf("getBucketRetentionConfig() errors: `%s`, wantErr: `%s`", err, tt.expectedError))
   799  			} else {
   800  				assert.Nil(err, fmt.Sprintf("getBucketRetentionConfig() errors: %v, wantErr: %v", err, tt.expectedError))
   801  				if !reflect.DeepEqual(resp, tt.expectedResponse) {
   802  					t.Errorf("getBucketRetentionConfig() resp: %v, expectedResponse: %v", resp, tt.expectedResponse)
   803  					return
   804  				}
   805  			}
   806  		})
   807  	}
   808  }
   809  
   810  func Test_SetBucketVersioning(t *testing.T) {
   811  	assert := assert.New(t)
   812  	ctx := context.WithValue(context.Background(), utils.ContextClientIP, "127.0.0.1")
   813  	errorMsg := "Error Message"
   814  	minClient := s3ClientMock{}
   815  	type args struct {
   816  		ctx               context.Context
   817  		state             VersionState
   818  		excludePrefix     []string
   819  		excludeFolders    bool
   820  		bucketName        string
   821  		client            s3ClientMock
   822  		setVersioningFunc func(ctx context.Context, state string, excludePrefix []string, excludeFolders bool) *probe.Error
   823  	}
   824  	tests := []struct {
   825  		name          string
   826  		args          args
   827  		expectedError error
   828  	}{
   829  		{
   830  			name: "Set Bucket Version Success",
   831  			args: args{
   832  				ctx:        ctx,
   833  				state:      VersionEnable,
   834  				bucketName: "test",
   835  				client:     minClient,
   836  				setVersioningFunc: func(_ context.Context, _ string, _ []string, _ bool) *probe.Error {
   837  					return nil
   838  				},
   839  			},
   840  			expectedError: nil,
   841  		},
   842  		{
   843  			name: "Set Bucket Version with Prefixes Success",
   844  			args: args{
   845  				ctx:           ctx,
   846  				state:         VersionEnable,
   847  				excludePrefix: []string{"prefix1", "prefix2"},
   848  				bucketName:    "test",
   849  				client:        minClient,
   850  				setVersioningFunc: func(_ context.Context, _ string, _ []string, _ bool) *probe.Error {
   851  					return nil
   852  				},
   853  			},
   854  			expectedError: nil,
   855  		},
   856  		{
   857  			name: "Set Bucket Version with Excluded Folders Success",
   858  			args: args{
   859  				ctx:            ctx,
   860  				state:          VersionEnable,
   861  				excludePrefix:  []string{"prefix1", "prefix2"},
   862  				excludeFolders: true,
   863  				bucketName:     "test",
   864  				client:         minClient,
   865  				setVersioningFunc: func(_ context.Context, _ string, _ []string, _ bool) *probe.Error {
   866  					return nil
   867  				},
   868  			},
   869  			expectedError: nil,
   870  		},
   871  		{
   872  			name: "Set Bucket Version Error",
   873  			args: args{
   874  				ctx:        ctx,
   875  				state:      VersionEnable,
   876  				bucketName: "test",
   877  				client:     minClient,
   878  				setVersioningFunc: func(_ context.Context, _ string, _ []string, _ bool) *probe.Error {
   879  					return probe.NewError(errors.New(errorMsg))
   880  				},
   881  			},
   882  			expectedError: errors.New(errorMsg),
   883  		},
   884  	}
   885  
   886  	for _, tt := range tests {
   887  		t.Run(tt.name, func(_ *testing.T) {
   888  			minioSetVersioningMock = tt.args.setVersioningFunc
   889  
   890  			err := doSetVersioning(tt.args.ctx, tt.args.client, tt.args.state, tt.args.excludePrefix, tt.args.excludeFolders)
   891  
   892  			fmt.Println(t.Name())
   893  			fmt.Println("Expected:", tt.expectedError, "Error:", err)
   894  
   895  			if tt.expectedError != nil {
   896  				fmt.Println(t.Name())
   897  				assert.Equal(tt.expectedError.Error(), err.Error(), fmt.Sprintf("getBucketRetentionConfig() errors: `%s`, wantErr: `%s`", err, tt.expectedError))
   898  			}
   899  		})
   900  	}
   901  }
   902  
   903  func mustTags(tagsMap map[string]string) *tags.Tags {
   904  	tags, _ := tags.NewTags(tagsMap, false)
   905  	return tags
   906  }
   907  
   908  func Test_getAccountBuckets(t *testing.T) {
   909  	type args struct {
   910  		ctx            context.Context
   911  		mockBucketList madmin.AccountInfo
   912  		mockError      error
   913  	}
   914  
   915  	// Declaring layout constant
   916  	const layout = "Jan 2, 2006 at 3:04pm (MST)"
   917  	// Calling Parse() method with its parameters
   918  	tm, _ := time.Parse(layout, "Feb 4, 2014 at 6:05pm (PST)")
   919  	tests := []struct {
   920  		name    string
   921  		args    args
   922  		want    []*models.Bucket
   923  		wantErr assert.ErrorAssertionFunc
   924  	}{
   925  		{
   926  			name: "Test list Buckets",
   927  			args: args{
   928  				ctx: context.Background(),
   929  				mockBucketList: madmin.AccountInfo{
   930  					AccountName: "test",
   931  					Buckets: []madmin.BucketAccessInfo{
   932  						{Name: "bucket-1", Created: tm, Size: 1024},
   933  						{Name: "bucket-2", Created: tm, Size: 0},
   934  					},
   935  					Policy: []byte(`
   936  			{
   937  				"Version": "2012-10-17",
   938  				"Statement": [{
   939  						"Action": [
   940  							"admin:*"
   941  						],
   942  						"Effect": "Allow",
   943  						"Sid": ""
   944  					},
   945  					{
   946  						"Action": [
   947  							"s3:*"
   948  						],
   949  						"Effect": "Allow",
   950  						"Resource": [
   951  							"arn:aws:s3:::*"
   952  						],
   953  						"Sid": ""
   954  					}
   955  				]
   956  			}`),
   957  				},
   958  			},
   959  			want: []*models.Bucket{
   960  				{
   961  					Name:         swag.String("bucket-1"),
   962  					CreationDate: tm.Format(time.RFC3339),
   963  					Details:      &models.BucketDetails{},
   964  					RwAccess:     &models.BucketRwAccess{},
   965  					Size:         1024,
   966  				},
   967  				{
   968  					Name:         swag.String("bucket-2"),
   969  					CreationDate: tm.Format(time.RFC3339),
   970  					Details:      &models.BucketDetails{},
   971  					RwAccess:     &models.BucketRwAccess{},
   972  				},
   973  			},
   974  			wantErr: assert.NoError,
   975  		},
   976  		{
   977  			name: "Test list Buckets Details",
   978  			args: args{
   979  				ctx: context.Background(),
   980  				mockBucketList: madmin.AccountInfo{
   981  					AccountName: "test",
   982  					Buckets: []madmin.BucketAccessInfo{
   983  						{
   984  							Name: "bucket-1", Created: tm, Size: 1024,
   985  							Details: &madmin.BucketDetails{
   986  								Versioning:          true,
   987  								VersioningSuspended: false,
   988  								Locking:             false,
   989  								Replication:         false,
   990  								Tagging:             nil,
   991  								Quota:               nil,
   992  							},
   993  						},
   994  						{Name: "bucket-2", Created: tm, Size: 0},
   995  					},
   996  					Policy: []byte(`
   997  			{
   998  				"Version": "2012-10-17",
   999  				"Statement": [{
  1000  						"Action": [
  1001  							"admin:*"
  1002  						],
  1003  						"Effect": "Allow",
  1004  						"Sid": ""
  1005  					},
  1006  					{
  1007  						"Action": [
  1008  							"s3:*"
  1009  						],
  1010  						"Effect": "Allow",
  1011  						"Resource": [
  1012  							"arn:aws:s3:::*"
  1013  						],
  1014  						"Sid": ""
  1015  					}
  1016  				]
  1017  			}`),
  1018  				},
  1019  			},
  1020  			want: []*models.Bucket{
  1021  				{
  1022  					Name:         swag.String("bucket-1"),
  1023  					CreationDate: tm.Format(time.RFC3339),
  1024  					Details: &models.BucketDetails{
  1025  						Locking:             false,
  1026  						Quota:               nil,
  1027  						Replication:         false,
  1028  						Tags:                nil,
  1029  						Versioning:          true,
  1030  						VersioningSuspended: false,
  1031  					},
  1032  					RwAccess: &models.BucketRwAccess{},
  1033  					Size:     1024,
  1034  				},
  1035  				{
  1036  					Name:         swag.String("bucket-2"),
  1037  					CreationDate: tm.Format(time.RFC3339),
  1038  					Details:      &models.BucketDetails{},
  1039  					RwAccess:     &models.BucketRwAccess{},
  1040  				},
  1041  			},
  1042  			wantErr: assert.NoError,
  1043  		},
  1044  		{
  1045  			name: "Test list Buckets Details Tags",
  1046  			args: args{
  1047  				ctx: context.Background(),
  1048  				mockBucketList: madmin.AccountInfo{
  1049  					AccountName: "test",
  1050  					Buckets: []madmin.BucketAccessInfo{
  1051  						{
  1052  							Name: "bucket-1", Created: tm, Size: 1024,
  1053  							Details: &madmin.BucketDetails{
  1054  								Versioning:          true,
  1055  								VersioningSuspended: false,
  1056  								Locking:             false,
  1057  								Replication:         false,
  1058  								Tagging: mustTags(map[string]string{
  1059  									"key": "val",
  1060  								}),
  1061  								Quota: nil,
  1062  							},
  1063  						},
  1064  						{Name: "bucket-2", Created: tm, Size: 0},
  1065  					},
  1066  					Policy: []byte(`
  1067  			{
  1068  				"Version": "2012-10-17",
  1069  				"Statement": [{
  1070  						"Action": [
  1071  							"admin:*"
  1072  						],
  1073  						"Effect": "Allow",
  1074  						"Sid": ""
  1075  					},
  1076  					{
  1077  						"Action": [
  1078  							"s3:*"
  1079  						],
  1080  						"Effect": "Allow",
  1081  						"Resource": [
  1082  							"arn:aws:s3:::*"
  1083  						],
  1084  						"Sid": ""
  1085  					}
  1086  				]
  1087  			}`),
  1088  				},
  1089  			},
  1090  			want: []*models.Bucket{
  1091  				{
  1092  					Name:         swag.String("bucket-1"),
  1093  					CreationDate: tm.Format(time.RFC3339),
  1094  					Details: &models.BucketDetails{
  1095  						Locking:     false,
  1096  						Quota:       nil,
  1097  						Replication: false,
  1098  						Tags: map[string]string{
  1099  							"key": "val",
  1100  						},
  1101  						Versioning:          true,
  1102  						VersioningSuspended: false,
  1103  					},
  1104  					RwAccess: &models.BucketRwAccess{},
  1105  					Size:     1024,
  1106  				},
  1107  				{
  1108  					Name:         swag.String("bucket-2"),
  1109  					CreationDate: tm.Format(time.RFC3339),
  1110  					Details:      &models.BucketDetails{},
  1111  					RwAccess:     &models.BucketRwAccess{},
  1112  				},
  1113  			},
  1114  			wantErr: assert.NoError,
  1115  		},
  1116  		{
  1117  			name: "Test list Buckets Details Quota",
  1118  			args: args{
  1119  				ctx: context.Background(),
  1120  				mockBucketList: madmin.AccountInfo{
  1121  					AccountName: "test",
  1122  					Buckets: []madmin.BucketAccessInfo{
  1123  						{
  1124  							Name: "bucket-1", Created: tm, Size: 1024,
  1125  							Details: &madmin.BucketDetails{
  1126  								Versioning:          true,
  1127  								VersioningSuspended: false,
  1128  								Locking:             false,
  1129  								Replication:         false,
  1130  								Tagging:             nil,
  1131  								Quota: &madmin.BucketQuota{
  1132  									Quota: 10,
  1133  									Type:  madmin.HardQuota,
  1134  								},
  1135  							},
  1136  						},
  1137  						{Name: "bucket-2", Created: tm, Size: 0},
  1138  					},
  1139  					Policy: []byte(`
  1140  			{
  1141  				"Version": "2012-10-17",
  1142  				"Statement": [{
  1143  						"Action": [
  1144  							"admin:*"
  1145  						],
  1146  						"Effect": "Allow",
  1147  						"Sid": ""
  1148  					},
  1149  					{
  1150  						"Action": [
  1151  							"s3:*"
  1152  						],
  1153  						"Effect": "Allow",
  1154  						"Resource": [
  1155  							"arn:aws:s3:::*"
  1156  						],
  1157  						"Sid": ""
  1158  					}
  1159  				]
  1160  			}`),
  1161  				},
  1162  			},
  1163  			want: []*models.Bucket{
  1164  				{
  1165  					Name:         swag.String("bucket-1"),
  1166  					CreationDate: tm.Format(time.RFC3339),
  1167  					Details: &models.BucketDetails{
  1168  						Locking: false,
  1169  						Quota: &models.BucketDetailsQuota{
  1170  							Quota: 10,
  1171  							Type:  "hard",
  1172  						},
  1173  						Replication:         false,
  1174  						Tags:                nil,
  1175  						Versioning:          true,
  1176  						VersioningSuspended: false,
  1177  					},
  1178  					RwAccess: &models.BucketRwAccess{},
  1179  					Size:     1024,
  1180  				},
  1181  				{
  1182  					Name:         swag.String("bucket-2"),
  1183  					CreationDate: tm.Format(time.RFC3339),
  1184  					Details:      &models.BucketDetails{},
  1185  					RwAccess:     &models.BucketRwAccess{},
  1186  				},
  1187  			},
  1188  			wantErr: assert.NoError,
  1189  		},
  1190  		{
  1191  			name: "Test list Buckets Error",
  1192  			args: args{
  1193  				ctx:            context.Background(),
  1194  				mockBucketList: madmin.AccountInfo{},
  1195  				mockError:      errors.New("some errors"),
  1196  			},
  1197  			want:    []*models.Bucket{},
  1198  			wantErr: assert.Error,
  1199  		},
  1200  	}
  1201  	for _, tt := range tests {
  1202  		t.Run(tt.name, func(_ *testing.T) {
  1203  			// mock function response from listBucketsWithContext(ctx)
  1204  			minioAccountInfoMock = func(_ context.Context) (madmin.AccountInfo, error) {
  1205  				return tt.args.mockBucketList, tt.args.mockError
  1206  			}
  1207  			client := AdminClientMock{}
  1208  
  1209  			got, err := getAccountBuckets(tt.args.ctx, client)
  1210  			if !tt.wantErr(t, err, fmt.Sprintf("getAccountBuckets(%v, %v)", tt.args.ctx, client)) {
  1211  				return
  1212  			}
  1213  			assert.EqualValues(t, tt.want, got, "getAccountBuckets(%v, %v)", tt.args.ctx, client)
  1214  		})
  1215  	}
  1216  }
  1217  
  1218  func Test_getMaxShareLinkExpirationSeconds(t *testing.T) {
  1219  	type args struct {
  1220  		session *models.Principal
  1221  	}
  1222  	tests := []struct {
  1223  		name     string
  1224  		args     args
  1225  		want     int64
  1226  		wantErr  bool
  1227  		preFunc  func()
  1228  		postFunc func()
  1229  	}{
  1230  		{
  1231  			name: "empty session returns error",
  1232  			args: args{
  1233  				session: nil,
  1234  			},
  1235  			want:    0,
  1236  			wantErr: true,
  1237  		},
  1238  		{
  1239  			name: "invalid/expired session returns error",
  1240  			args: args{
  1241  				session: &models.Principal{
  1242  					STSAccessKeyID:     "",
  1243  					STSSecretAccessKey: "",
  1244  					STSSessionToken:    "",
  1245  				},
  1246  			},
  1247  			want:    0,
  1248  			wantErr: true,
  1249  		},
  1250  		{
  1251  			name: "valid session, returns value from env variable",
  1252  			args: args{
  1253  				session: &models.Principal{
  1254  					STSAccessKeyID:     "VQH975JV49JYDLK7F81G",
  1255  					STSSecretAccessKey: "zZ2oMQrZwPWGEf1yyHneWFK2JBlGkVjYTJnfw75X",
  1256  					STSSessionToken:    "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NLZXkiOiJWUUg5NzVKVjQ5SllETEs3RjgxRyIsImV4cCI6MTY5Nzc0Mzg1MywicGFyZW50IjoibWluaW9hZG1pbiJ9.tRJVb3gbRFswKyNsxz_Dbw1SHoIQRRgA3xmXpXE4shScCsQXDydc7U_F9QOjL_BQDcgs65ZqWo3N2CIPmWoGDA",
  1257  				},
  1258  			},
  1259  			want:    3600,
  1260  			wantErr: false,
  1261  			preFunc: func() {
  1262  				os.Setenv(token.ConsoleSTSDuration, "1h")
  1263  			},
  1264  			postFunc: func() {
  1265  				os.Unsetenv(token.ConsoleSTSDuration)
  1266  			},
  1267  		},
  1268  	}
  1269  	for _, tt := range tests {
  1270  		tt := tt
  1271  		t.Run(tt.name, func(_ *testing.T) {
  1272  			if tt.preFunc != nil {
  1273  				tt.preFunc()
  1274  			}
  1275  			expTime, err := getMaxShareLinkExpirationSeconds(tt.args.session)
  1276  			if (err != nil) != tt.wantErr {
  1277  				t.Errorf("getMaxShareLinkExpirationSeconds() error = %v, wantErr %v", err, tt.wantErr)
  1278  				return
  1279  			}
  1280  			if !reflect.DeepEqual(expTime, tt.want) {
  1281  				t.Errorf("getMaxShareLinkExpirationSeconds() got = %v, want %v", expTime, tt.want)
  1282  			}
  1283  			if tt.postFunc != nil {
  1284  				tt.postFunc()
  1285  			}
  1286  		})
  1287  	}
  1288  }