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