github.com/redhat-appstudio/e2e-tests@v0.0.0-20230619105049-9a422b2094d7/tests/spi/access-control.go (about) 1 package spi 2 3 import ( 4 "bytes" 5 "context" 6 "fmt" 7 "strings" 8 "time" 9 10 "github.com/redhat-appstudio/e2e-tests/pkg/constants" 11 "github.com/redhat-appstudio/e2e-tests/pkg/utils" 12 "github.com/redhat-appstudio/service-provider-integration-operator/api/v1beta1" 13 14 . "github.com/onsi/ginkgo/v2" 15 . "github.com/onsi/gomega" 16 client "github.com/redhat-appstudio/e2e-tests/pkg/apis/kubernetes" 17 "github.com/redhat-appstudio/e2e-tests/pkg/framework" 18 corev1 "k8s.io/api/core/v1" 19 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 20 "k8s.io/apimachinery/pkg/types" 21 "k8s.io/client-go/tools/clientcmd" 22 "k8s.io/client-go/tools/remotecommand" 23 "k8s.io/kubectl/pkg/scheme" 24 crclient "sigs.k8s.io/controller-runtime/pkg/client" 25 ) 26 27 type User struct { 28 Framework *framework.Framework 29 LinkedAccessTokenName string 30 SPIGithubWorkSpaceSecretName string 31 WorkspaceURL string 32 APIProxyClientA *crclient.Client 33 APIProxyClientB *crclient.Client 34 APIProxyClientC *crclient.Client 35 } 36 37 /* 38 * Component: spi 39 * Description: SVPI-495 - Test automation to ensure that a user can't access and use secrets from another workspace 40 41 * User A is the owner of workspace A and has access to workspace C as the maintainer 42 * User B is the owner of workspace B 43 * User C is the owner of workspace C 44 45 * Test cases: 46 * check if user can access the SPIAccessToken from another workspace 47 * check if user can read the GitHub repo from another workspace 48 * check if user can read the secret from another workspace 49 * check if user's pod deployed in the user's workspace can read the GitHub repo from another workspace 50 */ 51 52 var _ = framework.SPISuiteDescribe(Label("spi-suite", "access-control"), func() { 53 54 defer GinkgoRecover() 55 56 var userA, userB, userC User 57 58 Describe("SVPI-495 - Test automation to ensure that a user can't access and use secrets from another workspace", Ordered, func() { 59 60 delete := func(user User) { 61 Expect(user.Framework.AsKubeAdmin.SPIController.DeleteAllBindingTokensInASpecificNamespace(user.Framework.UserNamespace)).To(Succeed()) 62 Expect(user.Framework.AsKubeAdmin.SPIController.DeleteAllAccessTokensInASpecificNamespace(user.Framework.UserNamespace)).To(Succeed()) 63 Expect(user.Framework.AsKubeAdmin.SPIController.DeleteAllAccessTokenDataInASpecificNamespace(user.Framework.UserNamespace)).To(Succeed()) 64 Expect(user.Framework.SandboxController.DeleteUserSignup(user.Framework.UserName)).NotTo(BeFalse()) 65 } 66 67 createAPIProxyClient := func(userToken, proxyURL string) *crclient.Client { 68 APIProxyClient, err := client.CreateAPIProxyClient(userToken, proxyURL) 69 Expect(err).NotTo(HaveOccurred()) 70 client := APIProxyClient.KubeRest() 71 return &client 72 } 73 74 createSPITokenBinding := func(user User) { 75 namespace := user.Framework.UserNamespace 76 secretName := user.SPIGithubWorkSpaceSecretName 77 78 // creates SPITokenBinding 79 SPITokenBinding, err := user.Framework.AsKubeDeveloper.SPIController.CreateSPIAccessTokenBinding(SPITokenBindingName, namespace, GithubPrivateRepoURL, secretName, "kubernetes.io/basic-auth") 80 Expect(err).NotTo(HaveOccurred()) 81 82 // start of upload token 83 // SPITokenBinding to be in AwaitingTokenData phase 84 // wait SPITokenBinding to be in AwaitingTokenData phase before trying to upload a token 85 Eventually(func() bool { 86 SPITokenBinding, err = user.Framework.AsKubeDeveloper.SPIController.GetSPIAccessTokenBinding(SPITokenBinding.Name, namespace) 87 if err != nil { 88 return false 89 } 90 91 return (SPITokenBinding.Status.Phase == v1beta1.SPIAccessTokenBindingPhaseAwaitingTokenData) 92 }, 1*time.Minute, 5*time.Second).Should(BeTrue(), "SPIAccessTokenBinding is not in AwaitingTokenData phase") 93 94 // uploads username and token using rest endpoint 95 // the UploadUrl in SPITokenBinding should be available before uploading the token 96 Eventually(func() bool { 97 SPITokenBinding, err = user.Framework.AsKubeDeveloper.SPIController.GetSPIAccessTokenBinding(SPITokenBinding.Name, namespace) 98 if err != nil { 99 return false 100 } 101 102 return SPITokenBinding.Status.UploadUrl != "" 103 }, 1*time.Minute, 10*time.Second).Should(BeTrue(), "uploadUrl not set") 104 Expect(err).NotTo(HaveOccurred()) 105 106 // LinkedAccessToken should exist 107 linkedAccessTokenName := SPITokenBinding.Status.LinkedAccessTokenName 108 Expect(linkedAccessTokenName).NotTo(BeEmpty()) 109 110 // keep LinkedAccessToken name 111 username := user.Framework.UserName 112 if strings.HasPrefix(username, "spi-user-a") { 113 userA.LinkedAccessTokenName = linkedAccessTokenName 114 } else if strings.HasPrefix(username, "spi-user-b") { 115 userB.LinkedAccessTokenName = linkedAccessTokenName 116 } else { 117 userC.LinkedAccessTokenName = linkedAccessTokenName 118 } 119 120 // get the url to manually upload the token 121 uploadURL := SPITokenBinding.Status.UploadUrl 122 Expect(uploadURL).NotTo(BeEmpty()) 123 124 // Get the token for the current openshift user 125 bearerToken, err := utils.GetOpenshiftToken() 126 Expect(err).NotTo(HaveOccurred()) 127 128 // build and upload the payload using the uploadURL. it should return 204 129 oauthCredentials := `{"access_token":"` + utils.GetEnv(constants.GITHUB_TOKEN_ENV, "") + `"}` 130 statusCode, err := user.Framework.AsKubeDeveloper.SPIController.UploadWithRestEndpoint(uploadURL, oauthCredentials, bearerToken) 131 Expect(err).NotTo(HaveOccurred()) 132 Expect(statusCode).Should(Equal(204)) 133 134 // SPITokenBinding to be in Injected phase 135 Eventually(func() bool { 136 SPITokenBinding, err = user.Framework.AsKubeDeveloper.SPIController.GetSPIAccessTokenBinding(SPITokenBinding.Name, namespace) 137 Expect(err).NotTo(HaveOccurred()) 138 return SPITokenBinding.Status.Phase == v1beta1.SPIAccessTokenBindingPhaseInjected 139 }, 1*time.Minute, 5*time.Second).Should(BeTrue(), "SPIAccessTokenBinding is not in Injected phase") 140 141 // SPIAccessToken exists and is in Read phase 142 Eventually(func() bool { 143 SPIAccessToken, err := user.Framework.AsKubeDeveloper.SPIController.GetSPIAccessToken(SPITokenBinding.Status.LinkedAccessTokenName, namespace) 144 145 if err != nil { 146 return false 147 } 148 149 return (SPIAccessToken.Status.Phase == v1beta1.SPIAccessTokenPhaseReady) 150 }, 1*time.Minute, 5*time.Second).Should(BeTrue(), "SPIAccessToken should be in ready phase") 151 // end of upload token 152 } 153 154 // check if guestUser can access a primary's secret in the primary's workspace 155 checkSecretAccess := func(client crclient.Client, primaryUser User, shouldAccess bool) { 156 // checks that guest user can access a primary's secret in primary's workspace 157 spiAccessToken := &v1beta1.SPIAccessToken{} 158 err := client.Get(context.TODO(), types.NamespacedName{Name: primaryUser.LinkedAccessTokenName, Namespace: primaryUser.Framework.UserNamespace}, spiAccessToken) 159 160 if shouldAccess { 161 Expect(err).NotTo(HaveOccurred()) 162 } else { 163 Expect(err).To(HaveOccurred()) 164 } 165 } 166 167 // check if guest user can read a primary's GitHub repo in the primary's workspace 168 checkRepositoryReading := func(client crclient.Client, primaryUser User, shouldRead bool) { 169 // create SPIFileContentRequest in primary's workspace URL 170 spiFcr := v1beta1.SPIFileContentRequest{ 171 ObjectMeta: metav1.ObjectMeta{ 172 GenerateName: "spi-file-content-request-", 173 Namespace: primaryUser.Framework.UserNamespace, 174 }, 175 Spec: v1beta1.SPIFileContentRequestSpec{RepoUrl: GithubPrivateRepoURL, FilePath: GithubPrivateRepoFilePath}, 176 } 177 err := client.Create(context.TODO(), &spiFcr) 178 179 if shouldRead { 180 Expect(err).NotTo(HaveOccurred()) 181 182 // check that guest user can read a primary's GitHub repo in the primary's workspace 183 Eventually(func() bool { 184 err = client.Get(context.TODO(), types.NamespacedName{Name: spiFcr.Name, Namespace: spiFcr.Namespace}, &spiFcr) 185 Expect(err).NotTo(HaveOccurred()) 186 187 return spiFcr.Status.Phase == v1beta1.SPIFileContentRequestPhaseDelivered && spiFcr.Status.Content != "" 188 }, 2*time.Minute, 10*time.Second).Should(BeTrue(), "content not provided by SPIFileContentRequest") 189 } else { 190 Expect(err).To(HaveOccurred()) 191 } 192 } 193 194 // check if guest user can read a primary's secret in the primary's workspace 195 checkSecretReading := func(client crclient.Client, primaryUser User, shouldRead bool) { 196 resultSecret := &corev1.Secret{} 197 err := client.Get(context.TODO(), types.NamespacedName{Name: primaryUser.SPIGithubWorkSpaceSecretName, Namespace: primaryUser.Framework.UserNamespace}, resultSecret) 198 199 if shouldRead { 200 Expect(err).ToNot(HaveOccurred()) 201 token := resultSecret.Data["password"] 202 Expect(token).ToNot(BeEmpty()) 203 } else { 204 Expect(err).To(HaveOccurred()) 205 } 206 } 207 208 // check that guest user can make a request to create a SPIFileContentRequest in the primary's workspace 209 makeGhReadRequestFromPod := func(guestUser, primaryUser User, podName, podNamespace, spiFcrName string) { 210 spiFcrData := fmt.Sprintf(`--- 211 apiVersion: appstudio.redhat.com/v1beta1 212 kind: SPIFileContentRequest 213 metadata: 214 name: %s 215 namespace: %s 216 spec: 217 filePath: README.md 218 repoUrl: %s 219 `, spiFcrName, primaryUser.Framework.UserNamespace, GithubPrivateRepoURL) 220 readRequest := fmt.Sprintf( 221 "curl '%s' \\"+ 222 "-k \\"+ 223 "-H 'Authorization: Bearer %s' \\"+ 224 "-X POST \\"+ 225 "-H 'Content-Type: application/yaml' \\"+ 226 "-d '%s'", 227 fmt.Sprintf("%s/apis/appstudio.redhat.com/v1beta1/namespaces/%s/spifilecontentrequests", primaryUser.WorkspaceURL, primaryUser.Framework.UserNamespace), 228 guestUser.Framework.UserToken, 229 spiFcrData, 230 ) 231 request := guestUser.Framework.AsKubeAdmin.CommonController.KubeInterface().CoreV1().RESTClient(). 232 Post().Namespace(podNamespace). 233 Resource("pods"). 234 Name(podName). 235 SubResource("exec"). 236 VersionedParams(&corev1.PodExecOptions{ 237 Command: []string{ 238 "/bin/sh", 239 "-c", 240 readRequest, 241 }, 242 Stdin: false, 243 Stdout: true, 244 Stderr: true, 245 TTY: true, 246 }, scheme.ParameterCodec) 247 248 config := clientcmd.NewNonInteractiveDeferredLoadingClientConfig( 249 clientcmd.NewDefaultClientConfigLoadingRules(), 250 &clientcmd.ConfigOverrides{}, 251 ) 252 restConfig, err := config.ClientConfig() 253 Expect(err).NotTo(HaveOccurred()) 254 255 exec, err := remotecommand.NewSPDYExecutor(restConfig, "POST", request.URL()) 256 Expect(err).NotTo(HaveOccurred()) 257 258 buffer := &bytes.Buffer{} 259 errBuffer := &bytes.Buffer{} 260 err = exec.Stream(remotecommand.StreamOptions{ 261 Stdout: buffer, 262 Stderr: errBuffer, 263 }) 264 Expect(err).ToNot(HaveOccurred(), fmt.Sprintf("reason: %v", err)) 265 Expect(buffer.String()).NotTo(BeEmpty()) 266 Expect(errBuffer.String()).To(BeEmpty()) 267 } 268 269 // check if guest user's pod deployed in guest user's workspace should be able to construct an API request that reads code in the Github repo for primary's user workspace 270 checkRepoReadingFromPod := func(client crclient.Client, guestUser, primaryUser User, shouldRead bool) { 271 namespace := guestUser.Framework.UserNamespace 272 p := &corev1.Pod{ 273 ObjectMeta: metav1.ObjectMeta{ 274 Namespace: namespace, 275 GenerateName: "pod-", 276 }, 277 Spec: corev1.PodSpec{ 278 RestartPolicy: corev1.RestartPolicyNever, 279 Containers: []corev1.Container{ 280 { 281 Name: "read", 282 Image: "quay.io/redhat-appstudio/buildah:v1.28", 283 // workaround to force the pod to be running 284 Command: []string{ 285 "sleep", 286 "600", 287 }, 288 }, 289 }, 290 }, 291 } 292 293 // create pod 294 pod, err := guestUser.Framework.AsKubeAdmin.CommonController.KubeInterface().CoreV1().Pods(namespace).Create(context.Background(), p, metav1.CreateOptions{}) 295 Expect(err).NotTo(HaveOccurred()) 296 297 // check that pod started 298 Eventually(func() bool { 299 pod, err := guestUser.Framework.AsKubeAdmin.CommonController.GetPod(namespace, pod.Name) 300 Expect(err).NotTo(HaveOccurred()) 301 302 return pod.Status.Phase == corev1.PodRunning 303 }, 1*time.Minute, 5*time.Second).Should(BeTrue(), "Pod not created successfully") 304 Expect(err).NotTo(HaveOccurred()) 305 306 // make read request 307 spiFcrName := utils.GetGeneratedNamespace("pod-spi-file-content-request") 308 makeGhReadRequestFromPod(guestUser, primaryUser, pod.Name, pod.Namespace, spiFcrName) 309 310 spiFcr := v1beta1.SPIFileContentRequest{} 311 if shouldRead { 312 // check that guest user's pod can read a primary's GitHub repo in the primary's workspace 313 Eventually(func() bool { 314 err = client.Get(context.TODO(), types.NamespacedName{Name: spiFcrName, Namespace: primaryUser.Framework.UserNamespace}, &spiFcr) 315 Expect(err).NotTo(HaveOccurred()) 316 317 return spiFcr.Status.Phase == v1beta1.SPIFileContentRequestPhaseDelivered && spiFcr.Status.Content != "" 318 }, 2*time.Minute, 10*time.Second).Should(BeTrue(), "content not provided by SPIFileContentRequest") 319 } else { 320 // check that guest user's pod can not read a primary's GitHub repo in the primary's workspace 321 err = client.Get(context.TODO(), types.NamespacedName{Name: spiFcrName, Namespace: primaryUser.Framework.UserNamespace}, &spiFcr) 322 Expect(err).To(HaveOccurred()) 323 } 324 } 325 326 BeforeAll(func() { 327 // Initialize the tests controllers for user A 328 // test user A is the owner and have access to the workspace A 329 fwUserA, err := framework.NewFramework(utils.GetGeneratedNamespace("spi-user-a")) 330 Expect(err).NotTo(HaveOccurred()) 331 namespaceUserA := fwUserA.UserNamespace 332 Expect(namespaceUserA).NotTo(BeEmpty()) 333 userA = User{ 334 Framework: fwUserA, 335 SPIGithubWorkSpaceSecretName: "e2e-github-secret-workspace-a", 336 WorkspaceURL: fmt.Sprintf("%s/workspaces/%s", fwUserA.ProxyUrl, fwUserA.UserName), 337 } 338 339 // Initialize the tests controllers for user B 340 // test user B is the owner and have access to the workspace B 341 fwUserB, err := framework.NewFramework(utils.GetGeneratedNamespace("spi-user-b")) 342 Expect(err).NotTo(HaveOccurred()) 343 namespaceUserB := fwUserB.UserNamespace 344 Expect(namespaceUserB).NotTo(BeEmpty()) 345 userB = User{ 346 Framework: fwUserB, 347 SPIGithubWorkSpaceSecretName: "e2e-github-secret-workspace-b", 348 WorkspaceURL: fmt.Sprintf("%s/workspaces/%s", fwUserB.ProxyUrl, fwUserB.UserName), 349 } 350 351 // Initialize the tests controllers for user C 352 // test user C is the owner and have access to the workspace C 353 fwUserC, err := framework.NewFramework(utils.GetGeneratedNamespace("spi-user-c")) 354 Expect(err).NotTo(HaveOccurred()) 355 namespaceUserC := fwUserC.UserNamespace 356 Expect(namespaceUserC).NotTo(BeEmpty()) 357 userC = User{ 358 Framework: fwUserC, 359 SPIGithubWorkSpaceSecretName: "e2e-github-secret-workspace-c", 360 WorkspaceURL: fmt.Sprintf("%s/workspaces/%s", fwUserC.ProxyUrl, fwUserC.UserName), 361 } 362 363 // create api proxy client with user A token and user's A workspace URL 364 userA.APIProxyClientA = createAPIProxyClient(userA.Framework.UserToken, userA.WorkspaceURL) 365 // create api proxy client with user A token and user's B workspace URL 366 userA.APIProxyClientB = createAPIProxyClient(userA.Framework.UserToken, userB.WorkspaceURL) 367 // create api proxy client with user A token and user's C workspace URL 368 userA.APIProxyClientC = createAPIProxyClient(userA.Framework.UserToken, userC.WorkspaceURL) 369 370 // create api proxy client with user B token and user's A workspace URL 371 userB.APIProxyClientA = createAPIProxyClient(userB.Framework.UserToken, userA.WorkspaceURL) 372 // create api proxy client with user B token and user's B workspace URL 373 userB.APIProxyClientB = createAPIProxyClient(userB.Framework.UserToken, userB.WorkspaceURL) 374 // create api proxy client with user B token and user's C workspace URL 375 userB.APIProxyClientC = createAPIProxyClient(userB.Framework.UserToken, userC.WorkspaceURL) 376 377 // create api proxy client with user C token and user's A workspace URL 378 userC.APIProxyClientA = createAPIProxyClient(userC.Framework.UserToken, userA.WorkspaceURL) 379 // create api proxy client with user C token and user's B workspace URL 380 userC.APIProxyClientB = createAPIProxyClient(userC.Framework.UserToken, userB.WorkspaceURL) 381 // create api proxy client with user C token and user's C workspace URL 382 userC.APIProxyClientC = createAPIProxyClient(userC.Framework.UserToken, userC.WorkspaceURL) 383 384 // share workspace C with user A with maintainer roles 385 _, err = fwUserC.AsKubeAdmin.CommonController.CreateSpaceBinding(fwUserA.UserName, fwUserC.UserName, "maintainer") 386 Expect(err).NotTo(HaveOccurred()) 387 388 // check if workspace C was shared with user A 389 Eventually(func() bool { 390 err = fwUserC.AsKubeAdmin.CommonController.CheckWorkspaceShare(fwUserA.UserName, fwUserC.UserNamespace) 391 return err == nil 392 }, 1*time.Minute, 5*time.Second).Should(BeTrue(), "error checking if the workspace C was shared with user A") 393 394 // check if user C is provisioned after workspace share 395 Eventually(func() bool { 396 _, err := fwUserC.SandboxController.GetUserProvisionedNamespace(fwUserC.UserName) 397 return err == nil 398 }, 1*time.Minute, 5*time.Second).Should(BeTrue(), "error getting provisioned usernamespace") 399 400 // create SPITokenBinding for user A 401 createSPITokenBinding(userA) 402 403 // create SPITokenBinding for user B 404 createSPITokenBinding(userB) 405 406 // create SPITokenBinding for user C 407 createSPITokenBinding(userC) 408 }) 409 410 AfterAll(func() { 411 if !CurrentSpecReport().Failed() { 412 delete(userA) 413 delete(userB) 414 delete(userC) 415 } 416 }) 417 418 It("checks that user A can access the SPIAccessToken A in workspace A", func() { 419 checkSecretAccess(*userA.APIProxyClientA, userA, true) 420 }) 421 422 It("checks that user A can not access the SPIAccessToken B in workspace B", func() { 423 checkSecretAccess(*userA.APIProxyClientB, userB, false) 424 }) 425 426 It("checks that user A can access the SPIAccessToken C in workspace C", func() { 427 // workspace C was shared with user A 428 checkSecretAccess(*userA.APIProxyClientC, userC, true) 429 }) 430 431 It("checks that user B can not access the SPIAccessToken A in workspace A", func() { 432 checkSecretAccess(*userB.APIProxyClientA, userA, false) 433 }) 434 435 It("checks that user B can access the SPIAccessToken B in workspace B", func() { 436 checkSecretAccess(*userB.APIProxyClientB, userB, true) 437 }) 438 439 It("checks that user B can not access the SPIAccessToken C in workspace C", func() { 440 checkSecretAccess(*userB.APIProxyClientC, userC, false) 441 }) 442 443 It("checks that user C can not access the SPIAccessToken A in workspace A", func() { 444 checkSecretAccess(*userC.APIProxyClientA, userA, false) 445 }) 446 447 It("checks that user C can not access the SPIAccessToken B in workspace B", func() { 448 checkSecretAccess(*userC.APIProxyClientB, userB, false) 449 }) 450 451 It("checks that user C can access the SPIAccessToken C in workspace C", func() { 452 checkSecretAccess(*userC.APIProxyClientC, userC, true) 453 }) 454 455 It("checks that user A can read the GitHub repo in workspace A", func() { 456 checkRepositoryReading(*userA.APIProxyClientA, userA, true) 457 }) 458 459 It("checks that user A can not read the GitHub repo in workspace B", func() { 460 checkRepositoryReading(*userA.APIProxyClientB, userB, false) 461 }) 462 463 It("checks that user A can read the GitHub repo in workspace C", func() { 464 // workspace C was shared with user A 465 checkRepositoryReading(*userA.APIProxyClientC, userC, true) 466 }) 467 468 It("checks that user B can not read the GitHub repo in workspace A", func() { 469 checkRepositoryReading(*userB.APIProxyClientA, userA, false) 470 }) 471 472 It("checks that user B can read the GitHub repo in workspace B", func() { 473 checkRepositoryReading(*userB.APIProxyClientB, userB, true) 474 }) 475 476 It("checks that user B can not read the GitHub repo in workspace C", func() { 477 checkRepositoryReading(*userB.APIProxyClientC, userC, false) 478 }) 479 480 It("checks that user C can not read the GitHub repo in workspace A", func() { 481 checkRepositoryReading(*userC.APIProxyClientA, userA, false) 482 }) 483 484 It("checks that user C can not read the GitHub repo in workspace B", func() { 485 checkRepositoryReading(*userC.APIProxyClientB, userB, false) 486 }) 487 488 It("checks that user C can read the GitHub repo in workspace C", func() { 489 checkRepositoryReading(*userC.APIProxyClientC, userC, true) 490 }) 491 492 It("checks that user A can read the secret in workspace A", func() { 493 checkSecretReading(*userA.APIProxyClientA, userA, true) 494 }) 495 496 It("checks that user A can not read the secret in workspace B", func() { 497 checkSecretReading(*userA.APIProxyClientB, userB, false) 498 }) 499 500 It("checks that user A can not read the secret in workspace C", func() { 501 // although workspace C is shared with user A, the role given is maintainer, 502 // which does not have any permissions for secrets object 503 checkSecretReading(*userA.APIProxyClientC, userC, false) 504 }) 505 506 It("checks that user B can not read the secret in workspace A", func() { 507 checkSecretReading(*userB.APIProxyClientA, userA, false) 508 }) 509 510 It("checks that user B can read the secret in workspace B", func() { 511 checkSecretReading(*userB.APIProxyClientB, userB, true) 512 }) 513 514 It("checks that user B can not read the secret in workspace C", func() { 515 checkSecretReading(*userB.APIProxyClientC, userC, false) 516 }) 517 518 It("checks that user C can not read the secret in workspace A", func() { 519 checkSecretReading(*userC.APIProxyClientA, userA, false) 520 }) 521 522 It("checks that user C can not read the secret in workspace B", func() { 523 checkSecretReading(*userC.APIProxyClientB, userB, false) 524 }) 525 526 It("checks that user C can read the secret in workspace C", func() { 527 checkSecretReading(*userC.APIProxyClientC, userC, true) 528 }) 529 530 It("checks that a user's A pod deployed in workspace A should be able to construct an API request that reads code in the Github repo for workspace A", func() { 531 checkRepoReadingFromPod(*userA.APIProxyClientA, userA, userA, true) 532 }) 533 534 It("checks that a user's A pod deployed in workspace A should not be able to construct an API request that reads code in the Github repo for workspace B", func() { 535 checkRepoReadingFromPod(*userA.APIProxyClientB, userA, userB, false) 536 }) 537 538 It("checks that a user's A pod deployed in workspace A should be able to construct an API request that reads code in the Github repo for workspace C", func() { 539 // workspace C was shared with user A 540 checkRepoReadingFromPod(*userA.APIProxyClientC, userA, userC, true) 541 }) 542 543 It("checks that a user's B pod deployed in workspace B should not be able to construct an API request that reads code in the Github repo for workspace A", func() { 544 checkRepoReadingFromPod(*userB.APIProxyClientA, userB, userA, false) 545 }) 546 547 It("checks that a user's B pod deployed in workspace B should be able to construct an API request that reads code in the Github repo for workspace B", func() { 548 checkRepoReadingFromPod(*userB.APIProxyClientB, userB, userB, true) 549 }) 550 551 It("checks that a user's B pod deployed in workspace B should not be able to construct an API request that reads code in the Github repo for workspace C", func() { 552 checkRepoReadingFromPod(*userB.APIProxyClientC, userB, userC, false) 553 }) 554 555 It("checks that a user's C pod deployed in workspace C should not be able to construct an API request that reads code in the Github repo for workspace A", func() { 556 checkRepoReadingFromPod(*userC.APIProxyClientA, userC, userA, false) 557 }) 558 559 It("checks that a user's C pod deployed in workspace C should not be able to construct an API request that reads code in the Github repo for workspace B", func() { 560 checkRepoReadingFromPod(*userC.APIProxyClientB, userC, userB, false) 561 }) 562 563 It("checks that a user's C pod deployed in workspace C should be able to construct an API request that reads code in the Github repo for workspace C", func() { 564 checkRepoReadingFromPod(*userC.APIProxyClientC, userC, userC, true) 565 }) 566 }) 567 })