clearer/property variable naming and ordering

This commit is contained in:
2025-05-07 09:17:27 -04:00
parent 187e558177
commit 84d1b4ea2f
3 changed files with 48 additions and 48 deletions

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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}")