/* * Copyright 2007 Soren Davidsen, Tanesha Networks * * 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. */ package och.comp.captcha.impl.recaptcha; import java.net.URLEncoder; import java.util.Enumeration; import java.util.Properties; import och.comp.captcha.impl.recaptcha.http.HttpLoader; import och.comp.captcha.impl.recaptcha.http.SimpleHttpLoader; public class ReCaptchaImpl implements ReCaptcha { public static final String PROPERTY_THEME = "theme"; public static final String PROPERTY_TABINDEX = "tabindex"; public static final String HTTP_SERVER = "http://api.recaptcha.net"; public static final String HTTPS_SERVER = "https://api-secure.recaptcha.net"; public static final String VERIFY_URL = "http://api-verify.recaptcha.net/verify"; private String privateKey; private String publicKey; private String recaptchaServer = HTTP_SERVER; private boolean includeNoscript = false; private HttpLoader httpLoader = new SimpleHttpLoader(); public void setPrivateKey(String privateKey) { this.privateKey = privateKey; } public void setPublicKey(String publicKey) { this.publicKey = publicKey; } public void setRecaptchaServer(String recaptchaServer) { this.recaptchaServer = recaptchaServer; } public void setIncludeNoscript(boolean includeNoscript) { this.includeNoscript = includeNoscript; } public void setHttpLoader(HttpLoader httpLoader) { this.httpLoader = httpLoader; } @Override @SuppressWarnings("deprecation") public ReCaptchaResponse checkAnswer(String remoteAddr, String challenge, String response) throws Exception { String postParameters = "privatekey=" + URLEncoder.encode(privateKey) + "&remoteip=" + URLEncoder.encode(remoteAddr) + "&challenge=" + URLEncoder.encode(challenge, "UTF-8") + "&response=" + URLEncoder.encode(response, "UTF-8"); String message = httpLoader.httpPost(VERIFY_URL, postParameters); if (message == null) { throw new ReCaptchaException("Null read from server."); } String[] a = message.split("\r?\n"); if (a.length < 1) { throw new ReCaptchaException("No answer returned from recaptcha: "+message); } boolean valid = "true".equals(a[0]); String errorMessage = null; if (!valid) { if (a.length > 1) errorMessage = a[1]; else errorMessage = "recaptcha4j-missing-error-message"; } return new ReCaptchaResponse(valid, errorMessage); } @SuppressWarnings("deprecation") @Override public String createRecaptchaHtml(String errorMessage, Properties options) { String errorPart = (errorMessage == null ? "" : "&error=" + URLEncoder.encode(errorMessage)); String message = fetchJSOptions(options); message += "<script type=\"text/javascript\" src=\"" + recaptchaServer + "/challenge?k=" + publicKey + errorPart + "\"></script>\r\n"; if (includeNoscript) { String noscript = "<noscript>\r\n" + " <iframe src=\""+recaptchaServer+"/noscript?k="+publicKey + errorPart + "\" height=\"300\" width=\"500\" frameborder=\"0\"></iframe><br>\r\n" + " <textarea name=\"recaptcha_challenge_field\" rows=\"3\" cols=\"40\"></textarea>\r\n" + " <input type=\"hidden\" name=\"recaptcha_response_field\" value=\"manual_challenge\">\r\n" + "</noscript>"; message += noscript; } return message; } @Override public String createRecaptchaHtml(String errorMessage, String theme, Integer tabindex) { Properties options = new Properties(); if (theme != null) { options.setProperty(PROPERTY_THEME, theme); } if (tabindex != null) { options.setProperty(PROPERTY_TABINDEX, String.valueOf(tabindex)); } return createRecaptchaHtml(errorMessage, options); } /** * Produces javascript array with the RecaptchaOptions encoded. * * @param properties * @return */ @SuppressWarnings("rawtypes") private String fetchJSOptions(Properties properties) { if (properties == null || properties.size() == 0) { return ""; } String jsOptions = "<script type=\"text/javascript\">\r\n" + "var RecaptchaOptions = {"; for (Enumeration e = properties.keys(); e.hasMoreElements(); ) { String property = (String) e.nextElement(); jsOptions += property + ":'" + properties.getProperty(property)+"'"; if (e.hasMoreElements()) { jsOptions += ","; } } jsOptions += "};\r\n</script>\r\n"; return jsOptions; } }