IdentityProviderConfigFactory extends OpenShiftClientConfigFactory { public Config buildConfig(Config defaultConfig, @Nullable String workspaceId) throws InfrastructureException { Subject subject = EnvironmentContext.getCurrent().getSubject(); if (oauthIdentityProvider == null) { LOG.debug("OAuth Provider is not configured, default config is used."); return defaultConfig; } if (subject == Subject.ANONYMOUS) { LOG.debug( "OAuth Provider is configured but default subject is anonymous, default config is used."); return defaultConfig; } if (workspaceId == null) { LOG.debug( "OAuth Provider is configured and this request is not related to any workspace. OAuth token will be retrieved."); return personalizeConfig(defaultConfig); } Optional<RuntimeContext> context = workspaceRuntimeProvider.get().getRuntimeContext(workspaceId); if (!context.isPresent()) { LOG.debug( "There is no runtime context for the specified workspace '%s'. It's the first workspace " + "related call, so context is personalized with OAuth token."); return personalizeConfig(defaultConfig); } String workspaceOwnerId = context.map(c -> c.getIdentity().getOwnerId()).orElse(null); boolean isRuntimeOwner = subject.getUserId().equals(workspaceOwnerId); if (!isRuntimeOwner) { LOG.debug( "OAuth Provider is configured, but current subject is not runtime owner, default config is used." + "Subject user id: '{}'. Runtime owner id: '{}'", subject.getUserId(), workspaceOwnerId); return defaultConfig; } LOG.debug( "OAuth Provider is configured and current subject is runtime owner. OAuth token will be retrieved."); return personalizeConfig(defaultConfig); } @Inject  IdentityProviderConfigFactory(
      KeycloakServiceClient keycloakServiceClient,
      KeycloakSettings keycloakSettings,
      Provider<WorkspaceRuntimes> workspaceRuntimeProvider,
      @Nullable @Named("che.infra.openshift.oauth_identity_provider") String oauthIdentityProvider,
      @Named("che.api") String apiEndpoint); @Override boolean isPersonalized(); Config buildConfig(Config defaultConfig, @Nullable String workspaceId);  }
@Test public void testFallbackToDefaultConfigWhenProvideIsNull() throws Exception { when(keycloakServiceClient.getIdentityProviderToken(anyString())).thenReturn(tokenResponse); configBuilder = new IdentityProviderConfigFactory( keycloakServiceClient, keycloakSettings, workspaceRuntimeProvider, null, API_ENDPOINT); assertSame(defaultConfig, configBuilder.buildConfig(defaultConfig, A_WORKSPACE_ID)); }
@Test public void testFallbackToDefaultConfigWhenSubjectIsAnonymous() throws Exception { when(keycloakServiceClient.getIdentityProviderToken(anyString())).thenReturn(tokenResponse); doReturn(Subject.ANONYMOUS).when(context).getSubject(); assertSame(defaultConfig, configBuilder.buildConfig(defaultConfig, A_WORKSPACE_ID)); }
@Test public void testFallbackToDefaultConfigWhenCurrentUserIsDifferentFromWorkspaceOwner() throws Exception { when(keycloakServiceClient.getIdentityProviderToken(anyString())).thenReturn(tokenResponse); when(runtimeIdentity.getOwnerId()).thenReturn(ANOTHER_USER_ID); assertSame(defaultConfig, configBuilder.buildConfig(defaultConfig, A_WORKSPACE_ID)); }
@SuppressWarnings("rawtypes") @Test public void testCreateUserConfigWhenNoRuntimeContext() throws Exception { when(keycloakServiceClient.getIdentityProviderToken(anyString())).thenReturn(tokenResponse); when(workspaceRuntimes.getRuntimeContext(anyString())).thenReturn(Optional.empty()); Config resultConfig = configBuilder.buildConfig(defaultConfig, A_WORKSPACE_ID); assertEquals(resultConfig.getOauthToken(), ACCESS_TOKEN); }
@Test public void testCreateUserConfigWhenWorkspaceIdIsNull() throws Exception { when(keycloakServiceClient.getIdentityProviderToken(anyString())).thenReturn(tokenResponse); Config resultConfig = configBuilder.buildConfig(defaultConfig, null); assertEquals(resultConfig.getOauthToken(), ACCESS_TOKEN); }
@Test public void testCreateUserConfig() throws Exception { when(keycloakServiceClient.getIdentityProviderToken(anyString())).thenReturn(tokenResponse); Config resultConfig = configBuilder.buildConfig(defaultConfig, A_WORKSPACE_ID); assertEquals(resultConfig.getOauthToken(), ACCESS_TOKEN); }
@Test(expectedExceptions = {InfrastructureException.class}) public void testThrowOnBadScope() throws Exception { when(keycloakServiceClient.getIdentityProviderToken(anyString())).thenReturn(tokenResponse); when(tokenResponse.getScope()).thenReturn("bad:scope"); Config resultConfig = configBuilder.buildConfig(defaultConfig, A_WORKSPACE_ID); assertEquals(resultConfig.getOauthToken(), ACCESS_TOKEN); }
@Test public void testRethrowOnUnauthorizedException() throws Exception { doThrow( new UnauthorizedException( DtoFactory.newDto(ServiceError.class).withMessage("Any other message"))) .when(keycloakServiceClient) .getIdentityProviderToken(anyString()); try { configBuilder.buildConfig(defaultConfig, A_WORKSPACE_ID); } catch (InfrastructureException e) { assertEquals(e.getMessage(), SHOULD_LINK_ERROR_MESSAGE, "The exception message is wrong"); return; } fail( "Should have thrown an exception with the following message: " + SHOULD_LINK_ERROR_MESSAGE); }
@Test(expectedExceptions = {InfrastructureException.class}) public void testRethrowOnBadRequestException() throws Exception { doThrow( new BadRequestException( DtoFactory.newDto(ServiceError.class).withMessage("Any other message"))) .when(keycloakServiceClient) .getIdentityProviderToken(anyString()); configBuilder.buildConfig(defaultConfig, A_WORKSPACE_ID); }
@Test public void testRethrowOnInvalidTokenBadRequestException() throws Exception { doThrow( new BadRequestException( DtoFactory.newDto(ServiceError.class).withMessage("Invalid token."))) .when(keycloakServiceClient) .getIdentityProviderToken(anyString()); try { configBuilder.buildConfig(defaultConfig, A_WORKSPACE_ID); } catch (InfrastructureException e) { assertEquals(e.getMessage(), SESSION_EXPIRED_MESSAGE, "The exception message is wrong"); return; } fail("Should have thrown an exception with the following message: " + SESSION_EXPIRED_MESSAGE); }
@Test(expectedExceptions = {InfrastructureException.class}) public void testRethrowOnAnyException() throws Exception { when(keycloakServiceClient.getIdentityProviderToken(anyString())) .thenThrow(org.eclipse.che.api.core.NotFoundException.class); configBuilder.buildConfig(defaultConfig, A_WORKSPACE_ID); }