segunda-feira, agosto 14, 2006

Captcha in JavaBB Project

I have noted that many "fake users" had already inserted in our DataBase. But, how it happened?
Simple! We weren't using Captcha control. Do you know what is Captcha?

From Wikipedia:
A CAPTCHA (an acronym for "completely automated public Turing test to tell computers and humans apart", trademarked by Carnegie Mellon University) is a type of challenge-response test used in computing to determine whether or not the user is human. The term was coined in 2000 by Luis von Ahn, Manuel Blum, Nicholas J. Hopper of Carnegie Mellon University, and John Langford of IBM. A common type of CAPTCHA requires that the user type the letters of a distorted image, sometimes with the addition of an obscured sequence of letters or digits that appears on the screen. Because the test is administered by a computer, in contrast to the standard Turing test that is administered by a human, a CAPTCHA is sometimes described as a reverse Turing test. This term, however, is ambiguous because it could also mean a Turing test in which the participants are both attempting to prove they are the computer.

After this, I've just put Captcha in JavaBB project, as you know, JavaBB is my OpenSource Project based on phpBB project.
JavaBB is a software based on Java, developed specifically with intention to join communities.
Based in phpbb, we are working pledged by the success of phpBB, to become javaBB so efficient as it.

Well, let's straight to some example of how you can use Captcha in your Java Project. In this example, I'm using SimpleCaptcha library. After all, what is SimpleCaptcha??

From SimpleCaptcha site:
The purpose of the simple java captcha project is to make it easy to generate good-looking captchas with a minimum of programming and preferably little configuration.

SimpleCaptcha is an open Source Java implementation for captcha creation. Integration is left to the developers of the individual projects because I don't (want) to know your implementations...

My original interest for the thing was after a distributed dictionary attack against one of our systems. Just to make it a little harder we put a quick hack of a picture on the site. The thing was configured so it would only enable itself when an x amount of logins would have failed over an y amount of time. Unfortunately this was found too confusing.
Put in your web.xml the follow lines:

<servlet>
<
servlet-name>Captcha < / servlet-name>
<
display-name>Captcha < / display-name>
<
servlet-class>nl.captcha.servlet.CaptchaServlet < / servlet-class>

And this mapping:

<servlet-mapping>
<servlet-name>Captcha< / servlet-name>
<
url-pattern>/Captcha.jpg< / url-pattern>
servlet-mapping>


Now that you have already configured your web.xml, you must use in your JSP file (velocity, freemarker template and so forth..) an image control like this:

<
img src="Captcha.jpg">

and in your Controller (Action of Struts, WebWork..) or in some JSP file, you must check the value from the text field against the captcha key stored in the session:
(String)session.getAttribute(nl.captcha.servlet.Constants.SIMPLE_CAPCHA_SESSION_KEY) ;

Note that with each request to the servlet the current value of the key in the session is replaced with a new one.

The image generated by SimpleCaptcha library



Well, now that you know how SimpleCaptcha works, you can download and try by yourself :)

segunda-feira, agosto 07, 2006

A little bit about Spring 2.0



Yesterday I was playing a little bit around with the new features of Spring 2.0.
I would know how Spring Team can think in features that can improve more and more this framework that in my opinion is enough great.
I made some and I’m really surprised the ability to attach post-instantiation processors to beans which have NOT been instantiated by the Spring container. This means a lot to me when I started thinking about how this feature can add value to the current scheme of things in a POJO based Spring configured application.

Let’s straight to example:
public class Product {
// price
// getters and setters
// domain behavior
}
As you know, a typical domain object is instantiated in the application either from the ORM layer -read Hibernate through persistence services- or by the user using factories. Any sort of service injection that is done will be through hardwired code
public class Product {
// ...
public BigDecimal calculatePrice(...) {
BigDecimal productVendorsPrices =
VendorsRateDAO.getInstance().find(...);
// ...
}
// ...
}
The above domain class now has a hardwired dependency on the class VendorsRateDAO, which brings in all sorts of unwanted side-effects :

Domain layer should be persistence agnostic
The domain classes should be unit-testable without the service layer
Proliferation of business logic in the controllers
// Controller class for product entry use case
public class ProductService {
// ...
public void enterProduct(...) {
Product pr = ProductFactory.create(...);
//..
}
// ...
}


Wow, its smell so dirty code!! The domain model becomes anemic !.

Using Spring 2.0

Using the new extension of AOP in Spring 2.0, you can inject any object even if it has been created outside the control of the container.
Spring 2.0 offers annotation driven aspects towards this end as the most recommended approach towards dependency injection into the domain model. Let us see how the Product class changes :
@Configurable("product")
public class Product {
// ...
public BigDecimal calculatePrice (...) {
BigDecimal interest =
dao.find(...);
// ...
}
// ...

// injected DAO
private VendorsRateDao dao;
public void setDao(VendorsRateDao dao) {
this.dao = dao;
}
}


And the usual stuff in the XML for application context :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
...>

  <aop:spring-configured/>

  <bean id="vendorsRateDAO"
    class="org.javafree.dao.VendorsRateDaoImpl"/>

  <bean id="trade"
    class="org.javafree.model.Product"
    lazy-init="true">
    <property name="dao" ref="vendorsRateDAO" />
  </bean>
</beans>

Well, now that you know how Spring can lets you Architecture more cleaner, why are you using EJB yet?