Commit 03c6e5aa authored by Brian Long's avatar Brian Long
Browse files

refactored group management/validation

parent 34feb28a
Loading
Loading
Loading
Loading
+56 −0
Original line number Diff line number Diff line
package com.inteligr8.activiti;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;
@@ -15,7 +19,9 @@ import org.springframework.stereotype.Component;
import com.activiti.api.security.AlfrescoSecurityConfigOverride;
import com.activiti.domain.idm.Group;
import com.activiti.domain.idm.Tenant;
import com.activiti.domain.idm.User;
import com.activiti.service.api.GroupService;
import com.activiti.service.api.UserService;
import com.activiti.service.idm.TenantService;
import com.activiti.service.license.LicenseService;

@@ -44,9 +50,18 @@ public class Inteligr8SecurityConfigurationRegistry implements AlfrescoSecurityC
    @Autowired(required = false)
    private TenantService tenantService;
    
    @Autowired(required = false)
    private UserService userService;
    
    @Autowired(required = false)
    private GroupService groupService;
    
    @Value("${keycloak-ext.default.admins.users:#{null}}")
    private String adminUserStrs;
    
    @Value("${keycloak-ext.group.admins.validate:false}")
    private boolean validateAdministratorsGroup;
	
	@Override
	public void configureGlobal(AuthenticationManagerBuilder authmanBuilder, UserDetailsService userDetailsService) {
		this.logger.trace("configureGlobal()");
@@ -55,6 +70,10 @@ public class Inteligr8SecurityConfigurationRegistry implements AlfrescoSecurityC
		
		if (this.logger.isTraceEnabled())
			this.logGroups();
		if (this.validateAdministratorsGroup)
			this.validateAdmins();
    	if (this.adminUserStrs != null && this.adminUserStrs.length() > 0)
    		this.associateAdmins();
		
		for (ActivitiSecurityConfigAdapter adapter : this.adapters) {
			if (adapter.isEnabled()) {
@@ -68,6 +87,9 @@ public class Inteligr8SecurityConfigurationRegistry implements AlfrescoSecurityC
	}
	
	private void logGroups() {
		if (this.groupService == null)
			return;
		
		Long tenantId = this.findDefaultTenantId();
		if (tenantId != null) {
			// not first boot
@@ -76,6 +98,40 @@ public class Inteligr8SecurityConfigurationRegistry implements AlfrescoSecurityC
		}
	}
	
	private void validateAdmins() {
		if (this.groupService == null)
			return;
		
    	Long tenantId = this.findDefaultTenantId();
		List<Group> groups = this.groupService.getSystemGroupWithName("Administrators", tenantId);
		if (groups.isEmpty())
			groups = Arrays.asList(this.groupService.createGroup("Administrators", tenantId, Group.TYPE_SYSTEM_GROUP, null));
		
		this.logger.info("Validating 'Administrators' group ...");
		for (Group group : groups)
			this.groupService.addCapabilitiesToGroup(group.getId(), Arrays.asList("access-all-models-in-tenant", "access-editor", "access-reports", "publish-app-to-dashboard", "tenant-admin", "tenant-admin-api", "upload-license"));
	}
	
	private void associateAdmins() {
		if (this.userService == null || this.groupService == null)
			return;
		
		List<String> adminUsers = Arrays.asList(this.adminUserStrs.split(","));
		if (adminUsers.isEmpty())
			return;
		
    	Long tenantId = this.findDefaultTenantId();
		List<Group> groups = this.groupService.getSystemGroupWithName("Administrators", tenantId);
		
		for (String email : adminUsers) {
    		User user = this.userService.findUserByEmail(email);

    		this.logger.debug("Adding {} to {}", user.getEmail(), "Administrators");
    		for (Group group : groups)
    			this.groupService.addUserToGroup(group, user);
		}
	}
    
    private Long findDefaultTenantId() {
    	String defaultTenantName = this.licenseService.getDefaultTenantName();
		this.logger.trace("Default Tenant: {}", defaultTenantName);
+0 −8
Original line number Diff line number Diff line
package com.inteligr8.activiti.keycloak;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@@ -62,14 +61,10 @@ public abstract class AbstractKeycloakActivitiAuthenticator implements Authentic
    @Value("${keycloak-ext.group.exclude.regex.patterns:#{null}}")
    protected String regexExcludes;
    
    @Value("${keycloak-ext.default.admins.users:#{null}}")
    private String adminUserStrs;
    
    protected final List<Pair<Pattern, String>> groupFormatters = new LinkedList<>();
    protected final Set<Pattern> resourceIncludes = new HashSet<>();
    protected final Set<Pattern> groupIncludes = new HashSet<>();
    protected final Set<Pattern> groupExcludes = new HashSet<>();
    protected final Set<String> adminUsers = new HashSet<>();
    
    @Override
    public void afterPropertiesSet() {
@@ -100,9 +95,6 @@ public abstract class AbstractKeycloakActivitiAuthenticator implements Authentic
    		for (int i = 0; i < regexPatternStrs.length; i++)
    			this.groupExcludes.add(Pattern.compile(regexPatternStrs[i]));
    	}
    	
    	if (this.adminUserStrs != null && this.adminUserStrs.length() > 0)
    		this.adminUsers.addAll(Arrays.asList(this.adminUserStrs.split(",")));
    }
    

+0 −29
Original line number Diff line number Diff line
package com.inteligr8.activiti.keycloak;

import java.util.Arrays;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
@@ -16,7 +15,6 @@ import org.keycloak.representations.AccessToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
@@ -64,33 +62,6 @@ public class KeycloakActivitiAppAuthenticator extends AbstractKeycloakActivitiAu
    @Autowired
    private GroupService groupService;
    
    @Value("${keycloak-ext.group.admins.validate:false}")
    private boolean validateAdministratorsGroup;
    
    @Override
    public void afterPropertiesSet() {
    	super.afterPropertiesSet();

    	if (!this.adminUsers.isEmpty()) {
	    	Long tenantId = this.findDefaultTenantId();
			List<Group> groups = this.groupService.getSystemGroupWithName("Administrators", tenantId);
			
    		if (this.validateAdministratorsGroup) {
				this.logger.info("Validating 'Administrators' group ...");
				for (Group group : groups)
					this.groupService.addCapabilitiesToGroup(group.getId(), Arrays.asList("access-all-models-in-tenant", "access-editor", "access-reports", "publish-app-to-dashboard", "tenant-admin", "tenant-admin-api", "upload-license"));
    		}
			
    		for (String email : this.adminUsers) {
	    		User user = this.userService.findUserByEmail(email);

	    		this.logger.debug("Adding {} to {}", user.getEmail(), "Administrators");
	    		for (Group group : groups)
	    			this.groupService.addUserToGroup(group, user);
    		}
    	}
    }
    
    /**
     * This method validates that the user exists, if not, it creates the
     * missing user.  Without this functionality, SSO straight up fails in APS.