001 /** 002 * Copyright 2004-2013 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 }