Author: tyrell
Date: Sun Feb 10 00:39:38 2008
New Revision: 13508
Log:
Adding captcha to the self registration page.
Added:
trunk/mashup/java/modules/www/captcha.jsp
Modified:
trunk/mashup/java/modules/core/src/org/wso2/mashup/webapp/identity/RegistrationBean.java
trunk/mashup/java/modules/www/register_self.jsp
Modified:
trunk/mashup/java/modules/core/src/org/wso2/mashup/webapp/identity/RegistrationBean.java
==============================================================================
---
trunk/mashup/java/modules/core/src/org/wso2/mashup/webapp/identity/RegistrationBean.java
(original)
+++
trunk/mashup/java/modules/core/src/org/wso2/mashup/webapp/identity/RegistrationBean.java
Sun Feb 10 00:39:38 2008
@@ -50,6 +50,8 @@
private String password;
private String confirmedPassword;
private String emailId;
+ private String captcha;
+
private boolean adminCreation;
private Hashtable errors;
@@ -93,6 +95,14 @@
this.emailId = emailId;
}
+ public String getCaptcha() {
+ return captcha;
+ }
+
+ public void setCaptcha(String captcha) {
+ this.captcha = captcha;
+ }
+
public boolean isAdminCreation() {
return adminCreation;
}
@@ -110,6 +120,7 @@
this.emailId = "";
this.password = "";
this.confirmedPassword = "";
+ this.captcha = "";
this.errors = new Hashtable();
}
@@ -148,8 +159,8 @@
RegistryConstants.REGISTRY);
Realm realm = (Realm)
context.getAttribute(RegistryConstants.REGISTRY_REALM);
SecureRegistry registry =
RegistryUtils.createSecureRegistry(MashupConstants.SYSTEM_USER,
-
MashupConstants.SYSTEM_USER_PASSWORD,
- jdbcRegistry, realm);
+
MashupConstants.SYSTEM_USER_PASSWORD,
+
jdbcRegistry, realm);
try {
// Get an instance of the user store admin and create the user.
UserStoreAdmin userStoreAdmin = realm.getUserStoreAdmin();
@@ -200,7 +211,7 @@
* @param request Servlet request.
* @return true if user is successfully validated.
*/
- public static boolean validate(HttpServletRequest request) throws
MashupFault{
+ public static boolean validate(HttpServletRequest request) throws
MashupFault {
boolean isVerified = false;
String confValue = request.getParameter("confirmation");
String userName;
@@ -235,6 +246,7 @@
/**
* Gets the current self registration status.
+ *
* @return true if enabled.
*/
public static boolean isSelfRegistrationEnabled() {
@@ -243,7 +255,7 @@
return "true".equals(status);
}
- /**
+ /**
* Authorizes user to the registry by granting him a role, then adding a
user directory and
* creating a profile granting user edit access.
*
@@ -251,7 +263,8 @@
* @param userName Identifier of user to be authorized.
* @return true if user authorization succeeds.
*/
- private static boolean authorizeUser(HttpServletRequest request, String
userName) throws MashupFault{
+ private static boolean authorizeUser(HttpServletRequest request, String
userName)
+ throws MashupFault {
boolean isAuthorized = false;
ServletContext context = request.getSession().getServletContext();
JDBCRegistry jdbcRegistry =
@@ -265,9 +278,10 @@
String eMail = (String) userProps.get(MashupConstants.EMAIL_ID);
// Create secure registry instance using the admin ID.
- SecureRegistry secureRegistry =
RegistryUtils.createSecureRegistry(MashupConstants.SYSTEM_USER,
-
MashupConstants.SYSTEM_USER_PASSWORD,
- jdbcRegistry,
realm);
+ SecureRegistry secureRegistry =
+
RegistryUtils.createSecureRegistry(MashupConstants.SYSTEM_USER,
+
MashupConstants.SYSTEM_USER_PASSWORD,
+ jdbcRegistry, realm);
// Add user to registry.
RegistryUtils.createUser(secureRegistry, realm, userName,
fullName, eMail, fullName);
isAuthorized = true;
@@ -288,6 +302,7 @@
*/
public boolean isInputValid(HttpServletRequest request) {
boolean valid = true;
+
if (userName.equals("")) {
errors.put("userName", "User name cannot be empty.");
valid = false;
@@ -295,6 +310,15 @@
// Full name and e-mail ID are not mandatory for creating the admin
profile.
if (!adminCreation) {
+
+ //First and formost checking captcha and returning immediately if
invalid
+ String expectedCaptchaValue = (String)
request.getSession().getAttribute("captcha");
+ if (!captcha.equals(expectedCaptchaValue)) {
+ errors.put("captcha",
+ "The text you typed in doesn't match with the text
in image. Please try again.");
+ return false;
+ }
+
if (fullName.equals("")) {
errors.put("fullName", "Full name cannot be empty.");
valid = false;
@@ -322,9 +346,10 @@
/**
* Performs the password validation and returns the validity state.
- * @param password The content of the password field.
+ *
+ * @param password The content of the password field.
* @param confirmedPassword The content of the confirmed password field.
- * @param errors table of errors.
+ * @param errors table of errors.
* @return true if the password and confirmation are valid.
*/
public static boolean isPasswordValid(String password, String
confirmedPassword,
Added: trunk/mashup/java/modules/www/captcha.jsp
==============================================================================
--- (empty file)
+++ trunk/mashup/java/modules/www/captcha.jsp Sun Feb 10 00:39:38 2008
@@ -0,0 +1,168 @@
+<%--
+ * Copyright 2006,2007 WSO2, Inc. http://www.wso2.org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+--%>
+<%@ page import="java.util.*" %>
+<%@ page import="javax.imageio.IIOImage" %>
+<%@ page import="javax.imageio.ImageIO" %>
+<%@ page import="javax.imageio.ImageWriteParam" %>
+<%@ page import="javax.imageio.ImageWriter" %>
+<%@ page import="javax.servlet.http.HttpServletRequest" %>
+<%@ page import="java.awt.*" %>
+<%@ page import="java.awt.geom.AffineTransform" %>
+<%@ page import="java.awt.image.BufferedImage" %>
+<%@ page import="java.io.IOException" %>
+<%@ page import="java.util.Iterator" %>
+<%
+ String imageFormat = "jpg";
+ response.setContentType("image/" + imageFormat);
+
+ try {
+ // you can pass in fontSize, width, height via the request
+
+ Color backgroundColor = Color.gray;
+ Color borderColor = Color.black;
+ Color textColor = Color.white;
+ Color circleColor = new Color(160, 160, 160);
+ Font textFont = new Font("Arial", Font.PLAIN, paramInt(request,
"fontSize", 24));
+ int charsToPrint = 6;
+ int width = paramInt(request, "width", 150);
+ int height = paramInt(request, "height", 80);
+ int circlesToDraw = 6;
+ float horizMargin = 20.0f;
+ float imageQuality = 0.95f; // max is 1.0 (this is for jpeg)
+ double rotationRange = 0.7; // this is radians
+ BufferedImage bufferedImage = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
+
+ Graphics2D g = (Graphics2D) bufferedImage.getGraphics();
+
+ g.setColor(backgroundColor);
+ g.fillRect(0, 0, width, height);
+
+ // lets make some noisey circles
+ g.setColor(circleColor);
+ for (int i = 0; i < circlesToDraw; i++) {
+ int circleRadius = (int) (Math.random() * height / 2.0);
+ int circleX = (int) (Math.random() * width - circleRadius);
+ int circleY = (int) (Math.random() * height - circleRadius);
+ g.drawOval(circleX, circleY, circleRadius * 2, circleRadius * 2);
+ }
+
+ g.setColor(textColor);
+ g.setFont(textFont);
+
+ FontMetrics fontMetrics = g.getFontMetrics();
+ int maxAdvance = fontMetrics.getMaxAdvance();
+ int fontHeight = fontMetrics.getHeight();
+
+ // i removed 1 and l and i because there are confusing to users...
+ // Z, z, and N also get confusing when rotated
+ // 0, O, and o are also confusing...
+ // lowercase G looks a lot like a 9 so i killed it
+ // this should ideally be done for every language...
+ // i like controlling the characters though because it helps prevent
confusion
+ String elegibleChars =
"ABCDEFGHJKLMPQRSTUVWXYabcdefhjkmnpqrstuvwxy23456789";
+ char[] chars = elegibleChars.toCharArray();
+
+ float spaceForLetters = -horizMargin * 2 + width;
+ float spacePerChar = spaceForLetters / (charsToPrint - 1.0f);
+
+ AffineTransform transform = g.getTransform();
+
+ StringBuffer finalString = new StringBuffer();
+
+ for (int i = 0; i < charsToPrint; i++) {
+ double randomValue = Math.random();
+ int randomIndex = (int) Math.round(randomValue * (chars.length -
1));
+ char characterToShow = chars[randomIndex];
+ finalString.append(characterToShow);
+
+ // this is a separate canvas used for the character so that
+ // we can rotate it independently
+ int charImageWidth = maxAdvance * 2;
+ int charImageHeight = fontHeight * 2;
+ int charWidth = fontMetrics.charWidth(characterToShow);
+ int charDim = Math.max(maxAdvance, fontHeight);
+ int halfCharDim = (int) (charDim / 2);
+
+ BufferedImage charImage =
+ new BufferedImage(charDim, charDim,
BufferedImage.TYPE_INT_ARGB);
+ Graphics2D charGraphics = charImage.createGraphics();
+ charGraphics.translate(halfCharDim, halfCharDim);
+ double angle = (Math.random() - 0.5) * rotationRange;
+ charGraphics.transform(AffineTransform.getRotateInstance(angle));
+ charGraphics.translate(-halfCharDim, -halfCharDim);
+ charGraphics.setColor(textColor);
+ charGraphics.setFont(textFont);
+
+ int charX = (int) (0.5 * charDim - 0.5 * charWidth);
+ charGraphics.drawString("" + characterToShow, charX,
+ (int) ((charDim - fontMetrics.getAscent())
+ / 2 + fontMetrics.getAscent()));
+
+ float x = horizMargin + spacePerChar * (i) - charDim / 2.0f;
+ int y = (int) ((height - charDim) / 2);
+
+ g.drawImage(charImage, (int) x, y, charDim, charDim, null, null);
+
+ charGraphics.dispose();
+ }
+
+ // let's do the border
+ g.setColor(borderColor);
+ g.drawRect(0, 0, width - 1, height - 1);
+
+ //Write the image as a jpg
+ Iterator iter = ImageIO.getImageWritersByFormatName(imageFormat);
+ if (iter.hasNext()) {
+ ImageWriter writer = (ImageWriter) iter.next();
+ ImageWriteParam iwp = writer.getDefaultWriteParam();
+ if (imageFormat.equalsIgnoreCase("jpg") ||
imageFormat.equalsIgnoreCase("jpeg")) {
+ iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+ iwp.setCompressionQuality(imageQuality);
+ }
+
writer.setOutput(ImageIO.createImageOutputStream(response.getOutputStream()));
+ IIOImage imageIO = new IIOImage(bufferedImage, null, null);
+ writer.write(null, imageIO, iwp);
+ } else {
+ throw new RuntimeException("no encoder found for jsp");
+ }
+
+ // let's stick the final string in the session
+ request.getSession().setAttribute("captcha", finalString.toString());
+
+ g.dispose();
+
+ } catch (Exception ioe) {
+ throw new RuntimeException("Unable to build image", ioe);
+ }
+
+ //Adding this because we called response.getOutputStream() above. This
will prevent and illegal state exception being thrown
+ out.clear();
+ out = pageContext.pushBody();
+%>
+
+<%!
+ public static String paramString(HttpServletRequest request, String
paramName,
+ String defaultString) {
+ return request.getParameter(paramName) != null ?
request.getParameter(paramName) :
+ defaultString;
+ }
+
+ public static int paramInt(HttpServletRequest request, String paramName,
int defaultInt) {
+ return request.getParameter(paramName) != null ?
+ Integer.parseInt(request.getParameter(paramName)) : defaultInt;
+ }
+
+%>
\ No newline at end of file
Modified: trunk/mashup/java/modules/www/register_self.jsp
==============================================================================
--- trunk/mashup/java/modules/www/register_self.jsp (original)
+++ trunk/mashup/java/modules/www/register_self.jsp Sun Feb 10 00:39:38 2008
@@ -82,7 +82,7 @@
<link href="css/styles.css" rel="stylesheet" type="text/css"/>
<script language="javascript" src="js/common.js"
type="text/javascript"></script>
<script language="javascript"
- type="text/javascript">userLoggedOn =
<%=RegistryUtils.isLoggedIn(registry) %>;</script>
+ type="text/javascript">userLoggedOn =
<%=RegistryUtils.isLoggedIn(registry) %>;</script>
</head>
<body>
<div id="page">
@@ -136,6 +136,18 @@
.getErrorMessage("confirmedPassword")%></font>
</td>
</tr>
+ <tr>
+ <td>
+ <div align="center"><img
src="captcha.jsp"/></div>
+ </td>
+ <td>
+ <label>Type the text you see in the image
here<font color="#FF0000">*</font></label>
+ <br/>
+ <input type="text" name="captcha"
+
value="<%=registrationHandler.getCaptcha()%>"/>
+ <br><font
color="#FF0000"><%=registrationHandler.getErrorMessage("captcha")%></font>
+ </td>
+ </tr>
<tr>
<td> </td>
<td><input type="submit" value="Register"/>
<input type="button" value="Cancel" onclick="document.location = '<%=
bounceback %>';"></td>
@@ -161,7 +173,7 @@
<div class="mashup_title">Self Registration Disabled</div>
<div> Self-registration disabled. Please contact
administrator to register yourself.</div>
<% } %>
- <br>
+ <br>
</div>
<%@ include file="footer.jsp" %>
</div>
_______________________________________________
Mashup-dev mailing list
[email protected]
http://www.wso2.org/cgi-bin/mailman/listinfo/mashup-dev