Commit 34317a70 authored by igoshin's avatar igoshin Committed by Matija Obreza

Finish google account integration (+2 squashed commits)

Squashed commits:
[0dcbc98] First version of user story "Login with google"
[66df377] First version of user story "Login with google"
parent 0940539f
......@@ -43,6 +43,8 @@
<spring.security.oauth2.version>1.0.5.RELEASE</spring.security.oauth2.version>
<spring.data.core.version>1.5.1.RELEASE</spring.data.core.version>
<spring.data.jpa.version>1.3.5.RELEASE</spring.data.jpa.version>
<org.springframework.social-version>1.0.3.RELEASE</org.springframework.social-version>
<org.springframework.social-google-version>1.0.0.M3</org.springframework.social-google-version>
<mysql.version>5.1.25</mysql.version>
......@@ -67,10 +69,25 @@
<name>ibiblio.mirrors</name>
<url>http://mirrors.ibiblio.org/pub/mirrors/maven2</url>
</repository>
<!-- <repository>
<id>sonatype mirror</id>
<url>http://search.maven.org/remotecontent?filepath=</url>
</repository> -->
<repository>
<id>spring-social-google</id>
<name>Spring Social Google</name>
<url>http://gabiaxel.github.io/maven/</url>
</repository>
<repository>
<id>sonatype-oss</id>
<url>https://oss.sonatype.org/content/groups/public</url>
</repository>
<repository>
<id>releases</id>
<name>Releases</name>
<url>https://oss.sonatype.org/content/repositories/releases</url>
</repository>
<!-- <repository>
<id>sonatype mirror</id>
<url>http://search.maven.org/remotecontent?filepath=</url>
</repository> -->
</repositories>
<dependencies>
......@@ -242,7 +259,61 @@
<scope>test</scope>
</dependency>
<!-- Hibernate dependencies -->
<dependency>
<groupId>org.springframework.social</groupId>
<artifactId>spring-social-google</artifactId>
<version>${org.springframework.social-google-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.social</groupId>
<artifactId>spring-social-web</artifactId>
<version>${org.springframework.social-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.social</groupId>
<artifactId>spring-social-core</artifactId>
<version>${org.springframework.social-version}</version>
</dependency>
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client-servlet</artifactId>
<version>1.17.0-rc</version>
</dependency>
<dependency>
<groupId>com.googlecode.googleplus</groupId>
<artifactId>google-plus-java-api</artifactId>
<exclusions>
<exclusion>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
</exclusion>
<exclusion>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
</exclusion>
</exclusions>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.google.api.client</groupId>
<artifactId>google-api-client</artifactId>
<exclusions>
<exclusion>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
</exclusion>
</exclusions>
<version>1.3.1-alpha</version>
</dependency>
<!-- Hibernate dependencies -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
......@@ -286,11 +357,11 @@
<version>${oval.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<!--<dependency>-->
<!--<groupId>com.fasterxml.jackson.core</groupId>-->
<!--<artifactId>jackson-databind</artifactId>-->
<!--<version>${jackson.version}</version>-->
<!--</dependency>-->
<!--Jetty -->
......@@ -357,6 +428,16 @@
<artifactId>mail</artifactId>
<version>1.5.0-b01</version>
</dependency>
<dependency>
<groupId>com.github.fernandospr</groupId>
<artifactId>javapns-jdk16</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>1.17.0-rc</version>
</dependency>
</dependencies>
<build>
......
......@@ -22,6 +22,7 @@ import org.genesys2.server.model.wrapper.UserWrapper;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.social.google.api.userinfo.GoogleUserInfo;
public interface UserService {
......@@ -71,4 +72,6 @@ public interface UserService {
void setAccountLockLocal(String uuid, boolean locked);
void userEmailValidated(String uuid) throws UserException;
void googleAuthentication(GoogleUserInfo userInfo) throws UserException;
}
......@@ -16,12 +16,6 @@
package org.genesys2.server.service.impl;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.genesys2.server.exception.NoUserFoundException;
......@@ -49,9 +43,12 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.social.google.api.userinfo.GoogleUserInfo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
@Service
@Transactional(readOnly = true)
public class UserServiceImpl implements UserService {
......@@ -350,7 +347,24 @@ public class UserServiceImpl implements UserService {
LOG.info("Ensured VALIDATEDUSER role for user " + user);
}
private void addRoleToCurrentUser(User user, String role) {
@Override
public void googleAuthentication(GoogleUserInfo userInfo) throws UserException {
User user=getUserByEmail(userInfo.getEmail());
userEmailValidated(user.getUuid());
List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
grantedAuthorities.add(new SimpleGrantedAuthority("USER"));
grantedAuthorities.add(new SimpleGrantedAuthority("VALIDATEDUSER"));
AuthUserDetails userDetails = new AuthUserDetails(user.getUuid(), user.getPassword() , grantedAuthorities);
userDetails.setUser(user);
Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
}
private void addRoleToCurrentUser(User user, String role) {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof AuthUserDetails) {
......
package org.genesys2.server.servlet.controller;
import org.apache.commons.lang.RandomStringUtils;
import org.genesys2.server.exception.UserException;
import org.genesys2.server.model.impl.User;
import org.genesys2.server.service.EMailVerificationService;
import org.genesys2.server.service.UserService;
import org.genesys2.server.servlet.util.GoogleOAuthUtil;
import org.json.JSONException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.social.google.api.Google;
import org.springframework.social.google.api.impl.GoogleTemplate;
import org.springframework.social.google.api.userinfo.GoogleUserInfo;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Controller
@RequestMapping("/g")
public class GoogleSocialController extends BaseController {
@Value("${google.auth.url}")
private String url;
@Autowired
private UserService userService;
@Autowired
private EMailVerificationService emailService;
@Autowired
private GoogleOAuthUtil oAuth;
@RequestMapping("/login")
public void redirectToGoogle(HttpServletResponse response) throws IOException {
response.sendRedirect(url);
}
@RequestMapping("/auth")
public String googleAuth(Model model, HttpServletRequest request) throws IOException, JSONException, UserException {
String accessToken = oAuth.exchangeForAccessToken(request);
if (accessToken == null) {
model.addAttribute("error", true);
return "/login";
}
Google google = new GoogleTemplate(accessToken);
GoogleUserInfo userInfo = google.userOperations().getUserInfo();
if (!userService.exists(userInfo.getEmail())) {
String pwd = RandomStringUtils.randomAlphanumeric(10);
User user = userService.createAccount(userInfo.getEmail(), pwd, userInfo.getName());
emailService.sendPasswordForGenesysAccount(user, pwd);
}
userService.googleAuthentication(userInfo);
return "redirect:/profile";
}
}
/**
* 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.
......@@ -19,6 +19,7 @@ package org.genesys2.server.servlet.controller;
import org.genesys2.server.model.Permissions;
import org.genesys2.server.model.UserRole;
import org.genesys2.server.model.impl.User;
import org.genesys2.server.security.lockout.AccountLockoutManager;
import org.genesys2.server.service.ContentService;
import org.genesys2.server.service.CropService;
import org.genesys2.server.service.EMailVerificationService;
......@@ -26,7 +27,6 @@ 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.security.access.AccessDeniedException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
......@@ -40,6 +40,10 @@ import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;
/**
* Controller which simply handles *.html requests
*/
......@@ -64,6 +68,9 @@ public class HtmlController extends BaseController {
@Autowired
private ContentService contentService;
@Autowired
private AccountLockoutManager lockoutManager;
@Value("${captcha.privateKey}")
private String captchaPrivateKey;
......@@ -97,7 +104,7 @@ public class HtmlController extends BaseController {
return "/registration";
}
@RequestMapping(value = "new-user")
@RequestMapping(value = "new-user")
public String addUser(@ModelAttribute User user, BindingResult bindingResult, HttpServletRequest req,
@RequestParam(value = "recaptcha_challenge_field", required = false) String challenge,
@RequestParam(value = "recaptcha_response_field", required = false) String response) {
......
package org.genesys2.server.servlet.util;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
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.json.JSONException;
import org.json.JSONObject;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class GoogleOAuthUtil {
private String clientId;
private String secret;
private String redirectUrl;
public String exchangeForAccessToken(HttpServletRequest request) throws IOException, JSONException {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("https://accounts.google.com/o/oauth2/token");
List<NameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair("code", request.getParameter("code")));
params.add(new BasicNameValuePair("client_id", clientId));
params.add(new BasicNameValuePair("client_secret", secret));
params.add(new BasicNameValuePair("redirect_uri", redirectUrl));
params.add(new BasicNameValuePair("grant_type", "authorization_code"));
params.add(new BasicNameValuePair("scope", ""));
httppost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
HttpResponse response = httpclient.execute(httppost);
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
StringBuilder builder = new StringBuilder();
for (String line = null; (line = reader.readLine()) != null; ) {
builder.append(line).append("\n");
}
JSONObject jsonObject = new JSONObject(builder.toString());
return jsonObject.getString("access_token") != null ? jsonObject.getString("access_token") : null;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public void setSecret(String secret) {
this.secret = secret;
}
public void setRedirectUrl(String redirectUrl) {
this.redirectUrl = redirectUrl;
}
}
......@@ -428,3 +428,4 @@ userprofile.email.send=Send email
verification.invalid-key=Token key is not valid.
verification.token-key=Validation key
login.invalid-token=Invalid access token
{
"en": {
"title": "Password for genesys account",
"body": "<h2><small>Genesys account</small><br/>Password for you genesys account</h2><p></p><h2>New password: {0}</h2><p>Thanks,<br/ >Genesys team</p>"
}
}
\ No newline at end of file
......@@ -31,5 +31,6 @@
<import resource="spring-security-acl.xml" />
<import resource="spring-security.xml" />
<import resource="spring-mail.xml" />
<import resource="spring-social.xml" />
</beans>
......@@ -29,7 +29,7 @@
<aop:aspectj-autoproxy />
<context:property-placeholder ignore-resource-not-found="true" location="classpath:/application.properties,classpath:/spring/spring.properties,classpath:/genesys.properties"/>
<context:property-placeholder ignore-resource-not-found="true" location="classpath:/*.properties,classpath:/spring/*.properties"/>
<context:component-scan base-package="org.genesys2.server">
<!--Include @Entity for scanning of Acl Classes purposes-->
......
......@@ -33,7 +33,7 @@
<property name="validationQuery" value="SELECT 1" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="true" />
<!--
<!--
<property name="timeBetweenEvictionRunsMillis" value="5000" />
<property name="minEvictableIdleTimeMillis" value="5000" />
<property name="minIdle" value="0" />
......@@ -54,6 +54,9 @@
<prop key="hibernate.hbm2ddl.auto">${db.hbm2ddl}</prop>
<prop key="hibernate.search.default.indexBase">${lucene.indexDir}</prop>
<prop key="hibernate.search.default.exclusive_index_use">false</prop>
<prop key="hibernate.connection.CharSet">utf8</prop>
<prop key="hibernate.connection.characterEncoding">utf8</prop>
<prop key="hibernate.connection.useUnicode">true</prop>
</props>
</property>
<property name="packagesToScan">
......
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd"
default-autowire="no">
<context:component-scan base-package="org.genesys2.server"/>
<context:property-placeholder ignore-resource-not-found="true" location="classpath:/spring/spring.properties"/>
<bean name="googleOAuthUtil" class="org.genesys2.server.servlet.util.GoogleOAuthUtil">
<property name="clientId" value="${google.consumerKey}"/>
<property name="secret" value="${google.consumerSecret}"/>
<property name="redirectUrl" value="${google.redirect.url}"/>
</bean>
</beans>
\ No newline at end of file
......@@ -16,12 +16,12 @@
base.url=http://localhost:8080
db.url=jdbc:mysql://localhost/genesys4?useUnicode=true&characterEncoding=UTF-8&useFastDateParsing=false
db.url=jdbc:mysql://localhost/genesys2
db.driverClassName = com.mysql.jdbc.Driver
db.username = root
db.password = 1
db.showSql=false
db.hbm2ddl=do-nothing
db.hbm2ddl=update
c3p0.acquireIncrement=1
c3p0.minPoolSize=1
......@@ -60,7 +60,6 @@ mail.user.from=test@example.com
mail.user.password=
mail.user.name=
mail.smtp.ssl.enable=true
mail.smtp.auth=true
mail.transport.protocol=smtp
......@@ -75,4 +74,9 @@ mail.debug.message= Email has been sent succesfully\n\
%s\
\n\n==================================
#google properties
google.consumerKey=534251255050-3o55n707i6fare7kcad32u6gs7r7t8h8.apps.googleusercontent.com
google.consumerSecret=tjbSs5iDFVeoNB7_mXX0M1dO
google.redirect.url=http://localhost:8080/g/auth
google.auth.url=https://accounts.google.com/o/oauth2/auth?redirect_uri=http://localhost:8080/g/auth&response_type=code&client_id=534251255050-3o55n707i6fare7kcad32u6gs7r7t8h8.apps.googleusercontent.com&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fplus.login+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fplus.me+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&approval_prompt=auto&access_type=online&include_granted_scopes=true
......@@ -11,6 +11,9 @@
<c:if test="${param['error'] ne null}">
<div class="alert alert-danger"><spring:message code="login.invalid-credentials"/></div>
</c:if>
<c:if test="${error}">
<div class="alert alert-danger"><spring:message code="login.invalid-token"/></div>
</c:if>
<form role="form" method="POST" action="/login-attempt" class="form-horizontal">
<div class="form-group">
<label for="j_username" class="col-lg-2 control-label"><spring:message code="login.username"/></label>
......
......@@ -213,6 +213,33 @@ html[dir="rtl"] #header .nav .dropdown-menu .checkbox {
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#88ba42', endColorstr='#accf7b',GradientType=0 );
}
#header .nav .dropdown-menu .btn-danger {
background: #d9534f;
background: -moz-linear-gradient(top, #d9534f 0%, #d9534f 50%, #c12e2a 51%, #c12e2a 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#d9534f), color-stop(50%,#d9534f), color-stop(51%,#c12e2a), color-stop(100%,#c12e2a));
background: -webkit-linear-gradient(top, #d9534f 0%,#d9534f 50%,#c12e2a 51%,#c12e2a 100%);
background: -o-linear-gradient(top, #d9534f 0%,#d9534f 50%,#c12e2a 51%,#c12e2a 100%);
background: -ms-linear-gradient(top, #d9534f 0%,#d9534f 50%,#c12e2a 51%,#c12e2a 100%);
background: linear-gradient(to bottom, #d9534f 0%,#d9534f 50%,#c12e2a 51%,#c12e2a 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#d9534f', endColorstr='#c12e2a',GradientType=0 );
color:#2b2924;
font-size:16px;
font-weight:bold;
margin:0 20px;
width:200px;
}
#header .nav .dropdown-menu .btn-danger:hover {
background: #c12e2a;
background: -moz-linear-gradient(top, #c12e2a 0%, #c12e2a 50%, #d9534f 51%, #d9534f 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#c12e2a), color-stop(50%,#c12e2a), color-stop(51%,#d9534f), color-stop(100%,#d9534f));
background: -webkit-linear-gradient(top, #c12e2a 0%,#c12e2a 50%,#d9534f 51%,#d9534f 100%);
background: -o-linear-gradient(top, #c12e2a 0%,#c12e2a 50%,#d9534f 51%,#d9534f 100%);
background: -ms-linear-gradient(top, #c12e2a 0%,#c12e2a 50%,#d9534f 51%,#d9534f 100%);
background: linear-gradient(to bottom, #c12e2a 0%,#c12e2a 50%,#d9534f 51%,#d9534f 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#c12e2a', endColorstr='#d9534f',GradientType=0 );
}
#header .nav .dropdown-menu .btn-default {
background:#e8e8e8;
color:#4d4c46;
......
......@@ -16,10 +16,6 @@
package org.genesys2.server.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import org.genesys2.server.service.HtmlSanitizer;
import org.junit.Test;
import org.junit.runner.RunWith;
......@@ -27,6 +23,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:spring/servlet.xml", "classpath:spring/application-context.xml" })
public class HtmlSanitizerTest {
......
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