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

fix: check for existing groups #2653

Merged
merged 44 commits into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
214dc88
fix sonar issue: Utility classes should not have public constructors
klaus-sap Oct 10, 2023
d02780e
Merge branch 'cloudfoundry:develop' into develop
klaus-sap Oct 12, 2023
931f880
fix: possibly unnecessary method call
klaus-sap Oct 18, 2023
57bc472
fix: define Java version
klaus-sap Oct 18, 2023
0352bb6
handle in separate PR
klaus-sap Oct 20, 2023
12d1a44
Merge branch 'cloudfoundry:develop' into develop
klaus-sap Oct 23, 2023
006e134
Merge branch 'cloudfoundry:develop' into develop
klaus-sap Oct 30, 2023
9a34f0a
feature: add attribute userConfig.allowedGroups to IdZ
klaus-sap Oct 30, 2023
71b7abb
Merge branch 'cloudfoundry:develop' into develop
klaus-sap Nov 17, 2023
7d2fb2d
revert format changes
strehle Nov 18, 2023
d4c52f4
revert format changes
strehle Nov 18, 2023
ec56ea6
fix Sonar warnings
klaus-sap Nov 20, 2023
ef8f6ca
remove TODO
klaus-sap Nov 20, 2023
9dd1e38
create new needed bean similar than the other beans created
strehle Nov 20, 2023
244110c
is an optional entry in identity zone configuration
strehle Nov 20, 2023
85891ed
Merge branch 'develop' of github.com:cloudfoundry/uaa into klaus-develop
strehle Nov 20, 2023
c7eb6d7
fix sonar smells
strehle Nov 20, 2023
6e6ab18
combine default and allowed groups
klaus-sap Nov 21, 2023
979f933
fix Sonar warnings
klaus-sap Nov 22, 2023
8cde93e
add test class
klaus-sap Nov 22, 2023
b7adddd
add testResultingAllowedGroups
klaus-sap Nov 22, 2023
a464bab
add testScopesIncludesAllowedAuthoritiesForUser
klaus-sap Nov 22, 2023
370be52
zoneId must not be null
klaus-sap Nov 22, 2023
a6722b5
use right asserts
klaus-sap Nov 22, 2023
ab2d5cf
remove null-check
klaus-sap Nov 23, 2023
bd87bed
add integration tests
klaus-sap Nov 23, 2023
fdc6b02
fix createNotAllowedGroupFails
klaus-sap Nov 23, 2023
f400598
introduce list allowedGroups
klaus-sap Nov 23, 2023
163194c
update allowedGroups on server
klaus-sap Nov 23, 2023
1e02b38
pass IdZ id
klaus-sap Nov 23, 2023
c9810f7
determine zone id
klaus-sap Nov 23, 2023
7102503
Merge branch 'develop' of github.com:cloudfoundry/uaa into integratio…
strehle Nov 24, 2023
1291228
update integration tests
strehle Nov 23, 2023
1658023
cleanup in integration tests, fixes mftop
strehle Nov 24, 2023
d1a2cac
Merge remote-tracking branch 'origin/develop' into klaus-rebase
strehle Dec 11, 2023
cc27f66
change log level to info
klaus-sap Dec 14, 2023
ef94dea
remove log message
klaus-sap Dec 14, 2023
56adc44
check for groups which would be not allowed after the update
klaus-sap Dec 15, 2023
86e7f03
must not remove default group from configuration
klaus-sap Dec 18, 2023
5ddf0ca
remove sonar comment
strehle Dec 19, 2023
dfd1fb1
Merge branch 'cloudfoundry:develop' into develop
klaus-sap Dec 21, 2023
ab81926
fix: check for existing groups
klaus-sap Dec 21, 2023
2182153
add unit test
strehle Dec 21, 2023
5c72b0e
refactor
strehle Dec 21, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

import static java.util.Optional.ofNullable;
import static org.springframework.http.HttpStatus.CONFLICT;
Expand Down Expand Up @@ -268,15 +268,12 @@ public ResponseEntity<IdentityZone> updateIdentityZone(
body.setId(id);
body = validator.validate(body, IdentityZoneValidator.Mode.MODIFY);

// check for groups which would be not allowed after the update
UserConfig userConfig = body.getConfig().getUserConfig();
if (!userConfig.allGroupsAllowed()) {
List<String> existingGroupNames = groupProvisioning.retrieveAll(body.getId())
.stream()
.map(ScimGroup::getDescription)
.collect(Collectors.toList());
if (!userConfig.resultingAllowedGroups().containsAll(existingGroupNames)) {
throw new UnprocessableEntityException("The identity zone details contains not-allowed groups.");
Set<String> allowedGroups = userConfig.resultingAllowedGroups();
// check for groups which would be not allowed after the update
if(groupProvisioning.retrieveAll(body.getId()).stream().anyMatch(g -> !allowedGroups.contains(g.getDisplayName()))) {
throw new UnprocessableEntityException("The identity zone user configuration contains not-allowed groups.");
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.cloudfoundry.identity.uaa.zone;

import org.cloudfoundry.identity.uaa.error.UaaException;
import org.cloudfoundry.identity.uaa.extensions.PollutionPreventionExtension;
import org.cloudfoundry.identity.uaa.provider.IdentityProviderProvisioning;
import org.cloudfoundry.identity.uaa.saml.SamlKey;
Expand All @@ -15,9 +16,12 @@
import org.springframework.validation.BindingResult;

import java.util.List;
import java.util.stream.Collectors;

import static org.cloudfoundry.identity.uaa.util.AssertThrowsWithMessage.assertThrowsWithMessageThat;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
Expand Down Expand Up @@ -133,6 +137,38 @@ void restore_keys() {

}

@Test
void extend_zone_allowed_groups_on_update() throws InvalidIdentityZoneDetailsException {
when(mockIdentityZoneValidator.validate(any(), any())).then(invocation -> invocation.getArgument(0));

IdentityZoneEndpoints spy = Mockito.spy(endpoints);
identityZone = createZone();
identityZone.getConfig().getUserConfig().setAllowedGroups(List.of("sps.write", "sps.read", "idps.write", "idps.read"));
when(mockIdentityZoneProvisioning.retrieveIgnoreActiveFlag(identityZone.getId())).thenReturn(identityZone);
when(mockIdentityZoneProvisioning.update(same(identityZone))).thenReturn(identityZone);
List<ScimGroup> existingScimGroups = List.of("sps.write", "sps.read").stream().
map(e -> new ScimGroup(e, e, identityZone.getId())).collect(Collectors.toList());
when(mockScimGroupProvisioning.retrieveAll(identityZone.getId())).thenReturn(existingScimGroups);
spy.updateIdentityZone(identityZone, identityZone.getId());
verify(spy, times(1)).createUserGroups(same(identityZone));
}

@Test
void reduce_zone_allowed_groups_on_update_should_fail() throws InvalidIdentityZoneDetailsException {
when(mockIdentityZoneValidator.validate(any(), any())).then(invocation -> invocation.getArgument(0));

identityZone = createZone();
identityZone.getConfig().getUserConfig().setAllowedGroups(List.of("clients.admin", "clients.write", "clients.read", "clients.secret"));
when(mockIdentityZoneProvisioning.retrieveIgnoreActiveFlag(identityZone.getId())).thenReturn(identityZone);
List<ScimGroup> existingScimGroups = List.of("sps.write", "sps.read", "idps.write", "idps.read",
"clients.admin", "clients.write", "clients.read", "clients.secret", "scim.write", "scim.read", "scim.create", "scim.userids",
"scim.zones", "groups.update", "password.write", "oauth.login", "uaa.admin").stream().
map(e -> new ScimGroup(e, e, identityZone.getId())).collect(Collectors.toList());
when(mockScimGroupProvisioning.retrieveAll(identityZone.getId())).thenReturn(existingScimGroups);
assertThrowsWithMessageThat(UaaException.class, () -> endpoints.updateIdentityZone(identityZone, identityZone.getId()),
is("The identity zone user configuration contains not-allowed groups."));
}

private static IdentityZone createZone() {
IdentityZone zone = MultitenancyFixture.identityZone("id", "subdomain");
IdentityZoneConfiguration config = zone.getConfig();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,43 @@ public void testCreateZone() {
assertNull(ObjectUtils.castInstance(identityProvider.getConfig(),UaaIdentityProviderDefinition.class).getPasswordPolicy());
}

@Test
public void testUpdateZoneAllowedGroups() {
IdentityZone idZone = new IdentityZone();
String id = UUID.randomUUID().toString();
idZone.setId(id);
idZone.setSubdomain(id);
idZone.setName("testUpdateZone-"+id);
ResponseEntity<String> response = client.exchange(
serverRunning.getUrl("/identity-zones"),
HttpMethod.POST,
new HttpEntity<>(idZone),
new ParameterizedTypeReference<String>() {},
id);
assertEquals(response.getBody(), HttpStatus.CREATED, response.getStatusCode());

List<String> existingGroups = List.of("sps.write", "sps.read", "idps.write", "idps.read", "clients.admin", "clients.write", "clients.read",
"clients.secret", "scim.write", "scim.read", "scim.create", "scim.userids", "scim.zones", "groups.update", "password.write", "oauth.login", "uaa.admin");
idZone.getConfig().getUserConfig().setAllowedGroups(existingGroups);
response = client.exchange(
serverRunning.getUrl("/identity-zones/"+id),
HttpMethod.PUT,
new HttpEntity<>(idZone),
new ParameterizedTypeReference<String>() {},
id);
assertEquals(response.getBody() , HttpStatus.OK, response.getStatusCode());

List<String> notAllExistingGroups = List.of("clients.admin", "clients.write", "clients.read", "clients.secret");
idZone.getConfig().getUserConfig().setAllowedGroups(notAllExistingGroups);
response = client.exchange(
serverRunning.getUrl("/identity-zones/"+id),
HttpMethod.PUT,
new HttpEntity<>(idZone),
new ParameterizedTypeReference<String>() {},
id);
assertEquals(response.getBody() , HttpStatus.UNPROCESSABLE_ENTITY, response.getStatusCode());
}

@Test
public void testCreateZoneWithClient() {
IdentityZone idZone = new IdentityZone();
Expand Down