private static Set<String> getZimletNames(List<Zimlet> zimlets) { Set<String> names = new LinkedHashSet<String>(); for (Zimlet zimlet : zimlets) { names.add(zimlet.getName()); } return names; }
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); }