diff --git a/dmp-backend/web/src/main/java/eu/eudat/configurations/WebMVCConfiguration.java b/dmp-backend/web/src/main/java/eu/eudat/configurations/WebMVCConfiguration.java index 91fb7babc..d1136aba9 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/configurations/WebMVCConfiguration.java +++ b/dmp-backend/web/src/main/java/eu/eudat/configurations/WebMVCConfiguration.java @@ -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 argumentResolvers) { - argumentResolvers.add(new PrincipalArgumentResolver(authenticationService)); - } + @Autowired + @Override + public void addArgumentResolvers(List 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())); + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Login.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Login.java index 15582d910..29cf87104 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Login.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Login.java @@ -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> externallogin(@RequestBody LoginInfo credentials) throws GeneralSecurityException { + ResponseEntity> 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().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> nativelogin(@RequestBody Credentials credentials) { + ResponseEntity> nativelogin(@RequestBody Credentials credentials) throws NullEmailException { this.logger.info(credentials.getUsername(), "Trying To Login"); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(userManager.authenticate(this.authenticationServiceImpl, credentials)).status(ApiMessageCode.SUCCESS_MESSAGE)); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().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> authMe(Principal principal) { + ResponseEntity> authMe(Principal principal) throws NullEmailException { this.logger.info(principal, "Getting Me"); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(this.authenticationServiceImpl.Touch(principal.getToken())).status(ApiMessageCode.NO_MESSAGE)); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().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> 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().status(ApiMessageCode.NO_MESSAGE)); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/exceptions/security/NullEmailException.java b/dmp-backend/web/src/main/java/eu/eudat/exceptions/security/NullEmailException.java new file mode 100644 index 000000000..2663898ae --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/exceptions/security/NullEmailException.java @@ -0,0 +1,8 @@ +package eu.eudat.exceptions.security; + +public class NullEmailException extends RuntimeException { + + public NullEmailException() { + super(); + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/handlers/PrincipalArgumentResolver.java b/dmp-backend/web/src/main/java/eu/eudat/logic/handlers/PrincipalArgumentResolver.java index 3e203525d..7e304042f 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/handlers/PrincipalArgumentResolver.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/handlers/PrincipalArgumentResolver.java @@ -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 claimsAnnotation = Arrays.stream(methodParameter.getParameterAnnotations()).filter(annotation -> annotation.annotationType().equals(ClaimedAuthorities.class)).findAny(); - List 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 claimsAnnotation = Arrays.stream(methodParameter.getParameterAnnotations()).filter(annotation -> annotation.annotationType().equals(ClaimedAuthorities.class)).findAny(); + List 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; + } } \ No newline at end of file diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java index d625b551a..364723317 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java @@ -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; diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/CustomAuthenticationProvider.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/CustomAuthenticationProvider.java index 9b63ed582..5e8c75dd6 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/CustomAuthenticationProvider.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/CustomAuthenticationProvider.java @@ -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(); } } } \ No newline at end of file diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/TokenValidator.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/TokenValidator.java index eeaf3cc40..f03ca04c8 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/TokenValidator.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/TokenValidator.java @@ -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; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/TokenValidatorFactoryImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/TokenValidatorFactoryImpl.java index d145da466..404de9b55 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/TokenValidatorFactoryImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/TokenValidatorFactoryImpl.java @@ -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"); } } - } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/b2access/B2AccessTokenValidator.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/b2access/B2AccessTokenValidator.java index f11b53728..a1057377b 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/b2access/B2AccessTokenValidator.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/b2access/B2AccessTokenValidator.java @@ -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) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/facebook/FacebookTokenValidator.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/facebook/FacebookTokenValidator.java index cc797cec4..92715c5fb 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/facebook/FacebookTokenValidator.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/facebook/FacebookTokenValidator.java @@ -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 )((Map )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) ((Map) 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; + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/google/GoogleTokenValidator.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/google/GoogleTokenValidator.java index 0a137b402..03e5166cb 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/google/GoogleTokenValidator.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/google/GoogleTokenValidator.java @@ -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); + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/linkedin/LinkedInTokenValidator.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/linkedin/LinkedInTokenValidator.java index b31cb532e..f89c82317 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/linkedin/LinkedInTokenValidator.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/linkedin/LinkedInTokenValidator.java @@ -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); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/twitter/TwitterTokenValidator.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/twitter/TwitterTokenValidator.java index 989a5dcc6..edd24cae1 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/twitter/TwitterTokenValidator.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/twitter/TwitterTokenValidator.java @@ -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() { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/AuthenticationService.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/AuthenticationService.java deleted file mode 100644 index 089cf84ca..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/AuthenticationService.java +++ /dev/null @@ -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); -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/AuthenticationServiceImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/AuthenticationServiceImpl.java deleted file mode 100644 index 2ae675891..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/AuthenticationServiceImpl.java +++ /dev/null @@ -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 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 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 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 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); - } -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/AbstractAuthenticationService.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/AbstractAuthenticationService.java new file mode 100644 index 000000000..731ea109c --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/AbstractAuthenticationService.java @@ -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 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 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 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()); + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/AuthenticationService.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/AuthenticationService.java new file mode 100644 index 000000000..a79faaed1 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/AuthenticationService.java @@ -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; +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/NonVerifiedUserEmailAuthenticationService.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/NonVerifiedUserEmailAuthenticationService.java new file mode 100644 index 000000000..62c5f60ae --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/NonVerifiedUserEmailAuthenticationService.java @@ -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 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; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/VerifiedUserAuthenticationService.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/VerifiedUserAuthenticationService.java new file mode 100644 index 000000000..acbb3dc86 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/VerifiedUserAuthenticationService.java @@ -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 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; + } +} diff --git a/dmp-backend/web/src/main/resources/application-devel.properties b/dmp-backend/web/src/main/resources/application-devel.properties index ecefd17ef..586e62f15 100644 --- a/dmp-backend/web/src/main/resources/application-devel.properties +++ b/dmp-backend/web/src/main/resources/application-devel.properties @@ -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=