Commit 07a38856 authored by Matija Obreza's avatar Matija Obreza
Browse files

Extracted ReCaptchaUtil for use in user registration and germplasm

requests.
Updated EasySMTA connector to latest development version.
parent 01f76b17
......@@ -94,7 +94,7 @@ public interface AccessionRepository extends JpaRepository<Accession, Long> {
Accession findByInstituteCodeAndAccessionNameAndGenus(String holdingInstitute, String accessionName, String genus);
@Query("select count(a.id) from Accession a where a.id in ( ?1 ) and a.availability = 'Y'")
@Query("select count(a.id) from Accession a where a.id in ( ?1 ) and a.availability = true")
long countAvailable(Set<Long> accessionIds);
}
......@@ -2,16 +2,22 @@ package org.genesys2.server.service.impl;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
......@@ -22,10 +28,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
public class EasySMTAConnector {
private static final Log LOG = LogFactory.getLog(EasySMTAConnector.class);
// FIXME Use the safe URL
// private static final String ITPGRFA_PID_URL =
// "https://www.itworks.it/itt/index.php?r=extsys/getUserDetails2";
private static final String ITPGRFA_PID_URL = "https://www.itworks.it/itt/index.php?r=extsys/getUserDetails2&esUsername=XXX&esPassword=YYY&usEmail=ZZZ";
@Value("${itpgrfa.easysmta.url}")
private String serverUrl;
@Value("${itpgrfa.easysmta.username}")
private String serverUsername;
......@@ -36,28 +40,27 @@ public class EasySMTAConnector {
public EasySMTAUserData getUserData(String emailAddress) {
final HttpClient httpclient = new DefaultHttpClient();
// FIXME Url contains username+password, see below
String url = ITPGRFA_PID_URL.replace("XXX", serverUsername);
url = url.replace("YYY", serverPassword);
url = url.replace("ZZZ", emailAddress);
LOG.info("Checking EasySMTA at " + serverUrl + " for email: " + emailAddress);
final HttpPost httpPost = new HttpPost(serverUrl);
LOG.warn("Using unsafe fetch URL: " + url);
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("esUsername", serverUsername));
nvps.add(new BasicNameValuePair("esPassword", serverPassword));
nvps.add(new BasicNameValuePair("usEmail", emailAddress));
try {
httpPost.setEntity(new UrlEncodedFormEntity(nvps));
} catch (UnsupportedEncodingException e1) {
LOG.error(e1, e1);
return null;
}
final HttpGet httpget = new HttpGet(url);
HttpResponse response = null;
BufferedReader br = null;
try {
LOG.info("Using " + serverUsername + " as Easy-SMTA username.");
// FIXME Use these when Easy-SMTA is fixed
// httpclient.getParams().setParameter("esUsername",
// serverUsername);
// httpclient.getParams().setParameter("esPassword",
// serverPassword);
// httpclient.getParams().setParameter("usEmail", emailAddress);
response = httpclient.execute(httpget);
response = httpclient.execute(httpPost);
// Get hold of the response entity
final HttpEntity entity = response.getEntity();
......@@ -68,7 +71,7 @@ public class EasySMTAConnector {
if (entity != null) {
ObjectMapper objectMapper = new ObjectMapper();
JsonNode tree = objectMapper.readTree(entity.getContent());
LOG.debug(tree);
LOG.info("EasySMTA: " + tree);
if (tree.has("errorCode")) {
// Check failed
......@@ -78,10 +81,6 @@ public class EasySMTAConnector {
} else {
if (LOG.isDebugEnabled()) {
LOG.debug(tree);
}
return new EasySMTAUserData(tree.get("pid").asText(), tree.get("name").asText(), tree.get("surname").asText(), tree.get("email").asText(),
tree.get("orgName").asText(), tree.get("country").asText());
}
......@@ -93,7 +92,7 @@ public class EasySMTAConnector {
LOG.error(e);
} finally {
IOUtils.closeQuietly(br);
httpget.releaseConnection();
httpPost.releaseConnection();
LOG.debug("EasySMTA streams closed.");
}
......@@ -124,7 +123,7 @@ public class EasySMTAConnector {
@Override
public String toString() {
return "PID " + firstName + " " + lastName + ", " + organization + ", country=" + countryIsoCode3;
return "ITPGRFA.PID email=" + email + " first=" + firstName + " last=" + lastName + ", org=" + organization + ", country=" + countryIsoCode3;
}
}
}
......@@ -16,22 +16,18 @@
package org.genesys2.server.servlet.controller;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import net.tanesha.recaptcha.ReCaptchaImpl;
import net.tanesha.recaptcha.ReCaptchaResponse;
import org.genesys2.server.model.Permissions;
import org.genesys2.server.model.UserRole;
import org.genesys2.server.model.impl.User;
import org.genesys2.server.service.ContentService;
import org.genesys2.server.service.CropService;
import org.genesys2.server.service.UserService;
import org.genesys2.util.ReCaptchaUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
......@@ -105,28 +101,10 @@ public class HtmlController extends BaseController {
validator.validate(user, bindingResult);
// Validate the reCAPTCHA
String remoteAddr = req.getRemoteAddr();
boolean isLocalRequest = false;
try {
InetAddress remoteInetAddr = InetAddress.getByName(remoteAddr);
isLocalRequest = remoteInetAddr.isLinkLocalAddress() || remoteInetAddr.isAnyLocalAddress() || remoteInetAddr.isLoopbackAddress();
_logger.warn("Remote addr: " + remoteAddr + " " + remoteInetAddr + " isLocal=" + isLocalRequest);
} catch (UnknownHostException e1) {
_logger.warn(e1.getMessage());
}
if (!isLocalRequest) {
ReCaptchaImpl reCaptcha = new ReCaptchaImpl();
reCaptcha.setPrivateKey(captchaPrivateKey);
ReCaptchaResponse reCaptchaResponse = reCaptcha.checkAnswer(remoteAddr, challenge, response);
if (!reCaptchaResponse.isValid()) {
_logger.warn("Invalid captcha.");
FieldError fieldError = new FieldError("comment", "captcha", response, false, new String[] { "errors.badCaptcha" }, null, "Please try again.");
bindingResult.addError(fieldError);
}
if (!ReCaptchaUtil.isValid(captchaPrivateKey, req.getRemoteAddr(), challenge, response)) {
_logger.warn("Invalid captcha.");
FieldError fieldError = new FieldError("comment", "captcha", response, false, new String[] { "errors.badCaptcha" }, null, "Please try again.");
bindingResult.addError(fieldError);
}
try {
......
......@@ -16,12 +16,16 @@
package org.genesys2.server.servlet.controller;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.genesys2.server.service.ContentService;
import org.genesys2.server.service.GenesysService;
import org.genesys2.server.service.impl.EasySMTAConnector;
import org.genesys2.server.service.impl.EasySMTAConnector.EasySMTAUserData;
import org.genesys2.util.ReCaptchaUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
......@@ -53,6 +57,12 @@ public class RequestController extends BaseController {
@Autowired
private EasySMTAConnector pidChecker;
@Value("${captcha.privateKey}")
private String captchaPrivateKey;
@Value("${captcha.publicKey}")
private String captchaPublicKey;
/**
* Give information about the request process
*
......@@ -73,18 +83,26 @@ public class RequestController extends BaseController {
@RequestMapping(method = RequestMethod.POST, value = "/start")
public String start(ModelMap model) {
model.addAttribute("blurp", contentService.getGlobalArticle("request-personal", getLocale()));
model.addAttribute("captchaPublicKey", captchaPublicKey);
return "/request/personal";
}
@RequestMapping(method = RequestMethod.POST, value = "/submit")
public String submit(ModelMap model, @RequestParam(value = "email", defaultValue = "", required = true) String emailAddress) {
public String submit(ModelMap model, HttpServletRequest req, @RequestParam(value = "email", defaultValue = "", required = true) String emailAddress, @RequestParam(value = "recaptcha_challenge_field", required = false) String challenge,
@RequestParam(value = "recaptcha_response_field", required = false) String response) {
emailAddress = emailAddress.trim();
if (StringUtils.isBlank(emailAddress)) {
_logger.warn("No email address was specified for request. Stopping here.");
return "/request/personal";
}
// Validate the reCAPTCHA
if (!ReCaptchaUtil.isValid(captchaPrivateKey, req.getRemoteAddr(), challenge, response)) {
_logger.warn("Recaptcha not valid. Stopping here.");
return "/request/personal";
}
_logger.info("Checking for ITPGRFA PID account for " + emailAddress);
EasySMTAUserData pid = pidChecker.getUserData(emailAddress);
......@@ -93,7 +111,7 @@ public class RequestController extends BaseController {
} else {
// TODO send email to registered email address, wait for response
_logger.info("TODO TODO TODO : Send email to : " + pid);
_logger.info("Send email to: " + pid);
}
......
/**
* Copyright 2013 Global Crop Diversity Trust
*
* 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 org.genesys2.util;
import java.net.InetAddress;
import java.net.UnknownHostException;
import net.tanesha.recaptcha.ReCaptcha;
import net.tanesha.recaptcha.ReCaptchaImpl;
import net.tanesha.recaptcha.ReCaptchaResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* {@link ReCaptcha} wrapper
*
* @author matijaobreza
*
*/
public class ReCaptchaUtil {
private final static Logger _logger = LoggerFactory.getLogger(ReCaptchaUtil.class);
// Validate the reCAPTCHA
public static boolean isValid(String captchaPrivateKey, String remoteAddr, String challenge, String response) {
boolean isLocalRequest = false;
try {
InetAddress remoteInetAddr = InetAddress.getByName(remoteAddr);
isLocalRequest = remoteInetAddr.isLinkLocalAddress() || remoteInetAddr.isAnyLocalAddress() || remoteInetAddr.isLoopbackAddress();
_logger.warn("Remote addr: " + remoteAddr + " " + remoteInetAddr + " isLocal=" + isLocalRequest);
} catch (UnknownHostException e1) {
_logger.warn(e1.getMessage());
}
if (isLocalRequest) {
_logger.info("Ignoring localhost re-captcha.");
return true;
}
ReCaptchaImpl reCaptcha = new ReCaptchaImpl();
reCaptcha.setPrivateKey(captchaPrivateKey);
ReCaptchaResponse reCaptchaResponse = reCaptcha.checkAnswer(remoteAddr, challenge, response);
return reCaptchaResponse.isValid();
}
}
......@@ -20,7 +20,7 @@
#db.username = sa
#db.password =
db.url=jdbc:mysql://127.0.0.1/genesys2?useUnicode=true&characterEncoding=UTF-8&useFastDateParsing=false&autoCommit=false
db.url=jdbc:mysql://127.0.0.1/genesys2?useUnicode=true&characterEncoding=UTF-8&useFastDateParsing=false
db.driverClassName = com.mysql.jdbc.Driver
db.username = root
db.password =
......@@ -42,6 +42,7 @@ captcha.publicKey=6Lf7oucSAAAAAGaS7ObroY2bNgCqMTmpyFVu7wMW
download.files.dir=./data/
# ITPGRFA Easy-SMTA account (if you have one)
itpgrfa.easysmta.url=
itpgrfa.easysmta.username=
itpgrfa.easysmta.password=
......
......@@ -20,7 +20,20 @@
<input type="text" name="email" class="span3 required email form-control" />
</div>
</div>
<div class="form-group">
<label class="col-lg-2 control-label"><spring:message code="captcha.text" /></label>
<div class="col-lg-3">
<script type="text/javascript" src="http://api.recaptcha.net/challenge?k=${captchaPublicKey}">
</script>
<noscript>
<iframe src="http://api.recaptcha.net/noscript?k=${captchaPublicKey}" height="300" width="500" frameborder="0"></iframe>
<br>
<textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
<input type="hidden" name="recaptcha_response_field" value="manual_challenge">
</noscript>
</div>
</div>
<div class="form-actions">
<input class="btn btn-primary" type="submit" value="<spring:message code="request.start-request" />" />
</div>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment