github.com/IBM-Cloud/bluemix-go@v0.0.0-20240314082800-4e02a69b84b2/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  }