Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add keycloak integration test #6085

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/ci-it-security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ jobs:
- name: Run Security IT
shell: bash
run: |
./mvnw clean install -DskipTests -T 1C -s .settings.xml -pl spring-cloud-dataflow-server -am -B --no-transfer-progress
./mvnw -s .settings.xml \
-pl spring-cloud-dataflow-server \
-Dgroups=oauth \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,17 @@
/**
* @author Gunnar Hillert
*/
public class DefaultAuthoritiesMapperTests {
class DefaultAuthoritiesMapperTests {

@Test
public void testNullConstructor() throws Exception {
void nullConstructor() throws Exception {
assertThatThrownBy(() -> {
new DefaultAuthoritiesMapper(null, "");
}).isInstanceOf(IllegalArgumentException.class).hasMessageContaining("providerRoleMappings must not be null.");
}

@Test
public void testMapScopesToAuthoritiesWithNullParameters() throws Exception {
void mapScopesToAuthoritiesWithNullParameters() throws Exception {
DefaultAuthoritiesMapper authoritiesMapper = new DefaultAuthoritiesMapper(Collections.emptyMap(), "");

assertThatThrownBy(() -> {
Expand All @@ -56,18 +56,19 @@ public void testMapScopesToAuthoritiesWithNullParameters() throws Exception {
}

@Test
public void testThat7AuthoritiesAreReturned() throws Exception {
void that7AuthoritiesAreReturned() throws Exception {
DefaultAuthoritiesMapper authoritiesMapper = new DefaultAuthoritiesMapper("uaa", false);
Set<GrantedAuthority> authorities = authoritiesMapper.mapScopesToAuthorities("uaa", Collections.emptySet(), null);

assertThat(authorities).hasSize(7);
assertThat(authorities.stream().map(authority -> authority.getAuthority()).collect(Collectors.toList()))
assertThat(authorities)
.extracting(GrantedAuthority::getAuthority)
.containsExactlyInAnyOrder("ROLE_MANAGE", "ROLE_CREATE", "ROLE_VIEW", "ROLE_DEPLOY", "ROLE_MODIFY",
"ROLE_SCHEDULE", "ROLE_DESTROY");
}

@Test
public void testEmptyMapConstructor() throws Exception {
void emptyMapConstructor() throws Exception {
Set<String> scopes = new HashSet<>();
scopes.add("dataflow.manage");
scopes.add("dataflow.view");
Expand All @@ -77,12 +78,13 @@ public void testEmptyMapConstructor() throws Exception {
Collection<? extends GrantedAuthority> authorities = authoritiesMapper.mapScopesToAuthorities("uaa", scopes, null);

assertThat(authorities).hasSize(3);
assertThat(authorities.stream().map(authority -> authority.getAuthority()).collect(Collectors.toList()))
assertThat(authorities)
.extracting(GrantedAuthority::getAuthority)
.containsExactlyInAnyOrder("ROLE_MANAGE", "ROLE_CREATE", "ROLE_VIEW");
}

@Test
public void testMapConstructorWithIncompleteRoleMappings() throws Exception {
void mapConstructorWithIncompleteRoleMappings() throws Exception {
ProviderRoleMapping roleMapping = new ProviderRoleMapping();
roleMapping.setMapOauthScopes(true);
roleMapping.addRoleMapping("ROLE_MANAGE", "foo-scope-in-oauth");
Expand All @@ -93,80 +95,115 @@ public void testMapConstructorWithIncompleteRoleMappings() throws Exception {
}

@Test
public void testThat7MappedAuthoritiesAreReturned() throws Exception {
Map<String, String> roleMappings = new HashMap<>();
roleMappings.put("ROLE_MANAGE", "foo-manage");
roleMappings.put("ROLE_VIEW", "bar-view");
roleMappings.put("ROLE_CREATE", "blubba-create");
roleMappings.put("ROLE_MODIFY", "foo-modify");
roleMappings.put("ROLE_DEPLOY", "foo-deploy");
roleMappings.put("ROLE_DESTROY", "foo-destroy");
roleMappings.put("ROLE_SCHEDULE", "foo-schedule");
void that3MappedAuthoritiesAreReturned() throws Exception {
Map<String, String> roleMappings = Map.of(
"ROLE_MANAGE", "dataflow_manage",
"ROLE_VIEW", "dataflow_view",
"ROLE_CREATE", "dataflow_create",
"ROLE_MODIFY", "dataflow_modify",
"ROLE_DEPLOY", "dataflow_deploy",
"ROLE_DESTROY", "dataflow_destroy",
"ROLE_SCHEDULE", "dataflow_schedule"
);

ProviderRoleMapping providerRoleMapping = new ProviderRoleMapping();
providerRoleMapping.setMapOauthScopes(true);
providerRoleMapping.getRoleMappings().putAll(roleMappings);

Set<String> scopes = new HashSet<>();
scopes.add("foo-manage");
scopes.add("bar-view");
scopes.add("blubba-create");
scopes.add("foo-modify");
scopes.add("foo-deploy");
scopes.add("foo-destroy");
scopes.add("foo-schedule");
Set<String> roles = Set.of("dataflow_manage", "dataflow_view", "dataflow_deploy");

DefaultAuthoritiesMapper defaultAuthoritiesMapper = new DefaultAuthoritiesMapper("uaa", providerRoleMapping);
Collection<? extends GrantedAuthority> authorities = defaultAuthoritiesMapper.mapScopesToAuthorities("uaa",
roles, null);

assertThat(authorities).hasSize(3);
assertThat(authorities)
.extracting(GrantedAuthority::getAuthority)
.containsExactlyInAnyOrder("ROLE_DEPLOY", "ROLE_MANAGE", "ROLE_VIEW");
}
@Test
void that7MappedAuthoritiesAreReturned() throws Exception {
Map<String, String> roleMappings = Map.of(
"ROLE_MANAGE", "foo-manage",
"ROLE_VIEW", "bar-view",
"ROLE_CREATE", "blubba-create",
"ROLE_MODIFY", "foo-modify",
"ROLE_DEPLOY", "foo-deploy",
"ROLE_DESTROY", "foo-destroy",
"ROLE_SCHEDULE", "foo-schedule"
);

ProviderRoleMapping providerRoleMapping = new ProviderRoleMapping();
providerRoleMapping.setMapOauthScopes(true);
providerRoleMapping.getRoleMappings().putAll(roleMappings);

Set<String> scopes = Set.of(
"foo-manage",
"bar-view",
"blubba-create",
"foo-modify",
"foo-deploy",
"foo-destroy",
"foo-schedule"
);

DefaultAuthoritiesMapper defaultAuthoritiesMapper = new DefaultAuthoritiesMapper("uaa", providerRoleMapping);
Collection<? extends GrantedAuthority> authorities = defaultAuthoritiesMapper.mapScopesToAuthorities("uaa",
scopes, null);

assertThat(authorities).hasSize(7);
assertThat(authorities.stream().map(authority -> authority.getAuthority()).collect(Collectors.toList()))
assertThat(authorities)
.extracting(GrantedAuthority::getAuthority)
.containsExactlyInAnyOrder("ROLE_CREATE", "ROLE_DEPLOY", "ROLE_DESTROY", "ROLE_MANAGE", "ROLE_MODIFY",
"ROLE_SCHEDULE", "ROLE_VIEW");
}

@Test
public void testThat3MappedAuthoritiesAreReturnedForDefaultMapping() throws Exception {
void that3MappedAuthoritiesAreReturnedForDefaultMapping() throws Exception {
ProviderRoleMapping providerRoleMapping = new ProviderRoleMapping();
providerRoleMapping.setMapOauthScopes(true);

Set<String> scopes = new HashSet<>();
scopes.add("dataflow.manage");
scopes.add("dataflow.view");
scopes.add("dataflow.create");
Set<String> scopes = Set.of(
"dataflow.manage",
"dataflow.view",
"dataflow.create"
);

DefaultAuthoritiesMapper defaultAuthoritiesExtractor = new DefaultAuthoritiesMapper("uaa", providerRoleMapping);
Collection<? extends GrantedAuthority> authorities = defaultAuthoritiesExtractor.mapScopesToAuthorities("uaa",
scopes, null);

assertThat(authorities).hasSize(3);
assertThat(authorities.stream().map(authority -> authority.getAuthority()).collect(Collectors.toList()))
assertThat(authorities)
.extracting(GrantedAuthority::getAuthority)
.containsExactlyInAnyOrder("ROLE_MANAGE", "ROLE_CREATE", "ROLE_VIEW");
}

@Test
public void testThat7MappedAuthoritiesAreReturnedForDefaultMappingWithoutMappingScopes() throws Exception {
Set<String> scopes = new HashSet<>();
scopes.add("dataflow.manage");
scopes.add("dataflow.view");
scopes.add("dataflow.create");
void that7MappedAuthoritiesAreReturnedForDefaultMappingWithoutMappingScopes() throws Exception {
Set<String> scopes = Set.of(
"dataflow.manage",
"dataflow.view",
"dataflow.create"
);

DefaultAuthoritiesMapper defaultAuthoritiesExtractor = new DefaultAuthoritiesMapper("uaa", false);
Collection<? extends GrantedAuthority> authorities = defaultAuthoritiesExtractor.mapScopesToAuthorities("uaa",
scopes, null);

assertThat(authorities).hasSize(7);
assertThat(authorities.stream().map(authority -> authority.getAuthority()).collect(Collectors.toList()))
assertThat(authorities)
.extracting(GrantedAuthority::getAuthority)
.containsExactlyInAnyOrder("ROLE_CREATE", "ROLE_DEPLOY", "ROLE_DESTROY", "ROLE_MANAGE", "ROLE_MODIFY",
"ROLE_SCHEDULE", "ROLE_VIEW");
}

@Test
public void testThat2MappedAuthoritiesAreReturnedForDefaultMapping() throws Exception {
Set<String> scopes = new HashSet<>();
scopes.add("dataflow.view");
scopes.add("dataflow.create");
void that2MappedAuthoritiesAreReturnedForDefaultMapping() throws Exception {
Set<String> scopes = Set.of(
"dataflow.view",
"dataflow.create"
);

DefaultAuthoritiesMapper defaultAuthoritiesExtractor = new DefaultAuthoritiesMapper("uaa", true);
Collection<? extends GrantedAuthority> authorities = defaultAuthoritiesExtractor.mapScopesToAuthorities("uaa",
Expand All @@ -178,19 +215,18 @@ public void testThat2MappedAuthoritiesAreReturnedForDefaultMapping() throws Exce
}

@Test
public void testThat7AuthoritiesAreReturnedAndOneOAuthScopeCoversMultipleServerRoles() throws Exception {
Map<String, String> roleMappings = new HashMap<>();
roleMappings.put("ROLE_MANAGE", "foo-manage");
roleMappings.put("ROLE_VIEW", "foo-manage");
roleMappings.put("ROLE_DEPLOY", "foo-manage");
roleMappings.put("ROLE_DESTROY", "foo-manage");
roleMappings.put("ROLE_MODIFY", "foo-manage");
roleMappings.put("ROLE_SCHEDULE", "foo-manage");
roleMappings.put("ROLE_CREATE", "blubba-create");

Set<String> scopes = new HashSet<>();
scopes.add("foo-manage");
scopes.add("blubba-create");
void that7AuthoritiesAreReturnedAndOneOAuthScopeCoversMultipleServerRoles() throws Exception {
Map<String, String> roleMappings = Map.of(
"ROLE_MANAGE", "foo-manage",
"ROLE_VIEW", "foo-manage",
"ROLE_DEPLOY", "foo-manage",
"ROLE_DESTROY", "foo-manage",
"ROLE_MODIFY", "foo-manage",
"ROLE_SCHEDULE", "foo-manage",
"ROLE_CREATE", "blubba-create"
);

Set<String> scopes = Set.of("foo-manage", "blubba-create");

DefaultAuthoritiesMapper defaultAuthoritiesExtractor = new DefaultAuthoritiesMapper("uaa", true, roleMappings);
Collection<? extends GrantedAuthority> authorities = defaultAuthoritiesExtractor.mapScopesToAuthorities("uaa",
Expand All @@ -203,61 +239,64 @@ public void testThat7AuthoritiesAreReturnedAndOneOAuthScopeCoversMultipleServerR
}

@Test
public void testThatUriStyleScopeRemovesLeadingPart() throws Exception {
Map<String, String> roleMappings = new HashMap<>();
roleMappings.put("ROLE_MANAGE", "foo-manage");
roleMappings.put("ROLE_VIEW", "foo-manage");
roleMappings.put("ROLE_DEPLOY", "foo-manage");
roleMappings.put("ROLE_DESTROY", "foo-manage");
roleMappings.put("ROLE_MODIFY", "foo-manage");
roleMappings.put("ROLE_SCHEDULE", "foo-manage");
roleMappings.put("ROLE_CREATE", "blubba-create");

Set<String> scopes = new HashSet<>();
scopes.add("api://foobar/foo-manage");
scopes.add("blubba-create");
void thatUriStyleScopeRemovesLeadingPart() throws Exception {
Map<String, String> roleMappings = Map.of(
"ROLE_MANAGE", "foo-manage",
"ROLE_VIEW", "foo-manage",
"ROLE_DEPLOY", "foo-manage",
"ROLE_DESTROY", "foo-manage",
"ROLE_MODIFY", "foo-manage",
"ROLE_SCHEDULE", "foo-manage",
"ROLE_CREATE", "blubba-create"
);

Set<String> scopes = Set.of("api://foobar/foo-manage", "blubba-create");

DefaultAuthoritiesMapper defaultAuthoritiesExtractor = new DefaultAuthoritiesMapper("uaa", true, roleMappings);
Collection<? extends GrantedAuthority> authorities = defaultAuthoritiesExtractor.mapScopesToAuthorities("uaa",
scopes, null);

assertThat(authorities).hasSize(7);
assertThat(authorities.stream().map(authority -> authority.getAuthority()).collect(Collectors.toList()))
assertThat(authorities)
.extracting(GrantedAuthority::getAuthority)
.containsExactlyInAnyOrder("ROLE_CREATE", "ROLE_DEPLOY", "ROLE_DESTROY", "ROLE_MANAGE", "ROLE_MODIFY",
"ROLE_SCHEDULE", "ROLE_VIEW");
}

@Test
public void testThatUriStyleScopeParsingCanBeDisabled() throws Exception {
Map<String, String> roleMappings = new HashMap<>();
roleMappings.put("ROLE_MANAGE", "/ROLE/2000803042");
roleMappings.put("ROLE_VIEW", "/ROLE/2000803036");
roleMappings.put("ROLE_DEPLOY", "/ROLE/2000803039");
roleMappings.put("ROLE_DESTROY", "/ROLE/20008030340");
roleMappings.put("ROLE_MODIFY", "/ROLE/2000803037");
roleMappings.put("ROLE_SCHEDULE", "/ROLE/2000803038");
roleMappings.put("ROLE_CREATE", "/ROLE/2000803041");
void thatUriStyleScopeParsingCanBeDisabled() throws Exception {
Map<String, String> roleMappings = Map.of(
"ROLE_MANAGE", "/ROLE/2000803042",
"ROLE_VIEW", "/ROLE/2000803036",
"ROLE_DEPLOY", "/ROLE/2000803039",
"ROLE_DESTROY", "/ROLE/20008030340",
"ROLE_MODIFY", "/ROLE/2000803037",
"ROLE_SCHEDULE", "/ROLE/2000803038",
"ROLE_CREATE", "/ROLE/2000803041"
);

ProviderRoleMapping providerRoleMapping = new ProviderRoleMapping();
providerRoleMapping.setMapOauthScopes(true);
providerRoleMapping.setParseOauthScopePathParts(false);
providerRoleMapping.getRoleMappings().putAll(roleMappings);

Set<String> scopes = new HashSet<>();
scopes.add("/ROLE/2000803042");
scopes.add("/ROLE/2000803036");
scopes.add("/ROLE/2000803039");
scopes.add("/ROLE/20008030340");
scopes.add("/ROLE/2000803037");
scopes.add("/ROLE/2000803038");
scopes.add("/ROLE/2000803041");
Set<String> scopes = Set.of(
"/ROLE/2000803042",
"/ROLE/2000803036",
"/ROLE/2000803039",
"/ROLE/20008030340",
"/ROLE/2000803037",
"/ROLE/2000803038",
"/ROLE/2000803041"
);

DefaultAuthoritiesMapper defaultAuthoritiesMapper = new DefaultAuthoritiesMapper("uaa", providerRoleMapping);
Collection<? extends GrantedAuthority> authorities = defaultAuthoritiesMapper.mapScopesToAuthorities("uaa",
scopes, null);

assertThat(authorities).hasSize(7);
assertThat(authorities.stream().map(authority -> authority.getAuthority()).collect(Collectors.toList()))
assertThat(authorities)
.extracting(GrantedAuthority::getAuthority)
.containsExactlyInAnyOrder("ROLE_CREATE", "ROLE_DEPLOY", "ROLE_DESTROY", "ROLE_MANAGE", "ROLE_MODIFY",
"ROLE_SCHEDULE", "ROLE_VIEW");
}
Expand Down
6 changes: 6 additions & 0 deletions spring-cloud-dataflow-parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
<!-- database driver versions -->
<oracle-ojdbc8.version>21.9.0.0</oracle-ojdbc8.version>
<db2-jcc.version>11.5.9.0</db2-jcc.version>
<testcontainers-keycloak.version>3.4.0</testcontainers-keycloak.version>
<!-- questionable testing libs -->
<org-json.version>20240303</org-json.version>
<littleproxy.version>1.1.2</littleproxy.version>
Expand Down Expand Up @@ -257,6 +258,11 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.github.dasniko</groupId>
<artifactId>testcontainers-keycloak</artifactId>
<version>${testcontainers-keycloak.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
auth.userInfoEndpoint(customizer -> {
customizer.userService(plainOauth2UserService).oidcUserService(oidcUserService);
});
auth.defaultSuccessUrl(authorizationProperties.getDashboardUrl());
});

http.oauth2ResourceServer(resourceserver -> {
Expand Down
10 changes: 10 additions & 0 deletions spring-cloud-dataflow-server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
Expand Down Expand Up @@ -104,6 +109,11 @@
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.dasniko</groupId>
<artifactId>testcontainers-keycloak</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
Expand Down
Loading
Loading