View Javadoc
1   /**
2    * Copyright 2014 Internet2
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package edu.internet2.middleware.grouper.permissions.limits.impl;
17  
18  import java.util.Date;
19  import java.util.Map;
20  import java.util.Set;
21  
22  import org.apache.commons.lang.StringUtils;
23  import org.apache.commons.logging.Log;
24  
25  import edu.internet2.middleware.grouper.attr.assign.AttributeAssign;
26  import edu.internet2.middleware.grouper.attr.value.AttributeAssignValue;
27  import edu.internet2.middleware.grouper.permissions.PermissionEntry;
28  import edu.internet2.middleware.grouper.permissions.limits.LimitElUtils;
29  import edu.internet2.middleware.grouper.permissions.limits.PermissionLimitBase;
30  import edu.internet2.middleware.grouper.permissions.limits.PermissionLimitBean;
31  import edu.internet2.middleware.grouper.permissions.limits.PermissionLimitDocumentation;
32  import edu.internet2.middleware.grouper.permissions.limits.PermissionLimitInterface;
33  import edu.internet2.middleware.grouper.permissions.limits.PermissionLimitUtils;
34  import edu.internet2.middleware.grouper.util.GrouperUtil;
35  
36  /**
37   * logic for the built in EL limit
38   * @author mchyzer
39   */
40  public class PermissionLimitElLogic extends PermissionLimitBase {
41  
42    /** if you are testing this, set it, otherwise, it will default */
43    public static Integer testingCacheMinutesInt = null;
44    
45    /** count how many times called logic for testing the cache */
46    public static int testingTimesCalledLogic = 0;
47  
48    /**
49     * @see PermissionLimitInterface#cacheLimitValueResultMinutes()
50     */
51    @Override
52    public int cacheLimitValueResultMinutes() {
53      return testingCacheMinutesInt == null ? super.cacheLimitValueResultMinutes() : testingCacheMinutesInt;
54    }
55  
56    /** logger */
57    private static final Log LOG = GrouperUtil.getLog(PermissionLimitElLogic.class);
58  
59    /**
60     * @see PermissionLimitInterface#allowPermission(PermissionEntry, AttributeAssign, Set, Map, Set)
61     */
62    public boolean allowPermission(PermissionEntry permissionEntry,
63        AttributeAssign limitAssignment, Set<AttributeAssignValue> limitAssignmentValues,
64        Map<String, Object> limitEnvVars, Set<PermissionLimitBean> permissionLimitBeans) {
65      
66      testingTimesCalledLogic++;
67      
68      boolean foundError = false;
69      String result = null;
70      RuntimeException theException = null;
71      try {
72      
73        String attributeDefNameName = limitAssignment.getAttributeDefName().getName();
74        
75        String expression = null;
76        if (GrouperUtil.length(limitAssignmentValues) == 1) {
77          expression = limitAssignmentValues.iterator().next().getValueString();
78          expression = StringUtils.trimToEmpty(expression);
79        }
80        
81        //this should have 1 string value
82        if (GrouperUtil.length(limitAssignmentValues) != 1 || StringUtils.isBlank(expression)) {
83          throw new RuntimeException(attributeDefNameName + " must have 1 string value: " + GrouperUtil.length(limitAssignmentValues) + 
84          ", limitAssignId: " + limitAssignment.getId());
85        }
86        
87        //add the curlies around if it not already there
88        if (!expression.startsWith("${") && !expression.endsWith("}")) {
89          expression = "${" + expression + "}";
90        }
91        
92        limitEnvVars.put("limitElUtils", new LimitElUtils());
93        
94        limitEnvVars.put("limitAssignmentId", limitAssignment.getId());
95        limitEnvVars.put("permissionAction", permissionEntry.getAction());
96        limitEnvVars.put("permissionMemberId", permissionEntry.getMemberId());
97        limitEnvVars.put("permissionRoleId", permissionEntry.getRoleId());
98        limitEnvVars.put("permissionRoleName", permissionEntry.getRoleName());
99        limitEnvVars.put("permissionAttributeDefNameId", permissionEntry.getAttributeDefNameId());
100       limitEnvVars.put("permissionAttributeDefNameName", permissionEntry.getAttributeDefNameName());
101   
102       //get custom el classes to add
103       Map<String, Object> customElClasses = PermissionLimitUtils.limitElClasses();
104       
105       limitEnvVars.putAll(GrouperUtil.nonNull(customElClasses));
106       
107       //dont be lenient on undefined variables
108       result = GrouperUtil.substituteExpressionLanguage(expression, limitEnvVars, false, false, false);
109       
110       return GrouperUtil.booleanObjectValue(result);
111     } catch (RuntimeException re) {
112       foundError = true;
113       throw re;
114     } finally {
115       
116       if (foundError || LOG.isDebugEnabled()) {
117         try {
118           StringBuilder logMessage = new StringBuilder();
119           if (logMessage != null) {
120             logMessage.append(", EL variables: ");
121             for (String varName : GrouperUtil.nonNull(limitEnvVars).keySet()) {
122               logMessage.append(varName);
123               Object value = limitEnvVars.get(varName);
124               if (value instanceof String || value instanceof Number || value instanceof Date || value == null) {
125                 logMessage.append("(").append(value).append(")");
126               } else {
127                 logMessage.append("(type: ").append(value.getClass()).append(")");
128               }
129               logMessage.append(",");
130             }
131           }
132           
133           if (!foundError) {
134             logMessage.append(", elResult: ").append(result);
135           }
136           
137           if (foundError) {
138             LOG.error(logMessage.toString(), theException);
139           } else {
140             LOG.debug(logMessage.toString());
141           }
142           
143         } catch (RuntimeException re2) {
144           LOG.error("loggingError", re2);
145           LOG.error("originalException", theException);
146         }
147       }
148       
149       
150       
151     }
152      
153   }
154 
155   /**
156    * @see PermissionLimitInterface#documentation()
157    */
158   public PermissionLimitDocumentation documentation() {
159     PermissionLimitDocumentationimitDocumentation.html#PermissionLimitDocumentation">PermissionLimitDocumentation permissionLimitDocumentation = new PermissionLimitDocumentation();
160     permissionLimitDocumentation.setDocumentationKey("grouperPermissionExpressionLanguage.doc");
161     
162     //comma separated realms
163     String realmNames = StringUtils.join(GrouperUtil.nonNull(PermissionLimitUtils.limitRealms()).iterator(), ", ");
164     
165     permissionLimitDocumentation.setArgs(GrouperUtil.toList(StringUtils.defaultIfEmpty(realmNames, "none")));
166     return permissionLimitDocumentation;
167   }
168 
169   /**
170    * @see PermissionLimitInterface#validateLimitAssignValue(AttributeAssign, Set)
171    */
172   public PermissionLimitDocumentation validateLimitAssignValue(AttributeAssign limitAssign, Set<AttributeAssignValue> limitAssignmentValues) {
173     String value = null;
174     
175     if (GrouperUtil.length(limitAssignmentValues) == 1) {
176       value = limitAssignmentValues.iterator().next().getValueString();
177     }
178     
179     if (StringUtils.isBlank(value)) {
180       return new PermissionLimitDocumentation("grouperPermissionExpressionLanguage.required");
181     }
182     
183     return null;
184   }
185 
186 }