github.com/IBM-Cloud/bluemix-go@v0.0.0-20240423071914-9e96525baef4/api/iam/iamv1/service_roles_test.go (about) 1 package iamv1 2 3 import ( 4 "log" 5 "net/http" 6 7 "github.com/IBM-Cloud/bluemix-go" 8 9 "github.com/IBM-Cloud/bluemix-go/client" 10 "github.com/IBM-Cloud/bluemix-go/crn" 11 "github.com/IBM-Cloud/bluemix-go/models" 12 "github.com/IBM-Cloud/bluemix-go/session" 13 "github.com/onsi/gomega/ghttp" 14 15 . "github.com/onsi/ginkgo" 16 . "github.com/onsi/gomega" 17 ) 18 19 var _ = Describe("ServiceRoles", func() { 20 var server *ghttp.Server 21 AfterEach(func() { 22 server.Close() 23 }) 24 25 var serviceRoleQueryResponse = `{ 26 "supportedRoles": [ 27 { 28 "crn": "crn:v1:bluemix:public:iam::::serviceRole:Writer", 29 "id": "crn:v1:bluemix:public:iam::::serviceRole:Writer", 30 "displayName": "Writer", 31 "description": "As a writer, you have permissions beyond the reader role, including creating and editing service-specific resources." 32 }, 33 { 34 "crn": "crn:v1:bluemix:public:iam::::serviceRole:Reader", 35 "id": "crn:v1:bluemix:public:iam::::serviceRole:Reader", 36 "displayName": "Reader", 37 "description": "As a reader, you can perform read-only actions within a service such as viewing service-specific resources." 38 }, 39 { 40 "crn": "crn:v1:bluemix:public:iam::::serviceRole:Manager", 41 "id": "crn:v1:bluemix:public:iam::::serviceRole:Manager", 42 "displayName": "Manager", 43 "description": "As a manager, you have permissions beyond the writer role to complete privileged actions as defined by the service. In addition, you can create and edit service-specific resources." 44 } 45 ], 46 "platformExtensions": { 47 "supportedRoles": [ 48 { 49 "crn": "crn:v1:bluemix:public:iam::::role:Administrator", 50 "id": "crn:v1:bluemix:public:iam::::role:Administrator", 51 "displayName": "Administrator", 52 "description": "As an administrator, you can perform all platform actions based on the resource this role is being assigned, including assigning access policies to other users." 53 }, 54 { 55 "crn": "crn:v1:bluemix:public:iam::::role:Operator", 56 "id": "crn:v1:bluemix:public:iam::::role:Operator", 57 "displayName": "Operator", 58 "description": "As an operator, you can perform platform actions required to configure and operate service instances, such as viewing a service's dashboard." 59 }, 60 { 61 "crn": "crn:v1:bluemix:public:iam::::role:Viewer", 62 "id": "crn:v1:bluemix:public:iam::::role:Viewer", 63 "displayName": "Viewer", 64 "description": "As a viewer, you can view service instances, but you can't modify them." 65 }, 66 { 67 "crn": "crn:v1:bluemix:public:iam::::role:Editor", 68 "id": "crn:v1:bluemix:public:iam::::role:Editor", 69 "displayName": "Editor", 70 "description": "As an editor, you can perform all platform actions except for managing the account and assigning access policies." 71 } 72 ] 73 } 74 }` 75 76 var notFoundResponse = `{ 77 "errorsArray": [ 78 { 79 "code": "BXNAC12104", 80 "response": "not_found_error", 81 "message": "Not Found Service name given returned empty query. ", 82 "level": "error", 83 "statusCode": 404, 84 "description": "Service name given returned empty query. ", 85 "transactionId": "string", 86 "instanceId": "a4d1e7b5-3f2f-4242-b555-78b7e695bbb1" 87 } 88 ] 89 }` 90 91 Describe("ListServiceRoles()", func() { 92 Context("Service roles are returned", func() { 93 BeforeEach(func() { 94 server = ghttp.NewServer() 95 server.AppendHandlers( 96 ghttp.CombineHandlers( 97 ghttp.VerifyRequest(http.MethodGet, "/acms/v1/roles", "serviceName=cloud-object-storage"), 98 ghttp.RespondWith(http.StatusOK, serviceRoleQueryResponse), 99 ), 100 ) 101 }) 102 It("should return all roles", func() { 103 roles, err := newTestServiceRoleRepo(server.URL()).ListServiceRoles("cloud-object-storage") 104 Expect(err).ShouldNot(HaveOccurred()) 105 Expect(roles).Should(HaveLen(7)) 106 Expect(roles).Should(Equal([]models.PolicyRole{ 107 models.PolicyRole{ 108 ID: crn.CRN{Scheme: "crn", Version: "v1", CName: "bluemix", CType: "public", ServiceName: "iam", ResourceType: "serviceRole", Resource: "Writer"}, 109 DisplayName: "Writer", 110 Description: "As a writer, you have permissions beyond the reader role, including creating and editing service-specific resources.", 111 }, 112 models.PolicyRole{ 113 ID: crn.CRN{Scheme: "crn", Version: "v1", CName: "bluemix", CType: "public", ServiceName: "iam", ResourceType: "serviceRole", Resource: "Reader"}, 114 DisplayName: "Reader", 115 Description: "As a reader, you can perform read-only actions within a service such as viewing service-specific resources.", 116 }, 117 models.PolicyRole{ 118 ID: crn.CRN{Scheme: "crn", Version: "v1", CName: "bluemix", CType: "public", ServiceName: "iam", ResourceType: "serviceRole", Resource: "Manager"}, 119 DisplayName: "Manager", 120 Description: "As a manager, you have permissions beyond the writer role to complete privileged actions as defined by the service. In addition, you can create and edit service-specific resources.", 121 }, 122 models.PolicyRole{ 123 ID: crn.CRN{Scheme: "crn", Version: "v1", CName: "bluemix", CType: "public", ServiceName: "iam", ResourceType: "role", Resource: "Administrator"}, 124 DisplayName: "Administrator", 125 Description: "As an administrator, you can perform all platform actions based on the resource this role is being assigned, including assigning access policies to other users.", 126 }, 127 models.PolicyRole{ 128 ID: crn.CRN{Scheme: "crn", Version: "v1", CName: "bluemix", CType: "public", ServiceName: "iam", ResourceType: "role", Resource: "Operator"}, 129 DisplayName: "Operator", 130 Description: "As an operator, you can perform platform actions required to configure and operate service instances, such as viewing a service's dashboard.", 131 }, 132 models.PolicyRole{ 133 ID: crn.CRN{Scheme: "crn", Version: "v1", CName: "bluemix", CType: "public", ServiceName: "iam", ResourceType: "role", Resource: "Viewer"}, 134 DisplayName: "Viewer", 135 Description: "As a viewer, you can view service instances, but you can't modify them.", 136 }, 137 models.PolicyRole{ 138 ID: crn.CRN{Scheme: "crn", Version: "v1", CName: "bluemix", CType: "public", ServiceName: "iam", ResourceType: "role", Resource: "Editor"}, 139 DisplayName: "Editor", 140 Description: "As an editor, you can perform all platform actions except for managing the account and assigning access policies.", 141 }, 142 })) 143 }) 144 }) 145 146 Context("Service not found", func() { 147 BeforeEach(func() { 148 server = ghttp.NewServer() 149 server.AppendHandlers( 150 ghttp.CombineHandlers( 151 ghttp.VerifyRequest(http.MethodGet, "/acms/v1/roles", "serviceName=cloud-object-storage"), 152 ghttp.RespondWith(http.StatusNotFound, notFoundResponse), 153 ), 154 ) 155 }) 156 157 It("should return error", func() { 158 roles, err := newTestServiceRoleRepo(server.URL()).ListServiceRoles("cloud-object-storage") 159 Expect(err).Should(HaveOccurred()) 160 Expect(roles).Should(BeEmpty()) 161 }) 162 }) 163 164 }) 165 166 Describe("ListServiceSpecificRoles()", func() { 167 Context("Service roles are returned", func() { 168 BeforeEach(func() { 169 server = ghttp.NewServer() 170 server.AppendHandlers( 171 ghttp.CombineHandlers( 172 ghttp.VerifyRequest(http.MethodGet, "/acms/v1/roles", "serviceName=cloud-object-storage"), 173 ghttp.RespondWith(http.StatusOK, serviceRoleQueryResponse), 174 ), 175 ) 176 }) 177 It("should return all roles", func() { 178 roles, err := newTestServiceRoleRepo(server.URL()).ListServiceSpecificRoles("cloud-object-storage") 179 Expect(err).ShouldNot(HaveOccurred()) 180 Expect(roles).Should(HaveLen(3)) 181 Expect(roles).Should(Equal([]models.PolicyRole{ 182 models.PolicyRole{ 183 ID: crn.CRN{Scheme: "crn", Version: "v1", CName: "bluemix", CType: "public", ServiceName: "iam", ResourceType: "serviceRole", Resource: "Writer"}, 184 DisplayName: "Writer", 185 Description: "As a writer, you have permissions beyond the reader role, including creating and editing service-specific resources.", 186 }, 187 models.PolicyRole{ 188 ID: crn.CRN{Scheme: "crn", Version: "v1", CName: "bluemix", CType: "public", ServiceName: "iam", ResourceType: "serviceRole", Resource: "Reader"}, 189 DisplayName: "Reader", 190 Description: "As a reader, you can perform read-only actions within a service such as viewing service-specific resources.", 191 }, 192 models.PolicyRole{ 193 ID: crn.CRN{Scheme: "crn", Version: "v1", CName: "bluemix", CType: "public", ServiceName: "iam", ResourceType: "serviceRole", Resource: "Manager"}, 194 DisplayName: "Manager", 195 Description: "As a manager, you have permissions beyond the writer role to complete privileged actions as defined by the service. In addition, you can create and edit service-specific resources.", 196 }, 197 })) 198 }) 199 }) 200 201 Context("Service not found", func() { 202 BeforeEach(func() { 203 server = ghttp.NewServer() 204 server.AppendHandlers( 205 ghttp.CombineHandlers( 206 ghttp.VerifyRequest(http.MethodGet, "/acms/v1/roles", "serviceName=cloud-object-storage"), 207 ghttp.RespondWith(http.StatusNotFound, notFoundResponse), 208 ), 209 ) 210 }) 211 212 It("should return error", func() { 213 roles, err := newTestServiceRoleRepo(server.URL()).ListServiceRoles("cloud-object-storage") 214 Expect(err).Should(HaveOccurred()) 215 Expect(roles).Should(BeEmpty()) 216 }) 217 }) 218 219 }) 220 221 Describe("ListSystemDefinedRoles()", func() { 222 Context("System defined roles are returned", func() { 223 BeforeEach(func() { 224 server = ghttp.NewServer() 225 server.AppendHandlers( 226 ghttp.CombineHandlers( 227 ghttp.VerifyRequest(http.MethodGet, "/acms/v1/roles"), 228 ghttp.RespondWith(http.StatusOK, `{ 229 "systemDefinedRoles": [ 230 { 231 "crn": "crn:v1:bluemix:public:iam::::serviceRole:IAMAuthz", 232 "id": "crn:v1:bluemix:public:iam::::serviceRole:IAMAuthz", 233 "displayName": "IAMAuthz", 234 "description": "IAMAuthz" 235 }, 236 { 237 "crn": "crn:v1:bluemix:public:iam::::role:Administrator", 238 "id": "crn:v1:bluemix:public:iam::::role:Administrator", 239 "displayName": "Administrator", 240 "description": "As an administrator, you can perform all platform actions based on the resource this role is being assigned, including assigning access policies to other users." 241 }, 242 { 243 "crn": "crn:v1:bluemix:public:iam::::role:Operator", 244 "id": "crn:v1:bluemix:public:iam::::role:Operator", 245 "displayName": "Operator", 246 "description": "As an operator, you can perform platform actions required to configure and operate service instances, such as viewing a service's dashboard." 247 }, 248 { 249 "crn": "crn:v1:bluemix:public:iam::::role:Viewer", 250 "id": "crn:v1:bluemix:public:iam::::role:Viewer", 251 "displayName": "Viewer", 252 "description": "As a viewer, you can view service instances, but you can't modify them." 253 }, 254 { 255 "crn": "crn:v1:bluemix:public:iam::::role:Editor", 256 "id": "crn:v1:bluemix:public:iam::::role:Editor", 257 "displayName": "Editor", 258 "description": "As an editor, you can perform all platform actions except for managing the account and assigning access policies." 259 }, 260 { 261 "crn": "crn:v1:bluemix:public:iam::::serviceRole:Reader", 262 "id": "crn:v1:bluemix:public:iam::::serviceRole:Reader", 263 "displayName": "Reader", 264 "description": "As a reader, you can perform read-only actions within a service such as viewing service-specific resources." 265 }, 266 { 267 "crn": "crn:v1:bluemix:public:iam::::serviceRole:Writer", 268 "id": "crn:v1:bluemix:public:iam::::serviceRole:Writer", 269 "displayName": "Writer", 270 "description": "As a writer, you have permissions beyond the reader role, including creating and editing service-specific resources." 271 }, 272 { 273 "crn": "crn:v1:bluemix:public:iam::::serviceRole:Manager", 274 "id": "crn:v1:bluemix:public:iam::::serviceRole:Manager", 275 "displayName": "Manager", 276 "description": "As a manager, you have permissions beyond the writer role to complete privileged actions as defined by the service. In addition, you can create and edit service-specific resources." 277 } 278 ] 279 }`), 280 ), 281 ) 282 }) 283 It("should return all roles", func() { 284 roles, err := newTestServiceRoleRepo(server.URL()).ListSystemDefinedRoles() 285 Expect(err).ShouldNot(HaveOccurred()) 286 Expect(roles).Should(HaveLen(8)) 287 Expect(roles).Should(Equal([]models.PolicyRole{ 288 { 289 ID: crn.CRN{Scheme: "crn", Version: "v1", CName: "bluemix", CType: "public", ServiceName: "iam", ResourceType: "serviceRole", Resource: "IAMAuthz"}, 290 DisplayName: "IAMAuthz", 291 Description: "IAMAuthz", 292 }, 293 { 294 ID: crn.CRN{Scheme: "crn", Version: "v1", CName: "bluemix", CType: "public", ServiceName: "iam", ResourceType: "role", Resource: "Administrator"}, 295 DisplayName: "Administrator", 296 Description: "As an administrator, you can perform all platform actions based on the resource this role is being assigned, including assigning access policies to other users.", 297 }, 298 { 299 ID: crn.CRN{Scheme: "crn", Version: "v1", CName: "bluemix", CType: "public", ServiceName: "iam", ResourceType: "role", Resource: "Operator"}, 300 DisplayName: "Operator", 301 Description: "As an operator, you can perform platform actions required to configure and operate service instances, such as viewing a service's dashboard.", 302 }, 303 { 304 ID: crn.CRN{Scheme: "crn", Version: "v1", CName: "bluemix", CType: "public", ServiceName: "iam", ResourceType: "role", Resource: "Viewer"}, 305 DisplayName: "Viewer", 306 Description: "As a viewer, you can view service instances, but you can't modify them.", 307 }, 308 { 309 ID: crn.CRN{Scheme: "crn", Version: "v1", CName: "bluemix", CType: "public", ServiceName: "iam", ResourceType: "role", Resource: "Editor"}, 310 DisplayName: "Editor", 311 Description: "As an editor, you can perform all platform actions except for managing the account and assigning access policies.", 312 }, 313 { 314 ID: crn.CRN{Scheme: "crn", Version: "v1", CName: "bluemix", CType: "public", ServiceName: "iam", ResourceType: "serviceRole", Resource: "Reader"}, 315 DisplayName: "Reader", 316 Description: "As a reader, you can perform read-only actions within a service such as viewing service-specific resources.", 317 }, 318 { 319 ID: crn.CRN{Scheme: "crn", Version: "v1", CName: "bluemix", CType: "public", ServiceName: "iam", ResourceType: "serviceRole", Resource: "Writer"}, 320 DisplayName: "Writer", 321 Description: "As a writer, you have permissions beyond the reader role, including creating and editing service-specific resources.", 322 }, 323 { 324 ID: crn.CRN{Scheme: "crn", Version: "v1", CName: "bluemix", CType: "public", ServiceName: "iam", ResourceType: "serviceRole", Resource: "Manager"}, 325 DisplayName: "Manager", 326 Description: "As a manager, you have permissions beyond the writer role to complete privileged actions as defined by the service. In addition, you can create and edit service-specific resources.", 327 }, 328 })) 329 }) 330 }) 331 332 Context("User token expires", func() { 333 BeforeEach(func() { 334 server = ghttp.NewServer() 335 server.AppendHandlers( 336 ghttp.CombineHandlers( 337 ghttp.VerifyRequest(http.MethodGet, "/acms/v1/roles"), 338 ghttp.RespondWith(http.StatusNotFound, notFoundResponse), 339 ), 340 ) 341 }) 342 343 It("should return error", func() { 344 roles, err := newTestServiceRoleRepo(server.URL()).ListSystemDefinedRoles() 345 Expect(err).Should(HaveOccurred()) 346 Expect(roles).Should(BeEmpty()) 347 }) 348 }) 349 }) 350 351 Describe("ListAuthorizationRoles()", func() { 352 Context("Authorization roles are returned", func() { 353 BeforeEach(func() { 354 server = ghttp.NewServer() 355 server.AppendHandlers( 356 ghttp.CombineHandlers( 357 ghttp.VerifyRequest(http.MethodGet, "/acms/v1/roles", "sourceServiceName=cloud-object-storage&serviceName=kms&policyType=authorization"), 358 ghttp.RespondWith(http.StatusOK, `{ 359 "supportedRoles": [ 360 { 361 "crn": "crn:v1:bluemix:public:iam::::serviceRole:Reader", 362 "id": "crn:v1:bluemix:public:iam::::serviceRole:Reader", 363 "displayName": "Reader", 364 "description": "As a reader, you can perform read-only actions within a service such as viewing service-specific resources.", 365 "actions": [ 366 { 367 "id": "kms.secrets.list", 368 "displayName": "key-protect-secrets-list-action", 369 "description": "kms.secrets.list" 370 }, 371 { 372 "id": "kms.secrets.wrap", 373 "displayName": "key-protect-secrets-wrap-action", 374 "description": "kms.secrets.wrap" 375 } 376 ] 377 } 378 ], 379 "platformExtensions": { 380 "supportedRoles": [] 381 } 382 }`), 383 ), 384 ) 385 }) 386 It("should return all roles", func() { 387 roles, err := newTestServiceRoleRepo(server.URL()).ListAuthorizationRoles("cloud-object-storage", "kms") 388 Expect(err).ShouldNot(HaveOccurred()) 389 Expect(roles).Should(HaveLen(1)) 390 Expect(roles).Should(Equal([]models.PolicyRole{ 391 models.PolicyRole{ 392 ID: crn.CRN{Scheme: "crn", Version: "v1", CName: "bluemix", CType: "public", ServiceName: "iam", ResourceType: "serviceRole", Resource: "Reader"}, 393 DisplayName: "Reader", 394 Description: "As a reader, you can perform read-only actions within a service such as viewing service-specific resources.", 395 Actions: []models.RoleAction{ 396 models.RoleAction{ 397 ID: "kms.secrets.list", 398 Name: "key-protect-secrets-list-action", 399 Description: "kms.secrets.list", 400 }, 401 models.RoleAction{ 402 ID: "kms.secrets.wrap", 403 Name: "key-protect-secrets-wrap-action", 404 Description: "kms.secrets.wrap", 405 }, 406 }, 407 }, 408 })) 409 }) 410 }) 411 412 Context("Service not found", func() { 413 BeforeEach(func() { 414 server = ghttp.NewServer() 415 server.AppendHandlers( 416 ghttp.CombineHandlers( 417 ghttp.VerifyRequest(http.MethodGet, "/acms/v1/roles", "sourceServiceName=cloud-object-storage&serviceName=kms&policyType=authorization"), 418 ghttp.RespondWith(http.StatusNotFound, notFoundResponse), 419 ), 420 ) 421 }) 422 423 It("should return error", func() { 424 roles, err := newTestServiceRoleRepo(server.URL()).ListAuthorizationRoles("cloud-object-storage", "kms") 425 Expect(err).Should(HaveOccurred()) 426 Expect(roles).Should(BeEmpty()) 427 }) 428 }) 429 430 Context("Authorization role not found", func() { 431 BeforeEach(func() { 432 server = ghttp.NewServer() 433 server.AppendHandlers( 434 ghttp.CombineHandlers( 435 ghttp.VerifyRequest(http.MethodGet, "/acms/v1/roles", "sourceServiceName=cloud-object-storage&serviceName=api-connect&policyType=authorization"), 436 ghttp.RespondWith(http.StatusNotFound, `{ 437 "errors": [ 438 { 439 "code": "BXNAC12104", 440 "response": "not_found_error", 441 "message": "Not Found serviceName api-connect does not has any supportedRoles for sourceServiceName cloud-object-storage", 442 "level": "error", 443 "statusCode": 404, 444 "description": "serviceName api-connect does not has any supportedRoles for sourceServiceName cloud-object-storage", 445 "transactionId": "0b47214bebd84cc08ab81c2e70a8cdbd", 446 "instanceId": "kubernetes" 447 } 448 ] 449 }`), 450 ), 451 ) 452 }) 453 454 It("should return error", func() { 455 roles, err := newTestServiceRoleRepo(server.URL()).ListAuthorizationRoles("cloud-object-storage", "api-connect") 456 Expect(err).Should(HaveOccurred()) 457 Expect(roles).Should(BeEmpty()) 458 }) 459 }) 460 }) 461 }) 462 463 func newTestServiceRoleRepo(url string) ServiceRoleRepository { 464 sess, err := session.New() 465 if err != nil { 466 log.Fatal(err) 467 } 468 conf := sess.Config.Copy() 469 conf.Endpoint = &url 470 471 client := client.Client{ 472 Config: conf, 473 ServiceName: bluemix.AccountService, 474 } 475 476 return NewServiceRoleRepository(&client) 477 }