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

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