KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > forms > formmodel > CaptchaField


1 /*
2  * Copyright 1999-2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.cocoon.forms.formmodel;
17
18 import java.security.NoSuchAlgorithmException JavaDoc;
19 import java.security.SecureRandom JavaDoc;
20 import java.util.Locale JavaDoc;
21 import java.util.Map JavaDoc;
22
23 import org.apache.avalon.framework.CascadingRuntimeException;
24 import org.apache.avalon.framework.context.Context;
25 import org.apache.cocoon.components.ContextHelper;
26 import org.apache.cocoon.environment.ObjectModelHelper;
27 import org.apache.cocoon.environment.Session;
28 import org.apache.cocoon.forms.FormsConstants;
29 import org.apache.cocoon.xml.AttributesImpl;
30 import org.xml.sax.ContentHandler JavaDoc;
31 import org.xml.sax.SAXException JavaDoc;
32
33
34 /**
35  * A {@link Field} for CAPTCHA validation. Upon generation, a secret random string is stored
36  * in a session attribute having a randomly generated name, for use by a
37  * {@link org.apache.cocoon.forms.validation.impl.CaptchaValidator}.
38  * <br>
39  * Usage sample:
40  * <pre>
41     &lt;fd:captcha id="f1" required="true">
42       &lt;fd:label>Copy the number shown into the input field&lt;/fd:label>
43       &lt;fd:datatype base="string"/>
44       &lt;fd:validation>
45         &lt;fd:captcha/>
46       &lt;/fd:validation>
47     &lt;/fd:captcha>
48  * </pre>
49  *
50  * @see <a HREF="http://www.captcha.net/">captcha.net</a>
51  * @version CVS $Id: CaptchaField.java 326838 2005-10-20 06:26:53Z sylvain $
52  */

53 public class CaptchaField extends Field {
54
55     public static final String JavaDoc SESSION_ATTR_PREFIX = "captcha-";
56
57     private static final String JavaDoc IMAGE_EL = "captcha-image";
58     private static final String JavaDoc SECRET_CHARS = "abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ123456789";
59     private static final int SESSION_ATTR_NAME_LENGTH = 6;
60
61     private Context avalonContext;
62     private int length;
63
64     /**
65      * Random number generator used to create session attribute name.
66      */

67     protected static SecureRandom JavaDoc random;
68
69     static {
70         try {
71             random = SecureRandom.getInstance("SHA1PRNG");
72         } catch(java.security.NoSuchAlgorithmException JavaDoc nsae) {
73             // Maybe we are on IBM's SDK
74
try {
75                 random = SecureRandom.getInstance("IBMSecureRandom");
76             } catch (NoSuchAlgorithmException JavaDoc e) {
77                 throw new CascadingRuntimeException("No random number generator available", e);
78             }
79         }
80         random.setSeed(System.currentTimeMillis());
81     }
82
83     public CaptchaField(CaptchaFieldDefinition fieldDefinition, Context avalonContext) {
84         super(fieldDefinition);
85         this.avalonContext = avalonContext;
86         this.length = fieldDefinition.getLength();
87     }
88
89     private String JavaDoc generateSecret() {
90         StringBuffer JavaDoc secret = new StringBuffer JavaDoc(length);
91         for (int n = 0 ; n < length ; n++) {
92             int randomnumber = random.nextInt(SECRET_CHARS.length());
93             secret.append(SECRET_CHARS.charAt(randomnumber));
94         }
95         return secret.toString();
96     }
97
98     public void generateItemSaxFragment(ContentHandler JavaDoc contentHandler, Locale JavaDoc locale) throws SAXException JavaDoc {
99         super.generateItemSaxFragment(contentHandler, locale);
100         byte[] bytes = new byte[SESSION_ATTR_NAME_LENGTH];
101         char[] result = new char[bytes.length * 2];
102         random.nextBytes(bytes);
103         for (int i = 0; i < SESSION_ATTR_NAME_LENGTH; i++) {
104             byte ch = bytes[i];
105             result[2 * i] = Character.forDigit(Math.abs(ch >> 4), 16);
106             result[2 * i + 1] = Character.forDigit(Math.abs(ch & 0x0f), 16);
107         }
108         String JavaDoc id = new String JavaDoc(result);
109         Map JavaDoc objectModel = ContextHelper.getObjectModel(this.avalonContext);
110         Session session = ObjectModelHelper.getRequest(objectModel).getSession(true);
111         String JavaDoc secret = generateSecret();
112         session.setAttribute(SESSION_ATTR_PREFIX + id, secret);
113         this.setAttribute("secret", secret);
114         AttributesImpl attrs = new AttributesImpl();
115         attrs.addAttribute("", "id", "id", "PCDATA", id);
116         contentHandler.startElement(FormsConstants.INSTANCE_NS, IMAGE_EL, FormsConstants.INSTANCE_PREFIX_COLON + IMAGE_EL, attrs);
117         contentHandler.endElement(FormsConstants.INSTANCE_NS, IMAGE_EL, FormsConstants.INSTANCE_PREFIX_COLON + IMAGE_EL);
118     }
119 }
120
Popular Tags