📄 spamfilter.java
字号:
} catch( IOException ex ) { log.info("Unable to read attachment data, continuing...",ex); } catch( ProviderException ex ) { log.info("Failed to read spam filter attachment, continuing...",ex); } } /** * Does a check against a known pattern list. * * @param context * @param content * @param change * @throws RedirectException */ private void checkPatternList(WikiContext context, String content, Change change) throws RedirectException { // // If we have no spam patterns defined, or we're trying to save // the page containing the patterns, just return. // if( m_spamPatterns == null || context.getPage().getName().equals( m_forbiddenWordsPage ) ) { return; } String ch = change.toString(); if( context.getHttpRequest() != null ) ch += context.getHttpRequest().getRemoteAddr(); for( Pattern p : m_spamPatterns ) { // log.debug("Attempting to match page contents with "+p.getPattern()); if( m_matcher.contains( ch, p ) ) { // // Spam filter has a match. // String uid = log( context, REJECT, REASON_REGEXP+"("+p.getPattern()+")", ch); log.info("SPAM:Regexp ("+uid+"). Content matches the spam filter '"+p.getPattern()+"'"); checkStrategy( context, REASON_REGEXP, "Herb says '"+p.getPattern()+"' is a bad spam word and I trust Herb! (Incident code "+uid+")"); } } } private void checkPatternList(WikiContext context, String content, String change ) throws RedirectException { Change c = new Change(); c.m_change = change; checkPatternList(context,content,c); } /** * Creates a simple text string describing the added content. * * @param context * @param newText * @return Empty string, if there is no change. */ private static Change getChange( WikiContext context, String newText ) { WikiPage page = context.getPage(); StringBuffer change = new StringBuffer(); WikiEngine engine = context.getEngine(); // Get current page version Change ch = new Change(); try { String oldText = engine.getPureText(page.getName(), WikiProvider.LATEST_VERSION); String[] first = Diff.stringToArray(oldText); String[] second = Diff.stringToArray(newText); Revision rev = Diff.diff(first, second, new MyersDiff()); if( rev == null || rev.size() == 0 ) { return ch; } for( int i = 0; i < rev.size(); i++ ) { Delta d = rev.getDelta(i); if( d instanceof AddDelta ) { d.getRevised().toString( change, "", "\r\n" ); ch.m_adds++; } else if( d instanceof ChangeDelta ) { d.getRevised().toString( change, "", "\r\n" ); ch.m_adds++; } else if( d instanceof DeleteDelta ) { ch.m_removals++; } } } catch (DifferentiationFailedException e) { log.error( "Diff failed", e ); } // // Don't forget to include the change note, too // String changeNote = (String)page.getAttribute(WikiPage.CHANGENOTE); if( changeNote != null ) { change.append("\r\n"); change.append(changeNote); } // // And author as well // if( page.getAuthor() != null ) { change.append("\r\n"+page.getAuthor()); } ch.m_change = change.toString(); return ch; } /** * Returns true, if this user should be ignored. For example, admin users. * * @param context * @return True, if this users should be ignored. */ private boolean ignoreThisUser(WikiContext context) { if( context.hasAdminPermissions() ) { return true; } if( m_ignoreAuthenticated && context.getWikiSession().isAuthenticated() ) { return true; } if( context.getVariable("captcha") != null ) { return true; } return false; } /** * Returns a random string of six uppercase characters. * * @return A random string */ private static String getUniqueID() { StringBuffer sb = new StringBuffer(); Random rand = new Random(); for( int i = 0; i < 6; i++ ) { char x = (char)('A'+rand.nextInt(26)); sb.append(x); } return sb.toString(); } /** * Returns a page to which we shall redirect, based on the current value * of the "captcha" parameter. * * @param ctx WikiContext * @return An URL to redirect to */ private String getRedirectPage( WikiContext ctx ) { if( m_useCaptcha ) return ctx.getURL( WikiContext.NONE, "Captcha.jsp", "page="+ctx.getEngine().encodeName(ctx.getPage().getName()) ); return ctx.getURL( WikiContext.VIEW, m_errorPage ); } /** * Checks whether the UserProfile matches certain checks. * * @param profile The profile to check * @param context The WikiContext * @return False, if this userprofile is suspect and should not be allowed to be added. * @since 2.6.1 */ public boolean isValidUserProfile( WikiContext context, UserProfile profile ) { try { checkPatternList( context, profile.getEmail(), profile.getEmail() ); checkPatternList( context, profile.getFullname(), profile.getFullname() ); checkPatternList( context, profile.getLoginName(), profile.getLoginName() ); } catch( RedirectException e ) { log.info("Detected attempt to create a spammer user account (see above for rejection reason)"); return false; } return true; } /** * This method is used to calculate an unique code when submitting the page * to detect edit conflicts. It currently incorporates the last-modified * date of the page, and the IP address of the submitter. * * @param page The WikiPage under edit * @param request The HTTP Request * @since 2.6 * @return A hash value for this page and session */ public static final String getSpamHash( WikiPage page, HttpServletRequest request ) { long lastModified = 0; if( page.getLastModified() != null ) lastModified = page.getLastModified().getTime(); long remote = request.getRemoteAddr().hashCode(); return Long.toString( lastModified ^ remote ); } /** * Returns the name of the hash field to be used in this request. * The value is unique per session, and once the session has expired, * you cannot edit anymore. * * @param request The page request * @return The name to be used in the hash field * @since 2.6 */ public static final String getHashFieldName( HttpServletRequest request ) { String hash = null; if( request.getSession() != null ) { hash = (String)request.getSession().getAttribute("_hash"); if( hash == null ) { hash = c_hashName; request.getSession().setAttribute( "_hash", hash ); } } if( c_hashName == null || c_lastUpdate < (System.currentTimeMillis() - HASH_DELAY*60*60*1000) ) { c_hashName = getUniqueID().toLowerCase(); c_lastUpdate = System.currentTimeMillis(); } return hash != null ? hash : c_hashName; } /** * This method checks if the hash value is still valid, i.e. if it exists at all. This * can occur in two cases: either this is a spam bot which is not adaptive, or it is * someone who has been editing one page for too long, and their session has expired. * <p> * This method puts a redirect to the http response field to page "SessionExpired" * and logs the incident in the spam log (it may or may not be spam, but it's rather likely * that it is). * * @param context The WikiContext * @param pageContext The JSP PageContext. * @return True, if hash is okay. False, if hash is not okay, and you need to redirect. * @throws IOException If redirection fails * @since 2.6 */ public static final boolean checkHash( WikiContext context, PageContext pageContext ) throws IOException { String hashName = getHashFieldName( (HttpServletRequest)pageContext.getRequest() ); if( pageContext.getRequest().getParameter(hashName) == null ) { if( pageContext.getAttribute( hashName ) == null ) { Change change = getChange( context, EditorManager.getEditedText( pageContext ) ); log( context, REJECT, "MissingHash", change.m_change ); String redirect = context.getURL(WikiContext.VIEW,"SessionExpired"); ((HttpServletResponse)pageContext.getResponse()).sendRedirect( redirect ); return false; } } return true; } /** * This helper method adds all the input fields to your editor that the SpamFilter requires * to check for spam. This <i>must</i> be in your editor form if you intend to use * the SpamFilter. * * @param pageContext The PageContext * @return A HTML string which contains input fields for the SpamFilter. */ public static final String insertInputFields( PageContext pageContext ) { WikiContext ctx = WikiContext.findContext(pageContext); WikiEngine engine = ctx.getEngine(); StringBuffer sb = new StringBuffer(); if (engine.getContentEncoding().equals("UTF-8")) { sb.append("<input name='encodingcheck' type='hidden' value='\u3041' />\n"); } return sb.toString(); } /** * A local class for storing host information. * * @since */ private class Host { private long m_addedTime = System.currentTimeMillis(); private long m_releaseTime; private String m_address; private Change m_change; public String getAddress() { return m_address; } public long getReleaseTime() { return m_releaseTime; } public long getAddedTime() { return m_addedTime; } public Change getChange() { return m_change; } public Host( String ipaddress, Change change ) { m_address = ipaddress; m_change = change; m_releaseTime = System.currentTimeMillis() + m_banTime * 60 * 1000L; } } private static class Change { public String m_change; public int m_adds; public int m_removals; public String toString() { return m_change; } public boolean equals(Object o) { if( o instanceof Change ) return m_change.equals( ((Change)o).m_change); return false; } public int hashCode() { return m_change.hashCode()+17; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -