clearer/property variable naming and ordering
This commit is contained in:
34
README.md
34
README.md
@@ -40,7 +40,7 @@ This extension requires the [`multiext-activiti-app-ext`](https://git.inteligr8.
|
||||
| Activiti App Extension | Activiti App |
|
||||
| --------------------------------------- | --------------- |
|
||||
| `keycloak-activiti-app-ext` v1.0 - v1.2 | v1.11.x |
|
||||
| `keycloak-activiti-app-ext` v1.3 | v1.11.x - v2.x |
|
||||
| `keycloak-activiti-app-ext` v1.3 - v1.4 | v1.11.x - v2.x |
|
||||
| `auth-activiti-app-ext` v2.0+ | v24.x+ |
|
||||
|
||||
## Configuration
|
||||
@@ -68,22 +68,22 @@ The following properties were added to increase the configurability of the built
|
||||
|
||||
The following properties provide the core functionality of this extension. That is role synchronization.
|
||||
|
||||
| Property | Default | Description |
|
||||
| ---------------------------------------------- | --------- | ----------- |
|
||||
| `auth-ext.sync.user.createMissing` | `true` | If the user is authenticated, the user may be created in APS. |
|
||||
| `auth-ext.sync.user.requireGroup` | | This is only applicable when `createMissing` is `true`. If this is unset or the OAuth Authorization Server gives the user the specified group/role, then the user record will be created in APS. |
|
||||
| `auth-ext.sync.user.clearNewUserGroups` | `true` | This is only applicable when `createMissing` is `true`. All default APS groups will be deleted from the new user record. |
|
||||
| `auth-ext.sync.group.createMissing` | `true` | If a filtered and translated OIDC group has no corresponding APS group, a group will be created in APS. See `auth-ext.sync.group.capabilities.patterns` for whether that group will be an APS Organization or APS Capability. |
|
||||
| `auth-ext.sync.group.additions` | `true` | If the user isn't in an APS group but OAuth claims the OIDC group, then add them to it. |
|
||||
| `auth-ext.sync.group.removals` | `true` | If the user is in APS group but OAuth claims no OIDC group, then remove them from it. |
|
||||
| `auth-ext.sync.group.internal` | `false` | When considering groups for creation or user membership, include internal groups. Internal groups are ones without an `externalId`. |
|
||||
| `auth-ext.sync.group.internal.externalize` | `false` | This is only applicable when `internal` is `true`. If an internal group is encountered during the operation of this extension, make it external with the current `externalId`. |
|
||||
| `auth-ext.sync.group.tenantize` | `false` | If a group without a tenant is encountered during the operation of this extension, make it part of the selected tenant. |
|
||||
| `auth-ext.sync.group.translate.patterns` | | A comma delimited set of regular expression patterns for the translation (reformatting) of authorities. |
|
||||
| `auth-ext.sync.group.translate.replacements` | | A comma delimited set of regular expression replacement strings for the translation (reformatting) of authorities. |
|
||||
| `auth-ext.sync.group.include.patterns` | | A comma delimited set of regular expression patterns on what authorities to include. This is processed before `translate` processing. A blank value includes everything. If anything is specified, then only matches could possibly be included; but could still be excluded explicitly. |
|
||||
| `auth-ext.sync.group.exclude.patterns` | | A comma delimited set of regular expression patterns on what authorities to exclude. This is processed before `translate` processing. A blank value excludes nothing. If anything is specified and `include` is empty, then only matches will be excluded. If both are specified, `exclude` overrules `include` matches. |
|
||||
| `auth-ext.sync.group.capabilities.patterns` | `Superusers` | A comma delimited set of regular expression patterns on what authorities to associate with APS Capabilities instead of APS Organizations (default). |
|
||||
| Property | Default | Description |
|
||||
| --------------------------------------------- | ------------ | ----------- |
|
||||
| `auth-ext.sync.user.createMissing` | `true` | If the user is authenticated, the user may be created in APS. |
|
||||
| `auth-ext.sync.user.requireOidcGroup` | | This is only applicable when `createMissing` is `true`. If this is unset or the OAuth Authorization Server gives the user the specified group/role, then the user record will be created in APS. |
|
||||
| `auth-ext.sync.user.clearNewUserGroups` | `true` | This is only applicable when `createMissing` is `true`. All default APS groups will be deleted from the new user record. |
|
||||
| `auth-ext.sync.group.createMissing` | `true` | If a filtered and translated OIDC group has no corresponding APS group, a group will be created in APS. See `auth-ext.sync.group.capabilities.patterns` for whether that group will be an APS Organization or APS Capability. |
|
||||
| `auth-ext.sync.group.additions` | `true` | If the user isn't in an APS group but OAuth claims the OIDC group, then add them to it. |
|
||||
| `auth-ext.sync.group.removals` | `true` | If the user is in APS group but OAuth claims no OIDC group, then remove them from it. |
|
||||
| `auth-ext.sync.group.internal` | `false` | When considering groups for creation or user membership, include internal groups. Internal groups are ones without an `externalId`. |
|
||||
| `auth-ext.sync.group.internal.externalize` | `false` | This is only applicable when `internal` is `true`. If an internal group is encountered during the operation of this extension, make it external with the current `externalId`. |
|
||||
| `auth-ext.sync.group.tenantize` | `false` | If a group without a tenant is encountered during the operation of this extension, make it part of the selected tenant. |
|
||||
| `auth-ext.sync.group.include.patterns` | | A comma delimited set of regular expression patterns on what OIDC groups to include. This is processed before `translate` processing. A blank value matches everything. If anything is specified, then only matches could possibly be included. Any matches of the `exclude` property patterns always override though. |
|
||||
| `auth-ext.sync.group.exclude.patterns` | | A comma delimited set of regular expression patterns on what OIDC groups to exclude. This is processed before `translate` processing. A blank value matches nothing (includes all that pass the `include` constraint). If anything is specified and `include` is empty, then all non-matches are included. If both are specified, `exclude` matches override `include` matches. |
|
||||
| `auth-ext.sync.group.translate.patterns` | | A comma delimited set of regular expression patterns for the translation (reformatting) of OIDC groups to APS groups. This list corresponds to the `replacements` property and must have the same number of commas. |
|
||||
| `auth-ext.sync.group.translate.replacements` | | A comma delimited set of regular expression replacement strings for the translation (reformatting) of OIDC groups to APS groups. This list corresponds to the `patterns` property and must have the same number of commas. |
|
||||
| `auth-ext.sync.group.capability.patterns` | `Superusers` | A comma delimited set of regular expression patterns on what translated OIDC groups to associate with APS Capability Groups instead of APS Organization Groups (default). This is processed after `translate` processing. |
|
||||
|
||||
### Authentication Data Fixers
|
||||
|
||||
|
@@ -139,9 +139,9 @@ public class GroupSyncService {
|
||||
this.logger.trace("Incoming OIDC groups: {}: {}", oidcUser.getEmail(), oidcGroups);
|
||||
|
||||
oidcGroups = this.filterGroups(oidcGroups);
|
||||
oidcGroups = this.translateGroups(oidcGroups);
|
||||
Set<String> translatedGroups = this.translateGroups(oidcGroups);
|
||||
|
||||
this.logger.debug("Filtered/translated OIDC groups: {}: {}", oidcUser.getEmail(), oidcGroups);
|
||||
this.logger.debug("Filtered/translated OIDC groups: {}: {}", oidcUser.getEmail(), translatedGroups);
|
||||
|
||||
long tenantId = this.tenantFinderService.findTenantId();
|
||||
|
||||
@@ -166,7 +166,7 @@ public class GroupSyncService {
|
||||
this.logger.trace("Inspecting APS group: {} => {} ({})", group.getId(), group.getName(), group.getExternalId());
|
||||
|
||||
if (group.getExternalId() != null) {
|
||||
String oidcGroup = this.apsGroupExternalIdToOidcGroup(group.getExternalId());
|
||||
String translatedGroup = this.apsGroupExternalIdToTranslatedOidcGroup(group.getExternalId());
|
||||
|
||||
if (this.retenantUntenantedGroups && group.getTenantId() == null) {
|
||||
this.logger.warn("Moving tenant-less APS group to tenant: {} => {}", group.getName(), tenantId);
|
||||
@@ -175,20 +175,20 @@ public class GroupSyncService {
|
||||
this.groupService.save(group);
|
||||
}
|
||||
|
||||
if (oidcGroups.remove(oidcGroup)) {
|
||||
this.logger.trace("User already belongs to APS group mapped to by OIDC group: {}: {} => {}", user.getExternalId(), oidcGroup, group.getName());
|
||||
if (translatedGroups.remove(translatedGroup)) {
|
||||
this.logger.trace("User already belongs to APS group mapped to by (translated) OIDC group: {}: {} => {}", user.getExternalId(), translatedGroup, group.getName());
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
String oidcGroup = this.apsGroupNameToOidcGroup(group.getName());
|
||||
String translatedGroup = this.apsGroupNameToTranslatedOidcGroup(group.getName());
|
||||
|
||||
if (oidcGroups.remove(oidcGroup)) {
|
||||
this.logger.trace("User already belongs to APS group mapped to by OIDC group: {}: {} => {}", user.getExternalId(), oidcGroup, group.getName());
|
||||
if (translatedGroups.remove(translatedGroup)) {
|
||||
this.logger.trace("User already belongs to APS group mapped to by (translated) OIDC group: {}: {} => {}", user.getExternalId(), translatedGroup, group.getName());
|
||||
|
||||
if (this.externalizeMatchingInternalGroups) {
|
||||
this.logger.warn("Classifying internal APS group as external: {} => {}", group.getName(), this.externalIdmSource);
|
||||
// register the group as external
|
||||
group.setExternalId(this.oidcGroupToApsGroupExternalId(oidcGroup));
|
||||
group.setExternalId(this.translatedOidcGroupToApsGroupExternalId(translatedGroup));
|
||||
group.setLastUpdate(new Date());
|
||||
this.groupService.save(group);
|
||||
// internal role already existed and the user is already a member
|
||||
@@ -212,21 +212,21 @@ public class GroupSyncService {
|
||||
}
|
||||
|
||||
// the user needs to be added to the remaining authorities
|
||||
for (String oidcGroup : oidcGroups) {
|
||||
this.logger.trace("Inspecting unaccounted for OIDC group: {}", oidcGroup);
|
||||
for (String translatedGroup : translatedGroups) {
|
||||
this.logger.trace("Inspecting unaccounted for (translated) OIDC group: {}", translatedGroup);
|
||||
|
||||
Group group;
|
||||
try {
|
||||
group = this.groupService.getGroupByExternalIdAndTenantId(this.oidcGroupToApsGroupExternalId(oidcGroup), tenantId);
|
||||
group = this.groupService.getGroupByExternalIdAndTenantId(this.translatedOidcGroupToApsGroupExternalId(translatedGroup), tenantId);
|
||||
} catch (NonUniqueResultException nure) {
|
||||
this.logger.warn("There are multiple groups matching the OIDC group for the external system: {} [{}]; skipping consideration of OIDC group", oidcGroup, this.externalIdmSource);
|
||||
this.logger.warn("There are multiple groups matching the (translated) OIDC group for the external system: {} [{}]; skipping consideration of OIDC group", translatedGroup, this.externalIdmSource);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (group == null && this.syncInternalGroups) {
|
||||
List<Group> groups = this.groupService.getGroupByNameAndTenantId(this.oidcGroupToApsGroupName(oidcGroup), tenantId);
|
||||
List<Group> groups = this.groupService.getGroupByNameAndTenantId(this.translatedOidcGroupToApsGroupName(translatedGroup), tenantId);
|
||||
if (groups.size() > 1) {
|
||||
this.logger.warn("There are multiple APS groups matching the OIDC group: {} [{}]; skipping consideration of OIDC group", oidcGroup, this.externalIdmSource);
|
||||
this.logger.warn("There are multiple APS groups matching the (translated) OIDC group: {} [{}]; skipping consideration of OIDC group", translatedGroup, this.externalIdmSource);
|
||||
continue;
|
||||
} else if (groups.size() == 1) {
|
||||
group = groups.iterator().next();
|
||||
@@ -234,7 +234,7 @@ public class GroupSyncService {
|
||||
if (this.externalizeMatchingInternalGroups) {
|
||||
this.logger.debug("Found an internal APS group; registering as external: {}", group.getName());
|
||||
|
||||
group.setExternalId(this.oidcGroupToApsGroupExternalId(oidcGroup));
|
||||
group.setExternalId(this.translatedOidcGroupToApsGroupExternalId(translatedGroup));
|
||||
group.setLastSyncTimeStamp(new Date());
|
||||
group.setLastUpdate(new Date());
|
||||
this.groupService.save(group);
|
||||
@@ -244,11 +244,11 @@ public class GroupSyncService {
|
||||
|
||||
if (group == null) {
|
||||
if (!this.createMissing) {
|
||||
this.logger.debug("APS Group does not exist for OIDC group; APS group creation is disabled; OIDC group will go unrecognized: {}", oidcGroup);
|
||||
this.logger.debug("APS Group does not exist for (translated) OIDC group; APS group creation is disabled; OIDC group will go unrecognized: {}", translatedGroup);
|
||||
continue;
|
||||
}
|
||||
|
||||
group = this.createApsGroup(oidcGroup, tenantId);
|
||||
group = this.createApsGroup(translatedGroup, tenantId);
|
||||
}
|
||||
|
||||
if (this.syncAdditions) {
|
||||
@@ -261,13 +261,13 @@ public class GroupSyncService {
|
||||
}
|
||||
}
|
||||
|
||||
protected Group createApsGroup(String oidcGroup, long tenantId) {
|
||||
this.logger.debug("APS Group does not exist for OIDC group; will attempt to create: {}", oidcGroup);
|
||||
String name = this.oidcGroupToApsGroupName(oidcGroup);
|
||||
String externalId = this.oidcGroupToApsGroupExternalId(oidcGroup);
|
||||
protected Group createApsGroup(String translatedGroup, long tenantId) {
|
||||
this.logger.debug("APS Group does not exist for (translated) OIDC group; will attempt to create: {}", translatedGroup);
|
||||
String name = this.translatedOidcGroupToApsGroupName(translatedGroup);
|
||||
String externalId = this.translatedOidcGroupToApsGroupExternalId(translatedGroup);
|
||||
|
||||
boolean syncAsOrg = this.isOidcGroupToBeOrganization(oidcGroup);
|
||||
this.logger.trace("Creating new APS group as {}: {}", syncAsOrg ? "organization" : "capability", oidcGroup);
|
||||
boolean syncAsOrg = this.isTranslatedOidcGroupToBeOrganization(translatedGroup);
|
||||
this.logger.trace("Creating new APS group as {}: {}", syncAsOrg ? "organization" : "capability", translatedGroup);
|
||||
int type = syncAsOrg ? Group.TYPE_FUNCTIONAL_GROUP : Group.TYPE_SYSTEM_GROUP;
|
||||
|
||||
Group apsGroup = this.groupService.createGroupFromExternalStore(name, tenantId, type, null, externalId, new Date());
|
||||
@@ -331,29 +331,29 @@ public class GroupSyncService {
|
||||
return translatedGroups;
|
||||
}
|
||||
|
||||
private String oidcGroupToApsGroupExternalId(String group) {
|
||||
private String translatedOidcGroupToApsGroupExternalId(String group) {
|
||||
return this.externalIdmSource + "_" + group;
|
||||
}
|
||||
|
||||
private String apsGroupExternalIdToOidcGroup(String externalId) {
|
||||
private String apsGroupExternalIdToTranslatedOidcGroup(String externalId) {
|
||||
int underscorePos = externalId.indexOf('_');
|
||||
return underscorePos < 0 ? externalId : externalId.substring(underscorePos + 1);
|
||||
}
|
||||
|
||||
private String oidcGroupToApsGroupName(String group) {
|
||||
private String translatedOidcGroupToApsGroupName(String group) {
|
||||
return group;
|
||||
}
|
||||
|
||||
private String apsGroupNameToOidcGroup(String externalId) {
|
||||
private String apsGroupNameToTranslatedOidcGroup(String externalId) {
|
||||
return externalId;
|
||||
}
|
||||
|
||||
private boolean isOidcGroupToBeOrganization(String role) {
|
||||
private boolean isTranslatedOidcGroupToBeOrganization(String translatedGroup) {
|
||||
if (this.capabilities.isEmpty())
|
||||
return true;
|
||||
|
||||
for (Pattern regex : this.capabilities) {
|
||||
Matcher matcher = regex.matcher(role);
|
||||
Matcher matcher = regex.matcher(translatedGroup);
|
||||
if (matcher.matches())
|
||||
return false;
|
||||
}
|
||||
|
@@ -42,7 +42,7 @@ public class UserSyncService {
|
||||
@Value("${auth-ext.sync.user.createMissing:true}")
|
||||
protected boolean createMissingUser;
|
||||
|
||||
@Value("${auth-ext.sync.user.requireGroup:#{null}}")
|
||||
@Value("${auth-ext.sync.user.requireOidcGroup:#{null}}")
|
||||
protected String requiredGroup;
|
||||
|
||||
@Value("${auth-ext.sync.user.clearNewUserGroups:true}")
|
||||
|
Reference in New Issue
Block a user