Asiri Rathnayake wrote:
Hi,
On Fri, Jan 15, 2010 at 2:35 PM, Caleb James DeLisle < calebdelisle@lavabit.com> wrote:
Hello folks,
I have a proposed method for migrating the captcha plugin to a component. I have posted a patch here: http://jira.xwiki.org/jira/browse/XWIKI-4741 which contains the core modifications which I am proposing. Though I have a patch, this is still in the design phase and I welcome anyone to suggest changes.
ComponentRole: Captcha /** * Check if the solution to the captcha is correct. * * @param answer The provided solution. * @return true if the solution is correct. */ boolean isAnswerCorrect(String answer);
May be I have understood wrong, but it seems only your velocity API (below) provides a method signature like:
boolean isAnswerCorrect(String captchaId, String answer);
Not exactly, I think you are thinking of: $captchaservice.isAnswerCorrect($sessionId, $answer) while captchaName is the hint for getting a component from the component manager. eg: $captchaservice.isAnswerCorrect("defaultImageCaptcha", $answer)
- Why not have this in component API? For an example, recaptcha works like this. It needs both a challengeId as well as it's answer for it to validate the response.
I have the component set up to automatically get the id from the servlet so that an application can just reference an image from the old struts based image captcha generator and the next answer given by the same web browser will fit that captcha. here is a working example: {{velocity}} #if($captchaservice.isAnswerCorrect("defaultImageCaptcha", $request.getParameter("captchaAnswer"))) #set($captchaAnswerIsCorrect = true) #else {{html}} <img src="$doc.getURL('jcaptcha')"/ > <form name="input" action="$doc.getURL()" method="get"> Fill in the letters in the image above: <br/> <input type="text" name="captchaAnswer" /> <input type="submit" value="I'm Human" /> </form> {{/html}} #end #if($captchaAnswerIsCorrect) = You win. #end {{/velocity}} The fact that the last call to the struts based jcaptcha component was from same session means that the answer provided will work. Perhaps it would be best to offer a way to check the answer with the sessionId either A: $captchaservice.isAnswerCorrect("defaultImageCaptcha", $sessionId, $answer) or B: #set($captcha = $captchaservice.getCaptcha("defaultImageCaptcha")) $captcha.isAnswerCorrect($sessionId, $answer) Also an easy way to get the session id using $request in Velocity? Something like: A: #set($sessionId = $captchaservice.getSessionId($request)) or B: #set($sessionId = $captcha.getSessionId($request))
- This methods should probably declare an exception (e.g. unable to contact recaptcha servers?)
I hadn't thought of recaptcha being an implementation of captcha but it makes perfect sense. does the all generic "throws Exception" seem right to you?
Implementing components: DefaultImageCaptchaAction DefaultSoundCaptchaAction
The new DefaultImageCaptcha component can be used to solve captchas which were downloaded through the old struts based jcaptcha plugin. Both components also implement org.xwiki.action.Action and when execute() is called, they send a captcha to the response.
The components depend on the request and response in the container being servlet request/response because com.octo.captcha.module.web.image.ImageToJpegHelper and com.octo.captcha.module.web.sound.SoundToWavHelper require HttpServletRequest and HttpServletResponse. Also to get the ID of the session in a way that is compatible with the old struts based method of getting captchas, an HttpServletRequest is needed. I am not happy with this design as it demands the use of the if instanceof then cast hack. I would like to hear any ideas about how to clean this up.
There is also a velocity initializer which provides a captcha service with:
/** * Check if the solution to the captcha is correct. * * @param captchaName The name of the Captcha you are checking the answer against * @param answer The provided solution * @return true if the solution is correct * @throws UnsupportedOperationException If there is no captcha by the name captchaName */ public boolean isAnswerCorrect(String captchaName, String answer) throws UnsupportedOperationException
If this is a velocity API (it sounds like that), it should not throw an exception, there is no way to catch it from velocity. It should probably return false in case of an error (and set an error message inside the context).
You are right, I wanted to be easy on the application programmer by letting them know that they haven't just gotten the captcha wrong, but throwing exceptions to velocity will open a can of worms.
I'm a bit unclear about your proposal and in doubt whether I have understood your proposal wrong. Please correct me if that is the case.
It is probably that my proposal is unclear, I think your understanding is correct though. Thank you for looking at it, Caleb
Thanks.
- Asiri
and
/** @return a List of the names of all registered classes implementing {@link org.xwiki.captcha.Captcha}. */ public List<String> listCaptchaNames()
In my opinion the html should all be in the application side and the core code should not even know it's URL. I am working on an application and would be interested to hear what requirements you think it should meet.
Sorry for the long mail, I am anxious to hear your ideas about this.
Caleb James DeLisle
_______________________________________________ devs mailing list devs@xwiki.org http://lists.xwiki.org/mailman/listinfo/devs
_______________________________________________ devs mailing list devs@xwiki.org http://lists.xwiki.org/mailman/listinfo/devs