1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kim.document.rule;
17
18 import java.util.List;
19 import java.util.Map;
20 import java.util.regex.Matcher;
21 import java.util.regex.Pattern;
22
23 import javax.xml.namespace.QName;
24
25 import org.apache.commons.lang.StringUtils;
26 import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
27 import org.kuali.rice.core.api.uif.RemotableAttributeError;
28 import org.kuali.rice.core.api.util.RiceKeyConstants;
29 import org.kuali.rice.kim.api.common.template.Template;
30 import org.kuali.rice.kim.api.permission.Permission;
31 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
32 import org.kuali.rice.kim.api.type.KimType;
33 import org.kuali.rice.kim.framework.permission.PermissionTypeService;
34 import org.kuali.rice.kim.impl.permission.GenericPermissionBo;
35 import org.kuali.rice.kns.document.MaintenanceDocument;
36 import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase;
37 import org.kuali.rice.krad.util.GlobalVariables;
38
39
40
41
42
43
44
45 public class GenericPermissionMaintenanceDocumentRule extends MaintenanceDocumentRuleBase {
46 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(GenericPermissionMaintenanceDocumentRule.class);
47
48 protected static final String DETAIL_VALUES_PROPERTY = "detailValues";
49 protected static final String NAMESPACE_CODE_PROPERTY = "namespaceCode";
50 protected static final String ERROR_MESSAGE_PREFIX = "error.document.kim.genericpermission.";
51 protected static final String ERROR_MISSING_TEMPLATE = ERROR_MESSAGE_PREFIX + "missingtemplate";
52 protected static final String ERROR_UNKNOWN_ATTRIBUTE = ERROR_MESSAGE_PREFIX + "unknownattribute";
53 protected static final String ERROR_ATTRIBUTE_VALIDATION = ERROR_MESSAGE_PREFIX + "attributevalidation";
54 protected static final String ERROR_NAMESPACE_AND_NAME_VALIDATION = ERROR_MESSAGE_PREFIX + "namespaceandnamevalidation";
55
56
57 @Override
58 protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) {
59 boolean rulesPassed = super.processCustomRouteDocumentBusinessRules( document );
60 try {
61 GenericPermissionBo newPerm = (GenericPermissionBo)getNewBo();
62 GenericPermissionBo oldPerm = (GenericPermissionBo)getOldBo();
63 rulesPassed &= validateDetailValuesFormat(newPerm.getDetailValues());
64 if(StringUtils.isNotBlank(newPerm.getNamespaceCode()) && StringUtils.isNotBlank(newPerm.getName()) && StringUtils.isBlank(newPerm.getId())){
65 rulesPassed &= validateNamespaceCodeAndName(newPerm.getNamespaceCode(), newPerm.getName());
66 }
67
68 if(StringUtils.isNotBlank(newPerm.getNamespaceCode()) &&
69 StringUtils.isNotBlank(newPerm.getName()) &&
70 StringUtils.isNotBlank(oldPerm.getId()) &&
71 StringUtils.isNotBlank(newPerm.getId()) &&
72 !StringUtils.equals(oldPerm.getId(), newPerm.getId())){
73 rulesPassed &= validateNamespaceCodeAndName(newPerm.getNamespaceCode(), newPerm.getName());
74 }
75
76 if(StringUtils.isNotBlank(newPerm.getNamespaceCode()) &&
77 StringUtils.isNotBlank(newPerm.getName()) &&
78 StringUtils.isNotBlank(oldPerm.getId()) &&
79 StringUtils.isNotBlank(newPerm.getId()) &&
80 StringUtils.equals(oldPerm.getId(), newPerm.getId()) &&
81 ( !StringUtils.equals(oldPerm.getNamespaceCode(), newPerm.getNamespaceCode()) ||
82 !StringUtils.equals(oldPerm.getName(), newPerm.getName())
83 )
84 ) {
85 rulesPassed &= validateNamespaceCodeAndName(newPerm.getNamespaceCode(), newPerm.getName());
86 }
87
88
89 if(StringUtils.isNotBlank(newPerm.getTemplateId())){
90 Template template = KimApiServiceLocator.getPermissionService().getPermissionTemplate(newPerm.getTemplateId());
91 if ( template == null ) {
92 GlobalVariables.getMessageMap().addToErrorPath( MAINTAINABLE_ERROR_PATH );
93 GlobalVariables.getMessageMap().putError( DETAIL_VALUES_PROPERTY, ERROR_MISSING_TEMPLATE, newPerm.getTemplateId() );
94 GlobalVariables.getMessageMap().removeFromErrorPath( MAINTAINABLE_ERROR_PATH );
95 rulesPassed &= false;
96 } else {
97 KimType kimType = KimApiServiceLocator.getKimTypeInfoService().getKimType(template.getKimTypeId());
98 Map<String, String> details = newPerm.getDetails();
99
100 for ( String attributeName : details.keySet() ) {
101 if ( kimType.getAttributeDefinitionByName(attributeName) == null ) {
102 GlobalVariables.getMessageMap().addToErrorPath( MAINTAINABLE_ERROR_PATH );
103 GlobalVariables.getMessageMap().putError( DETAIL_VALUES_PROPERTY, ERROR_UNKNOWN_ATTRIBUTE, attributeName, template.getNamespaceCode(), template.getName() );
104 GlobalVariables.getMessageMap().removeFromErrorPath( MAINTAINABLE_ERROR_PATH );
105 rulesPassed &= false;
106 }
107 }
108
109 if ( !GlobalVariables.getMessageMap().hasErrors() ) {
110 PermissionTypeService service = getPermissionTypeService( kimType.getServiceName() );
111 if ( service != null ) {
112 List<RemotableAttributeError> validationErrors = service.validateAttributes( kimType.getId(), details);
113 if ( validationErrors != null && !validationErrors.isEmpty() ) {
114 for ( RemotableAttributeError error : validationErrors ) {
115 GlobalVariables.getMessageMap().addToErrorPath( MAINTAINABLE_ERROR_PATH );
116 for (String errMsg : error.getErrors()) {
117 GlobalVariables.getMessageMap().putError( DETAIL_VALUES_PROPERTY, ERROR_ATTRIBUTE_VALIDATION, error.getAttributeName(), errMsg );
118 }
119 GlobalVariables.getMessageMap().removeFromErrorPath( MAINTAINABLE_ERROR_PATH );
120 }
121 rulesPassed &= false;
122 }
123 }
124 }
125
126 }
127
128 }
129
130 } catch ( RuntimeException ex ) {
131 LOG.error( "Error in processCustomRouteDocumentBusinessRules()", ex );
132 throw ex;
133 }
134 return rulesPassed;
135 }
136
137 protected boolean validateDetailValuesFormat(String permissionDetailValues){
138 if(permissionDetailValues != null){
139 Pattern pattern = Pattern.compile(".+"+"="+".+");
140
141 permissionDetailValues = permissionDetailValues.replace( "\r\n", "\n" );
142 permissionDetailValues = permissionDetailValues.replace( '\r', '\n' );
143 if(StringUtils.isNotBlank(permissionDetailValues)){
144 String[] values = permissionDetailValues.split( "\n" );
145 for(String attrib : values){
146 Matcher matcher = pattern.matcher(attrib);
147 if (!matcher.matches()) {
148 GlobalVariables.getMessageMap().putError(
149 MAINTAINABLE_ERROR_PATH + "." + DETAIL_VALUES_PROPERTY,
150 RiceKeyConstants.ERROR_INVALID_FORMAT,
151 new String[]{"Detail Values", permissionDetailValues});
152 return false;
153 }
154 }
155 }
156 }
157 return true;
158 }
159 protected boolean validateNamespaceCodeAndName(String namespaceCode,String name){
160 Permission permission = KimApiServiceLocator.getPermissionService().findPermByNamespaceCodeAndName(namespaceCode,name);
161 if(null != permission){
162 GlobalVariables.getMessageMap().putError(MAINTAINABLE_ERROR_PATH+"."+NAMESPACE_CODE_PROPERTY,ERROR_NAMESPACE_AND_NAME_VALIDATION,namespaceCode,name);
163 return false;
164 } else{
165 return true;
166 }
167 }
168
169 protected PermissionTypeService getPermissionTypeService( String serviceName ) {
170 if ( StringUtils.isBlank( serviceName ) ) {
171 return null;
172 }
173 try {
174 Object service = GlobalResourceLoader.getService(QName.valueOf(serviceName));
175
176 if ( service == null ) {
177 LOG.warn("null returned for permission type service for service name: " + serviceName);
178 } else {
179
180 if ( !(service instanceof PermissionTypeService) ) {
181 LOG.warn( "Service " + serviceName + " was not a KimPermissionTypeService. Was: " + service.getClass().getName() );
182 service = null;
183 }
184 }
185 return (PermissionTypeService)service;
186 } catch( Exception ex ) {
187 LOG.error( "Error retrieving service: " + serviceName + " from the KimImplServiceLocator.", ex );
188 }
189 return null;
190 }
191
192 }