001/*
002 * Copyright 2009 The Kuali Foundation.
003 * 
004 * Licensed under the Educational Community License, Version 1.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/ecl1.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.ole.sec.service.impl;
017
018import java.util.Map;
019
020import org.apache.commons.lang.StringUtils;
021import org.kuali.ole.sec.SecConstants;
022import org.kuali.ole.sec.service.AccessPermissionEvaluator;
023import org.kuali.rice.kim.api.identity.Person;
024
025
026/**
027 * @see org.kuali.ole.sec.service.AccessPermissionEvaluator
028 */
029public class AccessPermissionEvaluatorImpl implements AccessPermissionEvaluator {
030    private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AccessPermissionEvaluatorImpl.class);
031
032    protected String constraintCode;
033    protected String operatorCode;
034    protected String propertyValue;
035    protected Map<String, Object> otherKeyFieldValues;
036    protected Person person;
037    protected String[] matchValues;
038    protected boolean performEqualMatch;
039    protected boolean performLessThanMatch;
040    protected boolean performGreaterThanMatch;
041    protected boolean allowConstraint;
042    protected boolean notOperator;
043
044    public AccessPermissionEvaluatorImpl() {
045        super();
046
047        performEqualMatch = false;
048        performLessThanMatch = false;
049        performGreaterThanMatch = false;
050        allowConstraint = false;
051        notOperator = false;
052    }
053
054    /**
055     * @see org.kuali.ole.sec.service.AccessPermissionEvaluator#valueIsAllowed(java.lang.String)
056     */
057    public boolean valueIsAllowed(String value) {
058        boolean allowed = false;
059
060        initializeAfterPropsSet();
061
062        boolean match = false;
063        for (int i = 0; i < matchValues.length; i++) {
064            String matchValue = matchValues[i];
065
066            if (isMatch(matchValue, value)) {
067                match = true;
068                break;
069            }
070        }
071
072        if ((allowConstraint && notOperator) || (!allowConstraint && !notOperator)) {
073            allowed = !match;
074        }
075        else {
076            allowed = match;
077        }
078
079        return allowed;
080    }
081
082    /**
083     * Determines whether two values match performing an equal, greater than, or less than check and also considering wildcards
084     * 
085     * @param matchValue String value to match, can contain the * wildcard
086     * @param value String value to compare
087     * @return boolean true if values match, false otherwise
088     */
089    protected boolean isMatch(String matchValue, String value) {
090        boolean match = false;
091
092        boolean performWildcardMatch = false;
093        if (StringUtils.contains(matchValue, SecConstants.SecurityValueSpecialCharacters.WILDCARD_CHARACTER)) {
094            matchValue = StringUtils.remove(matchValue, SecConstants.SecurityValueSpecialCharacters.WILDCARD_CHARACTER);
095            performWildcardMatch = true;
096        }
097
098        if (performEqualMatch) {
099            if (performWildcardMatch) {
100                match = value.startsWith(matchValue);
101            }
102            else {
103                match = value.equals(matchValue);
104            }
105        }
106
107        if (!match && performLessThanMatch) {
108            match = value.compareTo(matchValue) < 0;
109        }
110
111        if (!match && performGreaterThanMatch) {
112            match = value.compareTo(matchValue) > 0;
113        }
114
115        return match;
116    }
117
118    /**
119     * Hooks for permission evaluators to do additional setup after properties have been set
120     */
121    protected void initializeAfterPropsSet() {
122        if (StringUtils.contains(constraintCode, SecConstants.SecurityConstraintCodes.ALLOWED)) {
123            allowConstraint = true;
124        }
125
126        if (SecConstants.SecurityDefinitionOperatorCodes.EQUAL.equals(operatorCode) || SecConstants.SecurityDefinitionOperatorCodes.NOT_EQUAL.equals(operatorCode) || SecConstants.SecurityDefinitionOperatorCodes.LESS_THAN_EQUAL.equals(operatorCode)
127                || SecConstants.SecurityDefinitionOperatorCodes.GREATER_THAN_EQUAL.equals(operatorCode)) {
128            performEqualMatch = true;
129        }
130
131        if (SecConstants.SecurityDefinitionOperatorCodes.LESS_THAN.equals(operatorCode) || SecConstants.SecurityDefinitionOperatorCodes.LESS_THAN_EQUAL.equals(operatorCode)) {
132            performLessThanMatch = true;
133        }
134
135        if (SecConstants.SecurityDefinitionOperatorCodes.GREATER_THAN.equals(operatorCode) || SecConstants.SecurityDefinitionOperatorCodes.GREATER_THAN_EQUAL.equals(operatorCode)) {
136            performGreaterThanMatch = true;
137        }
138        
139        if (SecConstants.SecurityDefinitionOperatorCodes.NOT_EQUAL.equals(operatorCode)) {
140            notOperator = true;
141        }
142
143        setMatchValues();
144    }
145
146    /**
147     * Sets the values to match on based on given value and other properties
148     */
149    protected void setMatchValues() {
150        if (StringUtils.contains(propertyValue, SecConstants.SecurityValueSpecialCharacters.MULTI_VALUE_SEPERATION_CHARACTER)) {
151            matchValues = StringUtils.split(propertyValue, SecConstants.SecurityValueSpecialCharacters.MULTI_VALUE_SEPERATION_CHARACTER);
152        }
153        else {
154            matchValues = new String[1];
155            matchValues[0] = propertyValue;
156        }
157    }
158
159    /**
160     * @see org.kuali.ole.sec.service.AccessPermissionEvaluator#setConstraintCode(java.lang.String)
161     */
162    public void setConstraintCode(String constraintCode) {
163        this.constraintCode = constraintCode;
164    }
165
166    /**
167     * @see org.kuali.ole.sec.service.AccessPermissionEvaluator#setOperatorCode(java.lang.String)
168     */
169    public void setOperatorCode(String operatorCode) {
170        this.operatorCode = operatorCode;
171    }
172
173    /**
174     * @see org.kuali.ole.sec.service.AccessPermissionEvaluator#setPropertyValue(java.lang.String)
175     */
176    public void setPropertyValue(String propertyValue) {
177        this.propertyValue = propertyValue;
178    }
179
180    /**
181     * @see org.kuali.ole.sec.service.AccessPermissionEvaluator#setOtherKeyFieldValueMap(java.util.Map)
182     */
183    public void setOtherKeyFieldValueMap(Map<String, Object> otherKeyFieldValues) {
184        this.otherKeyFieldValues = otherKeyFieldValues;
185    }
186
187    /**
188     * @see org.kuali.ole.sec.service.AccessPermissionEvaluator#setPerson(org.kuali.rice.kim.api.identity.Person)
189     */
190    public void setPerson(Person person) {
191        this.person = person;
192    }
193
194}