Commit 84d1b4ea authored by Brian Long's avatar Brian Long
Browse files

clearer/property variable naming and ordering

parent 187e5581
Loading
Loading
Loading
Loading
+17 −17
Original line number Diff line number Diff line
@@ -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
@@ -69,9 +69,9 @@ 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.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. |
@@ -79,11 +79,11 @@ The following properties provide the core functionality of this extension. That
| `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). |
| `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

+30 −30
Original line number Diff line number Diff line
@@ -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;
        }
+1 −1
Original line number Diff line number Diff line
@@ -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}")