001: /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
002: *
003: * Licensed under the Apache License, Version 2.0 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at
006: *
007: * http://www.apache.org/licenses/LICENSE-2.0
008: *
009: * Unless required by applicable law or agreed to in writing, software
010: * distributed under the License is distributed on an "AS IS" BASIS,
011: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: * See the License for the specific language governing permissions and
013: * limitations under the License.
014: */
015:
016: package org.acegisecurity.captcha;
017:
018: import org.acegisecurity.ConfigAttribute;
019: import org.acegisecurity.ConfigAttributeDefinition;
020:
021: import org.acegisecurity.context.SecurityContextHolder;
022:
023: import org.acegisecurity.intercept.web.FilterInvocation;
024:
025: import org.acegisecurity.securechannel.ChannelEntryPoint;
026: import org.acegisecurity.securechannel.ChannelProcessor;
027:
028: import org.apache.commons.logging.Log;
029: import org.apache.commons.logging.LogFactory;
030:
031: import org.springframework.beans.factory.InitializingBean;
032:
033: import org.springframework.util.Assert;
034:
035: import java.io.IOException;
036:
037: import java.util.Iterator;
038:
039: import javax.servlet.ServletException;
040:
041: /**
042: * <p>CaptchaChannel template : Ensures the user has enough human privileges by review of the {@link
043: * CaptchaSecurityContext} and using an abstract routine {@link
044: * #isContextValidConcerningHumanity(CaptchaSecurityContext)} (implemented by sub classes)</p>
045: * <P>The component uses 2 main parameters for its configuration :
046: * <ul>
047: * <li>a keyword to be mapped to urls in the {@link
048: * org.acegisecurity.securechannel.ChannelProcessingFilter} configuration<br>
049: * default value provided by sub classes.</li>
050: * <li>and a thresold : used by the routine {@link
051: * #isContextValidConcerningHumanity(CaptchaSecurityContext)} to evaluate whether the {@link
052: * CaptchaSecurityContext} is valid default value = 0</li>
053: * </ul>
054: * </p>
055: *
056: * @author marc antoine Garrigue
057: * @version $Id: CaptchaChannelProcessorTemplate.java 1496 2006-05-23 13:38:33Z benalex $
058: */
059: public abstract class CaptchaChannelProcessorTemplate implements
060: ChannelProcessor, InitializingBean {
061: //~ Instance fields ================================================================================================
062:
063: private ChannelEntryPoint entryPoint;
064: protected Log logger = LogFactory.getLog(this .getClass());
065: private String keyword = null;
066: private int thresold = 0;
067:
068: //~ Methods ========================================================================================================
069:
070: /**
071: * Verify if entryPoint and keyword are ok
072: *
073: * @throws Exception if not
074: */
075: public void afterPropertiesSet() throws Exception {
076: Assert.notNull(entryPoint, "entryPoint required");
077: Assert.hasLength(keyword, "keyword required");
078: }
079:
080: public void decide(FilterInvocation invocation,
081: ConfigAttributeDefinition config) throws IOException,
082: ServletException {
083: if ((invocation == null) || (config == null)) {
084: throw new IllegalArgumentException(
085: "Nulls cannot be provided");
086: }
087:
088: CaptchaSecurityContext context = null;
089: context = (CaptchaSecurityContext) SecurityContextHolder
090: .getContext();
091:
092: Iterator iter = config.getConfigAttributes();
093:
094: while (iter.hasNext()) {
095: ConfigAttribute attribute = (ConfigAttribute) iter.next();
096:
097: if (supports(attribute)) {
098: logger.debug("supports this attribute : " + attribute);
099:
100: if (!isContextValidConcerningHumanity(context)) {
101: logger
102: .debug("context is not allowed to access ressource, redirect to captcha entry point");
103: redirectToEntryPoint(invocation);
104: } else {
105: logger
106: .debug("has been successfully checked this keyword, increment request count");
107: context
108: .incrementHumanRestrictedRessoucesRequestsCount();
109: }
110: } else {
111: logger.debug("do not support this attribute");
112: }
113: }
114: }
115:
116: public ChannelEntryPoint getEntryPoint() {
117: return entryPoint;
118: }
119:
120: public String getKeyword() {
121: return keyword;
122: }
123:
124: public int getThresold() {
125: return thresold;
126: }
127:
128: abstract boolean isContextValidConcerningHumanity(
129: CaptchaSecurityContext context);
130:
131: private void redirectToEntryPoint(FilterInvocation invocation)
132: throws IOException, ServletException {
133: if (logger.isDebugEnabled()) {
134: logger
135: .debug("context is not valid : redirecting to entry point");
136: }
137:
138: entryPoint.commence(invocation.getRequest(), invocation
139: .getResponse());
140: }
141:
142: public void setEntryPoint(ChannelEntryPoint entryPoint) {
143: this .entryPoint = entryPoint;
144: }
145:
146: public void setKeyword(String keyword) {
147: this .keyword = keyword;
148: }
149:
150: public void setThresold(int thresold) {
151: this .thresold = thresold;
152: }
153:
154: public boolean supports(ConfigAttribute attribute) {
155: if ((attribute != null)
156: && (keyword.equals(attribute.getAttribute()))) {
157: return true;
158: } else {
159: return false;
160: }
161: }
162: }
|