1// Copyright (c) 2015-2021 MinIO, Inc. 2// 3// This file is part of MinIO Object Storage stack 4// 5// This program is free software: you can redistribute it and/or modify 6// it under the terms of the GNU Affero General Public License as published by 7// the Free Software Foundation, either version 3 of the License, or 8// (at your option) any later version. 9// 10// This program is distributed in the hope that it will be useful 11// but WITHOUT ANY WARRANTY; without even the implied warranty of 12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13// GNU Affero General Public License for more details. 14// 15// You should have received a copy of the GNU Affero General Public License 16// along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18package cmd 19 20import ( 21 "reflect" 22 "testing" 23 24 "github.com/minio/minio-go/v7/pkg/encrypt" 25) 26 27func TestParseEncryptionKeys(t *testing.T) { 28 sseKey1, err := encrypt.NewSSEC([]byte("32byteslongsecretkeymustbegiven2")) 29 if err != nil { 30 t.Fatal(err) 31 } 32 sseKey2, err := encrypt.NewSSEC([]byte("32byteslongsecretkeymustbegiven1")) 33 if err != nil { 34 t.Fatal(err) 35 } 36 sseSpaceKey1, err := encrypt.NewSSEC([]byte("32byteslongsecret mustbegiven1")) 37 if err != nil { 38 t.Fatal(err) 39 } 40 sseCommaKey1, err := encrypt.NewSSEC([]byte("32byteslongsecretkey,ustbegiven1")) 41 if err != nil { 42 t.Fatal(err) 43 } 44 testCases := []struct { 45 encryptionKey string 46 expectedEncMap map[string][]prefixSSEPair 47 success bool 48 }{ 49 { 50 encryptionKey: "myminio1/test2=32byteslongsecretkeymustbegiven2", 51 expectedEncMap: map[string][]prefixSSEPair{"myminio1": {{ 52 Prefix: "myminio1/test2", 53 SSE: sseKey1, 54 }}}, 55 success: true, 56 }, 57 { 58 encryptionKey: "myminio1/test2=32byteslongsecretkeymustbegiven", 59 expectedEncMap: nil, 60 success: false, 61 }, 62 { 63 encryptionKey: "myminio1/test2=32byteslongsecretkey,ustbegiven1", 64 expectedEncMap: map[string][]prefixSSEPair{"myminio1": {{ 65 Prefix: "myminio1/test2", 66 SSE: sseCommaKey1, 67 }}}, 68 success: true, 69 }, 70 { 71 encryptionKey: "myminio1/test2=32byteslongsecret mustbegiven1", 72 expectedEncMap: map[string][]prefixSSEPair{"myminio1": {{ 73 Prefix: "myminio1/test2", 74 SSE: sseSpaceKey1, 75 }}}, 76 success: true, 77 }, 78 { 79 encryptionKey: "myminio1/test2=32byteslongsecretkeymustbegiven2,myminio1/test1/a=32byteslongsecretkeymustbegiven1", 80 expectedEncMap: map[string][]prefixSSEPair{"myminio1": {{ 81 Prefix: "myminio1/test1/a", 82 SSE: sseKey2, 83 }, { 84 Prefix: "myminio1/test2", 85 SSE: sseKey1, 86 }}}, 87 success: true, 88 }, 89 } 90 for i, testCase := range testCases { 91 encMap, err := parseEncryptionKeys(testCase.encryptionKey) 92 if err != nil && testCase.success { 93 t.Fatalf("Test %d: Expected success, got %s", i+1, err) 94 } 95 if err == nil && !testCase.success { 96 t.Fatalf("Test %d: Expected error, got success", i+1) 97 } 98 if testCase.success && !reflect.DeepEqual(encMap, testCase.expectedEncMap) { 99 t.Errorf("Test %d: Expected %s, got %s", i+1, testCase.expectedEncMap, encMap) 100 } 101 } 102} 103 104func TestParseAttribute(t *testing.T) { 105 metaDataCases := []struct { 106 input string 107 output map[string]string 108 err error 109 status bool 110 }{ 111 // // When blank value is passed. 112 {"", map[string]string{}, ErrInvalidFileSystemAttribute, false}, 113 // When space is passed. 114 {" ", map[string]string{}, ErrInvalidFileSystemAttribute, false}, 115 // When / is passed. 116 {"/", map[string]string{}, ErrInvalidFileSystemAttribute, false}, 117 // When "atime:" is passed. 118 {"atime:/", map[string]string{"atime": ""}, ErrInvalidFileSystemAttribute, false}, 119 // When "atime:" is passed. 120 {"atime", map[string]string{"atime": ""}, nil, true}, 121 // When "atime:" is passed. 122 {"atime:", map[string]string{"atime": ""}, nil, true}, 123 // Passing a valid value 124 {"atime:1/gid:1/gname:a/md:/mode:3/mtime:1/uid:1/uname:a", 125 map[string]string{ 126 "atime": "1", 127 "gid": "1", 128 "gname": "a", 129 "md": "", 130 "mode": "3", 131 "mtime": "1", 132 "uid": "1", 133 "uname": "a", 134 }, nil, true}, 135 } 136 137 for idx, testCase := range metaDataCases { 138 meta, err := parseAttribute(map[string]string{ 139 metadataKey: testCase.input, 140 }) 141 if testCase.status == true { 142 if err != nil { 143 t.Fatalf("Test %d: generated error not matching, expected = `%s`, found = `%s`", idx+1, testCase.err, err) 144 } 145 if !reflect.DeepEqual(meta, testCase.output) { 146 t.Fatalf("Test %d: generated Map not matching, expected = `%s`, found = `%s`", idx+1, testCase.input, meta) 147 } 148 } 149 if testCase.status == false { 150 if !reflect.DeepEqual(meta, testCase.output) { 151 t.Fatalf("Test %d: generated Map not matching, expected = `%s`, found = `%s`", idx+1, testCase.input, meta) 152 } 153 if err != testCase.err { 154 t.Fatalf("Test %d: generated error not matching, expected = `%s`, found = `%s`", idx+1, testCase.err, err) 155 } 156 } 157 158 } 159} 160