001 /**
002 * Copyright 2004-2012 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 */
016 package org.kuali.hr.time.clock.location.validation;
017
018 import java.util.List;
019
020 import org.apache.commons.lang.StringUtils;
021 import org.apache.log4j.Logger;
022 import org.kuali.hr.time.authorization.AuthorizationValidationUtils;
023 import org.kuali.hr.time.authorization.DepartmentalRule;
024 import org.kuali.hr.time.authorization.DepartmentalRuleAuthorizer;
025 import org.kuali.hr.time.clock.location.ClockLocationRule;
026 import org.kuali.hr.time.clock.location.ClockLocationRuleIpAddress;
027 import org.kuali.hr.time.service.base.TkServiceLocator;
028 import org.kuali.hr.time.util.TkConstants;
029 import org.kuali.hr.time.util.ValidationUtils;
030 import org.kuali.rice.kns.document.MaintenanceDocument;
031 import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase;
032 import org.kuali.rice.krad.bo.PersistableBusinessObject;
033
034 public class ClockLocationRuleRule extends MaintenanceDocumentRuleBase {
035
036 private static Logger LOG = Logger.getLogger(ClockLocationRuleRule.class);
037
038 public static boolean validateIpAddress(String ip) {
039 LOG.debug("Validating IP address: " + ip);
040 if(ip == null) {
041 return false;
042 }
043 if(ip.isEmpty() || ip.length() > 15 || ip.endsWith(TkConstants.IP_SEPERATOR) || ip.startsWith(TkConstants.IP_SEPERATOR)) {
044 return false;
045 }
046 String[] lst = StringUtils.split(ip, TkConstants.IP_SEPERATOR);
047 if(lst.length > 4 || (lst.length <4 && ip.indexOf(TkConstants.WILDCARD_CHARACTER)< 0)) {
048 return false;
049 }
050 for(String str : lst) {
051 if(!str.matches(TkConstants.IP_WILDCARD_PATTERN)) {
052 return false;
053 }
054 }
055 return true;
056 }
057
058 boolean validateIpAddresses(List<ClockLocationRuleIpAddress> ipAddresses) {
059 for(ClockLocationRuleIpAddress ip : ipAddresses) {
060 if(!validateIpAddress(ip.getIpAddress())) {
061 return this.flagIPAddressError(ip.getIpAddress());
062 }
063 }
064 return true;
065 }
066
067 boolean flagIPAddressError(String ip) {
068 this.putFieldError("ipAddresses", "ipaddress.invalid.format", ip);
069 return false;
070 }
071
072 boolean validateWorkArea(ClockLocationRule clr) {
073 boolean valid = true;
074 if (clr.getWorkArea() != null
075 && !ValidationUtils.validateWorkArea(clr.getWorkArea(), clr
076 .getEffectiveDate())) {
077 this.putFieldError("workArea", "error.existence", "workArea '"
078 + clr.getWorkArea() + "'");
079 valid = false;
080 } else if (clr.getWorkArea() != null
081 && !clr.getWorkArea().equals(TkConstants.WILDCARD_LONG)) {
082 int count = TkServiceLocator.getWorkAreaService().getWorkAreaCount(clr.getDept(), clr.getWorkArea());
083 valid = (count > 0);
084 if (!valid) {
085 this.putFieldError("workArea", "dept.workarea.invalid.sync",
086 clr.getWorkArea() + "");
087 }
088 }
089 return valid;
090 }
091
092 protected boolean validateDepartment(ClockLocationRule clr) {
093 boolean ret = false;
094
095 if (!StringUtils.isEmpty(clr.getDept())) {
096 if (!ValidationUtils.validateDepartment(clr.getDept(), clr.getEffectiveDate())) {
097 this.putFieldError("dept", "error.existence", "department '" + clr.getDept() + "'");
098 } else if (!DepartmentalRuleAuthorizer.hasAccessToWrite(clr)) {
099 this.putFieldError("dept", "error.department.permissions", clr.getDept());
100 } else {
101 ret = true;
102 }
103 }
104
105 return ret;
106 }
107
108 protected boolean validateJobNumber(ClockLocationRule clr) {
109 boolean valid = true;
110 if (clr.getJobNumber() == null) {
111 valid = false;
112 } else if (!clr.getJobNumber().equals(TkConstants.WILDCARD_LONG)) {
113 int count = TkServiceLocator.getJobService().getJobCount(clr.getPrincipalId(), clr.getJobNumber(),null);
114 valid = (count > 0);
115 if (!valid) {
116 this.putFieldError("jobNumber", "principalid.job.invalid.sync",
117 clr.getJobNumber() + "");
118 }
119 }
120 return valid;
121 }
122
123 protected boolean validatePrincipalId(ClockLocationRule clr) {
124 boolean valid = false;
125 if (clr.getPrincipalId() == null) {
126 valid = false;
127 } else {
128 valid = true;
129 }
130 return valid;
131 }
132
133 /**
134 * This method will validate whether the wildcard combination and wild
135 * carded areas for this DepartmentalRule are valid or not. Errors are added
136 * to the field errors to report back to the user interface as well.
137 *
138 * @param clr The Departmental rule we are investigating.
139 *
140 * @return true if wild card setup is correct, false otherwise.
141 */
142 boolean validateWildcards(DepartmentalRule clr) {
143 boolean valid = true;
144
145 if (!ValidationUtils.validateWorkAreaDeptWildcarding(clr)) {
146 // add error when work area defined, department is wild carded.
147 this.putFieldError("dept", "error.wc.wadef", "department '" + clr.getDept() + "'");
148 valid = false;
149 }
150
151 if (StringUtils.equals(clr.getDept(), TkConstants.WILDCARD_CHARACTER) &&
152 !AuthorizationValidationUtils.canWildcardDepartment(clr)) {
153 this.putFieldError("dept", "error.wc.dept.perm", "department '" + clr.getDept() + "'");
154 valid = false;
155 }
156
157 if (clr!= null && clr.getWorkArea() != null && clr.getWorkArea().equals(TkConstants.WILDCARD_LONG) &&
158 !AuthorizationValidationUtils.canWildcardWorkArea(clr)) {
159 this.putFieldError("dept", "error.wc.wa.perm", "department '" + clr.getDept() + "'");
160 valid = false;
161 }
162
163 return valid;
164 }
165
166
167 /**
168 * It looks like the method that calls this class doesn't actually care
169 * about the return type.
170 */
171 @Override
172 protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) {
173 boolean valid = false;
174
175 PersistableBusinessObject pbo = (PersistableBusinessObject) this.getNewBo();
176 if (pbo instanceof ClockLocationRule) {
177 ClockLocationRule clr = (ClockLocationRule) pbo;
178 valid = this.validateDepartment(clr);
179 valid &= this.validateWorkArea(clr);
180 valid &= this.validateWildcards(clr);
181 valid &= this.validatePrincipalId(clr);
182 valid &= this.validateJobNumber(clr);
183 valid &= this.validateIpAddresses(clr.getIpAddresses());
184 }
185
186 return valid;
187 }
188 }