allowing for more dynamic organization/capability sync control
This commit is contained in:
@@ -42,8 +42,8 @@ The library is highly configurable. You configure it with properties specified
|
||||
### For Activiti App Only
|
||||
|
||||
| Property | Default | Description |
|
||||
| ----------------------------------------- | -------------- | ----------- |
|
||||
| `keycloak-ext.syncGroupAs` | `organization` | When creating a new group, should it be a functional (`organization`) group or a system (`capability`) group? |
|
||||
| ------------------------------------------------ | ------- | ----------- |
|
||||
| `keycloak-ext.group.organization.regex.patterns` | `.*` | When creating a new group, sync as APS Organization (functional group) when the role matches the specified regular expression. If it doesn't, add as APS Capability (system group). |
|
||||
| `keycloak-ext.external.id` | `ais` | When creating a new group or registering an internal group as external, use this ID as a prefix to the external group ID. |
|
||||
|
||||
### Rare
|
||||
|
2
pom.xml
2
pom.xml
@@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.inteligr8.activiti</groupId>
|
||||
<artifactId>keycloak-activiti-app-ext</artifactId>
|
||||
<version>1.2-SNAPSHOT</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<name>Keycloak Authentication & Authorization for APS</name>
|
||||
|
||||
<properties>
|
||||
|
@@ -12,6 +12,8 @@ import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.annotation.OverridingMethodsMustInvokeSuper;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.keycloak.KeycloakPrincipal;
|
||||
import org.keycloak.KeycloakSecurityContext;
|
||||
@@ -71,6 +73,7 @@ public abstract class AbstractKeycloakActivitiAuthenticator implements Authentic
|
||||
protected final Set<Pattern> groupExcludes = new HashSet<>();
|
||||
|
||||
@Override
|
||||
@OverridingMethodsMustInvokeSuper
|
||||
public void afterPropertiesSet() {
|
||||
if (this.regexPatterns != null) {
|
||||
String[] regexPatternStrs = StringUtils.split(this.regexPatterns, ',');
|
||||
|
@@ -1,12 +1,15 @@
|
||||
package com.inteligr8.activiti.keycloak;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.annotation.OverridingMethodsMustInvokeSuper;
|
||||
import javax.persistence.NonUniqueResultException;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@@ -59,15 +62,21 @@ public class KeycloakActivitiAppAuthenticator extends AbstractKeycloakActivitiAu
|
||||
@Value("${keycloak-ext.external.id:ais}")
|
||||
protected String externalIdmSource;
|
||||
|
||||
@Value("${keycloak-ext.syncGroupAs:organization}")
|
||||
protected String syncGroupAs;
|
||||
@Value("${keycloak-ext.group.organization.regex.patterns:.*}")
|
||||
protected String regexOrgIncludes;
|
||||
|
||||
protected boolean syncGroupAsOrganization() {
|
||||
return !this.syncGroupAsCapability();
|
||||
protected final Set<Pattern> orgIncludes = new HashSet<>();
|
||||
|
||||
@Override
|
||||
@OverridingMethodsMustInvokeSuper
|
||||
public void afterPropertiesSet() {
|
||||
super.afterPropertiesSet();
|
||||
|
||||
if (this.regexOrgIncludes != null) {
|
||||
String[] regexPatternStrs = StringUtils.split(this.regexOrgIncludes, ',');
|
||||
for (int i = 0; i < regexPatternStrs.length; i++)
|
||||
this.orgIncludes.add(Pattern.compile(regexPatternStrs[i]));
|
||||
}
|
||||
|
||||
protected boolean syncGroupAsCapability() {
|
||||
return this.syncGroupAs != null && this.syncGroupAs.toLowerCase().startsWith("cap");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,8 +172,6 @@ public class KeycloakActivitiAppAuthenticator extends AbstractKeycloakActivitiAu
|
||||
return;
|
||||
}
|
||||
|
||||
boolean syncAsOrg = this.syncGroupAsOrganization();
|
||||
|
||||
// check Activiti groups
|
||||
User userWithGroups = this.userService.getUser(user.getId(), true);
|
||||
for (Group group : userWithGroups.getGroups()) {
|
||||
@@ -228,6 +235,8 @@ public class KeycloakActivitiAppAuthenticator extends AbstractKeycloakActivitiAu
|
||||
if (group == null) {
|
||||
if (this.createMissingGroup) {
|
||||
this.logger.trace("Creating new group for role: {}", role);
|
||||
boolean syncAsOrg = this.isRoleToBeOrganization(role.getKey());
|
||||
this.logger.trace("Creating new group as {}: {}", syncAsOrg ? "organization" : "capability", role);
|
||||
String name = this.keycloakRoleToApsGroupName(role.getValue());
|
||||
String externalId = this.keycloakRoleToApsGroupExternalId(role.getKey());
|
||||
int type = syncAsOrg ? Group.TYPE_FUNCTIONAL_GROUP : Group.TYPE_SYSTEM_GROUP;
|
||||
@@ -264,4 +273,17 @@ public class KeycloakActivitiAppAuthenticator extends AbstractKeycloakActivitiAu
|
||||
return externalId;
|
||||
}
|
||||
|
||||
private boolean isRoleToBeOrganization(String role) {
|
||||
if (this.orgIncludes.isEmpty())
|
||||
return false;
|
||||
|
||||
for (Pattern regex : this.orgIncludes) {
|
||||
Matcher matcher = regex.matcher(role);
|
||||
if (matcher.matches())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user