org.broadleafcommerce.openadmin.server.security.service.AdminUserProvisioningServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.broadleafcommerce.openadmin.server.security.service.AdminUserProvisioningServiceImpl.java

Source

/*
 * #%L
 * BroadleafCommerce Open Admin Platform
 * %%
 * Copyright (C) 2009 - 2013 Broadleaf Commerce
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
package org.broadleafcommerce.openadmin.server.security.service;

import org.apache.commons.lang.StringUtils;
import org.broadleafcommerce.common.security.BroadleafExternalAuthenticationUserDetails;
import org.broadleafcommerce.openadmin.server.security.domain.AdminPermission;
import org.broadleafcommerce.openadmin.server.security.domain.AdminRole;
import org.broadleafcommerce.openadmin.server.security.domain.AdminUser;
import org.broadleafcommerce.openadmin.server.security.domain.AdminUserImpl;
import org.broadleafcommerce.openadmin.server.security.external.AdminExternalLoginUserExtensionManager;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

/**
 * This component allows for the default provisioning of an AdminUser and roles in the Broadleaf database, based on the 
 * external authentication of a user (e.g. LDAP or custom external authentication provider).
 * 
 * @author Kelly Tisdell
 *
 */
@Service("blAdminUserProvisioningService")
public class AdminUserProvisioningServiceImpl implements AdminUserProvisioningService {

    @Resource(name = "blAdminSecurityService")
    protected AdminSecurityService securityService;

    @Resource(name = "blAdminExternalLoginExtensionManager")
    protected AdminExternalLoginUserExtensionManager adminExternalLoginExtensionManager;

    protected Map<String, String[]> roleNameSubstitutions;

    @Override
    public AdminUserDetails provisionAdminUser(BroadleafExternalAuthenticationUserDetails details) {
        HashSet<String> newRoles = new HashSet<String>();

        if (roleNameSubstitutions != null && !roleNameSubstitutions.isEmpty()) {
            for (GrantedAuthority authority : details.getAuthorities()) {
                if (roleNameSubstitutions.containsKey(authority.getAuthority())) {
                    String[] roles = roleNameSubstitutions.get(authority.getAuthority());
                    for (String role : roles) {
                        newRoles.add(role.trim());
                    }
                } else {
                    newRoles.add(authority.getAuthority());
                }
            }
        } else {
            for (GrantedAuthority authority : details.getAuthorities()) {
                newRoles.add(authority.getAuthority());
            }
        }

        HashSet<GrantedAuthority> newAuthorities = new HashSet<GrantedAuthority>();
        for (String perm : AdminSecurityService.DEFAULT_PERMISSIONS) {
            newAuthorities.add(new SimpleGrantedAuthority(perm));
        }

        HashSet<AdminRole> grantedRoles = new HashSet<AdminRole>();
        List<AdminRole> adminRoles = securityService.readAllAdminRoles();
        if (adminRoles != null) {
            for (AdminRole role : adminRoles) {
                if (newRoles.contains(role.getName())) {
                    grantedRoles.add(role);
                    Set<AdminPermission> permissions = role.getAllPermissions();
                    if (permissions != null && !permissions.isEmpty()) {
                        for (AdminPermission permission : permissions) {
                            if (permission.isFriendly()) {
                                for (AdminPermission childPermission : permission.getAllChildPermissions()) {
                                    newAuthorities.add(new SimpleGrantedAuthority(childPermission.getName()));
                                }
                            } else {
                                newAuthorities.add(new SimpleGrantedAuthority(permission.getName()));
                            }
                        }
                    }
                }
            }
        }

        AdminUser adminUser = securityService.readAdminUserByUserName(details.getUsername());
        if (adminUser == null) {
            adminUser = new AdminUserImpl();
            adminUser.setLogin(details.getUsername());
        }

        if (StringUtils.isNotBlank(details.getEmail())) {
            adminUser.setEmail(details.getEmail());
        }

        StringBuilder name = new StringBuilder();
        if (StringUtils.isNotBlank(details.getFirstName())) {
            name.append(details.getFirstName()).append(" ");
        }
        if (StringUtils.isNotBlank(details.getLastName())) {
            name.append(details.getLastName());
        }

        String fullName = name.toString();
        if (StringUtils.isNotBlank(fullName)) {
            adminUser.setName(fullName);
        } else {
            adminUser.setName(details.getUsername());
        }

        //We have to do this because BLC replies on the role relationships being stored in the DB
        Set<AdminRole> roleSet = adminUser.getAllRoles();
        //First, remove all roles associated with the user if they already existed
        if (roleSet != null) {
            //First, remove all role relationships in case they have changed
            roleSet.clear();
        } else {
            roleSet = new HashSet<AdminRole>();
            adminUser.setAllRoles(roleSet);
        }

        //Now, add all of the role relationships back.
        if (adminRoles != null) {
            for (AdminRole role : adminRoles) {
                roleSet.add(role);
            }
        }

        //Add optional support for things like Multi-Tenant, etc...
        adminExternalLoginExtensionManager.getProxy().performAdditionalAuthenticationTasks(adminUser, details);

        //Save the user data and all of the roles...
        adminUser = securityService.saveAdminUser(adminUser);

        return new AdminUserDetails(adminUser.getId(), details.getUsername(), "", true, true, true, true,
                newAuthorities);
    }

    /**
     * This allows you to declaratively set a map containing values that will substitute role names from LDAP to Broadleaf roles names in cases that they might be different.
     * For example, if you have a role specified in LDAP under "memberOf" with a DN of "Marketing Administrator", you might want to
     * map that to the role "ADMIN".  By default the prefix "ROLE_" will be pre-pended to this name. So to configure this, you would specify:
     *
     * <bean class="org.broadleaf.loadtest.web.security.ActiveDirectoryUserDetailsContextMapper">
     *     <property name="roleMappings">
     *         <map>
     *             <entry key="Marketing_Administrator" value="ROLE_CATALOG_ADMIN"/>
     *         </map>
     *     </property>
     * </bean>
     *
     * With this configuration, all roles returned by LDAP that have a DN of "Marketing Administrator" will be converted to "ADMIN"
     * @param roleNameSubstitutions
     */
    public void setRoleNameSubstitutions(Map<String, String[]> roleNameSubstitutions) {
        this.roleNameSubstitutions = roleNameSubstitutions;
    }
}