1 64 65 69 package com.jcorporate.expresso.core.controller; 70 71 import com.jcorporate.expresso.core.cache.CacheException; 72 import com.jcorporate.expresso.core.cache.CacheManager; 73 import com.jcorporate.expresso.core.cache.CacheSystem; 74 import com.jcorporate.expresso.core.db.DBException; 75 import com.jcorporate.expresso.core.dbobj.ValidValue; 76 import com.jcorporate.expresso.core.i18n.Messages; 77 import com.jcorporate.expresso.core.security.User; 78 import com.jcorporate.expresso.kernel.util.FastStringBuffer; 79 import com.jcorporate.expresso.services.dbobj.ControllerSecurity; 80 import com.jcorporate.expresso.services.dbobj.DefaultUserInfo; 81 import com.jcorporate.expresso.services.dbobj.GroupMembers; 82 import com.jcorporate.expresso.services.dbobj.UserGroup; 83 import org.apache.log4j.Logger; 84 85 import java.util.Enumeration ; 86 import java.util.Hashtable ; 87 import java.util.Iterator ; 88 import java.util.Stack ; 89 import java.util.StringTokenizer ; 90 import java.util.Vector ; 91 92 93 98 public abstract class DBController extends Controller { 99 100 private static final String CACHE_NAME = DBController.class + "securityCache"; 102 105 private static final long CACHE_TTY = 60 * 1000 * 30; 106 107 private static boolean listenersSetup = false; 108 111 private static Logger sLog = Logger.getLogger(DBController.class); 112 113 116 public DBController() { 117 if (!listenersSetup) { 118 CacheManager.addListener(CACHE_NAME, UserGroup.class.getName()); 119 CacheManager.addListener(CACHE_NAME, ControllerSecurity.class.getName()); 120 CacheManager.addListener(CACHE_NAME, DefaultUserInfo.class.getName()); 121 CacheManager.addListener(CACHE_NAME, GroupMembers.class.getName()); 122 123 listenersSetup = true; 124 } 125 } 126 127 138 private static synchronized void addCachedSecurity(String group, 139 String dataContext, String className, String states) 140 throws CacheException { 141 CacheSystem cs = CacheManager.getCacheSystem(dataContext); 142 if (cs == null) { 143 return; 145 } 146 147 if (sLog.isDebugEnabled()) { 148 sLog.debug("Adding cached access for Group:'" + group + "' for state(s) '" + 149 states + "' controller " + className); 150 } 151 if (!cs.existsCache(CACHE_NAME)) { 152 cs.createCache(CACHE_NAME, false); 153 cs.addListener(CACHE_NAME, UserGroup.class.getName()); 154 cs.addListener(CACHE_NAME, ControllerSecurity.class.getName()); 155 cs.addListener(CACHE_NAME, DefaultUserInfo.class.getName()); 156 cs.addListener(CACHE_NAME, GroupMembers.class.getName()); 157 158 } 159 160 161 162 163 ValidValue existingVal = (ValidValue) cs.getItem(CACHE_NAME, 164 group + "|" + 165 className); 166 167 if (existingVal != null) { 168 String existing = existingVal.getDescription(); 169 170 171 172 173 Hashtable existingHash = new Hashtable (3); 174 String oneState = null; 175 StringTokenizer stk = new StringTokenizer (existing, " "); 176 177 while (stk.hasMoreElements()) { 178 oneState = stk.nextToken(); 179 existingHash.put(oneState, oneState); 180 } 181 182 StringTokenizer stk2 = new StringTokenizer (states, " "); 183 184 while (stk2.hasMoreElements()) { 185 oneState = stk2.nextToken(); 186 existingHash.put(oneState, oneState); 187 } 188 189 if (existingHash.get("*") != null) { 190 existing = ("*"); 191 } else { 192 193 FastStringBuffer existingBuffer = FastStringBuffer.getInstance(); 194 try { 195 for (Enumeration e = existingHash.keys(); e.hasMoreElements();) { 196 existingBuffer.append((String ) e.nextElement()); 197 existingBuffer.append(" "); 198 } 199 200 existing = existingBuffer.toString(); 201 } finally { 202 existingBuffer.release(); 203 existingBuffer = null; 204 } 205 } 206 207 cs.removeItem(CACHE_NAME, existingVal); 208 cs.addItem(CACHE_NAME, 209 new ValidValue(group + "|" + className, 210 existing), CACHE_TTY); 211 212 if (sLog.isDebugEnabled()) { 213 sLog.debug("Cache updated for group '" + group + "', controller " + 214 className + ", permissions now '" + existing + "'"); 215 } 216 217 return; 218 } else { 219 if (sLog.isDebugEnabled()) { 220 sLog.debug("There was no existing security in cache"); 221 } 222 223 cs.addItem(CACHE_NAME, 224 new ValidValue(group + "|" + className, states), 225 CACHE_TTY); 226 } 227 228 } 229 230 231 239 private static boolean containsAllowedState(String searchString, String state) { 240 if (searchString.equals("*")) { 241 return true; 242 } 243 244 if (searchString == null || searchString.length() == 0) { 245 return false; 246 } 247 248 StringTokenizer stok = new StringTokenizer (searchString, ","); 249 250 while (stok.hasMoreTokens()) { 251 String oneState = stok.nextToken().trim(); 252 if (oneState.equals(state)) { 253 return true; 254 } 255 } 256 257 return false; 258 } 259 260 270 public boolean stateAllowed(String newState, 271 ControllerRequest myRequest) 272 throws ControllerException { 273 try { 274 boolean allowed = isAllowed(myRequest, this, newState); 275 276 return allowed; 277 } catch (DBException de) { 278 throw new ControllerException("Unable to check Controller " + 279 "security", de); 280 } catch (CacheException ce) { 281 throw new ControllerException("Cache exception checking " + 282 "Controller security", ce); 283 } 284 } 285 286 296 public static boolean isAllowed(ControllerRequest request, DBController controller, String newState) throws DBException, 297 CacheException { 298 boolean allowed = false; 299 300 if (controller == null) { 301 return false; 302 } 303 304 User thisUser = new User(); 306 thisUser.setDataContext(request.getDataContext()); 307 thisUser.setUid(request.getUid()); 308 thisUser.retrieve(); 309 310 if (thisUser.isAdmin()) { 312 return true; 313 } 314 315 String controllerClassName = controller.getClass().getName(); 316 String missingGroupNames[] = null; 319 320 321 Vector usersGroups = thisUser.getGroups(); 323 int groupSize = usersGroups.size(); 324 325 String keySuffix = "|" + controllerClassName; 327 328 CacheSystem cs = CacheManager.getCacheSystem(request.getDataContext()); 329 330 synchronized (DBController.class) { 336 if (!cs.existsCache(CACHE_NAME)) { 339 cs.createCache(CACHE_NAME, false, 500); 340 cs.addListener(CACHE_NAME, UserGroup.class.getName()); 345 cs.addListener(CACHE_NAME, ControllerSecurity.class.getName()); 346 cs.addListener(CACHE_NAME, DefaultUserInfo.class.getName()); 347 cs.addListener(CACHE_NAME, GroupMembers.class.getName()); 348 } 349 350 int insertGroupIndex = 0; 358 for (int i = 0; i < groupSize; i++) { 359 String oneGroup = (String ) usersGroups.get(i); 360 String key = oneGroup + keySuffix; 361 ValidValue secVal = (ValidValue) cs.getItem(CACHE_NAME, key); 362 363 if (secVal == null) { 364 if (missingGroupNames == null) { 368 missingGroupNames = new String [groupSize]; 369 } 370 missingGroupNames[insertGroupIndex] = oneGroup; 371 insertGroupIndex++; 372 } else { 373 String sec = secVal.getDescription(); 376 377 if (containsAllowedState(sec, newState)) { 378 if (sLog.isDebugEnabled()) { 379 sLog.debug("User '" + request.getUid() + 380 "' allowed state '" + newState + 381 "' via cache"); 382 } 383 384 allowed = true; 385 break; 386 } 387 } 388 } 389 390 if (!allowed && missingGroupNames != null) { 391 ControllerSecurity csec = new ControllerSecurity(); 398 csec.setDataContext(request.getDataContext()); 399 400 ControllerSecurity oneSecurityEntry = null; 401 String allowedStates = null; 402 403 for (int i = 0; i < missingGroupNames.length; i++) { 404 String oneGroupName = missingGroupNames[i]; 405 if (oneGroupName != null) { 406 407 csec.clear(); 408 csec.setField(ControllerSecurity.CONTROLLER_CLASS, controllerClassName); 409 csec.setField(ControllerSecurity.GROUP_NAME, oneGroupName); 410 411 for (Iterator cse = csec.searchAndRetrieveList().iterator(); 412 cse.hasNext();) { 413 414 oneSecurityEntry = (ControllerSecurity) cse.next(); 415 allowedStates = oneSecurityEntry.getField(ControllerSecurity.STATES); 416 417 if (containsAllowedState(allowedStates, newState)) { 418 allowed = true; 419 } 420 addCachedSecurity(oneGroupName, 421 request.getDataContext(), 422 controllerClassName, allowedStates); 423 424 } 425 } else { 426 break; } 428 } 429 } 430 } return allowed; 432 } 433 434 435 448 protected String getString(String stringCode, Object [] args, 449 ControllerRequest myRequest) { 450 if (myRequest.getUser().equals("")) { 451 return super.getString(stringCode, args); 452 } else { 453 457 Stack s = this.getSchemaStack(); 458 if (s == null || s.isEmpty()) { 459 return Messages.getStringForUser(myRequest.getUid(), 460 myRequest.getDataContext(), getSchema(), stringCode, 461 args); 462 } else { 463 for (Iterator i = s.iterator(); i.hasNext();) { 464 try { 465 String schema = (String ) i.next(); 466 return Messages.getStringForUser(myRequest.getUid() 467 , myRequest.getDataContext(), schema, stringCode, 468 args); 469 } catch (IllegalArgumentException ex) { 470 if (!i.hasNext()) { 471 throw ex; 472 } 473 } 474 475 } 476 477 throw new IllegalArgumentException ("Unable to locate string " + stringCode 478 + " for any schema"); 479 } 480 } 481 } 482 483 } 484 | Popular Tags |