package org.jahia.modules.spamfiltering.filters; import org.jahia.bin.filters.AbstractServletFilter; import org.jahia.modules.spamfiltering.HostStats; import org.jahia.modules.spamfiltering.rules.SpamFilteringRuleService; import org.slf4j.Logger; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.Map; /** * A servlet filter needed since we cannot use a render filter on actions */ public class SpamServletFilter extends AbstractServletFilter { private static Logger logger = org.slf4j.LoggerFactory.getLogger(SpamServletFilter.class); private SpamFilteringRuleService spamFilteringRuleService; public void setSpamFilteringRuleService(SpamFilteringRuleService spamFilteringRuleService) { this.spamFilteringRuleService = spamFilteringRuleService; } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { Map<String, HostStats> blacklistedHosts = spamFilteringRuleService.getBlacklistedHosts(); boolean okToContinue = true; if (blacklistedHosts != null) { String remoteHost = servletRequest.getRemoteHost(); if (remoteHost == null) { remoteHost = servletRequest.getRemoteAddr(); } if (blacklistedHosts.containsKey(remoteHost)) { HostStats hostStats = blacklistedHosts.get(remoteHost); if (hostStats.isBlacklisted()) { long now = System.currentTimeMillis(); if (hostStats.getBlacklistingTimeout() == 0 || hostStats.getBlacklistingTimeout() > now && servletRequest instanceof HttpServletRequest) { HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; // host is blacklisted, let's refuse serving the request String httpMethod = httpServletRequest.getMethod().toLowerCase(); if (spamFilteringRuleService.isAllowReadingWhenBlacklisted() && (httpMethod.equals("get") || httpMethod.equals("head") || httpMethod.equals("options"))) { // even if the host is blacklisted, we still allow these three HTTP methods. logger.info("Host {} is blacklisted but read-only HTTP methods (get/head/options) are still allowed", hostStats); } else { httpServletRequest.getSession().invalidate(); okToContinue = false; } } else if (hostStats.getBlacklistingTimeout() != 0 && hostStats.getBlacklistingTimeout() <= now) { // black listing has expired, let's remove it. hostStats.setBlacklisted(false); hostStats.setBlacklistingTimeout(0); spamFilteringRuleService.getBlacklistedHosts().put(remoteHost, hostStats); } } } } if (okToContinue) { filterChain.doFilter(servletRequest, servletResponse); } } @Override public void destroy() { } }