Sunday, February 27, 2011

Integrating reCaptcha in wicket

Intro

Recaptcha is a very nice widget used to stop spam on your blogs or prevent automated form completion.

This post is about how you can integrate the reCaptcha in your wicket application.

Usage

We will create a panel called RecaptchaPanel. In order to use this component to your application all you'll have to do is this:

add(new RecaptchaPanel("recaptcha"));
and of course, add the component in your markup:


Implementation

Implementation is simple. All you have to do, is to follow several steps:

Add recaptcha dependency to your project


 net.tanesha.recaptcha4j
 recaptcha4j
 0.0.7

This library hides the implementation details and expose an API for dealing with recaptcha service.

Create associated markup (RecaptchaPanel.html)



  

Create RecaptchaPanel.java

import net.tanesha.recaptcha.ReCaptcha;
import net.tanesha.recaptcha.ReCaptchaFactory;
import net.tanesha.recaptcha.ReCaptchaImpl;
import net.tanesha.recaptcha.ReCaptchaResponse;

/**
 * Displays recaptcha widget. It is configured using a pair of public/private keys which can be registered at the
 * following location:
 * 
* https://www.google.com/recaptcha/admin/create
 * 
* More details about recaptcha API: http://code.google.com/apis/recaptcha/intro.html * * @author Alex Objelean */ @SuppressWarnings("serial") public class RecaptchaPanel extends Panel { private static final Logger LOG = LoggerFactory.getLogger(RecaptchaPanel.class); @SpringBean private ServiceProvider serviceProvider; public RecaptchaPanel(final String id) { super(id); final ReCaptcha recaptcha = ReCaptchaFactory.newReCaptcha(serviceProvider.getSettings().getRecaptchaPublicKey(), serviceProvider.getSettings().getRecaptchaPrivateKey(), false); add(new FormComponent("captcha") { @Override protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag) { replaceComponentTagBody(markupStream, openTag, recaptcha.createRecaptchaHtml(null, null)); } @Override public void validate() { final WebRequest request = (WebRequest)RequestCycle.get().getRequest(); final String remoteAddr = request.getHttpServletRequest().getRemoteAddr(); final ReCaptchaImpl reCaptcha = new ReCaptchaImpl(); reCaptcha.setPrivateKey(serviceProvider.getSettings().getRecaptchaPrivateKey()); final String challenge = request.getParameter("recaptcha_challenge_field"); final String uresponse = request.getParameter("recaptcha_response_field"); final ReCaptchaResponse reCaptchaResponse = reCaptcha.checkAnswer(remoteAddr, challenge, uresponse); if (!reCaptchaResponse.isValid()) { LOG.debug("wrong captcha"); error("Invalid captcha!"); } } }); } }

Things to notice:

  • ServiceProvider - is a spring bean containing reCaptcha configurations (public key and private key). These keys are different depending on the domain where your application is deployed (by default works for any key when using localhost domain). You can generate keys here: https://www.google.com/recaptcha/admin/create

  • The RecaptchaPanel contains a FormComponent, which allows implementing validate method, containing the validation logic.

  • Because reCaptcha use hardcoded values for hidden fields, this component cannot have multiple independent instances on the same page.

This component can be easily added to wicket-stuff or any other components library.

Conclusion

This post shows how easy you can integrate recaptcha widget in your application using wicket web framework.

Saturday, February 12, 2011

Keeping Git in sync with Perforce

This post is not about how great is Git and how "great" is perforce. It doesn't matter which one you prefer, in the end it is a matter of taste. If you don't know much about Git, you could find interesting this presentation: Linus Torvalds on Git

Unfortunately, the company I'm working for has a strict policy regarding SCM usage. For some reason we are forced to use perforce. For a git lover developer this is not nice at all. That is why I started to search for a way to enjoy the Git while keeping in sync from time to time the master branch with perforce.

My first attempt was related to git p4 plugin. Unfortunately it wasn't easy at all to make it work and after several hours I gave up.

My next attempt was to use a manual approach, which can be later simplified by creating a bash script. The idea is simple: since perforce doesn't pollute each folder of the project with all scm specific files (like: .svn or .cvs), the sync is reduced to copying everything from perforce
project folder to Git project folder and vice versa.

Let's say you have a project called testProject and you keep it at the following locations:

a) perforce: /se/perforce/testProject (Lets call it A)
b) Git: /git/testProject (Lets call it B)
Let's say you have developed several new features in your Git repository and pushed the changes to origin. Now you want to sync the changes with perforce.

Here are the steps you would follow:

  1. Get the latest changes from perforce
  2. Go to folder B and create a branch in Git called 'perforce' and delete all project files from here
  3. Copy everything from A to B. Because all the files are read-only, you should change the mode using the following command:
    chmod -v 777 * -R
    
    (we don't want the files to be read-only in Git project folder)
  4. Go to folder B and merge Git 'perforce' branch with the master branch (where your latest developed changes resides). After merge succeeds, you can 'push' the synced version to perforce.
  5. Delete all the project files from folder A.
  6. Copy all the project files from folder B to A.
  7. Make all the files back to read-only in folder A
    chmod -v 755 * -R
  8. Use 'reconcile offline work' in perforce and commit the changes. Now you are done with perforce and it has the latest changes.
  9. Bring the changes from the synced 'perforce' branch to the master and since you don't need the perforce branch anymore, you can delete it:
    git checkout master
    git merge perforce
    git branch -d perforce
    

And that's it.
To automate this steps, a bash script can be created. It would have the following parameters: perforce project location and Git project location. This way you can enjoy developing in Git and be compliant with your company rules in the same time.