private static Account validateAuthTokenInternal( Provisioning prov, AuthToken at, boolean addToLoggingContext) throws ServiceException { if (prov == null) { prov = Provisioning.getInstance(); } if (at.isExpired()) { throw ServiceException.AUTH_EXPIRED(); } // make sure that the authenticated account is still active and has not been deleted since the // last request String acctId = at.getAccountId(); Account acct = prov.get(AccountBy.id, acctId, at); if (acct == null) { throw ServiceException.AUTH_EXPIRED("account " + acctId + " not found"); } if (addToLoggingContext) { ZimbraLog.addAccountNameToContext(acct.getName()); } if (!acct.checkAuthTokenValidityValue(at)) { throw ServiceException.AUTH_EXPIRED("invalid validity value"); } boolean delegatedAuth = at.isDelegatedAuth(); String acctStatus = acct.getAccountStatus(prov); if (!delegatedAuth && !Provisioning.ACCOUNT_STATUS_ACTIVE.equals(acctStatus)) { throw ServiceException.AUTH_EXPIRED("account not active"); } // if using delegated auth, make sure the "admin" is really an active admin account if (delegatedAuth) { // note that delegated auth allows access unless the account's in maintenance mode if (Provisioning.ACCOUNT_STATUS_MAINTENANCE.equals(acctStatus)) { throw ServiceException.AUTH_EXPIRED("delegated account in MAINTENANCE mode"); } Account admin = prov.get(AccountBy.id, at.getAdminAccountId()); if (admin == null) { throw ServiceException.AUTH_EXPIRED( "delegating account " + at.getAdminAccountId() + " not found"); } boolean isAdmin = AdminAccessControl.isAdequateAdminAccount(admin); if (!isAdmin) { throw ServiceException.PERM_DENIED("not an admin for delegated auth"); } if (!Provisioning.ACCOUNT_STATUS_ACTIVE.equals(admin.getAccountStatus(prov))) { throw ServiceException.AUTH_EXPIRED("delegating account is not active"); } } return acct; }
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (!isHttpReq(request, response)) { return; } HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; AuthToken authToken; try { authToken = getAuthTokenForApp(req, resp, false); } catch (ServiceException se) { ZimbraLog.zimlet.info("can't get authToken: " + se.getMessage()); resp.sendError(HttpServletResponse.SC_FORBIDDEN); return; } if (authToken == null) { // error was already sent out return; } boolean isAdminAuth = false; // ZimbraLog.zimlet.info(">>> isAdminAuth: "+isAdminAuth); // get list of allowed zimlets Provisioning prov = Provisioning.getInstance(); List<Zimlet> allowedZimlets = new LinkedList<Zimlet>(); List<Zimlet> allZimlets = new LinkedList<Zimlet>(); try { isAdminAuth = AdminAccessControl.getAdminAccessControl(authToken) .isSufficientAdminForZimletFilterServlet(); // add all available zimlets if (!isAdminAuth) { // zimlets for this account's COS Account account = prov.get(AccountBy.id, authToken.getAccountId(), authToken); for (String zimletName : ZimletUtil.getAvailableZimlets(account).getZimletNamesAsArray()) { Zimlet zimlet = prov.getZimlet(zimletName); if (zimlet == null) continue; if (zimlet.isEnabled()) { allowedZimlets.add(zimlet); } allZimlets.add(zimlet); } } // add the admin zimlets else { allZimlets = prov.listAllZimlets(); Iterator<Zimlet> iter = allZimlets.iterator(); while (iter.hasNext()) { Zimlet zimlet = iter.next(); if (zimlet.isExtension()) { if (zimlet.isEnabled()) { allowedZimlets.add(zimlet); } } } } } catch (ServiceException e) { ZimbraLog.zimlet.info("unable to get list of zimlets"); resp.sendError(HttpServletResponse.SC_FORBIDDEN); return; } // order by priority List<Zimlet> zimletList = ZimletUtil.orderZimletsByPriority(allowedZimlets); Set<String> allowedZimletNames = getZimletNames(zimletList); Set<String> allZimletNames = getZimletNames(allZimlets); // get list of zimlets for request Set<String> zimletNames = new LinkedHashSet<String>(); String uri = req.getRequestURI(); boolean isZimletRes = uri.startsWith(ZIMLET_RES_URL_PREFIX); if (isZimletRes) { zimletNames.addAll(allowedZimletNames); } else { Matcher matcher = mPattern.matcher(uri); if (!matcher.matches()) { ZimbraLog.zimlet.info("no zimlet specified in request"); resp.sendError(HttpServletResponse.SC_FORBIDDEN); return; } zimletNames.add(matcher.group(1)); } // check access File basedir = new File(LC.zimlet_directory.value()); File devdir = new File(basedir, ZimletUtil.ZIMLET_DEV_DIR); Iterator<String> iter = zimletNames.iterator(); while (iter.hasNext()) { String zimletName = iter.next(); try { File devfile = new File(devdir, zimletName); if (devfile.exists()) { continue; } Zimlet zimlet = prov.getZimlet(zimletName); if (zimlet == null) { ZimbraLog.zimlet.info("no such zimlet: " + zimletName); iter.remove(); allZimlets.remove(zimlet); continue; } if (!allowedZimletNames.contains(zimletName)) { ZimbraLog.zimlet.info( "unauthorized request to zimlet " + zimletName + " from user " + authToken.getAccountId()); iter.remove(); allZimlets.remove(zimlet); continue; } if (zimlet.isExtension() && !isAdminAuth) { // ZimbraLog.zimlet.info("!!!!! removing extension zimlet: "+zimletName); iter.remove(); allZimlets.remove(zimlet); } } catch (ServiceException se) { ZimbraLog.zimlet.info( "service exception to zimlet " + zimletName + " from user " + authToken.getAccountId() + ": " + se.getMessage()); iter.remove(); } } if (!isZimletRes) { Matcher matcher = mPattern.matcher(uri); if (matcher.matches()) { String zimletName = matcher.group(1); if (!zimletNames.contains(zimletName)) { resp.sendError(HttpServletResponse.SC_FORBIDDEN); return; } } } // force compilation of template if (uri.endsWith(".template.js")) { Matcher matcher = mPattern.matcher(uri); if (matcher.matches()) { String zimletName = matcher.group(1); String opath = matcher.group(3); String ipath = opath.replaceAll(".js$", ""); boolean isDevZimlet = uri.indexOf("_dev") != -1; File zimletDir = new File(isDevZimlet ? devdir : basedir, zimletName); File ifile = new File(zimletDir, ipath); File ofile = new File(zimletDir, opath); if (!ofile.exists() || (ifile.exists() && ifile.lastModified() > ofile.lastModified())) { String prefix = zimletName + "."; try { TemplateCompiler.compile( zimletDir, zimletDir, prefix, new String[] {ipath}, true, true); } catch (IOException e) { // ignore, let fail } } } } // process request req.setAttribute(ZimletFilter.ALLOWED_ZIMLETS, zimletNames); req.setAttribute(ZimletFilter.ALL_ZIMLETS, allZimletNames); chain.doFilter(req, resp); }