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 29cf87104..a6315f15a 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 @@ -82,6 +82,12 @@ public class Login { return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(this.b2AccessTokenValidator.getAccessToken(b2AccessRequest)).status(ApiMessageCode.NO_MESSAGE)); } + @RequestMapping(method = RequestMethod.POST, value = {"/orcidRequestToken"}, produces = "application/json", consumes = "application/json") + public @ResponseBody + ResponseEntity> ORCIDRequestToken(@RequestBody ORCIDRequest orcidRequest) { + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(this.orcidTokenValidator.getAccessToken(orcidRequest)).status(ApiMessageCode.NO_MESSAGE)); + } + @RequestMapping(method = RequestMethod.POST, value = {"/me"}, consumes = "application/json", produces = "application/json") public @ResponseBody ResponseEntity> authMe(Principal principal) throws NullEmailException { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/B2AccessCustomProvider.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/B2Access/B2AccessCustomProvider.java similarity index 85% rename from dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/B2AccessCustomProvider.java rename to dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/B2Access/B2AccessCustomProvider.java index 64aaba361..27e615c76 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/B2AccessCustomProvider.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/B2Access/B2AccessCustomProvider.java @@ -1,4 +1,4 @@ -package eu.eudat.logic.security.customproviders; +package eu.eudat.logic.security.customproviders.B2Access; import eu.eudat.logic.security.validators.b2access.helpers.B2AccessResponseToken; diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/B2AccessCustomProviderImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/B2Access/B2AccessCustomProviderImpl.java similarity index 98% rename from dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/B2AccessCustomProviderImpl.java rename to dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/B2Access/B2AccessCustomProviderImpl.java index c8f482023..4a4066fb4 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/B2AccessCustomProviderImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/B2Access/B2AccessCustomProviderImpl.java @@ -1,4 +1,4 @@ -package eu.eudat.logic.security.customproviders; +package eu.eudat.logic.security.customproviders.B2Access; import com.google.api.client.repackaged.org.apache.commons.codec.binary.Base64; import eu.eudat.logic.security.validators.b2access.helpers.B2AccessResponseToken; diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/B2AccessUser.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/B2Access/B2AccessUser.java similarity index 90% rename from dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/B2AccessUser.java rename to dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/B2Access/B2AccessUser.java index f42ce4da9..a1dfcf95a 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/B2AccessUser.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/B2Access/B2AccessUser.java @@ -1,4 +1,4 @@ -package eu.eudat.logic.security.customproviders; +package eu.eudat.logic.security.customproviders.B2Access; /** * Created by ikalyvas on 2/22/2018. diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ORCID/ORCIDCustomProvider.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ORCID/ORCIDCustomProvider.java new file mode 100644 index 000000000..b98b20af8 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ORCID/ORCIDCustomProvider.java @@ -0,0 +1,9 @@ +package eu.eudat.logic.security.customproviders.ORCID; + +import eu.eudat.logic.security.validators.orcid.helpers.ORCIDResponseToken; + +public interface ORCIDCustomProvider { + ORCIDUser getUser(String accessToken); + + ORCIDResponseToken getAccessToken(String code, String redirectUri, String clientId, String clientSecret); +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ORCID/ORCIDCustomProviderImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ORCID/ORCIDCustomProviderImpl.java new file mode 100644 index 000000000..dc6272ab1 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ORCID/ORCIDCustomProviderImpl.java @@ -0,0 +1,65 @@ +package eu.eudat.logic.security.customproviders.ORCID; + +import eu.eudat.logic.security.validators.orcid.helpers.ORCIDResponseToken; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +import java.util.Map; + +@Component("ORCIDCustomProvider") +public class ORCIDCustomProviderImpl implements ORCIDCustomProvider { + + private Environment environment; + + @Autowired + public ORCIDCustomProviderImpl(Environment environment) { + this.environment = environment; + } + + + @Override + public ORCIDResponseToken getAccessToken(String code, String redirectUri, String clientId, String clientSecret) { + RestTemplate restTemplate = new RestTemplate(); + HttpHeaders headers = new HttpHeaders(); + headers.set("accept", "application/json"); + + MultiValueMap map = new LinkedMultiValueMap(); + map.add("client_id", this.environment.getProperty("orcid.login.client_id")); + map.add("client_secret", this.environment.getProperty("orcid.login.client_secret")); + map.add("grant_type", "authorization_code"); + map.add("code", code); + map.add("redirect_uri", redirectUri); + HttpEntity> request = new HttpEntity>(map, headers); + + Map values = restTemplate.postForObject(this.environment.getProperty("orcid.login.access_token_url"), request, Map.class); + ORCIDResponseToken orcidResponseToken = new ORCIDResponseToken(); + orcidResponseToken.setOrcidId((String) values.get("orcid")); + orcidResponseToken.setName((String) values.get("name")); + orcidResponseToken.setAccessToken((String) values.get("access_token")); + + return orcidResponseToken; + } + + @Override + public ORCIDUser getUser(String accessToken) { + RestTemplate restTemplate = new RestTemplate(); + HttpHeaders headers = this.createBearerAuthHeaders(accessToken); + HttpEntity entity = new HttpEntity<>(headers); + + //Map values = restTemplate.exchange(this.environment.getProperty("orcid.login.access_token_url"),); + return null; + } + + private HttpHeaders createBearerAuthHeaders(String accessToken) { + return new HttpHeaders() {{ + String authHeader = "Bearer " + accessToken; + set("Authorization", authHeader); + }}; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ORCID/ORCIDUser.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ORCID/ORCIDUser.java new file mode 100644 index 000000000..b0fa89678 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ORCID/ORCIDUser.java @@ -0,0 +1,38 @@ +package eu.eudat.logic.security.customproviders.ORCID; + +import java.util.Map; + +public class ORCIDUser { + private String orcidId; + private String name; + private String email; + + public String getOrcidId() { + return orcidId; + } + public void setOrcidId(String orcidId) { + this.orcidId = orcidId; + } + + 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 ORCIDUser getOrcidUser(Object data) { + this.orcidId = (String) ((Map) data).get("orcidId"); + this.name = (String) ((Map) data).get("name"); + this.email = (String) ((Map) data).get("email"); + return this; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/orcid/ORCIDTokenValidator.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/orcid/ORCIDTokenValidator.java new file mode 100644 index 000000000..8d365a052 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/orcid/ORCIDTokenValidator.java @@ -0,0 +1,54 @@ +package eu.eudat.logic.security.validators.orcid; + +import eu.eudat.exceptions.security.NonValidTokenException; +import eu.eudat.exceptions.security.NullEmailException; +import eu.eudat.logic.security.customproviders.ORCID.ORCIDCustomProvider; +import eu.eudat.logic.security.customproviders.ORCID.ORCIDUser; +import eu.eudat.logic.security.validators.TokenValidator; +import eu.eudat.logic.security.validators.orcid.helpers.ORCIDRequest; +import eu.eudat.logic.security.validators.orcid.helpers.ORCIDResponseToken; +import eu.eudat.logic.services.ApiContext; +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.stereotype.Component; + +import java.io.IOException; +import java.security.GeneralSecurityException; + +@Component("orcidTokenValidator") +public class ORCIDTokenValidator implements TokenValidator { + + private ORCIDCustomProvider orcidCustomProvider; + private Environment environment; + private AuthenticationService nonVerifiedUserAuthenticationService; + private ApiContext apiContext; + + @Autowired + public ORCIDTokenValidator(Environment environment, AuthenticationService nonVerifiedUserAuthenticationService, ORCIDCustomProvider orcidCustomProvider, ApiContext apiContext) { + this.environment = environment; + this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService; + this.orcidCustomProvider = orcidCustomProvider; + this.apiContext = apiContext; + } + + @Override + public Principal validateToken(LoginInfo credentials) throws NonValidTokenException, IOException, GeneralSecurityException, NullEmailException { + ORCIDUser orcidUser = new ORCIDUser().getOrcidUser(credentials.getData()); + LoginProviderUser user = new LoginProviderUser(); + user.setId(orcidUser.getOrcidId()); + user.setName(orcidUser.getName()); + user.setProvider(credentials.getProvider()); + user.setSecret(credentials.getTicket()); + return this.nonVerifiedUserAuthenticationService.Touch(user); + } + + public ORCIDResponseToken getAccessToken(ORCIDRequest orcidRequest) { + return this.orcidCustomProvider.getAccessToken(orcidRequest.getCode(), this.environment.getProperty("orcid.login.redirect_uri") + , this.environment.getProperty("orcid.login.client_id") + , this.environment.getProperty("orcid.login.client_secret")); + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/orcid/helpers/ORCIDRequest.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/orcid/helpers/ORCIDRequest.java new file mode 100644 index 000000000..8fb7dc752 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/orcid/helpers/ORCIDRequest.java @@ -0,0 +1,12 @@ +package eu.eudat.logic.security.validators.orcid.helpers; + +public class ORCIDRequest { + private String code; + + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/orcid/helpers/ORCIDResponseToken.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/orcid/helpers/ORCIDResponseToken.java new file mode 100644 index 000000000..86d7c9f7d --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/orcid/helpers/ORCIDResponseToken.java @@ -0,0 +1,28 @@ +package eu.eudat.logic.security.validators.orcid.helpers; + +public class ORCIDResponseToken { + private String orcidId; + private String name; + private String accessToken; + + public String getOrcidId() { + return orcidId; + } + public void setOrcidId(String orcidId) { + this.orcidId = orcidId; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + public String getAccessToken() { + return accessToken; + } + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; + } +} diff --git a/dmp-frontend/src/app/core/common/enum/auth-provider.ts b/dmp-frontend/src/app/core/common/enum/auth-provider.ts index c1302645c..460ce2b50 100644 --- a/dmp-frontend/src/app/core/common/enum/auth-provider.ts +++ b/dmp-frontend/src/app/core/common/enum/auth-provider.ts @@ -4,5 +4,6 @@ export enum AuthProvider { Twitter = 3, LinkedIn = 4, //NativeLogin=5, - B2Access = 6 + B2Access = 6, + ORCID = 7 } diff --git a/dmp-frontend/src/app/core/model/orcid/orcidUser.ts b/dmp-frontend/src/app/core/model/orcid/orcidUser.ts new file mode 100644 index 000000000..5642ee8fb --- /dev/null +++ b/dmp-frontend/src/app/core/model/orcid/orcidUser.ts @@ -0,0 +1,5 @@ +export class OrcidUser { + orcidId: string; + name: string; + email: string; +} diff --git a/dmp-frontend/src/app/ui/auth/login/img/ORCIDiD_medium.png b/dmp-frontend/src/app/ui/auth/login/img/ORCIDiD_medium.png new file mode 100644 index 000000000..eeb97949b Binary files /dev/null and b/dmp-frontend/src/app/ui/auth/login/img/ORCIDiD_medium.png differ diff --git a/dmp-frontend/src/app/ui/auth/login/login.component.html b/dmp-frontend/src/app/ui/auth/login/login.component.html index fb95f292e..49082dde1 100644 --- a/dmp-frontend/src/app/ui/auth/login/login.component.html +++ b/dmp-frontend/src/app/ui/auth/login/login.component.html @@ -2,23 +2,32 @@