001/**
002 * Copyright 2005-2015 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.kim.ldap;
017
018import static java.util.Arrays.asList;
019import static org.kuali.rice.core.util.BufferedLogger.debug;
020
021import java.util.List;
022import java.util.regex.Matcher;
023import java.util.regex.Pattern;
024
025import org.apache.commons.lang.StringUtils;
026import org.kuali.rice.coreservice.framework.parameter.ParameterService;
027import org.kuali.rice.kim.api.identity.principal.Principal;
028import org.springframework.ldap.core.DirContextOperations;
029
030/**
031 * 
032 */
033public class PrincipalMapper extends BaseMapper<Principal> {
034    private ParameterService parameterService;
035    
036    @Override
037    Principal mapDtoFromContext(DirContextOperations context) {
038        Principal.Builder builder = mapBuilderFromContext(context);
039        return builder != null ? builder.build() : null;
040    }
041
042    Principal.Builder mapBuilderFromContext(DirContextOperations context) {
043        final String entityId      = context.getStringAttribute(getConstants().getKimLdapIdProperty());
044        final String principalName = context.getStringAttribute(getConstants().getKimLdapNameProperty());
045        final Principal.Builder person = Principal.Builder.create(principalName);
046        
047        if (entityId == null) {
048            throw new InvalidLdapEntityException("LDAP Search Results yielded an invalid result with attributes " 
049                                                 + context.getAttributes());
050        }
051        
052        person.setPrincipalId(entityId);
053        person.setEntityId(entityId);
054        person.setActive(isPersonActive(context));
055
056        return person;
057    }
058    
059     /**
060     * 
061     * Checks the configured active principal affiliations, if one is found, returns true
062     * @param context
063     * @return true if a matching active affiliation is found
064     */
065    protected boolean isPersonActive(DirContextOperations context) {
066        String[] affils = context.getStringAttributes(getConstants().getAffiliationLdapProperty());
067        Object edsVal = getLdapValue("principals.active.Y");
068        if (affils != null && affils.length > 0
069                && edsVal != null) {
070            if (edsVal instanceof List) {
071                List<String> edsValLst = (List<String>)edsVal;
072                for (String affil : affils) {
073                    if (edsValLst.contains(affil)) {
074                        return true;
075                    }
076                }
077            } else {
078                String edsValStr = (String)edsVal;
079                for (String affil : affils) {
080                    if (StringUtils.equals(affil, edsValStr)) {
081                        return true;
082                    }
083                }
084            }
085        }
086        return false;
087    }
088
089    protected Object getLdapValue(String kimAttribute) {
090        Matcher matcher = getKimAttributeMatcher(kimAttribute);
091        debug("Does ", kimAttribute, " match? ", matcher.matches());
092        if (!matcher.matches()) {
093            return null;
094        }
095        String value = matcher.group(2);
096
097        // If it's actually a list. It can only be a list if there are commas
098        if (value.contains(",")) {
099            return asList(value.split(","));
100        }
101
102        return value;
103    }
104
105    protected Matcher getKimAttributeMatcher(String kimAttribute) {
106        String mappedParamValue = getParameterService().getParameterValueAsString(getConstants().getParameterNamespaceCode(),
107                                                                        getConstants().getParameterDetailTypeCode(),
108                                                                        getConstants().getMappedParameterName());
109
110        String regexStr = String.format("(%s|.*;%s)=([^=;]*).*", kimAttribute, kimAttribute);
111        debug("Matching KIM attribute with regex ", regexStr);
112        Matcher retval = Pattern.compile(regexStr).matcher(mappedParamValue);
113        
114        if (!retval.matches()) {
115            mappedParamValue = getParameterService().getParameterValueAsString(getConstants().getParameterNamespaceCode(),
116                                                                  getConstants().getParameterDetailTypeCode(),
117                                                                  getConstants().getMappedValuesName());
118            retval = Pattern.compile(regexStr).matcher(mappedParamValue);
119        }
120
121        return retval;
122    }
123
124
125    public ParameterService getParameterService() {
126        return this.parameterService;
127    }
128
129    public void setParameterService(ParameterService service) {
130        this.parameterService = service;
131    }
132}