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