Refactors authentication principal to handle users with and without confirmed email.

This commit is contained in:
gkolokythas 2019-07-12 16:58:17 +03:00
parent cc7534e24d
commit 25da5e97e5
20 changed files with 570 additions and 438 deletions

View File

@ -3,7 +3,7 @@ package eu.eudat.configurations;
import eu.eudat.controllers.interceptors.RequestInterceptor;
import eu.eudat.logic.handlers.PrincipalArgumentResolver;
import eu.eudat.logic.services.ApiContext;
import eu.eudat.logic.services.operations.AuthenticationService;
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
@ -17,24 +17,26 @@ import java.util.List;
@Configuration
public class WebMVCConfiguration extends WebMvcConfigurerAdapter {
private ApiContext apiContext;
private ApiContext apiContext;
private AuthenticationService authenticationService;
private AuthenticationService verifiedUserAuthenticationService;
private AuthenticationService nonVerifiedUserAuthenticationService;
@Autowired
public WebMVCConfiguration(ApiContext apiContext, AuthenticationService authenticationService) {
this.apiContext = apiContext;
this.authenticationService = authenticationService;
}
@Autowired
public WebMVCConfiguration(ApiContext apiContext, AuthenticationService verifiedUserAuthenticationService, AuthenticationService nonVerifiedUserAuthenticationService) {
this.apiContext = apiContext;
this.verifiedUserAuthenticationService = verifiedUserAuthenticationService;
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
}
@Autowired
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new PrincipalArgumentResolver(authenticationService));
}
@Autowired
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new PrincipalArgumentResolver(verifiedUserAuthenticationService, nonVerifiedUserAuthenticationService));
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new RequestInterceptor(this.apiContext.getHelpersService().getLoggerService()));
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new RequestInterceptor(this.apiContext.getHelpersService().getLoggerService()));
}
}

View File

@ -1,13 +1,17 @@
package eu.eudat.controllers;
import eu.eudat.core.logger.Logger;
import eu.eudat.exceptions.security.NullEmailException;
import eu.eudat.logic.managers.UserManager;
import eu.eudat.logic.security.CustomAuthenticationProvider;
import eu.eudat.logic.security.validators.b2access.B2AccessTokenValidator;
import eu.eudat.logic.security.validators.b2access.helpers.B2AccessRequest;
import eu.eudat.logic.security.validators.b2access.helpers.B2AccessResponseToken;
import eu.eudat.logic.security.validators.orcid.ORCIDTokenValidator;
import eu.eudat.logic.security.validators.orcid.helpers.ORCIDRequest;
import eu.eudat.logic.security.validators.orcid.helpers.ORCIDResponseToken;
import eu.eudat.logic.security.validators.twitter.TwitterTokenValidator;
import eu.eudat.logic.services.operations.AuthenticationServiceImpl;
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
import eu.eudat.models.data.helpers.responses.ResponseItem;
import eu.eudat.models.data.login.Credentials;
import eu.eudat.models.data.login.LoginInfo;
@ -29,24 +33,23 @@ import java.security.GeneralSecurityException;
public class Login {
private CustomAuthenticationProvider customAuthenticationProvider;
private AuthenticationServiceImpl authenticationServiceImpl;
private AuthenticationService nonVerifiedUserAuthenticationService;
private TwitterTokenValidator twitterTokenValidator;
private B2AccessTokenValidator b2AccessTokenValidator;
private ORCIDTokenValidator orcidTokenValidator;
private Logger logger;
private UserManager userManager;
@Autowired
public Login(CustomAuthenticationProvider customAuthenticationProvider, AuthenticationServiceImpl authenticationServiceImpl,
TwitterTokenValidator twitterTokenValidator, B2AccessTokenValidator b2AccessTokenValidator,
public Login(CustomAuthenticationProvider customAuthenticationProvider, AuthenticationService nonVerifiedUserAuthenticationService,
TwitterTokenValidator twitterTokenValidator, B2AccessTokenValidator b2AccessTokenValidator, ORCIDTokenValidator orcidTokenValidator,
UserManager userManager ,Logger logger) {
this.customAuthenticationProvider = customAuthenticationProvider;
this.authenticationServiceImpl = authenticationServiceImpl;
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
this.twitterTokenValidator = twitterTokenValidator;
this.b2AccessTokenValidator = b2AccessTokenValidator;
this.orcidTokenValidator = orcidTokenValidator;
this.logger = logger;
this.userManager = userManager;
}
@ -54,7 +57,7 @@ public class Login {
@Transactional
@RequestMapping(method = RequestMethod.POST, value = {"/externallogin"}, consumes = "application/json", produces = "application/json")
public @ResponseBody
ResponseEntity<ResponseItem<Principal>> externallogin(@RequestBody LoginInfo credentials) throws GeneralSecurityException {
ResponseEntity<ResponseItem<Principal>> externallogin(@RequestBody LoginInfo credentials) throws GeneralSecurityException, NullEmailException {
this.logger.info(credentials, "Trying To Login With " + credentials.getProvider());
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<Principal>().payload(customAuthenticationProvider.authenticate(credentials)).status(ApiMessageCode.SUCCESS_MESSAGE));
}
@ -62,9 +65,9 @@ public class Login {
@Transactional
@RequestMapping(method = RequestMethod.POST, value = {"/nativelogin"}, consumes = "application/json", produces = "application/json")
public @ResponseBody
ResponseEntity<ResponseItem<Principal>> nativelogin(@RequestBody Credentials credentials) {
ResponseEntity<ResponseItem<Principal>> nativelogin(@RequestBody Credentials credentials) throws NullEmailException {
this.logger.info(credentials.getUsername(), "Trying To Login");
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<Principal>().payload(userManager.authenticate(this.authenticationServiceImpl, credentials)).status(ApiMessageCode.SUCCESS_MESSAGE));
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<Principal>().payload(userManager.authenticate(this.nonVerifiedUserAuthenticationService, credentials)).status(ApiMessageCode.SUCCESS_MESSAGE));
}
@RequestMapping(method = RequestMethod.GET, value = {"/twitterRequestToken"}, produces = "application/json")
@ -81,16 +84,16 @@ public class Login {
@RequestMapping(method = RequestMethod.POST, value = {"/me"}, consumes = "application/json", produces = "application/json")
public @ResponseBody
ResponseEntity<ResponseItem<Principal>> authMe(Principal principal) {
ResponseEntity<ResponseItem<Principal>> authMe(Principal principal) throws NullEmailException {
this.logger.info(principal, "Getting Me");
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<Principal>().payload(this.authenticationServiceImpl.Touch(principal.getToken())).status(ApiMessageCode.NO_MESSAGE));
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<Principal>().payload(this.nonVerifiedUserAuthenticationService.Touch(principal.getToken())).status(ApiMessageCode.NO_MESSAGE));
}
@Transactional
@RequestMapping(method = RequestMethod.POST, value = {"/logout"}, consumes = "application/json", produces = "application/json")
public @ResponseBody
ResponseEntity<ResponseItem<Principal>> logout(Principal principal) {
this.authenticationServiceImpl.Logout(principal.getToken());
this.nonVerifiedUserAuthenticationService.Logout(principal.getToken());
this.logger.info(principal, "Logged Out");
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<Principal>().status(ApiMessageCode.NO_MESSAGE));
}

View File

@ -0,0 +1,8 @@
package eu.eudat.exceptions.security;
public class NullEmailException extends RuntimeException {
public NullEmailException() {
super();
}
}

View File

@ -2,13 +2,15 @@ package eu.eudat.logic.handlers;
import eu.eudat.exceptions.security.UnauthorisedException;
import eu.eudat.logic.security.claims.ClaimedAuthorities;
import eu.eudat.logic.services.operations.AuthenticationService;
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
import eu.eudat.models.data.security.Principal;
import eu.eudat.types.Authorities;
import org.apache.catalina.connector.RequestFacade;
import org.apache.tomcat.util.buf.MessageBytes;
import org.springframework.core.MethodParameter;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
@ -18,46 +20,51 @@ import java.util.*;
public final class PrincipalArgumentResolver implements HandlerMethodArgumentResolver {
private AuthenticationService authenticationService;
private AuthenticationService verifiedUserAuthenticationService;
private AuthenticationService nonVerifiedUserAuthenticationService;
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.getParameterType().equals(Principal.class);
}
public PrincipalArgumentResolver(AuthenticationService verifiedUserAuthenticationService, AuthenticationService nonVerifiedUserAuthenticationService) {
this.verifiedUserAuthenticationService = verifiedUserAuthenticationService;
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
}
@Override
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
String token = nativeWebRequest.getHeader("AuthToken");
Optional<Annotation> claimsAnnotation = Arrays.stream(methodParameter.getParameterAnnotations()).filter(annotation -> annotation.annotationType().equals(ClaimedAuthorities.class)).findAny();
List<Authorities> claimList = claimsAnnotation.map(annotation -> Arrays.asList(((ClaimedAuthorities) annotation).claims())).orElse(Authorities.all());
if (token == null && claimList.size() == 1 && claimList.get(0).equals(Authorities.ANONYMOUS))
return new Principal();
if (token == null) throw new UnauthorisedException("Authentication Information Is Missing");
UUID authToken;
try {
authToken = UUID.fromString(token);
} catch (IllegalArgumentException ex) {
throw new UnauthorisedException("Authentication Information Is Missing");
}
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.getParameterType().equals(Principal.class);
}
Principal principal = this.authenticationService.Touch(authToken);
if (principal == null) throw new UnauthorisedException("Authentication Information Missing");
if (!claimList.contains(Authorities.ANONYMOUS) && !principal.isAuthorized(claimList))
throw new UnauthorisedException("You are not Authorized For this Action");
@Override
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
String token = nativeWebRequest.getHeader("AuthToken");
return principal;
}
Boolean checkMailNull = ((ServletWebRequest) nativeWebRequest).getRequest().getRequestURI().startsWith("/api/emailConfirmation");
AuthenticationService authenticationService = checkMailNull ? this.nonVerifiedUserAuthenticationService : this.verifiedUserAuthenticationService;
public PrincipalArgumentResolver(AuthenticationService authenticationService) {
this.authenticationService = authenticationService;
}
Optional<Annotation> claimsAnnotation = Arrays.stream(methodParameter.getParameterAnnotations()).filter(annotation -> annotation.annotationType().equals(ClaimedAuthorities.class)).findAny();
List<Authorities> claimList = claimsAnnotation.map(annotation -> Arrays.asList(((ClaimedAuthorities) annotation).claims())).orElse(Authorities.all());
if (claimList.size() == 1 && claimList.get(0).equals(Authorities.ANONYMOUS))
return new Principal();
if (token == null) throw new UnauthorisedException("Authentication Information Is Missing");
UUID authToken;
try {
authToken = UUID.fromString(token);
} catch (IllegalArgumentException ex) {
throw new UnauthorisedException("Authentication Information Is Missing");
}
Principal principal = authenticationService.Touch(authToken);
if (principal == null) throw new UnauthorisedException("Authentication Information Missing");
if (!claimList.contains(Authorities.ANONYMOUS) && !principal.isAuthorized(claimList))
throw new UnauthorisedException("You are not Authorized For this Action");
private Date addADay(Date date) {
Date dt = new Date();
Calendar c = Calendar.getInstance();
c.setTime(dt);
c.add(Calendar.DATE, 1);
dt = c.getTime();
return dt;
}
return principal;
}
private Date addADay(Date date) {
Date dt = new Date();
Calendar c = Calendar.getInstance();
c.setTime(dt);
c.add(Calendar.DATE, 1);
dt = c.getTime();
return dt;
}
}

View File

@ -6,11 +6,12 @@ import eu.eudat.data.entities.DMP;
import eu.eudat.data.entities.UserInfo;
import eu.eudat.data.entities.UserRole;
import eu.eudat.data.query.items.table.userinfo.UserInfoTableRequestItem;
import eu.eudat.exceptions.security.NullEmailException;
import eu.eudat.exceptions.security.UnauthorisedException;
import eu.eudat.logic.builders.entity.UserRoleBuilder;
import eu.eudat.logic.builders.model.models.DataTableDataBuilder;
import eu.eudat.logic.services.ApiContext;
import eu.eudat.logic.services.operations.AuthenticationServiceImpl;
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
import eu.eudat.logic.utilities.builders.XmlBuilder;
import eu.eudat.models.HintedModelFactory;
import eu.eudat.models.data.dmp.DataManagementPlan;
@ -90,7 +91,7 @@ public class UserManager {
.createOrUpdate(userInfo);
}
public Principal authenticate(AuthenticationServiceImpl authenticationServiceImpl, Credentials credentials) {
public Principal authenticate(AuthenticationService authenticationServiceImpl, Credentials credentials) throws NullEmailException {
Principal principal = authenticationServiceImpl.Touch(credentials);
if (principal == null) throw new UnauthorisedException("Could not Sign In User");
return principal;

View File

@ -1,6 +1,7 @@
package eu.eudat.logic.security;
import eu.eudat.exceptions.security.NonValidTokenException;
import eu.eudat.exceptions.security.NullEmailException;
import eu.eudat.exceptions.security.UnauthorisedException;
import eu.eudat.models.data.login.LoginInfo;
import eu.eudat.models.data.security.Principal;
@ -18,7 +19,7 @@ public class CustomAuthenticationProvider {
@Autowired
private TokenValidatorFactory tokenValidatorFactory;
public Principal authenticate(LoginInfo credentials) throws GeneralSecurityException {
public Principal authenticate(LoginInfo credentials) throws GeneralSecurityException, NullEmailException {
String token = credentials.getTicket();
try {
Principal principal = this.tokenValidatorFactory.getProvider(credentials.getProvider()).validateToken(credentials);
@ -30,6 +31,9 @@ public class CustomAuthenticationProvider {
} catch (IOException e) {
e.printStackTrace();
throw new UnauthorisedException("IO Exeption");
} catch (NullEmailException e) {
e.printStackTrace();
throw new NullEmailException();
}
}
}

View File

@ -1,6 +1,7 @@
package eu.eudat.logic.security.validators;
import eu.eudat.exceptions.security.NonValidTokenException;
import eu.eudat.exceptions.security.NullEmailException;
import eu.eudat.models.data.login.LoginInfo;
import eu.eudat.models.data.security.Principal;
@ -9,6 +10,6 @@ import java.security.GeneralSecurityException;
public interface TokenValidator {
Principal validateToken(LoginInfo credentials) throws NonValidTokenException, IOException, GeneralSecurityException;
Principal validateToken(LoginInfo credentials) throws NonValidTokenException, IOException, GeneralSecurityException, NullEmailException;
}

View File

@ -1,14 +1,15 @@
package eu.eudat.logic.security.validators;
import eu.eudat.logic.security.customproviders.B2AccessCustomProvider;
import eu.eudat.logic.security.customproviders.B2Access.B2AccessCustomProvider;
import eu.eudat.logic.security.customproviders.ORCID.ORCIDCustomProvider;
import eu.eudat.logic.security.validators.b2access.B2AccessTokenValidator;
import eu.eudat.logic.security.validators.facebook.FacebookTokenValidator;
import eu.eudat.logic.security.validators.google.GoogleTokenValidator;
import eu.eudat.logic.security.validators.linkedin.LinkedInTokenValidator;
import eu.eudat.logic.security.validators.orcid.ORCIDTokenValidator;
import eu.eudat.logic.security.validators.twitter.TwitterTokenValidator;
import eu.eudat.logic.services.ApiContext;
import eu.eudat.logic.services.operations.AuthenticationService;
import eu.eudat.logic.services.operations.AuthenticationServiceImpl;
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
@ -17,7 +18,7 @@ import org.springframework.stereotype.Service;
@Service("tokenValidatorFactory")
public class TokenValidatorFactoryImpl implements TokenValidatorFactory {
public enum LoginProvider {
GOOGLE(1), FACEBOOK(2), TWITTER(3), LINKEDIN(4), NATIVELOGIN(5), B2_ACCESS(6);
GOOGLE(1), FACEBOOK(2), TWITTER(3), LINKEDIN(4), NATIVELOGIN(5), B2_ACCESS(6), ORCID(7);
private int value;
@ -43,6 +44,8 @@ public class TokenValidatorFactoryImpl implements TokenValidatorFactory {
return NATIVELOGIN;
case 6:
return B2_ACCESS;
case 7:
return ORCID;
default:
throw new RuntimeException("Unsupported LoginProvider");
}
@ -51,32 +54,35 @@ public class TokenValidatorFactoryImpl implements TokenValidatorFactory {
private ApiContext apiContext;
private Environment environment;
private AuthenticationServiceImpl authenticationService;
private AuthenticationService nonVerifiedUserAuthenticationService;
private B2AccessCustomProvider b2AccessCustomProvider;
private ORCIDCustomProvider orcidCustomProvider;
@Autowired
public TokenValidatorFactoryImpl(ApiContext apiContext, Environment environment, AuthenticationServiceImpl authenticationService, B2AccessCustomProvider b2AccessCustomProvider) {
public TokenValidatorFactoryImpl(ApiContext apiContext, Environment environment, AuthenticationService nonVerifiedUserAuthenticationService, B2AccessCustomProvider b2AccessCustomProvider, ORCIDCustomProvider orcidCustomProvider) {
this.apiContext = apiContext;
this.environment = environment;
this.authenticationService = authenticationService;
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
this.b2AccessCustomProvider = b2AccessCustomProvider;
this.orcidCustomProvider = orcidCustomProvider;
}
public TokenValidator getProvider(LoginProvider provider) {
switch (provider) {
case GOOGLE:
return new GoogleTokenValidator(this.apiContext, this.environment, this.authenticationService);
return new GoogleTokenValidator(this.apiContext, this.environment, this.nonVerifiedUserAuthenticationService);
case FACEBOOK:
return new FacebookTokenValidator(this.apiContext, this.environment, this.authenticationService);
return new FacebookTokenValidator(this.apiContext, this.environment, this.nonVerifiedUserAuthenticationService);
case LINKEDIN:
return new LinkedInTokenValidator(this.apiContext, this.environment, this.authenticationService);
return new LinkedInTokenValidator(this.apiContext, this.environment, this.nonVerifiedUserAuthenticationService);
case TWITTER:
return new TwitterTokenValidator(this.apiContext, this.environment, this.authenticationService);
return new TwitterTokenValidator(this.apiContext, this.environment, this.nonVerifiedUserAuthenticationService);
case B2_ACCESS:
return new B2AccessTokenValidator(this.environment, this.authenticationService, this.b2AccessCustomProvider);
return new B2AccessTokenValidator(this.environment, this.nonVerifiedUserAuthenticationService, this.b2AccessCustomProvider);
case ORCID:
return new ORCIDTokenValidator(this.environment, this.nonVerifiedUserAuthenticationService, this.orcidCustomProvider, this.apiContext);
default:
throw new RuntimeException("Login Provider Not Implemented");
}
}
}

View File

@ -1,15 +1,16 @@
package eu.eudat.logic.security.validators.b2access;
import eu.eudat.exceptions.security.NonValidTokenException;
import eu.eudat.exceptions.security.NullEmailException;
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
import eu.eudat.models.data.login.LoginInfo;
import eu.eudat.models.data.loginprovider.LoginProviderUser;
import eu.eudat.models.data.security.Principal;
import eu.eudat.logic.security.customproviders.B2AccessCustomProvider;
import eu.eudat.logic.security.customproviders.B2AccessUser;
import eu.eudat.logic.security.customproviders.B2Access.B2AccessCustomProvider;
import eu.eudat.logic.security.customproviders.B2Access.B2AccessUser;
import eu.eudat.logic.security.validators.TokenValidator;
import eu.eudat.logic.security.validators.b2access.helpers.B2AccessRequest;
import eu.eudat.logic.security.validators.b2access.helpers.B2AccessResponseToken;
import eu.eudat.logic.services.operations.AuthenticationServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
@ -24,18 +25,18 @@ import java.security.GeneralSecurityException;
public class B2AccessTokenValidator implements TokenValidator {
private B2AccessCustomProvider b2AccessCustomProvider;
private AuthenticationServiceImpl authenticationServiceImpl;
private AuthenticationService nonVerifiedUserAuthenticationService;
private Environment environment;
@Autowired
public B2AccessTokenValidator(Environment environment, AuthenticationServiceImpl authenticationServiceImpl, B2AccessCustomProvider b2AccessCustomProvider) {
this.authenticationServiceImpl = authenticationServiceImpl;
public B2AccessTokenValidator(Environment environment, AuthenticationService nonVerifiedUserAuthenticationService, B2AccessCustomProvider b2AccessCustomProvider) {
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
this.environment = environment;
this.b2AccessCustomProvider = b2AccessCustomProvider;
}
@Override
public Principal validateToken(LoginInfo credentials) throws NonValidTokenException, IOException, GeneralSecurityException {
public Principal validateToken(LoginInfo credentials) throws NonValidTokenException, IOException, GeneralSecurityException, NullEmailException {
B2AccessUser b2AccessUser = this.b2AccessCustomProvider.getUser(credentials.getTicket());
LoginProviderUser user = new LoginProviderUser();
user.setId(b2AccessUser.getId());
@ -43,7 +44,7 @@ public class B2AccessTokenValidator implements TokenValidator {
user.setName(b2AccessUser.getName());
user.setProvider(credentials.getProvider());
user.setSecret(credentials.getTicket());
return this.authenticationServiceImpl.Touch(user);
return this.nonVerifiedUserAuthenticationService.Touch(user);
}
public B2AccessResponseToken getAccessToken(B2AccessRequest b2AccessRequest) {

View File

@ -1,22 +1,19 @@
package eu.eudat.logic.security.validators.facebook;
import eu.eudat.exceptions.security.NonValidTokenException;
import eu.eudat.exceptions.security.UnauthorisedException;
import eu.eudat.models.data.login.LoginInfo;
import eu.eudat.models.data.loginprovider.LoginProviderUser;
import eu.eudat.models.data.security.Principal;
import eu.eudat.logic.security.validators.TokenValidator;
import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl;
import eu.eudat.logic.services.ApiContext;
import eu.eudat.logic.services.operations.AuthenticationServiceImpl;
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
import eu.eudat.models.data.login.LoginInfo;
import eu.eudat.models.data.loginprovider.LoginProviderUser;
import eu.eudat.models.data.security.Principal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.social.facebook.api.User;
import org.springframework.social.facebook.connect.FacebookServiceProvider;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
@ -25,50 +22,50 @@ import java.util.Map;
@Component("facebookTokenValidator")
public class FacebookTokenValidator implements TokenValidator {
private Environment environment;
private ApiContext apiContext;
private AuthenticationServiceImpl authenticationServiceImpl;
private FacebookServiceProvider facebookServiceProvider;
private Environment environment;
private ApiContext apiContext;
private AuthenticationService nonVerifiedUserAuthenticationService;
private FacebookServiceProvider facebookServiceProvider;
@Autowired
public FacebookTokenValidator(ApiContext apiContext, Environment environment, AuthenticationServiceImpl authenticationServiceImpl) {
this.environment = environment;
this.apiContext = apiContext;
this.authenticationServiceImpl = authenticationServiceImpl;
this.facebookServiceProvider = new FacebookServiceProvider(this.environment.getProperty("facebook.login.clientId"), this.environment.getProperty("facebook.login.clientSecret"), this.environment.getProperty("facebook.login.namespace"));
}
@Autowired
public FacebookTokenValidator(ApiContext apiContext, Environment environment, AuthenticationService nonVerifiedUserAuthenticationService) {
this.environment = environment;
this.apiContext = apiContext;
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
this.facebookServiceProvider = new FacebookServiceProvider(this.environment.getProperty("facebook.login.clientId"), this.environment.getProperty("facebook.login.clientSecret"), this.environment.getProperty("facebook.login.namespace"));
}
@Override
public Principal validateToken(LoginInfo credentials) throws NonValidTokenException, IOException, GeneralSecurityException {
User profile = getFacebookUser(credentials.getTicket());
LoginProviderUser user = new LoginProviderUser();
if (profile.getEmail() == null)
throw new UnauthorisedException("Cannot login user.Facebook account did not provide email");
@Override
public Principal validateToken(LoginInfo credentials) {
User profile = getFacebookUser(credentials.getTicket());
LoginProviderUser user = new LoginProviderUser();
if (profile.getEmail() == null)
throw new UnauthorisedException("Cannot login user.Facebook account did not provide email");
user.setEmail(profile.getEmail());
user.setId(profile.getId());
//user.setIsVerified(profile.isVerified());
user.setName(profile.getName());
user.setProvider(TokenValidatorFactoryImpl.LoginProvider.FACEBOOK);
String url = (String)((Map<String,Object> )((Map<String,Object> )profile.getExtraData().get("picture")).get("data")).get("url");
user.setAvatarUrl(url);
user.setSecret(credentials.getTicket());
return this.authenticationServiceImpl.Touch(user);
}
user.setEmail(profile.getEmail());
user.setId(profile.getId());
//user.setIsVerified(profile.isVerified());
user.setName(profile.getName());
user.setProvider(TokenValidatorFactoryImpl.LoginProvider.FACEBOOK);
String url = (String) ((Map<String, Object>) ((Map<String, Object>) profile.getExtraData().get("picture")).get("data")).get("url");
user.setAvatarUrl(url);
user.setSecret(credentials.getTicket());
return this.nonVerifiedUserAuthenticationService.Touch(user);
}
private User getFacebookUser(String accessToken) {
String[] fields = {"id", "email", "first_name", "last_name", "name", "verified","picture"};
User profile = this.facebookServiceProvider.getApi(accessToken).fetchObject("me", User.class, fields);
return profile;
}
private User getFacebookUser(String accessToken) {
String[] fields = {"id", "email", "first_name", "last_name", "name", "verified", "picture"};
User profile = this.facebookServiceProvider.getApi(accessToken).fetchObject("me", User.class, fields);
return profile;
}
private Date addADay(Date date) {
Date dt = new Date();
Calendar c = Calendar.getInstance();
c.setTime(dt);
c.add(Calendar.DATE, 1);
dt = c.getTime();
return dt;
}
private Date addADay(Date date) {
Date dt = new Date();
Calendar c = Calendar.getInstance();
c.setTime(dt);
c.add(Calendar.DATE, 1);
dt = c.getTime();
return dt;
}
}

View File

@ -6,13 +6,12 @@ import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import eu.eudat.exceptions.security.NonValidTokenException;
import eu.eudat.models.data.login.LoginInfo;
import eu.eudat.models.data.loginprovider.LoginProviderUser;
import eu.eudat.logic.security.validators.TokenValidator;
import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl;
import eu.eudat.logic.services.ApiContext;
import eu.eudat.logic.services.operations.AuthenticationServiceImpl;
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
import eu.eudat.models.data.login.LoginInfo;
import eu.eudat.models.data.loginprovider.LoginProviderUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
@ -24,40 +23,40 @@ import java.util.Collections;
@Component("googleTokenValidator")
public class GoogleTokenValidator implements TokenValidator {
private static final HttpTransport transport = new NetHttpTransport();
private ApiContext apiContext;
private AuthenticationServiceImpl authenticationServiceImpl;
private GoogleIdTokenVerifier verifier;
private Environment environment;
private static final HttpTransport transport = new NetHttpTransport();
private ApiContext apiContext;
private AuthenticationService nonVerifiedUserAuthenticationService;
private GoogleIdTokenVerifier verifier;
private Environment environment;
@Autowired
public GoogleTokenValidator(ApiContext apiContext, Environment environment, AuthenticationServiceImpl authenticationServiceImpl) {
this.apiContext = apiContext;
this.environment = environment;
this.authenticationServiceImpl = authenticationServiceImpl;
verifier = new GoogleIdTokenVerifier.Builder(transport, JacksonFactory.getDefaultInstance())
.setAudience(Collections.singletonList(this.environment.getProperty("google.login.clientId")))
.build();
}
@Autowired
public GoogleTokenValidator(ApiContext apiContext, Environment environment, AuthenticationService nonVerifiedUserAuthenticationService) {
this.apiContext = apiContext;
this.environment = environment;
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
verifier = new GoogleIdTokenVerifier.Builder(transport, JacksonFactory.getDefaultInstance())
.setAudience(Collections.singletonList(this.environment.getProperty("google.login.clientId")))
.build();
}
private GoogleIdToken verifyUserAndGetUser(String idTokenString) throws IOException, GeneralSecurityException {
GoogleIdToken idToken = verifier.verify(idTokenString);
return idToken;
}
private GoogleIdToken verifyUserAndGetUser(String idTokenString) throws IOException, GeneralSecurityException {
GoogleIdToken idToken = verifier.verify(idTokenString);
return idToken;
}
@Override
public eu.eudat.models.data.security.Principal validateToken(LoginInfo credentials) throws NonValidTokenException, IOException, GeneralSecurityException {
GoogleIdToken idToken = this.verifyUserAndGetUser(credentials.getTicket());
Payload payload = idToken.getPayload();
LoginProviderUser user = new LoginProviderUser();
user.setAvatarUrl((String) payload.get("picture"));
user.setSecret(credentials.getTicket());
user.setId( payload.getSubject());
user.setProvider(TokenValidatorFactoryImpl.LoginProvider.GOOGLE);
user.setName((String) payload.get("name"));
user.setEmail(payload.getEmail());
user.setIsVerified(payload.getEmailVerified());
return this.authenticationServiceImpl.Touch(user);
}
@Override
public eu.eudat.models.data.security.Principal validateToken(LoginInfo credentials) throws IOException, GeneralSecurityException {
GoogleIdToken idToken = this.verifyUserAndGetUser(credentials.getTicket());
Payload payload = idToken.getPayload();
LoginProviderUser user = new LoginProviderUser();
user.setAvatarUrl((String) payload.get("picture"));
user.setSecret(credentials.getTicket());
user.setId(payload.getSubject());
user.setProvider(TokenValidatorFactoryImpl.LoginProvider.GOOGLE);
user.setName((String) payload.get("name"));
user.setEmail(payload.getEmail());
user.setIsVerified(payload.getEmailVerified());
return this.nonVerifiedUserAuthenticationService.Touch(user);
}
}

View File

@ -1,11 +1,10 @@
package eu.eudat.logic.security.validators.linkedin;
import eu.eudat.exceptions.security.NonValidTokenException;
import eu.eudat.exceptions.security.UnauthorisedException;
import eu.eudat.logic.security.validators.TokenValidator;
import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl;
import eu.eudat.logic.services.ApiContext;
import eu.eudat.logic.services.operations.AuthenticationServiceImpl;
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
import eu.eudat.models.data.login.LoginInfo;
import eu.eudat.models.data.loginprovider.LoginProviderUser;
import eu.eudat.models.data.security.Principal;
@ -17,28 +16,25 @@ import org.springframework.social.linkedin.connect.LinkedInServiceProvider;
import org.springframework.social.oauth2.AccessGrant;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.security.GeneralSecurityException;
@Component("linkedInTokenValidator")
public class LinkedInTokenValidator implements TokenValidator {
private Environment environment;
private ApiContext apiContext;
private AuthenticationServiceImpl authenticationServiceImpl;
private AuthenticationService nonVerifiedUserAuthenticationService;
private LinkedInServiceProvider linkedInServiceProvider;
@Autowired
public LinkedInTokenValidator(ApiContext apiContext, Environment environment, AuthenticationServiceImpl authenticationServiceImpl) {
public LinkedInTokenValidator(ApiContext apiContext, Environment environment, AuthenticationService nonVerifiedUserAuthenticationService) {
this.environment = environment;
this.apiContext = apiContext;
this.authenticationServiceImpl = authenticationServiceImpl;
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
this.linkedInServiceProvider = new LinkedInServiceProvider(this.environment.getProperty("linkedin.login.clientId"), this.environment.getProperty("linkedin.login.clientSecret"));
}
@Override
public Principal validateToken(LoginInfo credentials) throws NonValidTokenException, IOException, GeneralSecurityException {
public Principal validateToken(LoginInfo credentials) {
AccessGrant accessGrant = this.linkedInServiceProvider.getOAuthOperations().exchangeForAccess(credentials.getTicket(), this.environment.getProperty("linkedin.login.redirect_uri"), null);
LinkedIn linkedInService = this.linkedInServiceProvider.getApi(accessGrant.getAccessToken());
LinkedInProfile linkedInProfile = linkedInService.profileOperations().getUserProfile();
@ -53,6 +49,6 @@ public class LinkedInTokenValidator implements TokenValidator {
user.setName(linkedInProfile.getFirstName() + " " + linkedInProfile.getLastName());
user.setProvider(TokenValidatorFactoryImpl.LoginProvider.LINKEDIN);
user.setSecret(accessGrant.getAccessToken());
return this.authenticationServiceImpl.Touch(user);
return this.nonVerifiedUserAuthenticationService.Touch(user);
}
}

View File

@ -1,11 +1,12 @@
package eu.eudat.logic.security.validators.twitter;
import eu.eudat.exceptions.security.NonValidTokenException;
import eu.eudat.exceptions.security.NullEmailException;
import eu.eudat.exceptions.security.UnauthorisedException;
import eu.eudat.logic.security.validators.TokenValidator;
import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl;
import eu.eudat.logic.services.ApiContext;
import eu.eudat.logic.services.operations.AuthenticationServiceImpl;
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
import eu.eudat.models.data.login.LoginInfo;
import eu.eudat.models.data.loginprovider.LoginProviderUser;
import eu.eudat.models.data.security.Principal;
@ -28,19 +29,19 @@ public class TwitterTokenValidator implements TokenValidator {
private Environment environment;
private ApiContext apiContext;
private AuthenticationServiceImpl authenticationServiceImpl;
private AuthenticationService nonVerifiedUserAuthenticationService;
private TwitterServiceProvider twitterServiceProvider;
@Autowired
public TwitterTokenValidator(ApiContext apiContext, Environment environment, AuthenticationServiceImpl authenticationServiceImpl) {
public TwitterTokenValidator(ApiContext apiContext, Environment environment, AuthenticationService nonVerifiedUserAuthenticationService) {
this.environment = environment;
this.apiContext = apiContext;
this.authenticationServiceImpl = authenticationServiceImpl;
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
this.twitterServiceProvider = new TwitterServiceProvider(this.environment.getProperty("twitter.login.clientId"), this.environment.getProperty("twitter.login.clientSecret"));
}
@Override
public Principal validateToken(LoginInfo credentials) throws NonValidTokenException, IOException, GeneralSecurityException {
public Principal validateToken(LoginInfo credentials) throws NonValidTokenException, IOException, GeneralSecurityException, NullEmailException {
String verifier = (String) credentials.getData();
OAuthToken oAuthToken = new OAuthToken(credentials.getTicket(), verifier);
AuthorizedRequestToken authorizedRequestToken = new AuthorizedRequestToken(oAuthToken, verifier);
@ -59,7 +60,7 @@ public class TwitterTokenValidator implements TokenValidator {
user.setName(profile.getName());
user.setProvider(TokenValidatorFactoryImpl.LoginProvider.TWITTER);
user.setSecret(finalOauthToken.getValue());
return this.authenticationServiceImpl.Touch(user);
return this.nonVerifiedUserAuthenticationService.Touch(user);
}
public OAuthToken getRequestToken() {

View File

@ -1,21 +0,0 @@
package eu.eudat.logic.services.operations;
import eu.eudat.models.data.login.Credentials;
import eu.eudat.models.data.loginprovider.LoginProviderUser;
import eu.eudat.models.data.security.Principal;
import java.util.UUID;
/**
* Created by ikalyvas on 3/1/2018.
*/
public interface AuthenticationService {
Principal Touch(LoginProviderUser profile);
Principal Touch(Credentials credentials);
void Logout(UUID token);
Principal Touch(UUID token);
}

View File

@ -1,224 +0,0 @@
package eu.eudat.logic.services.operations;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.eudat.data.dao.criteria.UserInfoCriteria;
import eu.eudat.data.entities.Credential;
import eu.eudat.data.entities.UserInfo;
import eu.eudat.data.entities.UserRole;
import eu.eudat.data.entities.UserToken;
import eu.eudat.logic.builders.entity.CredentialBuilder;
import eu.eudat.logic.builders.entity.UserInfoBuilder;
import eu.eudat.logic.builders.entity.UserTokenBuilder;
import eu.eudat.logic.builders.model.models.PrincipalBuilder;
import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl;
import eu.eudat.logic.services.ApiContext;
import eu.eudat.models.data.login.Credentials;
import eu.eudat.models.data.loginprovider.LoginProviderUser;
import eu.eudat.models.data.security.Principal;
import eu.eudat.types.Authorities;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.IOException;
import java.util.*;
@Service("authenticationService")
public class AuthenticationServiceImpl implements AuthenticationService {
private ApiContext apiContext;
private Environment environment;
@Autowired
public AuthenticationServiceImpl(ApiContext apiContext, Environment environment) {
this.environment = environment;
this.apiContext = apiContext;
}
public Principal Touch(UUID token) {
UserToken tokenEntry = this.apiContext.getOperationsContext().getDatabaseRepository().getUserTokenDao().find(token);
if (tokenEntry == null || tokenEntry.getExpiresAt().before(new Date())) return null;
return this.Touch(tokenEntry);
}
public void Logout(UUID token) {
UserToken tokenEntry = this.apiContext.getOperationsContext().getDatabaseRepository().getUserTokenDao().find(token);
this.apiContext.getOperationsContext().getDatabaseRepository().getUserTokenDao().delete(tokenEntry);
}
private Principal Touch(UserToken token) {
if (token == null || token.getExpiresAt().before(new Date())) return null;
UserInfo user = this.apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(token.getUser().getId());
if (user == null) return null;
String avatarUrl;
try {
avatarUrl = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("avatarUrl").asText() : "";
} catch (Exception e) {
avatarUrl = "";
}
String culture;
try {
culture = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("culture").get("name").asText() : "";
} catch (Exception e) {
culture = "";
}
String language;
try {
language = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("language").get("value").asText() : "";
} catch (Exception e) {
language = "";
}
String timezone;
try {
timezone = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("timezone").asText() : "";
} catch (Exception e) {
timezone = "";
}
Principal principal = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(PrincipalBuilder.class)
.id(user.getId()).token(token.getToken())
.expiresAt(token.getExpiresAt()).name(user.getName())
.avatarUrl(avatarUrl)
.culture(culture)
.language(language)
.timezone(timezone)
.build();
List<UserRole> userRoles = apiContext.getOperationsContext().getDatabaseRepository().getUserRoleDao().getUserRoles(user);
for (UserRole item : userRoles) {
if (principal.getAuthz() == null) principal.setAuthorities(new HashSet<>());
principal.getAuthz().add(Authorities.fromInteger(item.getRole()));
}
return principal;
}
public Principal Touch(Credentials credentials) {
Credential credential = this.apiContext.getOperationsContext().getDatabaseRepository().getCredentialDao().getLoggedInCredentials(credentials.getUsername(), credentials.getSecret(), TokenValidatorFactoryImpl.LoginProvider.NATIVELOGIN.getValue());
if (credential == null && credentials.getUsername().equals(environment.getProperty("autouser.root.username"))) {
try {
credential = this.autoCreateUser(credentials.getUsername(), credentials.getSecret());
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
if (credential == null) return null;
UserToken userToken = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserTokenBuilder.class)
.issuedAt(new Date()).user(credential.getUserInfo())
.token(UUID.randomUUID()).expiresAt(addADay(new Date()))
.build();
userToken = apiContext.getOperationsContext().getDatabaseRepository().getUserTokenDao().createOrUpdate(userToken);
return this.Touch(userToken);
}
public Principal Touch(LoginProviderUser profile) {
UserInfoCriteria criteria = new UserInfoCriteria();
criteria.setEmail(profile.getEmail());
UserInfo userInfo = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().asQueryable().withHint("userInfo").where((builder, root) -> builder.equal(root.get("email"), profile.getEmail())).getSingleOrDefault();
if (userInfo == null) {
Optional<Credential> optionalCredential = Optional.ofNullable(apiContext.getOperationsContext().getDatabaseRepository().getCredentialDao()
.asQueryable().withHint("credentialUserInfo")
.where((builder, root) -> builder.and(builder.equal(root.get("provider"), profile.getProvider().getValue()), builder.equal(root.get("externalId"), profile.getId())))
.getSingleOrDefault());
userInfo = optionalCredential.map(Credential::getUserInfo).orElse(null);
}
final Credential credential = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(CredentialBuilder.class)
.id(UUID.randomUUID()).creationTime(new Date()).status(1)
.lastUpdateTime(new Date()).provider(profile.getProvider().getValue())
.secret(profile.getSecret()).externalId(profile.getId())
.build();
if (userInfo == null) {
userInfo = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserInfoBuilder.class)
.name(profile.getName()).verified_email(profile.getIsVerified())
.email(profile.getEmail()).created(new Date()).lastloggedin(new Date())
.additionalinfo("{\"data\":{\"avatar\":{\"url\":\"" + profile.getAvatarUrl() + "\"}}}")
.authorization_level((short) 1).usertype((short) 1)
.build();
userInfo = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().createOrUpdate(userInfo);
credential.setPublicValue(userInfo.getName());
credential.setUserInfo(userInfo);
apiContext.getOperationsContext().getDatabaseRepository().getCredentialDao().createOrUpdate(credential);
UserRole role = new UserRole();
role.setRole(Authorities.USER.getValue());
role.setUserInfo(userInfo);
apiContext.getOperationsContext().getDatabaseRepository().getUserRoleDao().createOrUpdate(role);
} else {
Map<String, Object> additionalInfo = userInfo.getAdditionalinfo() != null ?
new JSONObject(userInfo.getAdditionalinfo()).toMap() : new HashMap<>();
additionalInfo.put("avatarUrl", profile.getAvatarUrl());
userInfo.setLastloggedin(new Date());
userInfo.setAdditionalinfo(new JSONObject(additionalInfo).toString());
Set<Credential> credentials = userInfo.getCredentials();
if (credentials.contains(credential)) {
Credential oldCredential = credentials.stream().filter(item -> credential.getProvider().equals(item.getProvider())).findFirst().get();
credential.setId(oldCredential.getId());
} else {
credential.setUserInfo(userInfo);
credential.setId(UUID.randomUUID());
credential.setPublicValue(userInfo.getName());
apiContext.getOperationsContext().getDatabaseRepository().getCredentialDao().createOrUpdate(credential);
userInfo.getCredentials().add(credential);
}
userInfo = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().createOrUpdate(userInfo);
}
UserToken userToken = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserTokenBuilder.class)
.token(UUID.randomUUID()).user(userInfo)
.expiresAt(addADay(new Date())).issuedAt(new Date())
.build();
apiContext.getOperationsContext().getDatabaseRepository().getUserTokenDao().createOrUpdate(userToken);
return Touch(userToken.getToken());
}
private Date addADay(Date date) {
Date dt = new Date();
Calendar c = Calendar.getInstance();
c.setTime(dt);
c.add(Calendar.DATE, 1);
dt = c.getTime();
return dt;
}
@Transactional
private Credential autoCreateUser(String username, String password) {
if (!environment.getProperty("autouser.root.username").equals(username) || !environment.getProperty("autouser.root.password").equals(password))
return null;
UserInfo userInfo = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserInfoBuilder.class)
.name(username).email(environment.getProperty("autouser.root.email")).created(new Date())
.lastloggedin(new Date()).authorization_level((short) 1).usertype((short) 1)
.build();
userInfo = this.apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().createOrUpdate(userInfo);
UserRole role = new UserRole();
role.setRole(Authorities.ADMIN.getValue());
role.setUserInfo(userInfo);
this.apiContext.getOperationsContext().getDatabaseRepository().getUserRoleDao().createOrUpdate(role);
Credential credential = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(CredentialBuilder.class)
.id(UUID.randomUUID()).userInfo(userInfo).publicValue(username).secret(password)
.provider((int) TokenValidatorFactoryImpl.LoginProvider.NATIVELOGIN.getValue())
.creationTime(new Date()).lastUpdateTime(new Date()).status(0)
.build();
return this.apiContext.getOperationsContext().getDatabaseRepository().getCredentialDao().createOrUpdate(credential);
}
}

View File

@ -0,0 +1,174 @@
package eu.eudat.logic.services.operations.authentication;
import eu.eudat.data.entities.Credential;
import eu.eudat.data.entities.UserInfo;
import eu.eudat.data.entities.UserRole;
import eu.eudat.data.entities.UserToken;
import eu.eudat.exceptions.security.NullEmailException;
import eu.eudat.logic.builders.entity.CredentialBuilder;
import eu.eudat.logic.builders.entity.UserInfoBuilder;
import eu.eudat.logic.builders.entity.UserTokenBuilder;
import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl;
import eu.eudat.logic.services.ApiContext;
import eu.eudat.models.data.login.Credentials;
import eu.eudat.models.data.loginprovider.LoginProviderUser;
import eu.eudat.models.data.security.Principal;
import eu.eudat.types.Authorities;
import org.json.JSONObject;
import org.springframework.core.env.Environment;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
public abstract class AbstractAuthenticationService implements AuthenticationService {
protected ApiContext apiContext;
protected Environment environment;
public AbstractAuthenticationService(ApiContext apiContext, Environment environment) {
this.apiContext = apiContext;
this.environment = environment;
}
protected Date addADay(Date date) {
Date dt = new Date();
Calendar c = Calendar.getInstance();
c.setTime(dt);
c.add(Calendar.DATE, 1);
dt = c.getTime();
return dt;
}
abstract Principal Touch(UserToken token);
@Transactional
protected Credential autoCreateUser(String username, String password) {
if (!environment.getProperty("autouser.root.username").equals(username) || !environment.getProperty("autouser.root.password").equals(password))
return null;
UserInfo userInfo = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserInfoBuilder.class)
.name(username).email(environment.getProperty("autouser.root.email")).created(new Date())
.lastloggedin(new Date()).authorization_level((short) 1).usertype((short) 1)
.build();
userInfo = this.apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().createOrUpdate(userInfo);
UserRole role = new UserRole();
role.setRole(Authorities.ADMIN.getValue());
role.setUserInfo(userInfo);
this.apiContext.getOperationsContext().getDatabaseRepository().getUserRoleDao().createOrUpdate(role);
Credential credential = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(CredentialBuilder.class)
.id(UUID.randomUUID()).userInfo(userInfo).publicValue(username).secret(password)
.provider((int) TokenValidatorFactoryImpl.LoginProvider.NATIVELOGIN.getValue())
.creationTime(new Date()).lastUpdateTime(new Date()).status(0)
.build();
return this.apiContext.getOperationsContext().getDatabaseRepository().getCredentialDao().createOrUpdate(credential);
}
public Principal Touch(UUID token) {
UserToken tokenEntry = this.apiContext.getOperationsContext().getDatabaseRepository().getUserTokenDao().find(token);
if (tokenEntry == null || tokenEntry.getExpiresAt().before(new Date())) return null;
return this.Touch(tokenEntry);
}
public void Logout(UUID token) {
UserToken tokenEntry = this.apiContext.getOperationsContext().getDatabaseRepository().getUserTokenDao().find(token);
this.apiContext.getOperationsContext().getDatabaseRepository().getUserTokenDao().delete(tokenEntry);
}
public Principal Touch(Credentials credentials) throws NullEmailException {
Credential credential = this.apiContext.getOperationsContext().getDatabaseRepository().getCredentialDao().getLoggedInCredentials(credentials.getUsername(), credentials.getSecret(), TokenValidatorFactoryImpl.LoginProvider.NATIVELOGIN.getValue());
if (credential == null && credentials.getUsername().equals(environment.getProperty("autouser.root.username"))) {
try {
credential = this.autoCreateUser(credentials.getUsername(), credentials.getSecret());
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
if (credential == null) return null;
UserToken userToken = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserTokenBuilder.class)
.issuedAt(new Date()).user(credential.getUserInfo())
.token(UUID.randomUUID()).expiresAt(addADay(new Date()))
.build();
userToken = apiContext.getOperationsContext().getDatabaseRepository().getUserTokenDao().createOrUpdate(userToken);
return this.Touch(userToken);
}
public Principal Touch(LoginProviderUser profile) throws NullEmailException {
UserInfo userInfo = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().asQueryable().withHint("userInfo").where((builder, root) -> builder.equal(root.get("email"), profile.getEmail())).getSingleOrDefault();
if (userInfo == null) {
Optional<Credential> optionalCredential = Optional.ofNullable(apiContext.getOperationsContext().getDatabaseRepository().getCredentialDao()
.asQueryable().withHint("credentialUserInfo")
.where((builder, root) -> builder.and(builder.equal(root.get("provider"), profile.getProvider().getValue()), builder.equal(root.get("externalId"), profile.getId())))
.getSingleOrDefault());
userInfo = optionalCredential.map(Credential::getUserInfo).orElse(null);
}
final Credential credential = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(CredentialBuilder.class)
.id(UUID.randomUUID())
.creationTime(new Date())
.status(1)
.lastUpdateTime(new Date())
.provider(profile.getProvider().getValue())
.secret(profile.getSecret())
.externalId(profile.getId())
.build();
if (userInfo == null) {
userInfo = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserInfoBuilder.class)
.name(profile.getName()).verified_email(profile.getIsVerified())
.email(profile.getEmail()).created(new Date()).lastloggedin(new Date())
.additionalinfo("{\"data\":{\"avatar\":{\"url\":\"" + profile.getAvatarUrl() + "\"}}}")
.authorization_level((short) 1).usertype((short) 1)
.build();
userInfo = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().createOrUpdate(userInfo);
credential.setPublicValue(userInfo.getName());
credential.setUserInfo(userInfo);
apiContext.getOperationsContext().getDatabaseRepository().getCredentialDao().createOrUpdate(credential);
UserRole role = new UserRole();
role.setRole(Authorities.USER.getValue());
role.setUserInfo(userInfo);
apiContext.getOperationsContext().getDatabaseRepository().getUserRoleDao().createOrUpdate(role);
} else {
Map<String, Object> additionalInfo = userInfo.getAdditionalinfo() != null ?
new JSONObject(userInfo.getAdditionalinfo()).toMap() : new HashMap<>();
additionalInfo.put("avatarUrl", profile.getAvatarUrl());
userInfo.setLastloggedin(new Date());
userInfo.setAdditionalinfo(new JSONObject(additionalInfo).toString());
Set<Credential> credentials = userInfo.getCredentials();
if (credentials.contains(credential)) {
Credential oldCredential = credentials.stream().filter(item -> credential.getProvider().equals(item.getProvider())).findFirst().get();
credential.setId(oldCredential.getId());
} else {
credential.setUserInfo(userInfo);
credential.setId(UUID.randomUUID());
credential.setPublicValue(userInfo.getName());
apiContext.getOperationsContext().getDatabaseRepository().getCredentialDao().createOrUpdate(credential);
userInfo.getCredentials().add(credential);
}
userInfo = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().createOrUpdate(userInfo);
}
UserToken userToken = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserTokenBuilder.class)
.token(UUID.randomUUID()).user(userInfo)
.expiresAt(addADay(new Date())).issuedAt(new Date())
.build();
apiContext.getOperationsContext().getDatabaseRepository().getUserTokenDao().createOrUpdate(userToken);
return Touch(userToken.getToken());
}
}

View File

@ -0,0 +1,22 @@
package eu.eudat.logic.services.operations.authentication;
import eu.eudat.exceptions.security.NullEmailException;
import eu.eudat.models.data.login.Credentials;
import eu.eudat.models.data.loginprovider.LoginProviderUser;
import eu.eudat.models.data.security.Principal;
import java.util.UUID;
/**
* Created by ikalyvas on 3/1/2018.
*/
public interface AuthenticationService {
Principal Touch(LoginProviderUser profile) throws NullEmailException;
Principal Touch(Credentials credentials) throws NullEmailException;
void Logout(UUID token);
Principal Touch(UUID token) throws NullEmailException;
}

View File

@ -0,0 +1,70 @@
package eu.eudat.logic.services.operations.authentication;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.eudat.data.entities.UserInfo;
import eu.eudat.data.entities.UserRole;
import eu.eudat.data.entities.UserToken;
import eu.eudat.logic.builders.model.models.PrincipalBuilder;
import eu.eudat.logic.services.ApiContext;
import eu.eudat.models.data.security.Principal;
import eu.eudat.types.Authorities;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
@Service("nonVerifiedUserAuthenticationService")
public class NonVerifiedUserEmailAuthenticationService extends AbstractAuthenticationService {
public NonVerifiedUserEmailAuthenticationService(ApiContext apiContext, Environment environment) {
super(apiContext, environment);
}
public Principal Touch(UserToken token) {
if (token == null || token.getExpiresAt().before(new Date())) return null;
UserInfo user = this.apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(token.getUser().getId());
if (user == null) return null;
String avatarUrl;
try {
avatarUrl = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("avatarUrl").asText() : "";
} catch (Exception e) {
avatarUrl = "";
}
String culture;
try {
culture = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("culture").get("name").asText() : "";
} catch (Exception e) {
culture = "";
}
String language;
try {
language = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("language").get("value").asText() : "";
} catch (Exception e) {
language = "";
}
String timezone;
try {
timezone = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("timezone").asText() : "";
} catch (Exception e) {
timezone = "";
}
Principal principal = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(PrincipalBuilder.class)
.id(user.getId()).token(token.getToken())
.expiresAt(token.getExpiresAt()).name(user.getName())
.avatarUrl(avatarUrl)
.culture(culture)
.language(language)
.timezone(timezone)
.build();
List<UserRole> userRoles = apiContext.getOperationsContext().getDatabaseRepository().getUserRoleDao().getUserRoles(user);
for (UserRole item : userRoles) {
if (principal.getAuthz() == null) principal.setAuthorities(new HashSet<>());
principal.getAuthz().add(Authorities.fromInteger(item.getRole()));
}
return principal;
}
}

View File

@ -0,0 +1,79 @@
package eu.eudat.logic.services.operations.authentication;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.eudat.data.entities.Credential;
import eu.eudat.data.entities.UserInfo;
import eu.eudat.data.entities.UserRole;
import eu.eudat.data.entities.UserToken;
import eu.eudat.exceptions.security.NullEmailException;
import eu.eudat.logic.builders.entity.CredentialBuilder;
import eu.eudat.logic.builders.entity.UserInfoBuilder;
import eu.eudat.logic.builders.entity.UserTokenBuilder;
import eu.eudat.logic.builders.model.models.PrincipalBuilder;
import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl;
import eu.eudat.logic.services.ApiContext;
import eu.eudat.models.data.login.Credentials;
import eu.eudat.models.data.loginprovider.LoginProviderUser;
import eu.eudat.models.data.security.Principal;
import eu.eudat.types.Authorities;
import org.json.JSONObject;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import java.util.*;
@Service("verifiedUserAuthenticationService")
public class VerifiedUserAuthenticationService extends AbstractAuthenticationService {
public VerifiedUserAuthenticationService(ApiContext apiContext, Environment environment) {
super(apiContext, environment);
}
public Principal Touch(UserToken token) {
if (token == null || token.getExpiresAt().before(new Date())) return null;
UserInfo user = this.apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(token.getUser().getId());
if (user == null) return null;
if (user.getEmail() == null) throw new NullEmailException();
String avatarUrl;
try {
avatarUrl = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("avatarUrl").asText() : "";
} catch (Exception e) {
avatarUrl = "";
}
String culture;
try {
culture = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("culture").get("name").asText() : "";
} catch (Exception e) {
culture = "";
}
String language;
try {
language = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("language").get("value").asText() : "";
} catch (Exception e) {
language = "";
}
String timezone;
try {
timezone = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("timezone").asText() : "";
} catch (Exception e) {
timezone = "";
}
Principal principal = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(PrincipalBuilder.class)
.id(user.getId()).token(token.getToken())
.expiresAt(token.getExpiresAt()).name(user.getName())
.avatarUrl(avatarUrl)
.culture(culture)
.language(language)
.timezone(timezone)
.build();
List<UserRole> userRoles = apiContext.getOperationsContext().getDatabaseRepository().getUserRoleDao().getUserRoles(user);
for (UserRole item : userRoles) {
if (principal.getAuthz() == null) principal.setAuthorities(new HashSet<>());
principal.getAuthz().add(Authorities.fromInteger(item.getRole()));
}
return principal;
}
}

View File

@ -35,6 +35,12 @@ b2access.externallogin.user_info_url=https://b2access-integration.fz-juelich.de:
b2access.externallogin.access_token_url=https://b2access-integration.fz-juelich.de:443/oauth2/token
b2access.externallogin.redirect_uri=http://opendmp.eu/api/oauth/authorized/b2access
#############ORCID CONFIGURATIONS#########
orcid.login.client_id=APP-766DI5LP8T75FC4R
orcid.login.client_secret=f6ddc717-f49e-4bce-b302-2e479b226a24
orcid.login.access_token_url=https://orcid.org/oauth/token
orcid.login.redirect_uri=http://localhost:4200/login/external/orcid
#############ZENODO CONFIGURATIONS#########
zenodo.url=https://sandbox.zenodo.org/api/
zenodo.access_token=