1package alicloud 2 3import ( 4 "context" 5 "fmt" 6 "testing" 7 8 "github.com/hashicorp/vault/sdk/logical" 9) 10 11/* 12 testEnv allows us to reuse the same requests and response-checking 13 for both integration tests that don't hit Alibaba's real API, and 14 for acceptance tests that do hit their real API. 15*/ 16type testEnv struct { 17 AccessKey string 18 SecretKey string 19 RoleARN string 20 21 Backend logical.Backend 22 Context context.Context 23 Storage logical.Storage 24 25 MostRecentSecret *logical.Secret 26} 27 28func (e *testEnv) AddConfig(t *testing.T) { 29 req := &logical.Request{ 30 Operation: logical.UpdateOperation, 31 Path: "config", 32 Storage: e.Storage, 33 Data: map[string]interface{}{ 34 "access_key": e.AccessKey, 35 "secret_key": e.SecretKey, 36 }, 37 } 38 resp, err := e.Backend.HandleRequest(e.Context, req) 39 if err != nil || (resp != nil && resp.IsError()) { 40 t.Fatalf("bad: resp: %#v\nerr:%v", resp, err) 41 } 42 if resp != nil { 43 t.Fatal("expected nil response to represent a 204") 44 } 45} 46 47func (e *testEnv) ReadFirstConfig(t *testing.T) { 48 req := &logical.Request{ 49 Operation: logical.ReadOperation, 50 Path: "config", 51 Storage: e.Storage, 52 } 53 resp, err := e.Backend.HandleRequest(e.Context, req) 54 if err != nil || (resp != nil && resp.IsError()) { 55 t.Fatalf("bad: resp: %#v\nerr:%v", resp, err) 56 } 57 if resp == nil { 58 t.Fatal("expected a response") 59 } 60 if resp.Data["access_key"] != e.AccessKey { 61 t.Fatal("expected access_key of " + e.AccessKey) 62 } 63 if resp.Data["secret_key"] != nil { 64 t.Fatal("secret_key should not be returned") 65 } 66} 67 68func (e *testEnv) UpdateConfig(t *testing.T) { 69 req := &logical.Request{ 70 Operation: logical.UpdateOperation, 71 Path: "config", 72 Storage: e.Storage, 73 Data: map[string]interface{}{ 74 "access_key": "foo", 75 "secret_key": "bar", 76 }, 77 } 78 resp, err := e.Backend.HandleRequest(e.Context, req) 79 if err != nil || (resp != nil && resp.IsError()) { 80 t.Fatalf("bad: resp: %#v\nerr:%v", resp, err) 81 } 82 if resp != nil { 83 t.Fatal("expected nil response to represent a 204") 84 } 85} 86 87func (e *testEnv) ReadSecondConfig(t *testing.T) { 88 req := &logical.Request{ 89 Operation: logical.ReadOperation, 90 Path: "config", 91 Storage: e.Storage, 92 } 93 resp, err := e.Backend.HandleRequest(e.Context, req) 94 if err != nil || (resp != nil && resp.IsError()) { 95 t.Fatalf("bad: resp: %#v\nerr:%v", resp, err) 96 } 97 if resp == nil { 98 t.Fatal("expected a response") 99 } 100 if resp.Data["access_key"] != "foo" { 101 t.Fatal("expected access_key of foo") 102 } 103 if resp.Data["secret_key"] != nil { 104 t.Fatal("secret_key should not be returned") 105 } 106} 107 108func (e *testEnv) DeleteConfig(t *testing.T) { 109 req := &logical.Request{ 110 Operation: logical.DeleteOperation, 111 Path: "config", 112 Storage: e.Storage, 113 } 114 resp, err := e.Backend.HandleRequest(e.Context, req) 115 if err != nil || (resp != nil && resp.IsError()) { 116 t.Fatalf("bad: resp: %#v\nerr:%v", resp, err) 117 } 118 if resp != nil { 119 t.Fatal("expected nil response to represent a 204") 120 } 121} 122 123func (e *testEnv) ReadEmptyConfig(t *testing.T) { 124 req := &logical.Request{ 125 Operation: logical.ReadOperation, 126 Path: "config", 127 Storage: e.Storage, 128 } 129 resp, err := e.Backend.HandleRequest(e.Context, req) 130 if err != nil || (resp != nil && resp.IsError()) { 131 t.Fatalf("bad: resp: %#v\nerr:%v", resp, err) 132 } 133 if resp != nil { 134 t.Fatal("expected nil response to represent a 204") 135 } 136} 137 138func (e *testEnv) AddPolicyBasedRole(t *testing.T) { 139 req := &logical.Request{ 140 Operation: logical.CreateOperation, 141 Path: "role/policy-based", 142 Storage: e.Storage, 143 Data: map[string]interface{}{ 144 "remote_policies": []string{ 145 "name:AliyunOSSReadOnlyAccess,type:System", 146 "name:AliyunRDSReadOnlyAccess,type:System", 147 }, 148 "inline_policies": rawInlinePolicies, 149 }, 150 } 151 resp, err := e.Backend.HandleRequest(e.Context, req) 152 if err != nil || (resp != nil && resp.IsError()) { 153 t.Fatalf("bad: resp: %#v\nerr:%v", resp, err) 154 } 155 if resp != nil { 156 t.Fatal("expected nil response to represent a 204") 157 } 158} 159 160func (e *testEnv) ReadPolicyBasedRole(t *testing.T) { 161 req := &logical.Request{ 162 Operation: logical.ReadOperation, 163 Path: "role/policy-based", 164 Storage: e.Storage, 165 } 166 resp, err := e.Backend.HandleRequest(e.Context, req) 167 if err != nil || (resp != nil && resp.IsError()) { 168 t.Fatalf("bad: resp: %#v\nerr:%v", resp, err) 169 } 170 if resp == nil { 171 t.Fatal("expected a response") 172 } 173 174 if resp.Data["role_arn"] != "" { 175 t.Fatalf("expected no role_arn but received %s", resp.Data["role_arn"]) 176 } 177 178 inlinePolicies := resp.Data["inline_policies"].([]*inlinePolicy) 179 for i, inlinePolicy := range inlinePolicies { 180 if inlinePolicy.PolicyDocument["Version"] != "1" { 181 t.Fatalf("expected version of 1 but received %s", inlinePolicy.PolicyDocument["Version"]) 182 } 183 stmts := inlinePolicy.PolicyDocument["Statement"].([]interface{}) 184 if len(stmts) != 1 { 185 t.Fatalf("expected 1 statement but received %d", len(stmts)) 186 } 187 stmt := stmts[0].(map[string]interface{}) 188 action := stmt["Action"].([]interface{})[0].(string) 189 if stmt["Effect"] != "Allow" { 190 t.Fatalf("expected Allow statement but received %s", stmt["Effect"]) 191 } 192 resource := stmt["Resource"].([]interface{})[0].(string) 193 if resource != "acs:oss:*:*:*" { 194 t.Fatalf("received incorrect resource: %s", resource) 195 } 196 switch i { 197 case 0: 198 if action != "rds:*" { 199 t.Fatalf("expected rds:* but received %s", action) 200 } 201 case 1: 202 if action != "oss:*" { 203 t.Fatalf("expected oss:* but received %s", action) 204 } 205 } 206 } 207 208 remotePolicies := resp.Data["remote_policies"].([]*remotePolicy) 209 for i, remotePol := range remotePolicies { 210 switch i { 211 case 0: 212 if remotePol.Name != "AliyunOSSReadOnlyAccess" { 213 t.Fatalf("received unexpected policy name of %s", remotePol.Name) 214 } 215 if remotePol.Type != "System" { 216 t.Fatalf("received unexpected policy type of %s", remotePol.Type) 217 } 218 case 1: 219 if remotePol.Name != "AliyunRDSReadOnlyAccess" { 220 t.Fatalf("received unexpected policy name of %s", remotePol.Name) 221 } 222 if remotePol.Type != "System" { 223 t.Fatalf("received unexpected policy type of %s", remotePol.Type) 224 } 225 } 226 } 227 228 ttl := fmt.Sprintf("%d", resp.Data["ttl"]) 229 if ttl != "0" { 230 t.Fatalf("expected ttl of 0 but received %s", ttl) 231 } 232 233 maxTTL := fmt.Sprintf("%d", resp.Data["max_ttl"]) 234 if maxTTL != "0" { 235 t.Fatalf("expected max_ttl of 0 but received %s", maxTTL) 236 } 237} 238 239func (e *testEnv) AddARNBasedRole(t *testing.T) { 240 req := &logical.Request{ 241 Operation: logical.CreateOperation, 242 Path: "role/role-based", 243 Storage: e.Storage, 244 Data: map[string]interface{}{ 245 "role_arn": e.RoleARN, 246 }, 247 } 248 resp, err := e.Backend.HandleRequest(e.Context, req) 249 if err != nil || (resp != nil && resp.IsError()) { 250 t.Fatalf("bad: resp: %#v\nerr:%v", resp, err) 251 } 252 if resp != nil { 253 t.Fatal("expected nil response to represent a 204") 254 } 255} 256 257func (e *testEnv) ReadARNBasedRole(t *testing.T) { 258 req := &logical.Request{ 259 Operation: logical.ReadOperation, 260 Path: "role/role-based", 261 Storage: e.Storage, 262 } 263 resp, err := e.Backend.HandleRequest(e.Context, req) 264 if err != nil || (resp != nil && resp.IsError()) { 265 t.Fatalf("bad: resp: %#v\nerr:%v", resp, err) 266 } 267 if resp == nil { 268 t.Fatal("expected a response") 269 } 270 271 if resp.Data["role_arn"] != e.RoleARN { 272 t.Fatalf("received unexpected role_arn of %s", resp.Data["role_arn"]) 273 } 274 275 inlinePolicies := resp.Data["inline_policies"].([]*inlinePolicy) 276 if len(inlinePolicies) != 0 { 277 t.Fatalf("expected no inline policies but received %+v", inlinePolicies) 278 } 279 280 remotePolicies := resp.Data["remote_policies"].([]*remotePolicy) 281 if len(remotePolicies) != 0 { 282 t.Fatalf("expected no remote policies but received %+v", remotePolicies) 283 } 284 285 ttl := fmt.Sprintf("%d", resp.Data["ttl"]) 286 if ttl != "0" { 287 t.Fatalf("expected ttl of 0 but received %s", ttl) 288 } 289 290 maxTTL := fmt.Sprintf("%d", resp.Data["max_ttl"]) 291 if maxTTL != "0" { 292 t.Fatalf("expected max_ttl of 0 but received %s", maxTTL) 293 } 294} 295 296func (e *testEnv) UpdateARNBasedRole(t *testing.T) { 297 req := &logical.Request{ 298 Operation: logical.UpdateOperation, 299 Path: "role/role-based", 300 Storage: e.Storage, 301 Data: map[string]interface{}{ 302 "role_arn": "acs:ram::5138828231865461:role/notrustedactors", 303 }, 304 } 305 resp, err := e.Backend.HandleRequest(e.Context, req) 306 if err != nil || (resp != nil && resp.IsError()) { 307 t.Fatalf("bad: resp: %#v\nerr:%v", resp, err) 308 } 309 if resp != nil { 310 t.Fatal("expected nil response to represent a 204") 311 } 312} 313 314func (e *testEnv) ReadUpdatedRole(t *testing.T) { 315 req := &logical.Request{ 316 Operation: logical.ReadOperation, 317 Path: "role/role-based", 318 Storage: e.Storage, 319 } 320 resp, err := e.Backend.HandleRequest(e.Context, req) 321 if err != nil || (resp != nil && resp.IsError()) { 322 t.Fatalf("bad: resp: %#v\nerr:%v", resp, err) 323 } 324 if resp == nil { 325 t.Fatal("expected a response") 326 } 327 328 if resp.Data["role_arn"] != "acs:ram::5138828231865461:role/notrustedactors" { 329 t.Fatalf("received unexpected role_arn of %s", resp.Data["role_arn"]) 330 } 331 332 inlinePolicies := resp.Data["inline_policies"].([]*inlinePolicy) 333 if len(inlinePolicies) != 0 { 334 t.Fatalf("expected no inline policies but received %+v", inlinePolicies) 335 } 336 337 remotePolicies := resp.Data["remote_policies"].([]*remotePolicy) 338 if len(remotePolicies) != 0 { 339 t.Fatalf("expected no remote policies but received %+v", remotePolicies) 340 } 341 342 ttl := fmt.Sprintf("%d", resp.Data["ttl"]) 343 if ttl != "0" { 344 t.Fatalf("expected ttl of 100 but received %s", ttl) 345 } 346 347 maxTTL := fmt.Sprintf("%d", resp.Data["max_ttl"]) 348 if maxTTL != "0" { 349 t.Fatalf("expected max_ttl of 1000 but received %s", maxTTL) 350 } 351} 352 353func (e *testEnv) ListTwoRoles(t *testing.T) { 354 req := &logical.Request{ 355 Operation: logical.ListOperation, 356 Path: "role", 357 Storage: e.Storage, 358 } 359 resp, err := e.Backend.HandleRequest(e.Context, req) 360 if err != nil || (resp != nil && resp.IsError()) { 361 t.Fatalf("bad: resp: %#v\nerr:%v", resp, err) 362 } 363 if resp == nil { 364 t.Fatal("expected a response") 365 } 366 keys := resp.Data["keys"].([]string) 367 if len(keys) != 2 { 368 t.Fatalf("expected 2 keys but received %d", len(keys)) 369 } 370 if keys[0] != "policy-based" { 371 t.Fatalf("expectied policy-based role name but received %s", keys[0]) 372 } 373 if keys[1] != "role-based" { 374 t.Fatalf("expected role-based role name but received %s", keys[1]) 375 } 376} 377 378func (e *testEnv) DeleteARNBasedRole(t *testing.T) { 379 req := &logical.Request{ 380 Operation: logical.DeleteOperation, 381 Path: "role/role-based", 382 Storage: e.Storage, 383 } 384 resp, err := e.Backend.HandleRequest(e.Context, req) 385 if err != nil || (resp != nil && resp.IsError()) { 386 t.Fatalf("bad: resp: %#v\nerr:%v", resp, err) 387 } 388 if resp != nil { 389 t.Fatal("expected nil response to represent a 204") 390 } 391} 392 393func (e *testEnv) ListOneRole(t *testing.T) { 394 req := &logical.Request{ 395 Operation: logical.ListOperation, 396 Path: "role", 397 Storage: e.Storage, 398 } 399 resp, err := e.Backend.HandleRequest(e.Context, req) 400 if err != nil || (resp != nil && resp.IsError()) { 401 t.Fatalf("bad: resp: %#v\nerr:%v", resp, err) 402 } 403 if resp == nil { 404 t.Fatal("expected a response") 405 } 406 keys := resp.Data["keys"].([]string) 407 if len(keys) != 1 { 408 t.Fatalf("expected 2 keys but received %d", len(keys)) 409 } 410 if keys[0] != "policy-based" { 411 t.Fatalf("expectied policy-based role name but received %s", keys[0]) 412 } 413} 414 415func (e *testEnv) ReadPolicyBasedCreds(t *testing.T) { 416 req := &logical.Request{ 417 Operation: logical.ReadOperation, 418 Path: "creds/policy-based", 419 Storage: e.Storage, 420 } 421 resp, err := e.Backend.HandleRequest(e.Context, req) 422 if err != nil || (resp != nil && resp.IsError()) { 423 t.Fatalf("bad: resp: %#v\nerr:%v", resp, err) 424 } 425 if resp == nil { 426 t.Fatal("expected a response") 427 } 428 429 if resp.Data["access_key"] == "" { 430 t.Fatal("failed to receive access_key") 431 } 432 if resp.Data["secret_key"] == "" { 433 t.Fatal("failed to receive secret_key") 434 } 435 e.MostRecentSecret = resp.Secret 436} 437 438func (e *testEnv) RenewPolicyBasedCreds(t *testing.T) { 439 req := &logical.Request{ 440 Operation: logical.RenewOperation, 441 Storage: e.Storage, 442 Secret: e.MostRecentSecret, 443 Data: map[string]interface{}{ 444 "lease_id": "foo", 445 }, 446 } 447 resp, err := e.Backend.HandleRequest(e.Context, req) 448 if err != nil || (resp != nil && resp.IsError()) { 449 t.Fatalf("bad: resp: %#v\nerr:%v", resp, err) 450 } 451 if resp == nil { 452 t.Fatal("expected a response") 453 } 454 if resp.Secret != e.MostRecentSecret { 455 t.Fatalf("expected %+v but got %+v", e.MostRecentSecret, resp.Secret) 456 } 457} 458 459func (e *testEnv) RevokePolicyBasedCreds(t *testing.T) { 460 req := &logical.Request{ 461 Operation: logical.RevokeOperation, 462 Storage: e.Storage, 463 Secret: e.MostRecentSecret, 464 Data: map[string]interface{}{ 465 "lease_id": "foo", 466 }, 467 } 468 resp, err := e.Backend.HandleRequest(e.Context, req) 469 if err != nil || (resp != nil && resp.IsError()) { 470 t.Fatalf("bad: resp: %#v\nerr:%v", resp, err) 471 } 472 if resp != nil { 473 t.Fatal("expected nil response to represent a 204") 474 } 475} 476 477func (e *testEnv) ReadARNBasedCreds(t *testing.T) { 478 req := &logical.Request{ 479 Operation: logical.ReadOperation, 480 Path: "creds/role-based", 481 Storage: e.Storage, 482 } 483 resp, err := e.Backend.HandleRequest(e.Context, req) 484 if err != nil || (resp != nil && resp.IsError()) { 485 t.Fatalf("bad: resp: %#v\nerr:%v", resp, err) 486 } 487 if resp == nil { 488 t.Fatal("expected a response") 489 } 490 491 if resp.Data["access_key"] == "" { 492 t.Fatal("received blank access_key") 493 } 494 if resp.Data["secret_key"] == "" { 495 t.Fatal("received blank secret_key") 496 } 497 if fmt.Sprintf("%s", resp.Data["expiration"]) == "" { 498 t.Fatal("received blank expiration") 499 } 500 if resp.Data["security_token"] == "" { 501 t.Fatal("received blank security_token") 502 } 503 e.MostRecentSecret = resp.Secret 504} 505 506func (e *testEnv) RenewARNBasedCreds(t *testing.T) { 507 req := &logical.Request{ 508 Operation: logical.RenewOperation, 509 Storage: e.Storage, 510 Secret: e.MostRecentSecret, 511 Data: map[string]interface{}{ 512 "lease_id": "foo", 513 }, 514 } 515 resp, err := e.Backend.HandleRequest(e.Context, req) 516 if err != nil || (resp != nil && resp.IsError()) { 517 t.Fatalf("bad: resp: %#v\nerr:%v", resp, err) 518 } 519 if resp != nil { 520 t.Fatal("expected nil response to represent a 204") 521 } 522} 523 524func (e *testEnv) RevokeARNBasedCreds(t *testing.T) { 525 req := &logical.Request{ 526 Operation: logical.RevokeOperation, 527 Storage: e.Storage, 528 Secret: e.MostRecentSecret, 529 Data: map[string]interface{}{ 530 "lease_id": "foo", 531 }, 532 } 533 resp, err := e.Backend.HandleRequest(e.Context, req) 534 if err != nil || (resp != nil && resp.IsError()) { 535 t.Fatalf("bad: resp: %#v\nerr:%v", resp, err) 536 } 537 if resp != nil { 538 t.Fatal("expected nil response to represent a 204") 539 } 540} 541 542const rawInlinePolicies = `[ 543 { 544 "Statement": [{ 545 "Action": ["rds:*"], 546 "Effect": "Allow", 547 "Resource": ["acs:oss:*:*:*"] 548 }], 549 "Version": "1" 550 }, 551 { 552 "Statement": [{ 553 "Action": ["oss:*"], 554 "Effect": "Allow", 555 "Resource": ["acs:oss:*:*:*"] 556 }], 557 "Version": "1" 558 } 559] 560` 561