diff --git a/dmp-backend/pom.xml b/dmp-backend/pom.xml
index d6d887e24..82a0eea7e 100644
--- a/dmp-backend/pom.xml
+++ b/dmp-backend/pom.xml
@@ -179,6 +179,13 @@
2.0.3.RELEASE
+
+
+ org.springframework.social
+ spring-social-linkedin
+ 1.0.0.RELEASE
+
+
diff --git a/dmp-backend/src/main/java/eu/eudat/handlers/PrincipalArgumentResolver.java b/dmp-backend/src/main/java/eu/eudat/handlers/PrincipalArgumentResolver.java
index d9734a2af..28ff46a27 100644
--- a/dmp-backend/src/main/java/eu/eudat/handlers/PrincipalArgumentResolver.java
+++ b/dmp-backend/src/main/java/eu/eudat/handlers/PrincipalArgumentResolver.java
@@ -19,28 +19,29 @@ import java.util.UUID;
public final class PrincipalArgumentResolver implements HandlerMethodArgumentResolver {
private AuthenticationService authenticationService;
+
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.getParameterType().equals(Principal.class);
}
@Override
- public Object resolveArgument(MethodParameter methodParameter,ModelAndViewContainer modelAndViewContainer,NativeWebRequest nativeWebRequest,WebDataBinderFactory webDataBinderFactory) throws Exception {
+ public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
String token = nativeWebRequest.getHeader("AuthToken");
- if(token == null)throw new UnauthorisedException("Authentication Information Is Missing");
+ if (token == null) throw new UnauthorisedException("Authentication Information Is Missing");
UUID authToken;
- try{
+ try {
authToken = UUID.fromString(token);
- }catch (IllegalArgumentException ex){
+ } catch (IllegalArgumentException ex) {
throw new UnauthorisedException("Authentication Information Is Missing");
}
Principal principal = this.authenticationService.Touch(authToken);
- if(principal==null)throw new UnauthorisedException("Authentication Information Missing");
+ if (principal == null) throw new UnauthorisedException("Authentication Information Missing");
return principal;
}
- public PrincipalArgumentResolver(AuthenticationService authenticationService){
+ public PrincipalArgumentResolver(AuthenticationService authenticationService) {
this.authenticationService = authenticationService;
}
diff --git a/dmp-backend/src/main/java/eu/eudat/models/loginprovider/LoginProviderUser.java b/dmp-backend/src/main/java/eu/eudat/models/loginprovider/LoginProviderUser.java
new file mode 100644
index 000000000..74c69e6c6
--- /dev/null
+++ b/dmp-backend/src/main/java/eu/eudat/models/loginprovider/LoginProviderUser.java
@@ -0,0 +1,54 @@
+package eu.eudat.models.loginprovider;
+
+import eu.eudat.security.validators.TokenValidatorFactoryImpl;
+
+/**
+ * Created by ikalyvas on 1/9/2018.
+ */
+public class LoginProviderUser {
+ private String name;
+ private String email;
+ private String secret;
+ private boolean isVerified;
+ private TokenValidatorFactoryImpl.LoginProvider provider;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public boolean getIsVerified() {
+ return isVerified;
+ }
+
+ public void setIsVerified(boolean verified) {
+ isVerified = verified;
+ }
+
+ public TokenValidatorFactoryImpl.LoginProvider getProvider() {
+ return provider;
+ }
+
+ public void setProvider(TokenValidatorFactoryImpl.LoginProvider provider) {
+ this.provider = provider;
+ }
+
+ public String getSecret() {
+ return secret;
+ }
+
+ public void setSecret(String secret) {
+ this.secret = secret;
+ }
+}
diff --git a/dmp-backend/src/main/java/eu/eudat/security/validators/TokenValidatorFactoryImpl.java b/dmp-backend/src/main/java/eu/eudat/security/validators/TokenValidatorFactoryImpl.java
index b86b0d21f..0258da90e 100644
--- a/dmp-backend/src/main/java/eu/eudat/security/validators/TokenValidatorFactoryImpl.java
+++ b/dmp-backend/src/main/java/eu/eudat/security/validators/TokenValidatorFactoryImpl.java
@@ -1,8 +1,8 @@
package eu.eudat.security.validators;
-import eu.eudat.models.project.Project;
-import eu.eudat.security.validators.google.FacebookTokenValidator;
+import eu.eudat.security.validators.facebook.FacebookTokenValidator;
import eu.eudat.security.validators.google.GoogleTokenValidator;
+import eu.eudat.security.validators.linkedin.LinkedInTokenValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -42,11 +42,12 @@ public class TokenValidatorFactoryImpl implements TokenValidatorFactory{
private GoogleTokenValidator googleTokenValidator;
private FacebookTokenValidator facebookTokenValidator;
-
+ private LinkedInTokenValidator linkedInTokenValidator;
@Autowired
- public TokenValidatorFactoryImpl(GoogleTokenValidator googleTokenValidator, FacebookTokenValidator facebookTokenValidator) {
+ public TokenValidatorFactoryImpl(GoogleTokenValidator googleTokenValidator, FacebookTokenValidator facebookTokenValidator,LinkedInTokenValidator linkedInTokenValidator) {
this.googleTokenValidator = googleTokenValidator;
this.facebookTokenValidator = facebookTokenValidator;
+ this.linkedInTokenValidator = linkedInTokenValidator;
}
public TokenValidator getProvider(LoginProvider provider) {
@@ -55,6 +56,8 @@ public class TokenValidatorFactoryImpl implements TokenValidatorFactory{
return this.googleTokenValidator;
case FACEBOOK:
return this.facebookTokenValidator;
+ case LINKEDIN:
+ return this.linkedInTokenValidator;
default:
throw new RuntimeException("Login Provider Not Implemented");
}
diff --git a/dmp-backend/src/main/java/eu/eudat/security/validators/facebook/FacebookTokenValidator.java b/dmp-backend/src/main/java/eu/eudat/security/validators/facebook/FacebookTokenValidator.java
new file mode 100644
index 000000000..d8c9e6960
--- /dev/null
+++ b/dmp-backend/src/main/java/eu/eudat/security/validators/facebook/FacebookTokenValidator.java
@@ -0,0 +1,79 @@
+package eu.eudat.security.validators.facebook;
+
+import eu.eudat.dao.entities.UserInfoDao;
+import eu.eudat.dao.entities.security.CredentialDao;
+import eu.eudat.dao.entities.security.UserTokenDao;
+import eu.eudat.entities.Credential;
+import eu.eudat.entities.UserInfo;
+import eu.eudat.entities.UserToken;
+import eu.eudat.exceptions.NonValidTokenException;
+import eu.eudat.models.criteria.UserInfoCriteria;
+import eu.eudat.models.loginprovider.LoginProviderUser;
+import eu.eudat.models.security.Principal;
+import eu.eudat.security.validators.TokenValidator;
+import eu.eudat.security.validators.TokenValidatorFactoryImpl;
+import eu.eudat.services.ApiContext;
+import eu.eudat.services.AuthenticationService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.social.connect.Connection;
+import org.springframework.social.connect.ConnectionKey;
+import org.springframework.social.facebook.api.Facebook;
+import org.springframework.social.facebook.api.User;
+import org.springframework.social.facebook.connect.FacebookConnectionFactory;
+import org.springframework.social.facebook.connect.FacebookServiceProvider;
+import org.springframework.social.oauth2.AccessGrant;
+import org.springframework.social.oauth2.OAuth2Operations;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.util.*;
+
+/**
+ * Created by ikalyvas on 1/9/2018.
+ */
+@Component("facebookTokenValidator")
+public class FacebookTokenValidator implements TokenValidator {
+
+ private Environment environment;
+ private ApiContext apiContext;
+ private AuthenticationService authenticationService;
+ private FacebookServiceProvider facebookServiceProvider;
+
+ @Autowired
+ public FacebookTokenValidator(Environment environment,ApiContext apiContext,AuthenticationService authenticationService) {
+ this.environment = environment;
+ this.apiContext= apiContext;
+ this.authenticationService = authenticationService;
+ 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(String token) throws NonValidTokenException, IOException, GeneralSecurityException {
+ User profile = getFacebookUser(token);
+ LoginProviderUser user = new LoginProviderUser();
+ user.setEmail(profile.getEmail());
+ user.setIsVerified(profile.isVerified());
+ user.setName(profile.getName());
+ user.setProvider(TokenValidatorFactoryImpl.LoginProvider.FACEBOOK);
+ user.setSecret(token);
+ return this.authenticationService.Touch(user);
+ }
+
+
+ private User getFacebookUser(String accessToken) {
+ String [] fields = { "id", "email", "first_name", "last_name","name","verified" };
+ 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;
+ }
+}
diff --git a/dmp-backend/src/main/java/eu/eudat/security/validators/google/FacebookTokenValidator.java b/dmp-backend/src/main/java/eu/eudat/security/validators/google/FacebookTokenValidator.java
deleted file mode 100644
index 58cf562f2..000000000
--- a/dmp-backend/src/main/java/eu/eudat/security/validators/google/FacebookTokenValidator.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package eu.eudat.security.validators.google;
-
-import eu.eudat.dao.entities.UserInfoDao;
-import eu.eudat.dao.entities.security.CredentialDao;
-import eu.eudat.dao.entities.security.UserTokenDao;
-import eu.eudat.entities.Credential;
-import eu.eudat.entities.UserInfo;
-import eu.eudat.entities.UserToken;
-import eu.eudat.exceptions.NonValidTokenException;
-import eu.eudat.models.criteria.UserInfoCriteria;
-import eu.eudat.models.security.Principal;
-import eu.eudat.security.validators.TokenValidator;
-import eu.eudat.security.validators.TokenValidatorFactoryImpl;
-import eu.eudat.services.ApiContext;
-import eu.eudat.services.AuthenticationService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.env.Environment;
-import org.springframework.social.connect.Connection;
-import org.springframework.social.connect.ConnectionKey;
-import org.springframework.social.facebook.api.Facebook;
-import org.springframework.social.facebook.api.User;
-import org.springframework.social.facebook.connect.FacebookConnectionFactory;
-import org.springframework.social.facebook.connect.FacebookServiceProvider;
-import org.springframework.social.oauth2.AccessGrant;
-import org.springframework.social.oauth2.OAuth2Operations;
-import org.springframework.stereotype.Component;
-
-import java.io.IOException;
-import java.security.GeneralSecurityException;
-import java.util.*;
-
-/**
- * Created by ikalyvas on 1/9/2018.
- */
-@Component("facebookTokenValidator")
-public class FacebookTokenValidator implements TokenValidator {
-
- private Environment environment;
- private ApiContext apiContext;
- private FacebookServiceProvider facebookServiceProvider;
-
- @Autowired
- public FacebookTokenValidator(Environment environment,ApiContext apiContext) {
- this.environment = environment;
- this.apiContext= apiContext;
- 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(String token) throws NonValidTokenException, IOException, GeneralSecurityException {
- User profile = getFacebookUserId(token);
-
- UserInfoCriteria criteria = new UserInfoCriteria();
- criteria.setEmail(profile.getEmail());
- List users = apiContext.getDatabaseRepository().getUserInfoDao().getWithCriteria(criteria).toList();
- UserInfo userInfo = null;
- if(users.size()>0)userInfo = users.get(0);
- final Credential credential = new Credential();
- credential.setId(UUID.randomUUID());
- credential.setCreationTime(new Date());
- credential.setStatus(1);
- credential.setLastUpdateTime(new Date());
- credential.setProvider((int)TokenValidatorFactoryImpl.LoginProvider.FACEBOOK.getValue());
- credential.setSecret(token);
- if(userInfo == null) {
- userInfo = new UserInfo();
- userInfo.setName((String)profile.getName());
- userInfo.setVerified_email(profile.isVerified());
- userInfo.setEmail(profile.getEmail());
- userInfo.setCreated(new Date());
- userInfo.setLastloggedin(new Date());
- userInfo.setAuthorization_level(new Short("1"));
- userInfo.setUsertype(new Short("1"));
- userInfo = apiContext.getDatabaseRepository().getUserInfoDao().createOrUpdate(userInfo);
-
- credential.setPublicValue(userInfo.getName());
-
- credential.setUserInfo(userInfo);
- apiContext.getDatabaseRepository().getCredentialDao().createOrUpdate(credential);
- }
- else {
- userInfo.setLastloggedin(new Date());
- 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.getDatabaseRepository().getCredentialDao().createOrUpdate(credential);
- userInfo.getCredentials().add(credential);
- }
- userInfo = apiContext.getDatabaseRepository().getUserInfoDao().createOrUpdate(userInfo);
-
- }
-
- UserToken userToken = new UserToken();
- userToken.setUser(userInfo);
- userToken.setIssuedAt(new Date());
- userToken.setToken(UUID.randomUUID());
- userToken.setExpiresAt(addADay(new Date()));
- apiContext.getDatabaseRepository().getUserTokenDao().create(userToken);
- return apiContext.getAuthenticationService().Touch(userToken.getToken());
- }
-
-
- private User getFacebookUserId(String accessToken) {
- String [] fields = { "id", "email", "first_name", "last_name","name" };
- 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;
- }
-}
diff --git a/dmp-backend/src/main/java/eu/eudat/security/validators/google/GoogleTokenValidator.java b/dmp-backend/src/main/java/eu/eudat/security/validators/google/GoogleTokenValidator.java
index 593b7e99e..e81a58eae 100644
--- a/dmp-backend/src/main/java/eu/eudat/security/validators/google/GoogleTokenValidator.java
+++ b/dmp-backend/src/main/java/eu/eudat/security/validators/google/GoogleTokenValidator.java
@@ -15,8 +15,10 @@ import eu.eudat.entities.Credential;
import eu.eudat.entities.UserToken;
import eu.eudat.models.criteria.UserInfoCriteria;
import eu.eudat.models.login.LoginInfo;
+import eu.eudat.models.loginprovider.LoginProviderUser;
import eu.eudat.security.validators.TokenValidator;
import eu.eudat.security.validators.TokenValidatorFactoryImpl;
+import eu.eudat.services.ApiContext;
import eu.eudat.services.AuthenticationService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -28,6 +30,7 @@ import com.google.api.client.json.jackson2.JacksonFactory;
import eu.eudat.dao.entities.UserInfoDao;
import eu.eudat.entities.UserInfo;
import eu.eudat.exceptions.NonValidTokenException;
+import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
@@ -37,23 +40,23 @@ import static com.sun.org.apache.xalan.internal.xsltc.compiler.Constants.REDIREC
public class GoogleTokenValidator implements TokenValidator {
private static final HttpTransport transport = new NetHttpTransport();
- @Autowired private UserInfoDao userInfoDao;
- @Autowired private CredentialDao credentialDao;
- @Autowired private AuthenticationService authenticationService;
- @Autowired private UserTokenDao userTokenDao;
+ private ApiContext apiContext;
+ private AuthenticationService authenticationService;
private GoogleIdTokenVerifier verifier;
- public GoogleTokenValidator(){
+ private Environment environment;
+
+ @Autowired
+ public GoogleTokenValidator(ApiContext apiContext, Environment environment,AuthenticationService authenticationService){
+ this.apiContext = apiContext;
+ this.environment = environment;
+ this.authenticationService = authenticationService;
verifier = new GoogleIdTokenVerifier.Builder(transport, JacksonFactory.getDefaultInstance())
- .setAudience(Collections.singletonList("524432312250-sc9qsmtmbvlv05r44onl6l93ia3k9deo.apps.googleusercontent.com"))
- // Or, if multiple clients access the backend:
- //.setAudience(Arrays.asList(CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3))
+ .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;
}
@@ -62,73 +65,13 @@ public class GoogleTokenValidator implements TokenValidator {
GoogleIdToken idToken = this.verifyUserAndGetUser(token);
Payload payload = idToken.getPayload();
-
- UserInfoCriteria criteria = new UserInfoCriteria();
- criteria.setEmail(payload.getEmail());
- List users = userInfoDao.getWithCriteria(criteria).toList();
- UserInfo userInfo = null;
- if(users.size()>0)userInfo = users.get(0);
- final Credential credential = new Credential();
- credential.setId(UUID.randomUUID());
- credential.setCreationTime(new Date());
- credential.setStatus(1);
- credential.setLastUpdateTime(new Date());
- credential.setProvider((int)TokenValidatorFactoryImpl.LoginProvider.GOOGLE.getValue());
- credential.setSecret(token);
- if(userInfo == null) {
- userInfo = new UserInfo();
- userInfo.setName((String)payload.get("name"));
- userInfo.setVerified_email(payload.getEmailVerified());
- userInfo.setEmail(payload.getEmail());
- userInfo.setCreated(new Date());
- userInfo.setLastloggedin(new Date());
- userInfo.setAuthorization_level(new Short("1"));
- userInfo.setUsertype(new Short("1"));
- userInfo = userInfoDao.createOrUpdate(userInfo);
-
- credential.setPublicValue(userInfo.getName());
-
- credential.setUserInfo(userInfo);
- credentialDao.createOrUpdate(credential);
- }
- else {
- userInfo.setLastloggedin(new Date());
- 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());
-
- credentialDao.createOrUpdate(credential);
- userInfo.getCredentials().add(credential);
- }
- userInfo = userInfoDao.createOrUpdate(userInfo);
-
- }
-
- UserToken userToken = new UserToken();
- userToken.setUser(userInfo);
- userToken.setIssuedAt(new Date());
- userToken.setToken(UUID.randomUUID());
- userToken.setExpiresAt(addADay(new Date()));
- userTokenDao.create(userToken);
- return authenticationService.Touch(userToken.getToken());
-
+ LoginProviderUser user = new LoginProviderUser();
+ user.setSecret(token);
+ user.setProvider(TokenValidatorFactoryImpl.LoginProvider.GOOGLE);
+ user.setName((String)payload.get("name"));
+ user.setEmail(payload.getEmail());
+ user.setIsVerified(payload.getEmailVerified());
+ return this.authenticationService.Touch(user);
}
-
- 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/src/main/java/eu/eudat/security/validators/linkedin/LinkedInTokenValidator.java b/dmp-backend/src/main/java/eu/eudat/security/validators/linkedin/LinkedInTokenValidator.java
new file mode 100644
index 000000000..2bbb829dd
--- /dev/null
+++ b/dmp-backend/src/main/java/eu/eudat/security/validators/linkedin/LinkedInTokenValidator.java
@@ -0,0 +1,53 @@
+package eu.eudat.security.validators.linkedin;
+
+import eu.eudat.exceptions.NonValidTokenException;
+import eu.eudat.models.loginprovider.LoginProviderUser;
+import eu.eudat.models.security.Principal;
+import eu.eudat.security.validators.TokenValidator;
+import eu.eudat.security.validators.TokenValidatorFactoryImpl;
+import eu.eudat.services.ApiContext;
+import eu.eudat.services.AuthenticationService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.social.facebook.connect.FacebookServiceProvider;
+import org.springframework.social.linkedin.api.LinkedIn;
+import org.springframework.social.linkedin.api.LinkedInProfile;
+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;
+
+/**
+ * Created by ikalyvas on 1/10/2018.
+ */
+@Component("linkedInTokenValidator")
+public class LinkedInTokenValidator implements TokenValidator {
+
+ private Environment environment;
+ private ApiContext apiContext;
+ private AuthenticationService authenticationService;
+ private LinkedInServiceProvider linkedInServiceProvider;
+
+ @Autowired
+ public LinkedInTokenValidator(Environment environment,ApiContext apiContext,AuthenticationService authenticationService) {
+ this.environment = environment;
+ this.apiContext= apiContext;
+ this.authenticationService = authenticationService;
+ this.linkedInServiceProvider = new LinkedInServiceProvider(this.environment.getProperty("linkedin.login.clientId"), this.environment.getProperty("linkedin.login.clientSecret"));
+ }
+ @Override
+ public Principal validateToken(String token) throws NonValidTokenException, IOException, GeneralSecurityException {
+ AccessGrant accessGrant =this.linkedInServiceProvider.getOAuthOperations().exchangeForAccess(token,"http://localhost:4200/login/linkedin",null);
+ LinkedIn linkedInService = this.linkedInServiceProvider.getApi(accessGrant.getAccessToken());
+ LinkedInProfile linkedInProfile = linkedInService.profileOperations().getUserProfile();
+ LoginProviderUser user = new LoginProviderUser();
+ user.setEmail(linkedInProfile.getEmailAddress());
+ user.setIsVerified(true); //TODO
+ user.setName(linkedInProfile.getFirstName()+" "+linkedInProfile.getLastName());
+ user.setProvider(TokenValidatorFactoryImpl.LoginProvider.LINKEDIN);
+ user.setSecret(accessGrant.getAccessToken());
+ return this.authenticationService.Touch(user);
+ }
+}
diff --git a/dmp-backend/src/main/java/eu/eudat/services/ApiContext.java b/dmp-backend/src/main/java/eu/eudat/services/ApiContext.java
index 341ab43c7..5f7cc8c78 100644
--- a/dmp-backend/src/main/java/eu/eudat/services/ApiContext.java
+++ b/dmp-backend/src/main/java/eu/eudat/services/ApiContext.java
@@ -12,5 +12,4 @@ public interface ApiContext {
InvitationService getInvitationService();
RemoteFetcher getRemoteFetcher();
MailService getMailService();
- AuthenticationService getAuthenticationService();
}
diff --git a/dmp-backend/src/main/java/eu/eudat/services/ApiContextImpl.java b/dmp-backend/src/main/java/eu/eudat/services/ApiContextImpl.java
index 7dfe45117..ff0554386 100644
--- a/dmp-backend/src/main/java/eu/eudat/services/ApiContextImpl.java
+++ b/dmp-backend/src/main/java/eu/eudat/services/ApiContextImpl.java
@@ -16,7 +16,6 @@ public class ApiContextImpl implements ApiContext{
private RemoteFetcher remoteFetcher;
private InvitationService invitationService;
private MailService mailService;
- private AuthenticationService authenticationService;
@Autowired
public void setDatabaseRepository(DatabaseRepository databaseRepository) {
@@ -68,13 +67,4 @@ public class ApiContextImpl implements ApiContext{
this.mailService = mailService;
}
- @Override
- public AuthenticationService getAuthenticationService() {
- return authenticationService;
- }
-
- @Autowired
- public void setAuthenticationService(AuthenticationService authenticationService) {
- this.authenticationService = authenticationService;
- }
}
diff --git a/dmp-backend/src/main/java/eu/eudat/services/AuthenticationService.java b/dmp-backend/src/main/java/eu/eudat/services/AuthenticationService.java
index 83570e5fd..fd96f6af6 100644
--- a/dmp-backend/src/main/java/eu/eudat/services/AuthenticationService.java
+++ b/dmp-backend/src/main/java/eu/eudat/services/AuthenticationService.java
@@ -2,30 +2,34 @@ package eu.eudat.services;
import eu.eudat.dao.entities.UserInfoDao;
import eu.eudat.dao.entities.security.UserTokenDao;
+import eu.eudat.entities.Credential;
import eu.eudat.entities.UserInfo;
import eu.eudat.entities.UserToken;
+import eu.eudat.models.criteria.UserInfoCriteria;
+import eu.eudat.models.loginprovider.LoginProviderUser;
import eu.eudat.models.security.Principal;
+import eu.eudat.security.validators.TokenValidatorFactoryImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.xml.ws.ServiceMode;
-import java.util.Date;
-import java.util.List;
-import java.util.UUID;
+import java.util.*;
/**
* Created by ikalyvas on 12/15/2017.
*/
@Service("authenticationService ")
public class AuthenticationService {
+ private ApiContext apiContext;
+
@Autowired
- UserTokenDao userTokenDao;
- @Autowired
- UserInfoDao userInfoDao;
+ public AuthenticationService(ApiContext apiContext) {
+ this.apiContext = apiContext;
+ }
public Principal Touch(UUID token)
{
- UserToken tokenEntry = userTokenDao.read(token);
+ UserToken tokenEntry = this.apiContext.getDatabaseRepository().getUserTokenDao().read(token);
if (tokenEntry == null || tokenEntry.getExpiresAt().before(new Date())) return null;
Principal principal = this.Touch(tokenEntry);
@@ -35,15 +39,15 @@ public class AuthenticationService {
public void Logout(UUID token)
{
- UserToken tokenEntry = userTokenDao.read(token);
- userTokenDao.delete(tokenEntry);
+ UserToken tokenEntry = this.apiContext.getDatabaseRepository().getUserTokenDao().read(token);
+ this.apiContext.getDatabaseRepository().getUserTokenDao().delete(tokenEntry);
}
private Principal Touch(UserToken token)
{
if (token == null || token.getExpiresAt().before(new Date())) return null;
- UserInfo user = this.userInfoDao.find(token.getUser().getId());
+ UserInfo user = this.apiContext.getDatabaseRepository().getUserInfoDao().find(token.getUser().getId());
if (user == null /*|| user.Status != ActivityStatus.Active*/) return null;
//List appRoles = this._unitOfWork.UserRoles.GetAll().Where(x => x.UserId == token.UserId /*&& x.Status == ActivityStatus.Active*/).ToList();
@@ -64,4 +68,66 @@ public class AuthenticationService {
*/
return principal;
}
+
+ public Principal Touch(LoginProviderUser profile){
+ UserInfoCriteria criteria = new UserInfoCriteria();
+ criteria.setEmail(profile.getEmail());
+ List users = apiContext.getDatabaseRepository().getUserInfoDao().getWithCriteria(criteria).toList();
+ UserInfo userInfo = null;
+ if(users.size()>0)userInfo = users.get(0);
+ final Credential credential = new Credential();
+ credential.setId(UUID.randomUUID());
+ credential.setCreationTime(new Date());
+ credential.setStatus(1);
+ credential.setLastUpdateTime(new Date());
+ credential.setProvider((int) TokenValidatorFactoryImpl.LoginProvider.FACEBOOK.getValue());
+ credential.setSecret(profile.getSecret());
+ if(userInfo == null) {
+ userInfo = new UserInfo();
+ userInfo.setName((String)profile.getName());
+ userInfo.setVerified_email(profile.getIsVerified());
+ userInfo.setEmail(profile.getEmail());
+ userInfo.setCreated(new Date());
+ userInfo.setLastloggedin(new Date());
+ userInfo.setAuthorization_level(new Short("1"));
+ userInfo.setUsertype(new Short("1"));
+ userInfo = apiContext.getDatabaseRepository().getUserInfoDao().createOrUpdate(userInfo);
+ credential.setPublicValue(userInfo.getName());
+ credential.setUserInfo(userInfo);
+ apiContext.getDatabaseRepository().getCredentialDao().createOrUpdate(credential);
+ }
+ else {
+ userInfo.setLastloggedin(new Date());
+ 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.getDatabaseRepository().getCredentialDao().createOrUpdate(credential);
+ userInfo.getCredentials().add(credential);
+ }
+ userInfo = apiContext.getDatabaseRepository().getUserInfoDao().createOrUpdate(userInfo);
+ }
+
+ UserToken userToken = new UserToken();
+ userToken.setUser(userInfo);
+ userToken.setIssuedAt(new Date());
+ userToken.setToken(UUID.randomUUID());
+ userToken.setExpiresAt(addADay(new Date()));
+ apiContext.getDatabaseRepository().getUserTokenDao().create(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;
+ }
}
diff --git a/dmp-backend/src/main/resources/application.properties b/dmp-backend/src/main/resources/application.properties
index 130b4497e..b3f2a4757 100644
--- a/dmp-backend/src/main/resources/application.properties
+++ b/dmp-backend/src/main/resources/application.properties
@@ -33,6 +33,11 @@ mail.from = citesagrdev@gmail.com
facebook.login.clientId = 110586756143149
facebook.login.clientSecret = 522a847f05c873d0222c85109e24f55a
facebook.login.namespace = eudat
+########################GOOGLE LOGIN Properties#############################
+google.login.clientId = 524432312250-sc9qsmtmbvlv05r44onl6l93ia3k9deo.apps.googleusercontent.com
+########################LINKEDIN LOGIN Properties#############################
+linkedin.login.clientId = 86bl8vfk77clh9
+linkedin.login.clientSecret = 2OCO9e3wKylW05Tt
########################Persistence/Hibernate/Batch##############################
#persistence.hibernate.jdbc.batch_size = 30
#persistence.hibernate.order_inserts = true
diff --git a/dmp-frontend/src/app/app-routing.module.ts b/dmp-frontend/src/app/app-routing.module.ts
index 977a7ff96..490152415 100644
--- a/dmp-frontend/src/app/app-routing.module.ts
+++ b/dmp-frontend/src/app/app-routing.module.ts
@@ -14,8 +14,8 @@ import { ProjectEditorComponent } from './projects/editor/project-editor.compone
import { DataManagementPlanEditorComponent } from './dmps/editor/dmp-editor.component';
import { DatasetEditorComponent } from './datasets/editor/dataset-editor.component';
import { DatasetListingComponent } from './datasets/dataset-listing.component';
-import { LoginComponent } from './login/login.component';
import { DatasetWizardComponent } from './dataset-wizard/dataset-wizard.component';
+import { LoginComponent } from './user-management/login/login.component';
const appRoutes: Routes = [
@@ -31,7 +31,7 @@ const appRoutes: Routes = [
{ path: 'dataset/:id', component: DatasetWizardComponent, canActivate: [AuthGuard] },
{ path: 'datasets/new', component: DatasetWizardComponent, canActivate: [AuthGuard] },
{ path: 'invitation/:id', component: InvitationAcceptedComponent},
- { path: 'login', component: LoginComponent },
+ { path: 'login', loadChildren: './user-management/login.module#LoginModule' },
{ path: "unauthorized", loadChildren: './unauthorized/unauthorized.module#UnauthorizedModule' },
{ path: 'welcome', component: HomepageComponent, canActivate: [AuthGuard] },
{ path: '', redirectTo: '/welcome', pathMatch: 'full' },
diff --git a/dmp-frontend/src/app/app.constants.ts b/dmp-frontend/src/app/app.constants.ts
index 2cf927bf2..d599ff1c5 100644
--- a/dmp-frontend/src/app/app.constants.ts
+++ b/dmp-frontend/src/app/app.constants.ts
@@ -1,5 +1,6 @@
export const HostConfiguration = {
Server: 'http://192.168.32.96:8080/',
+ App: 'http://localhost:4200/'
//CASHost: 'https://login-devel.uoa.gr/login',
//Service: 'http://elkefinman/login'
}
\ No newline at end of file
diff --git a/dmp-frontend/src/app/app.module.ts b/dmp-frontend/src/app/app.module.ts
index 928946f83..40b1cc6c0 100644
--- a/dmp-frontend/src/app/app.module.ts
+++ b/dmp-frontend/src/app/app.module.ts
@@ -1,3 +1,6 @@
+import { HostConfiguration } from './app.constants';
+import { LoginOptions } from './user-management/utilties/LoginOptions';
+import { LoginModule } from './user-management/login.module';
import { InvitationAcceptedComponent } from './invitation-accepted/invitation-accepted.component';
import { InvitationComponent } from './invitation/invitation.component';
import { UnauthorizedComponent } from './unauthorized/unauthorized.component';
@@ -47,7 +50,6 @@ import { BaseHttpService } from './utilities/cite-http-service-module/base-http.
import { DataManagementPlanListingComponent } from './dmps/dmp-listing.component';
import { ProjectEditorComponent } from './projects/editor/project-editor.component';
import { DataManagementPlanEditorComponent } from './dmps/editor/dmp-editor.component';
-import { LoginComponent } from './login/login.component';
import { FigurecardComponent } from './shared/components/figurecard/figurecard.component';
import { DatasetListingComponent } from './datasets/dataset-listing.component';
import { DatasetEditorComponent } from './datasets/editor/dataset-editor.component';
@@ -69,7 +71,6 @@ import { AutocompleteComponent } from './shared/components/autocomplete/autocomp
TableOfContentsFieldSetComponent,
TableOfContentsGroupComponent,
TableOfContentsSectionComponent,
- LoginComponent,
PageNotFoundComponent,
HomepageComponent,
ProjectListingComponent,
@@ -95,6 +96,23 @@ import { AutocompleteComponent } from './shared/components/autocomplete/autocomp
ReactiveFormsModule,
SharedModule,
FormsModule,
+ LoginModule.forRoot({
+ loginProviders: [
+ LoginOptions.facebookOauth,
+ LoginOptions.googleOauth,
+ LoginOptions.nativeLogin,
+ LoginOptions.linkedInOauth
+ ],
+ facebookConfiguration: { clientId: "110586756143149" },
+ googleConfiguration: { clientId: '524432312250-sc9qsmtmbvlv05r44onl6l93ia3k9deo.apps.googleusercontent.com' },
+ linkedInConfiguration: {
+ clientId: "86bl8vfk77clh9",
+ oauthUrl: "https://www.linkedin.com/oauth/v2/authorization",
+ redirectUri: HostConfiguration.App + "login/linkedin",
+ accessTokenUri: "https://www.linkedin.com/oauth/v2/accessToken",
+ clientSecret: "2OCO9e3wKylW05Tt"
+ }
+ }),
HttpModule,
HttpClientModule,
CommonModule,
diff --git a/dmp-frontend/src/app/login/login.component.html b/dmp-frontend/src/app/login/login.component.html
deleted file mode 100644
index 08ccaa75b..000000000
--- a/dmp-frontend/src/app/login/login.component.html
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-
-
-
-
-
Or Be Classical
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/dmp-frontend/src/app/login/login.component.ts b/dmp-frontend/src/app/login/login.component.ts
deleted file mode 100644
index c0bdc7046..000000000
--- a/dmp-frontend/src/app/login/login.component.ts
+++ /dev/null
@@ -1,101 +0,0 @@
-import { LoginProviders } from '../models/login/LoginInfo';
-import { HttpClient } from '@angular/common/http';
-import { Component, OnInit, ElementRef, AfterViewInit, VERSION, Injectable, NgZone } from '@angular/core';
-import { Router, ActivatedRoute, Params } from "@angular/router";
-import { MatPaginator, MatSort, MatSnackBar } from "@angular/material";
-import { TranslateService } from "@ngx-translate/core";
-import { AuthService } from '../services/auth/auth.service';
-import { SnackBarNotificationComponent } from '../shared/components/notificaiton/snack-bar-notification.component';
-
-declare const gapi: any;
-declare const FB: any;
-
-@Component({
- selector: 'login',
- templateUrl: './login.component.html',
- styleUrls: ['./login.component.scss']
-})
-export class LoginComponent implements OnInit {
-
- public auth2: any;
-
- constructor(private router: Router,
- public authService: AuthService,
- public route: ActivatedRoute,
- public snackBar: MatSnackBar,
- public language: TranslateService,
- private zone: NgZone
- ) { }
-
-
-
- ngOnInit() {
- gapi.load('auth2', () => {
- this.auth2 = gapi.auth2.init({
- client_id: '524432312250-sc9qsmtmbvlv05r44onl6l93ia3k9deo.apps.googleusercontent.com',
- cookiepolicy: 'single_host_origin',
- scope: 'profile email'
- });
- this.attachGoogleSignin(document.getElementById('googleSignInButton'));
- });
-
- FB.init({
- appId: '110586756143149',
- cookie: false, // enable cookies to allow the server to access
- // the session
- xfbml: true, // parse social plugins on this page
- version: 'v2.8' // use graph api version 2.5
- });
- }
-
- public attachGoogleSignin(element) {
- this.auth2.attachClickHandler(element, {},
- (googleUser) => {
-
- var id_token = googleUser.getAuthResponse().id_token;
- if (id_token) {
- this.authService.login({ ticket: id_token, provider: LoginProviders.Google }).subscribe(
- res => this.onLogInSuccess(res),
- error => this.onLogInError(error)
- )
- }
-
- }, (error) => {
- alert(JSON.stringify(error, undefined, 2));
- });
- }
-
- public onLogInSuccess(logoutMessage: any) {
- this.snackBar.openFromComponent(SnackBarNotificationComponent, {
- data: { message: 'GENERAL.SNACK-BAR.SUCCESSFUL-LOGIN', language: this.language },
- duration: 3000,
- extraClasses: ['snackbar-success']
- });
- this.route.queryParams.subscribe((params: Params) => {
- let redirectUrl = params['returnUrl'] ? params['returnUrl'] : '/';
- this.zone.run(() => this.router.navigate([redirectUrl]));
- })
- }
-
- public onLogInError(errorMessage: string) {
- console.log(errorMessage);
- this.snackBar.openFromComponent(SnackBarNotificationComponent, {
- data: { message: 'GENERAL.SNACK-BAR.UNSUCCESSFUL-LOGIN', language: this.language },
- duration: 3000,
- extraClasses: ['snackbar-warning']
- })
- }
-
- public facebookLogin() {
-
- FB.login((response: any) => {
- if (response.status === 'connected' || 'not_authorized') {
- this.authService.login({ ticket: response.authResponse.accessToken, provider: LoginProviders.Facebook }).subscribe(
- res => this.onLogInSuccess(res),
- error => this.onLogInError(error)
- )
- }
-
- }, { scope: 'user_friends,email' });
- }
-}
\ No newline at end of file
diff --git a/dmp-frontend/src/app/models/login/LoginInfo.ts b/dmp-frontend/src/app/models/login/LoginInfo.ts
index b84cc403b..26d96ba25 100644
--- a/dmp-frontend/src/app/models/login/LoginInfo.ts
+++ b/dmp-frontend/src/app/models/login/LoginInfo.ts
@@ -1,7 +1,9 @@
-export enum LoginProviders{
+export enum LoginProviders {
Google = 1,
- Facebook = 2
- }
+ Facebook = 2,
+ Twitter = 3,
+ LinkedIn = 4
+}
export class LoginInfo {
public ticket: string;
diff --git a/dmp-frontend/src/app/shared/shared.module.ts b/dmp-frontend/src/app/shared/shared.module.ts
index 11a5961d9..9c0afda68 100644
--- a/dmp-frontend/src/app/shared/shared.module.ts
+++ b/dmp-frontend/src/app/shared/shared.module.ts
@@ -28,6 +28,7 @@ import { DataManagementPlanCriteriaComponent } from './components/criteria/data-
],
exports: [
+ MaterialModule,
NavigationComponent,
SnackBarNotificationComponent,
ProjectCriteriaComponent,
diff --git a/dmp-frontend/src/app/user-management/login.module.ts b/dmp-frontend/src/app/user-management/login.module.ts
new file mode 100644
index 000000000..250127327
--- /dev/null
+++ b/dmp-frontend/src/app/user-management/login.module.ts
@@ -0,0 +1,37 @@
+import { SnackBarNotificationComponent } from '../shared/components/notificaiton/snack-bar-notification.component';
+import { LinkedInLoginComponent } from './login/linkedin-login/linkedin-login.component';
+import { LoginRoutes } from './login.routes';
+import { MaterialModule } from '../shared/material/material.module';
+import { SharedModule } from '../shared/shared.module';
+import { LoginServiceConfiguration } from './utilties/LoginServiceConfiguration';
+import { LoginService } from './utilties/login-service';
+import { LoginComponent } from './login/login.component';
+import { ModuleWithProviders, NgModule } from "@angular/core";
+import { CommonModule } from '@angular/common';
+
+@NgModule({
+ imports: [
+ SharedModule,
+ CommonModule,
+ LoginRoutes
+ ],
+ declarations: [
+ LoginComponent,
+ LinkedInLoginComponent
+ ],
+ exports: [
+ LoginComponent,
+ LinkedInLoginComponent
+ ],
+ providers: [LoginService]
+})
+export class LoginModule {
+ static forRoot(config: LoginServiceConfiguration): ModuleWithProviders {
+ return {
+ ngModule: LoginModule,
+ providers: [
+ { provide: LoginServiceConfiguration, useValue: config }
+ ],
+ };
+ }
+}
\ No newline at end of file
diff --git a/dmp-frontend/src/app/user-management/login.routes.ts b/dmp-frontend/src/app/user-management/login.routes.ts
new file mode 100644
index 000000000..756ce2429
--- /dev/null
+++ b/dmp-frontend/src/app/user-management/login.routes.ts
@@ -0,0 +1,11 @@
+import { LinkedInLoginComponent } from './login/linkedin-login/linkedin-login.component';
+import { LoginComponent } from './login/login.component';
+import { RouterModule, Routes } from '@angular/router';
+
+const routes: Routes = [
+ { path: '', component: LoginComponent },
+ { path: 'linkedin', component: LinkedInLoginComponent }
+
+];
+
+export const LoginRoutes = RouterModule.forChild(routes);
diff --git a/dmp-frontend/src/app/user-management/login/linkedin-login/linkedin-login.component.html b/dmp-frontend/src/app/user-management/login/linkedin-login/linkedin-login.component.html
new file mode 100644
index 000000000..e69de29bb
diff --git a/dmp-frontend/src/app/user-management/login/linkedin-login/linkedin-login.component.ts b/dmp-frontend/src/app/user-management/login/linkedin-login/linkedin-login.component.ts
new file mode 100644
index 000000000..af9ebe386
--- /dev/null
+++ b/dmp-frontend/src/app/user-management/login/linkedin-login/linkedin-login.component.ts
@@ -0,0 +1,26 @@
+import { LoginService } from '../../utilties/login-service';
+import { Component, OnInit } from '@angular/core'
+import { Router, ActivatedRoute, Params } from '@angular/router';
+
+@Component({
+ selector: 'linkedin-login',
+ templateUrl: './linkedin-login.component.html',
+})
+export class LinkedInLoginComponent implements OnInit {
+
+ constructor(
+ private router: Router,
+ private route: ActivatedRoute,
+ private loginService: LoginService
+ ) {
+
+ }
+
+ ngOnInit(): void {
+ this.route.queryParams.subscribe((data: any) => {
+ if (!data["code"]) this.loginService.linkedinAuthorize()
+ else this.loginService.linkedInloginUser(data["code"])
+ })
+ }
+
+}
\ No newline at end of file
diff --git a/dmp-frontend/src/app/user-management/login/login.component.html b/dmp-frontend/src/app/user-management/login/login.component.html
new file mode 100644
index 000000000..92a68f384
--- /dev/null
+++ b/dmp-frontend/src/app/user-management/login/login.component.html
@@ -0,0 +1,47 @@
+
\ No newline at end of file
diff --git a/dmp-frontend/src/app/login/login.component.scss b/dmp-frontend/src/app/user-management/login/login.component.scss
similarity index 100%
rename from dmp-frontend/src/app/login/login.component.scss
rename to dmp-frontend/src/app/user-management/login/login.component.scss
diff --git a/dmp-frontend/src/app/user-management/login/login.component.ts b/dmp-frontend/src/app/user-management/login/login.component.ts
new file mode 100644
index 000000000..60c969e52
--- /dev/null
+++ b/dmp-frontend/src/app/user-management/login/login.component.ts
@@ -0,0 +1,59 @@
+import { LoginOptions } from '../utilties/LoginOptions';
+import { LoginService } from '../utilties/login-service';
+import { HttpClient } from '@angular/common/http';
+import { Component, OnInit, ElementRef, AfterViewInit, VERSION, Injectable, NgZone } from '@angular/core';
+import { Router, ActivatedRoute, Params } from "@angular/router";
+import { MatPaginator, MatSort, MatSnackBar } from "@angular/material";
+import { TranslateService } from "@ngx-translate/core";
+
+
+
+@Component({
+ selector: 'login',
+ templateUrl: './login.component.html',
+ styleUrls: ['./login.component.scss']
+})
+export class LoginComponent implements OnInit {
+
+ public auth2: any;
+
+ constructor(
+ private loginService: LoginService
+ ) {
+ }
+
+
+
+ ngOnInit() {
+ this.loginService.initProviders();
+ }
+
+ public facebookLogin() {
+ this.loginService.facebookLogin();
+ }
+
+ public linkedInLogin() {
+ this.loginService.linkedInInitialiseLogin();
+ }
+
+ public hasFacebookOauth(): boolean {
+ return this.loginService.hasProvider(LoginOptions.facebookOauth);
+ }
+
+ public hasLinkedInOauth(): boolean {
+ return this.loginService.hasProvider(LoginOptions.linkedInOauth);
+ }
+
+ public hasTwitterOauth(): boolean {
+ return this.loginService.hasProvider(LoginOptions.twitterOauth);
+ }
+
+ public hasGoogleOauth(): boolean {
+ return this.loginService.hasProvider(LoginOptions.googleOauth);
+ }
+
+ public hasNativeLogin(): boolean {
+ return this.loginService.hasProvider(LoginOptions.nativeLogin);
+ }
+
+}
\ No newline at end of file
diff --git a/dmp-frontend/src/app/user-management/login/twitter-login/twitter-login.component.html b/dmp-frontend/src/app/user-management/login/twitter-login/twitter-login.component.html
new file mode 100644
index 000000000..e69de29bb
diff --git a/dmp-frontend/src/app/user-management/login/twitter-login/twitter-login.component.ts b/dmp-frontend/src/app/user-management/login/twitter-login/twitter-login.component.ts
new file mode 100644
index 000000000..49dd238f2
--- /dev/null
+++ b/dmp-frontend/src/app/user-management/login/twitter-login/twitter-login.component.ts
@@ -0,0 +1,9 @@
+import { Component } from '@angular/core'
+@Component({
+ selector: 'twitter-login',
+ templateUrl: './twitter-login.component.html',
+ styleUrls: ['./login.component.scss']
+})
+export class TwitterLoginComponent {
+
+}
\ No newline at end of file
diff --git a/dmp-frontend/src/app/user-management/utilties/LoginOptions.ts b/dmp-frontend/src/app/user-management/utilties/LoginOptions.ts
new file mode 100644
index 000000000..51187d8ba
--- /dev/null
+++ b/dmp-frontend/src/app/user-management/utilties/LoginOptions.ts
@@ -0,0 +1,8 @@
+export enum LoginOptions{
+ linkedInOauth = 1,
+ facebookOauth = 2,
+ twitterOauth = 3,
+ googleOauth = 4,
+ nativeLogin = 5,
+ all = 6
+}
\ No newline at end of file
diff --git a/dmp-frontend/src/app/user-management/utilties/LoginProviderConfiguration.ts b/dmp-frontend/src/app/user-management/utilties/LoginProviderConfiguration.ts
new file mode 100644
index 000000000..b57517bd7
--- /dev/null
+++ b/dmp-frontend/src/app/user-management/utilties/LoginProviderConfiguration.ts
@@ -0,0 +1,19 @@
+export abstract class LoginProviderConfiguration {
+ public clientId: string
+}
+
+export class FacebookLoginConfiguration extends LoginProviderConfiguration {
+}
+
+export class GoogleLoginConfiguration extends LoginProviderConfiguration {
+}
+
+export class TwitterLoginConfiguration extends LoginProviderConfiguration {
+}
+
+export class LinkedInConfiguration extends LoginProviderConfiguration {
+ public oauthUrl: string
+ public redirectUri: string
+ public accessTokenUri: string
+ public clientSecret: string
+}
\ No newline at end of file
diff --git a/dmp-frontend/src/app/user-management/utilties/LoginServiceConfiguration.ts b/dmp-frontend/src/app/user-management/utilties/LoginServiceConfiguration.ts
new file mode 100644
index 000000000..bb251a8b3
--- /dev/null
+++ b/dmp-frontend/src/app/user-management/utilties/LoginServiceConfiguration.ts
@@ -0,0 +1,14 @@
+import {
+ FacebookLoginConfiguration,
+ GoogleLoginConfiguration,
+ LinkedInConfiguration,
+ TwitterLoginConfiguration,
+} from './LoginProviderConfiguration';
+import { LoginOptions } from './LoginOptions';
+export class LoginServiceConfiguration {
+ public loginProviders: LoginOptions[];
+ public facebookConfiguration?: FacebookLoginConfiguration;
+ public googleConfiguration?: GoogleLoginConfiguration;
+ public twitterConfiguration?: TwitterLoginConfiguration;
+ public linkedInConfiguration?: LinkedInConfiguration;
+}
\ No newline at end of file
diff --git a/dmp-frontend/src/app/user-management/utilties/login-service.ts b/dmp-frontend/src/app/user-management/utilties/login-service.ts
new file mode 100644
index 000000000..c1c218a85
--- /dev/null
+++ b/dmp-frontend/src/app/user-management/utilties/login-service.ts
@@ -0,0 +1,173 @@
+import { HostConfiguration } from '../../app.constants';
+import { LoginProviderConfiguration } from './LoginProviderConfiguration';
+import { AuthService } from '../../services/auth/auth.service';
+import { LoginOptions } from './LoginOptions';
+import { LoginServiceConfiguration } from './LoginServiceConfiguration';
+import { LoginProviders } from '../../models/login/LoginInfo';
+import { Optional, NgZone, Injectable } from '@angular/core';
+import { Observable } from 'rxjs/Observable';
+import { MatSnackBar } from '@angular/material';
+import { SnackBarNotificationComponent } from '../../shared/components/notificaiton/snack-bar-notification.component';
+import { Router, ActivatedRoute, Params } from '@angular/router';
+import { TranslateService } from '@ngx-translate/core';
+import { HttpClient, HttpHeaders } from '@angular/common/http';
+
+declare const gapi: any;
+declare const FB: any;
+declare const IN: any;
+
+@Injectable()
+export class LoginService {
+
+ private providers: LoginOptions[]
+ private auth2: any;
+ constructor(
+ private router: Router,
+ public authService: AuthService,
+ public route: ActivatedRoute,
+ public snackBar: MatSnackBar,
+ public language: TranslateService,
+ private zone: NgZone,
+ private httpClient: HttpClient
+ @Optional() private config: LoginServiceConfiguration,
+ ) {
+ if (config) {
+ this.providers = config.loginProviders;
+ }
+ else this.providers = [LoginOptions.nativeLogin];
+ }
+
+ public initProviders() {
+ if (this.hasProvider(LoginOptions.googleOauth)) this.initialiseGoogleOauth();
+ if (this.hasProvider(LoginOptions.facebookOauth)) this.initialiseFacebookOauth();
+ }
+
+ public hasProvider(provider: LoginOptions) {
+ for (let i = 0; i < this.providers.length; i++) {
+ if (provider === this.providers[i]) return this.isProviderProperlyConfigured(provider)
+ }
+ return false;
+ }
+
+ private isProviderProperlyConfigured(provider: LoginOptions) {
+ switch (provider) {
+ case LoginOptions.facebookOauth: return this.hasAllRequiredFieldsConfigured(this.config.facebookConfiguration);
+ case LoginOptions.googleOauth: return this.hasAllRequiredFieldsConfigured(this.config.googleConfiguration)
+ case LoginOptions.linkedInOauth: return this.hasAllRequiredFieldsConfigured(this.config.linkedInConfiguration);
+ case LoginOptions.twitterOauth: return this.hasAllRequiredFieldsConfigured(this.config.twitterConfiguration);
+ case LoginOptions.nativeLogin: return true;
+ default: throw new Error("Unsupported Provider Type")
+ }
+ }
+
+ private hasAllRequiredFieldsConfigured(configuration: LoginProviderConfiguration) {
+ if (configuration != null && configuration.clientId != null) return true
+ return false;
+ }
+
+ /*
+ * GOOGLE SIGN IN
+ */
+
+ private initialiseGoogleOauth(): void {
+ gapi.load('auth2', () => {
+ this.auth2 = gapi.auth2.init({
+ client_id: this.config.googleConfiguration.clientId,
+ cookiepolicy: 'single_host_origin',
+ scope: 'profile email'
+ });
+ this.attachGoogleSignin(document.getElementById('googleSignInButton'));
+ });
+ }
+
+ public attachGoogleSignin(element) {
+ if (!element) return
+ this.auth2.attachClickHandler(element, {},
+ (googleUser) => {
+ var id_token = googleUser.getAuthResponse().id_token;
+ if (id_token) {
+ this.authService.login({ ticket: id_token, provider: LoginProviders.Google }).subscribe(
+ res => this.onLogInSuccess(res),
+ error => this.onLogInError(error)
+ )
+ }
+ }, (error) => {
+ alert(JSON.stringify(error, undefined, 2));
+ });
+ }
+
+
+
+ /*
+ * FACEBOOK SIGN IN
+ */
+
+
+ private initialiseFacebookOauth(): void {
+ FB.init({
+ appId: this.config.facebookConfiguration.clientId,
+ cookie: false,
+ xfbml: true,
+ version: 'v2.8'
+ });
+ }
+
+
+
+
+ public facebookLogin() {
+ FB.login((response: any) => {
+ if (response.status === 'connected' || 'not_authorized') {
+ this.authService.login({ ticket: response.authResponse.accessToken, provider: LoginProviders.Facebook }).subscribe(
+ res => this.onLogInSuccess(res),
+ error => this.onLogInError(error)
+ )
+ }
+ }, { scope: 'user_friends,email' });
+ }
+
+ /*
+ * LINKEDIN SIGN IN
+ */
+
+ public linkedinAuthorize() {
+ window.location.href = this.config.linkedInConfiguration.oauthUrl + "?response_type=code&client_id=" + this.config.linkedInConfiguration.clientId + "&redirect_uri=" + this.config.linkedInConfiguration.redirectUri + "&state=987654321"
+ }
+
+ public linkedInInitialiseLogin() {
+ this.router.navigate(["/login/linkedin"])
+ }
+
+ public linkedInloginUser(code: string) {
+ this.authService.login({ ticket: code, provider: LoginProviders.LinkedIn }).subscribe(
+ res => this.onLogInSuccess(res),
+ error => this.onLogInError(error)
+ )
+ }
+
+ /*
+ * LOGIN HANDLERS
+ */
+
+
+ public onLogInSuccess(logoutMessage: any) {
+ this.snackBar.openFromComponent(SnackBarNotificationComponent, {
+ data: { message: 'GENERAL.SNACK-BAR.SUCCESSFUL-LOGIN', language: this.language },
+ duration: 3000,
+ extraClasses: ['snackbar-success']
+ });
+ this.route.queryParams.subscribe((params: Params) => {
+ let redirectUrl = params['returnUrl'] ? params['returnUrl'] : '/';
+ this.zone.run(() => this.router.navigate([redirectUrl]));
+ })
+ }
+
+ public onLogInError(errorMessage: string) {
+ console.log(errorMessage);
+ this.snackBar.openFromComponent(SnackBarNotificationComponent, {
+ data: { message: 'GENERAL.SNACK-BAR.UNSUCCESSFUL-LOGIN', language: this.language },
+ duration: 3000,
+ extraClasses: ['snackbar-warning']
+ })
+ }
+}
\ No newline at end of file
diff --git a/dmp-frontend/src/index.html b/dmp-frontend/src/index.html
index eed89e6c8..eb9b05831 100644
--- a/dmp-frontend/src/index.html
+++ b/dmp-frontend/src/index.html
@@ -13,6 +13,9 @@
+