public static void checkPermission(String key, boolean allowSystem) throws NoAccessException { long l = 0; if (Plugin.logCheckTime && Logger.isDebugEnabled()) { Plugin.debug(">>>>>>> [%s]", key); l = System.currentTimeMillis(); } if (Boolean.parseBoolean(Play.configuration.getProperty(ConfigConstants.DISABLE, "false"))) { return; } IAuthorizeable a = reg_.get(key); if (null == a) { throw new RuntimeException("oops, something wrong with enhancer... ?"); } IAccount acc = null; try { IAccount accFact = AAAFactory.account(); acc = accFact.getCurrent(); if (null == acc) { if (allowSystem) { if (!Boolean.parseBoolean( Play.configuration.getProperty(ConfigConstants.SYSTEM_PERMISSION_CHECK, "false"))) { // suppress permission check for system account return; } acc = accFact.getSystemAccount(); } if (null == acc) { throw new NoAccessException("cannot determine principal account"); } } // superuser check boolean isSuperUser = false; if (Plugin.superuser > 0) { IPrivilege p = acc.getPrivilege(); if (null != p) isSuperUser = p.getLevel() >= Plugin.superuser; } if (!isSuperUser && !acc.hasAccessTo(a)) { throw new NoAccessException("Access denied"); } } catch (NoAccessException nae) { throw nae; } catch (Exception e) { throw new NoAccessException(e); } finally { if (Plugin.logCheckTime && Logger.isDebugEnabled()) { Plugin.debug("<<<<<<< [%s]: %sms", key, System.currentTimeMillis() - l); } } }
private static void registAuthoriable_(String key, RequireRight rr, RequirePrivilege rp) { if (Logger.isTraceEnabled()) { Plugin.trace( "register authoriable [%s: (%s|%s)]", key, (null == rr) ? "null-right" : rr.value(), (null == rp) ? "null-privilege" : rp.value()); } reg_.put(key, new Authority(key, rr, rp)); }
public void buildAuthorityRegistry() throws Exception { if (Authority.reg_.size() < 1) { Plugin.debug("building authority registry"); // force build authority registry for (ApplicationClass ac : Play.classes.all()) { enhance_(ac, true); } } Authority.ensureRightPrivilege(); }
private void enhance_(ApplicationClass applicationClass, boolean buildAuthorityRegistryOnly) throws Exception { Plugin.trace("about to enhance applicationClass: %s", applicationClass); CtClass ctClass = makeClass(applicationClass); Set<CtBehavior> s = new HashSet<CtBehavior>(); s.addAll(Arrays.asList(ctClass.getDeclaredMethods())); s.addAll(Arrays.asList(ctClass.getMethods())); s.addAll(Arrays.asList(ctClass.getConstructors())); s.addAll(Arrays.asList(ctClass.getDeclaredConstructors())); for (final CtBehavior ctBehavior : s) { if (!Modifier.isPublic(ctBehavior.getModifiers()) || javassist.Modifier.isAbstract(ctBehavior.getModifiers())) { continue; } boolean needsEnhance = false; RequireRight rr = null; RequirePrivilege rp = null; RequireAccounting ra = null; boolean allowSystem = false; Object[] aa = ctBehavior.getAnnotations(); for (Object o : aa) { if (o instanceof RequirePrivilege) { needsEnhance = true; rp = (RequirePrivilege) o; continue; } if (o instanceof RequireRight) { needsEnhance = true; rr = (RequireRight) o; continue; } if (o instanceof AllowSystemAccount) { allowSystem = true; continue; } if (o instanceof RequireAccounting) { needsEnhance = true; ra = (RequireAccounting) o; } } if (!needsEnhance) continue; String key = ctBehavior.getLongName(); String errMsg = String.format("Error enhancing class %s.%s: ", ctClass, ctBehavior); // process rr & rp if (null != rr || null != rp) { // check before/after enhancement Authority.registAuthoriable_(key, rr, rp); if (!buildAuthorityRegistryOnly) { // verify if before attribute of rr and rp is consistent if (null != rr && null != rp && (rr.before() != rp.before())) { String reason = "The before setting of RequireRight and RequirePrivilege doesn't match"; throw new RuntimeException(errMsg + reason); } boolean before = true; if (null != rr) before = rr.before(); if (null != rp) before = rp.before(); // try best to guess the target object String curObj = ""; if (null != rr) { // target object only impact dynamic access checking, hence rr shall not be null boolean isConstructor = ctBehavior instanceof CtConstructor; boolean isStatic = false; if (!isConstructor) isStatic = Modifier.isStatic(ctBehavior.getModifiers()); int paraCnt = ctBehavior.getParameterTypes().length; int id = rr.target(); // calibrate target id if (0 == id) { if (isConstructor) { id = -1; } else if (isStatic) { if (paraCnt > 0) id = 1; else id = -1; } } else if (id > paraCnt) { id = paraCnt; } // speculate cur target statement String sid = null; if (id == -1) sid = "_"; if (id > -1) sid = String.valueOf(id); if (null != sid) { curObj = "play.modules.aaa.PlayDynamicRightChecker.setObjectIfNoCurrent($" + sid + ");"; } if (-1 == id) before = false; } // check permission enhancement if (before) { ctBehavior.insertBefore( curObj + " play.modules.aaa.enhancer.Enhancer.Authority.checkPermission(\"" + key + "\", " + Boolean.toString(allowSystem) + ");"); } else { ctBehavior.insertAfter( curObj + " play.modules.aaa.enhancer.Enhancer.Authority.checkPermission(\"" + key + "\", " + Boolean.toString(allowSystem) + ");"); } } } if (buildAuthorityRegistryOnly) continue; // process ra if (null != ra) { CtClass[] paraTypes = ctBehavior.getParameterTypes(); String sParam = null; if (0 < paraTypes.length) { sParam = "new Object[0]"; } else { sParam = "{$$}"; } String msg = ra.value(); if (null == msg || "".equals(msg)) msg = key; if (ra.before()) { ctBehavior.insertBefore( "play.modules.aaa.utils.Accounting.info(\"" + msg + "\", " + Boolean.toString(allowSystem) + ", " + sParam + ");"); } else { ctBehavior.insertAfter( "play.modules.aaa.utils.Accounting.info(\"" + msg + "\", " + Boolean.toString(allowSystem) + ", " + sParam + ");"); } CtClass etype = ClassPool.getDefault().get("java.lang.Exception"); ctBehavior.addCatch( "{play.modules.aaa.utils.Accounting.error($e, \"" + msg + "\", " + Boolean.toString(allowSystem) + ", " + sParam + "); throw $e;}", etype); } } if (buildAuthorityRegistryOnly) return; applicationClass.enhancedByteCode = ctClass.toBytecode(); ctClass.detach(); }