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 flags for delete behaviour of authz scopes and policies #905

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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## [Unreleased]

### Added
- Support for managing `Client Authorization Policies` like other resources by configuring `import.managed.client-authorization-policies=<full|no-delete>`. This prevents deletion of remote managed policies.
- Support for managing `Client Authorization Scopes` like other resources by configuring `import.managed.client-authorization-scopes=<full|no-delete>`. This prevents deletion of remote managed scopes.

## [5.8.0] - 2023-07-14

### Added
Expand Down
2 changes: 2 additions & 0 deletions docs/MANAGED.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ groups will be deleted. If you define `groups` but set an empty array, keycloak
| Identity Provider Mappers | - | `identity-provider-mapper` |
| Clients | - | `client` |
| Clients Authorization Resources | The 'Default Resource' is always included. | `client-authorization-resources` |
| Clients Authorization Policies | - | `client-authorization-policies` |
| Clients Authorization Scopes | - | `client-authorization-scopes` |

## Disable deletion of managed entities

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,21 @@ public static class ImportManagedProperties {
@NotNull
private final ImportManagedPropertiesValues clientAuthorizationResources;

@NotNull
private final ImportManagedPropertiesValues clientAuthorizationPolicies;

@NotNull
private final ImportManagedPropertiesValues clientAuthorizationScopes;

public ImportManagedProperties(ImportManagedPropertiesValues requiredAction, ImportManagedPropertiesValues group,
ImportManagedPropertiesValues clientScope, ImportManagedPropertiesValues scopeMapping,
ImportManagedPropertiesValues clientScopeMapping, ImportManagedPropertiesValues component,
ImportManagedPropertiesValues subComponent, ImportManagedPropertiesValues authenticationFlow,
ImportManagedPropertiesValues identityProvider, ImportManagedPropertiesValues identityProviderMapper,
ImportManagedPropertiesValues role, ImportManagedPropertiesValues client,
ImportManagedPropertiesValues clientAuthorizationResources) {
ImportManagedPropertiesValues clientAuthorizationResources,
ImportManagedPropertiesValues clientAuthorizationPolicies,
ImportManagedPropertiesValues clientAuthorizationScopes) {
this.requiredAction = requiredAction;
this.group = group;
this.clientScope = clientScope;
Expand All @@ -170,6 +178,8 @@ public ImportManagedProperties(ImportManagedPropertiesValues requiredAction, Imp
this.role = role;
this.client = client;
this.clientAuthorizationResources = clientAuthorizationResources;
this.clientAuthorizationPolicies = clientAuthorizationPolicies;
this.clientAuthorizationScopes = clientAuthorizationScopes;
}

public ImportManagedPropertiesValues getRequiredAction() {
Expand Down Expand Up @@ -224,6 +234,14 @@ public ImportManagedPropertiesValues getClientAuthorizationResources() {
return clientAuthorizationResources;
}

public ImportManagedPropertiesValues getClientAuthorizationPolicies() {
return clientAuthorizationPolicies;
}

public ImportManagedPropertiesValues getClientAuthorizationScopes() {
return clientAuthorizationScopes;
}

public enum ImportManagedPropertiesValues {
FULL, NO_DELETE
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,13 @@ private void updateAuthorization(
removeAuthorizationResources(realmName, client, existingAuthorization.getResources(), sanitizedAuthorizationResources);
}

removeAuthorizationPolicies(realmName, client, existingAuthorization.getPolicies(), sanitizedAuthorizationPolicies);
removeAuthorizationScopes(realmName, client, existingAuthorization.getScopes(), authorizationSettingsToImport.getScopes());
if (importConfigProperties.getManaged().getClientAuthorizationPolicies() == FULL) {
removeAuthorizationPolicies(realmName, client, existingAuthorization.getPolicies(), sanitizedAuthorizationPolicies);
}

if (importConfigProperties.getManaged().getClientAuthorizationScopes() == FULL) {
removeAuthorizationScopes(realmName, client, existingAuthorization.getScopes(), authorizationSettingsToImport.getScopes());
}

// refresh existingAuthorization
existingAuthorization = clientRepository.getAuthorizationConfigById(
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ import.managed.identity-provider-mapper=full
import.managed.role=full
import.managed.client=full
import.managed.client-authorization-resources=full
import.managed.client-authorization-policies=full
import.managed.client-authorization-scopes=full

logging.group.http=org.apache.http.wire
logging.group.realm-config=de.adorsys.keycloak.config.provider.KeycloakImportProvider
logging.group.keycloak-config-cli=de.adorsys.keycloak.config.service,de.adorsys.keycloak.config.KeycloakConfigRunner,de.adorsys.keycloak.config.provider.KeycloakProvider
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;

@TestPropertySource(properties = {
"import.managed.authentication-flow=no-delete",
Expand All @@ -48,6 +49,8 @@
"import.managed.role=no-delete",
"import.managed.client=no-delete",
"import.managed.client-authorization-resources=no-delete",
"import.managed.client-authorization-policies=no-delete",
"import.managed.client-authorization-scopes=no-delete",
})
@SuppressWarnings({"java:S5961", "java:S5976"})
class ImportManagedNoDeleteIT extends AbstractImportIT {
Expand Down Expand Up @@ -155,5 +158,23 @@ private void assertRealm() {
.stream().filter(resource -> clientResourcesList.contains(resource.getName()))
.collect(Collectors.toList());
assertThat(createdClientResourcesList, hasSize(2));

int createdScopesCount = createdRealm
.getClients()
.stream().filter(client -> Objects.equals(client.getName(), "moped-client")).findAny()
.orElseThrow(() -> new RuntimeException("Cannot find client 'moped-client'"))
.getAuthorizationSettings().getScopes()
.size();
assertThat(createdScopesCount, is(4));

long createdPoliciesCount = createdRealm
.getClients()
.stream().filter(client -> Objects.equals(client.getName(), "moped-client")).findAny()
.orElseThrow(() -> new RuntimeException("Cannot find client 'moped-client'"))
.getAuthorizationSettings().getPolicies().stream()
.filter(policy -> !policy.getName().equals("Default Policy"))
.filter(policy -> !policy.getName().equals("Default Permission"))
.count();
assertThat(createdPoliciesCount, is(1L));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,18 @@
]
}
],
"policies": [],
"policies": [
{
"name": "Policy A",
"description": "",
"type": "client",
"logic": "POSITIVE",
"decisionStrategy": "UNANIMOUS",
"config": {
"clients": "[\"moped-client\"]"
}
}
],
"scopes": [
{
"name": "urn:servlet-authz:protected:admin:access"
Expand Down
Loading