github.com/minio/console@v1.3.0/integration/service_account_test.go (about) 1 // This file is part of MinIO Console Server 2 // Copyright (c) 2022 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 integration 18 19 import ( 20 "bytes" 21 "encoding/base64" 22 "encoding/json" 23 "fmt" 24 "log" 25 "net/http" 26 "testing" 27 "time" 28 29 "github.com/go-openapi/swag" 30 31 "github.com/stretchr/testify/assert" 32 ) 33 34 func TestAddServiceAccount(t *testing.T) { 35 /* 36 This is an atomic API Test to add a user service account, the intention 37 is simple, add a user and make sure the response is 201 meaning that the 38 user got added successfully. 39 After test completion, it is expected that user is removed, so other 40 tests like users.ts can run over clean data and we don't collide against 41 it. 42 */ 43 44 assert := assert.New(t) 45 46 client := &http.Client{ 47 Timeout: 3 * time.Second, 48 } 49 50 // Add service account 51 requestDataAddServiceAccount := map[string]interface{}{ 52 "accessKey": "testuser1", 53 "secretKey": "password", 54 "policy": `{ 55 "Version": "2012-10-17", 56 "Statement": [ 57 { 58 "Effect": "Allow", 59 "Action": [ 60 "s3:GetBucketLocation", 61 "s3:GetObject" 62 ], 63 "Resource": [ 64 "arn:aws:s3:::*" 65 ] 66 } 67 ] 68 }`, 69 } 70 71 requestDataJSON, _ := json.Marshal(requestDataAddServiceAccount) 72 requestDataBody := bytes.NewReader(requestDataJSON) 73 request, err := http.NewRequest( 74 "POST", "http://localhost:9090/api/v1/service-account-credentials", requestDataBody) 75 if err != nil { 76 log.Println(err) 77 return 78 } 79 request.Header.Add("Cookie", fmt.Sprintf("token=%s", token)) 80 request.Header.Add("Content-Type", "application/json") 81 82 response, err := client.Do(request) 83 if err != nil { 84 log.Println(err) 85 return 86 } 87 if response != nil { 88 fmt.Println("POST StatusCode:", response.StatusCode) 89 assert.Equal(201, response.StatusCode, "Status Code is incorrect") 90 } 91 92 // {{baseUrl}}/user?name=proident velit 93 // Investiga como se borra en el browser. 94 request, err = http.NewRequest( 95 "DELETE", "http://localhost:9090/api/v1/service-accounts/"+base64.StdEncoding.EncodeToString([]byte("testuser1")), nil) 96 if err != nil { 97 log.Println(err) 98 return 99 } 100 request.Header.Add("Cookie", fmt.Sprintf("token=%s", token)) 101 request.Header.Add("Content-Type", "application/json") 102 response, err = client.Do(request) 103 if err != nil { 104 log.Println(err) 105 return 106 } 107 if response != nil { 108 fmt.Println("DELETE StatusCode:", response.StatusCode) 109 assert.Equal(204, response.StatusCode, "has to be 204 when delete user") 110 } 111 } 112 113 func Test_ServiceAccountsAPI(t *testing.T) { 114 assert := assert.New(t) 115 116 type args struct { 117 api string 118 policy *string 119 } 120 tests := []struct { 121 name string 122 args args 123 expectedStatus int 124 expectedError error 125 }{ 126 { 127 name: "Create Service Account - Default", 128 args: args{ 129 api: "/service-accounts", 130 policy: nil, 131 }, 132 expectedStatus: 201, 133 expectedError: nil, 134 }, 135 { 136 name: "Create Service Account - Valid Policy", 137 args: args{ 138 api: "/service-accounts", 139 policy: swag.String(` 140 { 141 "Version": "2012-10-17", 142 "Statement": [ 143 { 144 "Effect": "Allow", 145 "Action": [ 146 "s3:GetBucketLocation", 147 "s3:GetObject" 148 ], 149 "Resource": [ 150 "arn:aws:s3:::*" 151 ] 152 } 153 ] 154 }`), 155 }, 156 expectedStatus: 201, 157 expectedError: nil, 158 }, 159 { 160 name: "Create Service Account - Invalid Policy", 161 args: args{ 162 api: "/service-accounts", 163 policy: swag.String(` 164 { 165 "Version": "2012-10-17", 166 "Statement": [ 167 { 168 "Effect": "Allow", 169 "Action": [ 170 "s3:GetBucketLocation" 171 "s3:GetObject" 172 ], 173 "Resource": [ 174 "arn:aws:s3:::*" 175 ] 176 } 177 ] 178 }`), 179 }, 180 expectedStatus: 500, 181 expectedError: nil, 182 }, 183 } 184 185 for _, tt := range tests { 186 t.Run(tt.name, func(_ *testing.T) { 187 client := &http.Client{ 188 Timeout: 3 * time.Second, 189 } 190 191 // Add service account 192 193 requestDataPolicy := map[string]interface{}{} 194 if tt.args.policy != nil { 195 requestDataPolicy["policy"] = *tt.args.policy 196 } 197 198 requestDataJSON, _ := json.Marshal(requestDataPolicy) 199 requestDataBody := bytes.NewReader(requestDataJSON) 200 request, err := http.NewRequest( 201 "POST", fmt.Sprintf("http://localhost:9090/api/v1%s", tt.args.api), requestDataBody) 202 if err != nil { 203 log.Println(err) 204 return 205 } 206 request.Header.Add("Cookie", fmt.Sprintf("token=%s", token)) 207 request.Header.Add("Content-Type", "application/json") 208 response, err := client.Do(request) 209 if err != nil { 210 log.Println(err) 211 return 212 } 213 if response != nil { 214 assert.Equal(tt.expectedStatus, response.StatusCode, "Status Code is incorrect") 215 } 216 }) 217 } 218 } 219 220 func DeleteMultipleServiceAccounts(serviceAccounts []string) (*http.Response, error) { 221 /* 222 Helper function to delete multiple service accounts 223 URL: http://localhost:9001/api/v1/service-accounts/delete-multi 224 HTTP Verb: DELETE 225 Data: ["U3RADB7J2ZZHELR0WSBB","ZE8H1HYOA6AVGKFCV6YU"] 226 Response: Status Code: 204 No Content 227 */ 228 client := &http.Client{ 229 Timeout: 3 * time.Second, 230 } 231 requestDataJSON, _ := json.Marshal(serviceAccounts) 232 requestDataBody := bytes.NewReader(requestDataJSON) 233 request, err := http.NewRequest( 234 "DELETE", "http://localhost:9090/api/v1/service-accounts/delete-multi", requestDataBody) 235 if err != nil { 236 log.Println(err) 237 } 238 request.Header.Add("Cookie", fmt.Sprintf("token=%s", token)) 239 request.Header.Add("Content-Type", "application/json") 240 response, err := client.Do(request) 241 return response, err 242 } 243 244 func TestCreateServiceAccountForUserWithCredentials(t *testing.T) { 245 /* 246 To test creation of service account for a user. 247 */ 248 249 // Test's variables 250 userName := "testcreateserviceaccountforuserwithcredentials1" 251 assert := assert.New(t) 252 policy := "" 253 254 // 1. Create the user 255 groups := []string{} 256 policies := []string{} 257 secretKey := "testcreateserviceaccountforuserwithcrede" 258 response, err := AddUser(userName, "secretKey", groups, policies) 259 if err != nil { 260 log.Println(err) 261 return 262 } 263 if response != nil { 264 fmt.Println("StatusCode:", response.StatusCode) 265 assert.Equal(201, response.StatusCode, "Status Code is incorrect") 266 } 267 268 // Table driven testing part 269 type args struct { 270 accessKey string 271 } 272 tests := []struct { 273 name string 274 args args 275 expectedStatus int 276 }{ 277 { 278 name: "Service Account With Valid Credentials", 279 expectedStatus: 201, 280 args: args{ 281 accessKey: "testcreateserviceacc", 282 }, 283 }, 284 { 285 name: "Service Account With Invalid Credentials", 286 expectedStatus: 500, 287 args: args{ 288 accessKey: "tooooooooooooooooooooolongggggggggggggggggg", 289 }, 290 }, 291 } 292 for _, tt := range tests { 293 t.Run(tt.name, func(_ *testing.T) { 294 // 2. Create the service account for the user 295 createServiceAccountWithCredentialsResponse, 296 createServiceAccountWithCredentialsError := CreateServiceAccountForUserWithCredentials( 297 userName, 298 policy, 299 tt.args.accessKey, 300 secretKey, 301 ) 302 if createServiceAccountWithCredentialsError != nil { 303 log.Println(createServiceAccountWithCredentialsError) 304 assert.Fail("Error in createServiceAccountWithCredentialsError") 305 } 306 if createServiceAccountWithCredentialsResponse != nil { 307 fmt.Println("StatusCode:", createServiceAccountWithCredentialsResponse.StatusCode) 308 assert.Equal( 309 tt.expectedStatus, // different status expected per table's row 310 createServiceAccountWithCredentialsResponse.StatusCode, 311 inspectHTTPResponse(createServiceAccountWithCredentialsResponse), 312 ) 313 } 314 315 // 3. Verify the service account for the user 316 listOfAccountsResponse, 317 listOfAccountsError := ReturnsAListOfServiceAccountsForAUser(userName) 318 if listOfAccountsError != nil { 319 log.Println(listOfAccountsError) 320 assert.Fail("Error in listOfAccountsError") 321 } 322 finalResponse := inspectHTTPResponse(listOfAccountsResponse) 323 if listOfAccountsResponse != nil { 324 fmt.Println("StatusCode:", listOfAccountsResponse.StatusCode) 325 assert.Equal( 326 200, listOfAccountsResponse.StatusCode, 327 finalResponse, 328 ) 329 } 330 }) 331 } 332 333 // Delete Multiple Service Accounts 334 serviceAccount := make([]string, 1) 335 serviceAccount[0] = "testcreateserviceacc" 336 response, err = DeleteMultipleServiceAccounts(serviceAccount) 337 if err != nil { 338 log.Println(err) 339 return 340 } 341 if response != nil { 342 fmt.Println("StatusCode:", response.StatusCode) 343 assert.Equal( 344 204, 345 response.StatusCode, 346 inspectHTTPResponse(response), 347 ) 348 } 349 }