Author: michiel
Date: 2010-02-08 16:45:28 +0100 (Mon, 08 Feb 2010)
New Revision: 40902

Added:
   
mmbase/trunk/applications/resources/src/main/java/org/mmbase/datatypes/CaptchaDataType.java
Modified:
   mmbase/trunk/applications/resources/src/main/config/datatypes.xml
   
mmbase/trunk/applications/resources/src/main/resources/META-INF/tags/mm/resources/captcha.tagx
Log:
  MMB-1926

Modified: mmbase/trunk/applications/resources/src/main/config/datatypes.xml
===================================================================
--- mmbase/trunk/applications/resources/src/main/config/datatypes.xml   
2010-02-08 15:44:49 UTC (rev 40901)
+++ mmbase/trunk/applications/resources/src/main/config/datatypes.xml   
2010-02-08 15:45:28 UTC (rev 40902)
@@ -35,6 +35,20 @@
         <class name="org.mmbase.datatypes.processors.BinaryFile$Delete" />
       </deleteprocessor>
     </specialization>
+
+
+    <specialization id="captcha">
+      <class name="org.mmbase.datatypes.CaptchaDataType" />
+      <handler
+          mimetype="text/html,application/xhtml+xml"
+          name="org.mmbase.datatypes.CaptchaDataType$Handler">
+        <param name="length">6</param>
+        <param name="swirl">30</param>
+        <param name="background">transparent</param>
+      </handler>
+      <required value="true" />
+      <length value="6" enforce="always" />
+    </specialization>
   </datatype>
 
 

Copied: 
mmbase/trunk/applications/resources/src/main/java/org/mmbase/datatypes/CaptchaDataType.java
 (from rev 40901, 
mmbase/branches/MMBase-1_9/applications/resources/src/main/java/org/mmbase/datatypes/CaptchaDataType.java)
===================================================================
--- 
mmbase/trunk/applications/resources/src/main/java/org/mmbase/datatypes/CaptchaDataType.java
                         (rev 0)
+++ 
mmbase/trunk/applications/resources/src/main/java/org/mmbase/datatypes/CaptchaDataType.java
 2010-02-08 15:45:28 UTC (rev 40902)
@@ -0,0 +1,228 @@
+/*
+
+This software is OSI Certified Open Source Software.
+OSI Certified is a certification mark of the Open Source Initiative.
+
+The license (Mozilla version 1.0) can be read at the MMBase site.
+See http://www.MMBase.org/license
+
+*/
+package org.mmbase.datatypes;
+
+import org.mmbase.datatypes.handlers.*;
+import org.mmbase.bridge.*;
+import org.mmbase.bridge.util.*;
+import org.mmbase.util.*;
+import org.mmbase.util.logging.*;
+import javax.servlet.http.*;
+import java.util.*;
+import java.io.*;
+import org.mmbase.util.images.*;
+
+
+/**
+
+ * @author Michiel Meeuwissen
+ * @since MMBase-1.9.3
+ */
+
+public class CaptchaDataType extends StringDataType {
+
+    private static final Logger LOG = 
Logging.getLoggerInstance(CaptchaDataType.class);
+
+    public static final String KEY = CaptchaDataType.class.getName() + ".KEY";
+
+    public static final String BASE = "temporary_images";
+
+    protected CaptchaRestriction  captchaRestriction =  new 
CaptchaRestriction();
+
+    private static final byte[] GIFBYTES = new byte[]{
+             0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x01, 0x00, 0x01, 0x00,
+             (byte)0x80, 0x00, 0x00, (byte)0xff, (byte)0xff, (byte)0xff,
+             0x00, 0x00, 0x00, 0x21, (byte)0xf9, 0x04, 0x00, 0x00, 0x00,
+             0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00,
+             0x01, 0x00, 0x01, 0x00, 0x40, 0x02, 0x02, 0x44, 0x01, 0x00,
+             0x3b, 0x0a};
+
+    private static final Timer DELETER = new Timer(true);
+
+    public static class CaptchaImage {
+        public File file;
+        public final String text;
+        public int height;
+        public int width;
+        public String background = "white";
+        public String fillColor = "black";
+        public int swirl = 30;
+
+        public CaptchaImage(String text) {
+            this.text = text;
+        }
+        // Silly stupid getters are needed in EL. EL sucks.
+
+        public File getFile() {
+            return file;
+        }
+        public String getPath() {
+            return org.mmbase.servlet.MMBaseServlet.getBasePath("files") + 
BASE + "/" + getFile().getName();
+        }
+        public int getHeight() {
+            return height;
+        }
+        public int getWidth() {
+            return width;
+        }
+        public String getText() {
+            return text;
+        }
+
+    }
+    private static final String[] CHARSET = {"3","4","5","6","7","8", 
"a","b","c","d","e","f","h","i","j","k","m","n","p","q","r","s","t","u","v","w","x","y"};
    // 29
+    private static final Random RAND = new Random();
+    public static String createString(int length) {
+        StringBuilder sb = new StringBuilder();
+        for(int n = 0; n < length; n++) {
+            sb = sb.append(CHARSET[RAND.nextInt(CHARSET.length)]);
+        }
+        return sb.toString();
+    }
+
+
+    public static void createCaptchaImage(InputStream input, final 
CaptchaImage image) throws IOException {
+        if (input == null) {
+            input = new ByteArrayInputStream(GIFBYTES);
+        }
+        final File directory =  org.mmbase.servlet.FileServlet.getFile(BASE, 
null);
+        directory.mkdir();
+        image.file = File.createTempFile("captcha", ".png", directory);
+        image.file.deleteOnExit();
+        FileReceiver receiver = new FileReceiver(image.file);
+        List<String> commands = new ArrayList<String>();
+        if (image.background != null && !image.background.equals("white") && 
!image.background.equals("#fff")) {
+            if ("transparent".equals(image.background)) {
+                commands.add("transparent(white)");
+            } else {
+                commands.add("fill(" + image.background + ")");
+                commands.add("draw(color 0,0 reset)");
+            }
+        }
+        commands.add("gravity(west)");
+        commands.add("s(80x22!)");
+        commands.add("fill(" + image.fillColor + ")");
+        commands.add("pointsize(20)");
+        commands.add("text(0,0,\'" + image.text + "')");
+        commands.add("f(png)");
+        commands.add("swirl(" + image.swirl + ")");
+        ImageConversionRequest req =
+            Factory.getImageConversionRequest(input, "gif", receiver, 
commands);
+
+        req.waitForConversion();
+        DELETER.schedule(new TimerTask() { public void run() 
{image.file.delete();} }, 60000);
+        Dimension dim = receiver.getDimension();
+        image.width  = dim.getWidth();
+        image.height = dim.getHeight();
+    }
+
+    public CaptchaDataType(String name) {
+        super(name);
+    }
+
+    @Override
+    protected Collection<LocalizedString> 
validateCastValue(Collection<LocalizedString> errors, Object castValue, Object 
value, Node node, Field field) {
+        LOG.debug("Validating " + castValue);
+        errors = super.validateCastValue(errors, castValue, value,  node, 
field);
+        errors = captchaRestriction.validate(errors, castValue, node, field);
+        return errors;
+    }
+
+
+    protected class CaptchaRestriction extends AbstractRestriction<String> {
+        private static final long serialVersionUID = 0L;
+        CaptchaRestriction(CaptchaRestriction source) {
+            super(source);
+        }
+        CaptchaRestriction() {
+            super("captcha", null);
+        }
+
+        @Override
+        protected boolean simpleValid(final Object v, final Node node, final 
Field field) {
+            Cloud cloud = CloudThreadLocal.currentCloud();
+            if (cloud == null) {
+                LOG.debug("" + v + " is valid because no cloud found");
+                return true;
+            } else {
+                HttpServletRequest req = (HttpServletRequest) 
cloud.getProperty(Cloud.PROP_REQUEST);
+                if (req == null) {
+                    LOG.debug("" + v + " is valid because no request found in 
cloud");
+                    return true;
+                }
+                HttpSession session = req.getSession(false);
+                if (session == null) {
+                    LOG.debug("" + v + " is invalid because no session found 
in cloud");
+                    return false;
+                }
+                String mustbe = (String) session.getAttribute(KEY);
+                if (mustbe == null) {
+                    LOG.debug("" + v + " is invalid because " + KEY + " not 
found in session");
+                    return false;
+                }
+                LOG.debug("Found " + KEY + " is " + value + " (user provided  
'" + v + "')");
+                return mustbe.equalsIgnoreCase(Casting.toString(v));
+            }
+        }
+    }
+
+
+    public static class Handler extends 
org.mmbase.datatypes.handlers.html.StringHandler {
+
+        private int length = 5;
+        private int swirl = 30;
+        private String background = "white";
+
+
+        public void setLength(int l) {
+            length = l;
+        }
+        public void setSwirl(int s) {
+            swirl = s;
+        }
+
+        public void setBackground(String bg) {
+            background = bg;
+        }
+
+        @Override
+        public String input(Request request, Node node, Field field, boolean 
search)  {
+            if (search) {
+                return super.input(request, node, field, search);
+            } else {
+                HttpServletRequest req = (HttpServletRequest) 
request.getCloud().getProperty(Cloud.PROP_REQUEST);
+                HttpSession session = req.getSession(true);
+                CaptchaImage image = new 
CaptchaDataType.CaptchaImage(createString(length));
+                image.swirl = swirl;
+                image.background = background;
+                StringBuilder show =  new StringBuilder();
+                try {
+                    CaptchaDataType.createCaptchaImage(null, image);
+                    session.setAttribute(CaptchaDataType.KEY, image.text);
+                    show.append("<img src='");
+                    show.append(req.getContextPath());
+                    show.append(image.getPath());
+                    show.append("' alt='captcha' width='");
+                    show.append(image.getWidth());
+                    show.append("' height='");
+                    show.append(image.getHeight());
+                    show.append("' />");
+                } catch (Exception e) {
+                    LOG.error(e);
+                    show.append(e.getMessage());
+                }
+                show.append(super.input(request, node, field, search));
+                return show.toString();
+            }
+        }
+
+    }
+
+}

Modified: 
mmbase/trunk/applications/resources/src/main/resources/META-INF/tags/mm/resources/captcha.tagx
===================================================================
--- 
mmbase/trunk/applications/resources/src/main/resources/META-INF/tags/mm/resources/captcha.tagx
      2010-02-08 15:44:49 UTC (rev 40901)
+++ 
mmbase/trunk/applications/resources/src/main/resources/META-INF/tags/mm/resources/captcha.tagx
      2010-02-08 15:45:28 UTC (rev 40902)
@@ -19,16 +19,10 @@
   <jsp:directive.attribute name="fill"     type="java.lang.String" />
 
   <!-- If the key is stated explicitely, no new key is generated, but this 
given one is shown. -->
-  
+
   <jsp:directive.attribute name="key"      type="java.lang.String" />
   <jsp:declaration>
-    static final byte[] gifBytes = new byte[]{
-             0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x01, 0x00, 0x01, 0x00,
-             (byte)0x80, 0x00, 0x00, (byte)0xff, (byte)0xff, (byte)0xff,
-             0x00, 0x00, 0x00, 0x21, (byte)0xf9, 0x04, 0x00, 0x00, 0x00,
-             0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00,
-             0x01, 0x00, 0x01, 0x00, 0x40, 0x02, 0x02, 0x44, 0x01, 0x00,
-             0x3b, 0x0a};
+
     static final String[] charset = {"3","4","5","6","7","8", 
"a","b","c","d","e","f","h","i","j","k","m","n","p","q","r","s","t","u","v","w","x","y"};
    // 29 elements
     static final Random rand = new Random();
     static Timer deleter = new Timer(true);
@@ -105,4 +99,4 @@
       </c:otherwise>
     </c:choose>
   </mm:link>
-</jsp:root>
\ No newline at end of file
+</jsp:root>

_______________________________________________
Cvs mailing list
[email protected]
http://lists.mmbase.org/mailman/listinfo/cvs

Reply via email to