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 15acf15ae..53950a5a2 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 @@ -10,6 +10,9 @@ import eu.eudat.logic.security.validators.b2access.helpers.B2AccessResponseToken import eu.eudat.logic.security.validators.linkedin.LinkedInTokenValidator; import eu.eudat.logic.security.validators.linkedin.helpers.LinkedInRequest; import eu.eudat.logic.security.validators.linkedin.helpers.LinkedInResponseToken; +import eu.eudat.logic.security.validators.openaire.OpenAIRETokenValidator; +import eu.eudat.logic.security.validators.openaire.helpers.OpenAIRERequest; +import eu.eudat.logic.security.validators.openaire.helpers.OpenAIREResponseToken; 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; @@ -41,6 +44,7 @@ public class Login { private B2AccessTokenValidator b2AccessTokenValidator; private ORCIDTokenValidator orcidTokenValidator; private LinkedInTokenValidator linkedInTokenValidator; + private OpenAIRETokenValidator openAIRETokenValidator; private Logger logger; @@ -48,13 +52,14 @@ public class Login { @Autowired public Login(CustomAuthenticationProvider customAuthenticationProvider, AuthenticationService nonVerifiedUserAuthenticationService, TwitterTokenValidator twitterTokenValidator, LinkedInTokenValidator linkedInTokenValidator, B2AccessTokenValidator b2AccessTokenValidator, - ORCIDTokenValidator orcidTokenValidator, UserManager userManager, Logger logger) { + ORCIDTokenValidator orcidTokenValidator, OpenAIRETokenValidator openAIRETokenValidator, UserManager userManager, Logger logger) { this.customAuthenticationProvider = customAuthenticationProvider; this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService; this.twitterTokenValidator = twitterTokenValidator; this.linkedInTokenValidator = linkedInTokenValidator; this.b2AccessTokenValidator = b2AccessTokenValidator; this.orcidTokenValidator = orcidTokenValidator; + this.openAIRETokenValidator = openAIRETokenValidator; this.logger = logger; this.userManager = userManager; } @@ -99,6 +104,12 @@ public class Login { return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(this.orcidTokenValidator.getAccessToken(orcidRequest)).status(ApiMessageCode.NO_MESSAGE)); } + @RequestMapping(method = RequestMethod.POST, value = {"/openAireRequestToken"}, produces = "application/json", consumes = "application/json") + public @ResponseBody + ResponseEntity> openAIRERequestToken(@RequestBody OpenAIRERequest openAIRERequest) { + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(this.openAIRETokenValidator.getAccessToken(openAIRERequest)).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/OpenAIRE/OpenAIRECustomProvider.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/OpenAIRE/OpenAIRECustomProvider.java new file mode 100644 index 000000000..3b7855e08 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/OpenAIRE/OpenAIRECustomProvider.java @@ -0,0 +1,10 @@ +package eu.eudat.logic.security.customproviders.OpenAIRE; + +import eu.eudat.logic.security.validators.openaire.helpers.OpenAIREResponseToken; + +public interface OpenAIRECustomProvider { + + OpenAIREResponseToken getAccessToken(String code, String redirectUri, String clientId, String clientSecret); + + OpenAIREUser getUser(String accessToken); +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/OpenAIRE/OpenAIRECustomProviderImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/OpenAIRE/OpenAIRECustomProviderImpl.java new file mode 100644 index 000000000..3d1d7e276 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/OpenAIRE/OpenAIRECustomProviderImpl.java @@ -0,0 +1,63 @@ +package eu.eudat.logic.security.customproviders.OpenAIRE; + +import eu.eudat.logic.security.validators.openaire.helpers.OpenAIREResponseToken; +import eu.eudat.logic.services.operations.authentication.AuthenticationService; +import org.springframework.core.env.Environment; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +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("openAIRECustomProvider") +public class OpenAIRECustomProviderImpl implements OpenAIRECustomProvider { + + private Environment environment; + + public OpenAIRECustomProviderImpl(Environment environment) { + this.environment = environment; + } + + public OpenAIREUser getUser(String accessToken) { + RestTemplate restTemplate = new RestTemplate(); + HttpHeaders headers = this.createBearerAuthHeaders(accessToken); + HttpEntity entity = new HttpEntity<>(headers); + + Map values = restTemplate.exchange(this.environment.getProperty("openaire.login.userinfo_endpoint"), HttpMethod.GET, entity, Map.class).getBody(); + return new OpenAIREUser().getOpenAIREUser(values); + } + + public OpenAIREResponseToken getAccessToken(String code, String redirectUri, String clientId, String clientSecret) { + RestTemplate template = new RestTemplate(); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + + MultiValueMap map = new LinkedMultiValueMap(); + + map.add("grant_type", "authorization_code"); + map.add("code", code); + map.add("redirect_uri", redirectUri); + map.add("client_id", clientId); + map.add("client_secret", clientSecret); + HttpEntity> request = new HttpEntity>(map, headers); + + Map values = template.postForObject(this.environment.getProperty("openaire.login.access_token_url"), request, Map.class); + OpenAIREResponseToken openAIREResponseToken = new OpenAIREResponseToken(); + openAIREResponseToken.setAccessToken((String) values.get("access_token")); + openAIREResponseToken.setExpiresIn((Integer) values.get("expires_in")); + + return openAIREResponseToken; + } + + private HttpHeaders createBearerAuthHeaders(String accessToken) { + return new HttpHeaders() {{ + String authHeader = "Bearer " + new String(accessToken); + set("Authorization", authHeader); + }}; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/OpenAIRE/OpenAIREUser.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/OpenAIRE/OpenAIREUser.java new file mode 100644 index 000000000..e20b65132 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/OpenAIRE/OpenAIREUser.java @@ -0,0 +1,37 @@ +package eu.eudat.logic.security.customproviders.OpenAIRE; + +import java.util.Map; + +public class OpenAIREUser { + private String id; + private String name; + private String email; + + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + + 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 OpenAIREUser getOpenAIREUser(Object data) { + this.id = (String) ((Map) data).get("sub"); + 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/TokenValidatorFactoryImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/TokenValidatorFactoryImpl.java index ed17db2e0..b4c5f6b3f 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 @@ -2,12 +2,13 @@ package eu.eudat.logic.security.validators; import eu.eudat.logic.security.customproviders.B2Access.B2AccessCustomProvider; import eu.eudat.logic.security.customproviders.LinkedIn.LinkedInCustomProvider; -import eu.eudat.logic.security.customproviders.LinkedIn.LinkedInCustomProviderImpl; import eu.eudat.logic.security.customproviders.ORCID.ORCIDCustomProvider; +import eu.eudat.logic.security.customproviders.OpenAIRE.OpenAIRECustomProvider; 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.openaire.OpenAIRETokenValidator; import eu.eudat.logic.security.validators.orcid.ORCIDTokenValidator; import eu.eudat.logic.security.validators.twitter.TwitterTokenValidator; import eu.eudat.logic.services.ApiContext; @@ -20,7 +21,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), ORCID(7); + GOOGLE(1), FACEBOOK(2), TWITTER(3), LINKEDIN(4), NATIVELOGIN(5), B2_ACCESS(6), ORCID(7), OPENAIRE(8); private int value; @@ -48,6 +49,8 @@ public class TokenValidatorFactoryImpl implements TokenValidatorFactory { return B2_ACCESS; case 7: return ORCID; + case 8: + return OPENAIRE; default: throw new RuntimeException("Unsupported LoginProvider"); } @@ -60,18 +63,20 @@ public class TokenValidatorFactoryImpl implements TokenValidatorFactory { private B2AccessCustomProvider b2AccessCustomProvider; private ORCIDCustomProvider orcidCustomProvider; private LinkedInCustomProvider linkedInCustomProvider; + private OpenAIRECustomProvider openAIRECustomProvider; @Autowired public TokenValidatorFactoryImpl( ApiContext apiContext, Environment environment, AuthenticationService nonVerifiedUserAuthenticationService, B2AccessCustomProvider b2AccessCustomProvider, - ORCIDCustomProvider orcidCustomProvider, LinkedInCustomProvider linkedInCustomProvider) { + ORCIDCustomProvider orcidCustomProvider, LinkedInCustomProvider linkedInCustomProvider, OpenAIRECustomProvider openAIRECustomProvider) { this.apiContext = apiContext; this.environment = environment; this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService; this.b2AccessCustomProvider = b2AccessCustomProvider; this.orcidCustomProvider = orcidCustomProvider; this.linkedInCustomProvider = linkedInCustomProvider; + this.openAIRECustomProvider = openAIRECustomProvider; } public TokenValidator getProvider(LoginProvider provider) { @@ -88,6 +93,8 @@ public class TokenValidatorFactoryImpl implements TokenValidatorFactory { return new B2AccessTokenValidator(this.environment, this.nonVerifiedUserAuthenticationService, this.b2AccessCustomProvider); case ORCID: return new ORCIDTokenValidator(this.environment, this.nonVerifiedUserAuthenticationService, this.orcidCustomProvider); + case OPENAIRE: + return new OpenAIRETokenValidator(this.environment, this.nonVerifiedUserAuthenticationService, this.openAIRECustomProvider); default: throw new RuntimeException("Login Provider Not Implemented"); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/openaire/OpenAIRETokenValidator.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/openaire/OpenAIRETokenValidator.java new file mode 100644 index 000000000..74981af98 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/openaire/OpenAIRETokenValidator.java @@ -0,0 +1,52 @@ +package eu.eudat.logic.security.validators.openaire; + +import eu.eudat.exceptions.security.NonValidTokenException; +import eu.eudat.exceptions.security.NullEmailException; +import eu.eudat.logic.security.customproviders.OpenAIRE.OpenAIRECustomProvider; +import eu.eudat.logic.security.customproviders.OpenAIRE.OpenAIREUser; +import eu.eudat.logic.security.validators.TokenValidator; +import eu.eudat.logic.security.validators.openaire.helpers.OpenAIRERequest; +import eu.eudat.logic.security.validators.openaire.helpers.OpenAIREResponseToken; +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.core.env.Environment; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.security.GeneralSecurityException; + +@Component("openAIRETokenValidator") +public class OpenAIRETokenValidator implements TokenValidator { + + private Environment environment; + private AuthenticationService nonVerifiedUserAuthenticationService; + private OpenAIRECustomProvider openAIRECustomProvider; + + public OpenAIRETokenValidator(Environment environment, AuthenticationService nonVerifiedUserAuthenticationService, OpenAIRECustomProvider openAIRECustomProvider) { + this.environment = environment; + this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService; + this.openAIRECustomProvider = openAIRECustomProvider; + } + + public OpenAIREResponseToken getAccessToken(OpenAIRERequest openAIRERequest) { + return this.openAIRECustomProvider.getAccessToken( + openAIRERequest.getCode(), this.environment.getProperty("openaire.login.redirect_uri"), + this.environment.getProperty("openaire.login.client_id"), this.environment.getProperty("openaire.login.client_secret") + ); + } + + @Override + public Principal validateToken(LoginInfo credentials) throws NonValidTokenException, IOException, GeneralSecurityException, NullEmailException { + OpenAIREUser openAIREUser = this.openAIRECustomProvider.getUser(credentials.getTicket()); + LoginProviderUser user = new LoginProviderUser(); + user.setId(openAIREUser.getId()); + user.setEmail(openAIREUser.getEmail()); + user.setName(openAIREUser.getName()); + user.setProvider(credentials.getProvider()); + user.setSecret(credentials.getTicket()); + + return this.nonVerifiedUserAuthenticationService.Touch(user); + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/openaire/helpers/OpenAIRERequest.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/openaire/helpers/OpenAIRERequest.java new file mode 100644 index 000000000..928ef2b55 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/openaire/helpers/OpenAIRERequest.java @@ -0,0 +1,12 @@ +package eu.eudat.logic.security.validators.openaire.helpers; + +public class OpenAIRERequest { + 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/openaire/helpers/OpenAIREResponseToken.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/openaire/helpers/OpenAIREResponseToken.java new file mode 100644 index 000000000..372a3482e --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/openaire/helpers/OpenAIREResponseToken.java @@ -0,0 +1,20 @@ +package eu.eudat.logic.security.validators.openaire.helpers; + +public class OpenAIREResponseToken { + private String accessToken; + private Integer expiresIn; + + public String getAccessToken() { + return accessToken; + } + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; + } + + public Integer getExpiresIn() { + return expiresIn; + } + public void setExpiresIn(Integer expiresIn) { + this.expiresIn = expiresIn; + } +} diff --git a/dmp-backend/web/src/main/resources/application-devel.properties b/dmp-backend/web/src/main/resources/application-devel.properties index f05d23d04..ed4bfe83e 100644 --- a/dmp-backend/web/src/main/resources/application-devel.properties +++ b/dmp-backend/web/src/main/resources/application-devel.properties @@ -52,6 +52,13 @@ 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 +#############OPENAIRE CONFIGURATIONS######### +openaire.login.client_id= +openaire.login.client_secret= +openaire.login.access_token_url= +openaire.login.redirect_uri= +openaire.login.userinfo_endpoint= + #############CONFIRMATION EMAIL CONFIGURATIONS######### conf_email.expiration_time_seconds=14400 conf_email.subject=OpenDMP email confirmation diff --git a/dmp-backend/web/src/main/resources/application-production.properties b/dmp-backend/web/src/main/resources/application-production.properties index cd4b738b6..28aa72581 100644 --- a/dmp-backend/web/src/main/resources/application-production.properties +++ b/dmp-backend/web/src/main/resources/application-production.properties @@ -68,6 +68,13 @@ orcid.login.client_secret= orcid.login.access_token_url=https://orcid.org/oauth/token orcid.login.redirect_uri=https://opendmp.eu/login/external/orcid +#############OPENAIRE CONFIGURATIONS######### +openaire.login.client_id= +openaire.login.client_secret= +openaire.login.access_token_url= +openaire.login.redirect_uri= +openaire.login.userinfo_endpoint= + #############SPRING DATASOURCE CONFIGURATIONS######### spring.datasource.maxIdle: 10 spring.datasource.max-active: 70 diff --git a/dmp-backend/web/src/main/resources/application-staging.properties b/dmp-backend/web/src/main/resources/application-staging.properties index 3cdae2ccc..8ab713dfd 100644 --- a/dmp-backend/web/src/main/resources/application-staging.properties +++ b/dmp-backend/web/src/main/resources/application-staging.properties @@ -74,6 +74,13 @@ orcid.login.client_secret= orcid.login.access_token_url=https://orcid.org/oauth/token orcid.login.redirect_uri=https://opendmp.eu/login/external/orcid +#############OPENAIRE CONFIGURATIONS######### +openaire.login.client_id= +openaire.login.client_secret= +openaire.login.access_token_url= +openaire.login.redirect_uri= +openaire.login.userinfo_endpoint= + #############ZENODO CONFIGURATIONS######### zenodo.url=https://sandbox.zenodo.org/api/ zenodo.access_token= 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 460ce2b50..3dcc29b9b 100644 --- a/dmp-frontend/src/app/core/common/enum/auth-provider.ts +++ b/dmp-frontend/src/app/core/common/enum/auth-provider.ts @@ -5,5 +5,6 @@ export enum AuthProvider { LinkedIn = 4, //NativeLogin=5, B2Access = 6, - ORCID = 7 + ORCID = 7, + OpenAire = 8 } diff --git a/dmp-frontend/src/app/ui/auth/login/img/openaire.png b/dmp-frontend/src/app/ui/auth/login/img/openaire.png new file mode 100644 index 000000000..473bb3f59 Binary files /dev/null and b/dmp-frontend/src/app/ui/auth/login/img/openaire.png differ diff --git a/dmp-frontend/src/app/ui/auth/login/img/openaire_small.png b/dmp-frontend/src/app/ui/auth/login/img/openaire_small.png new file mode 100644 index 000000000..b4c2a3df3 Binary files /dev/null and b/dmp-frontend/src/app/ui/auth/login/img/openaire_small.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 da8ce40e0..5b3511141 100644 --- a/dmp-frontend/src/app/ui/auth/login/login.component.html +++ b/dmp-frontend/src/app/ui/auth/login/login.component.html @@ -28,6 +28,10 @@ + diff --git a/dmp-frontend/src/app/ui/auth/login/login.component.scss b/dmp-frontend/src/app/ui/auth/login/login.component.scss index 0ec524671..af54ca616 100644 --- a/dmp-frontend/src/app/ui/auth/login/login.component.scss +++ b/dmp-frontend/src/app/ui/auth/login/login.component.scss @@ -191,6 +191,16 @@ span.orcidIconMedium { margin-right: 2em; } +span.openaireIcon { + background: url(img/openaire_small.png) no-repeat; + background-position: center; + float: right; + width: 100px; + height: 56px; + margin-left: 2em; + margin-right: 2em; +} + .b2access-button { margin-top: 10px; width: fit-content; @@ -201,6 +211,11 @@ span.orcidIconMedium { width: fit-content; } +.openaire-button { + margin-top: 10px; + width: fit-content; +} + .login-logo { background: url(img/open-dmp.png) no-repeat; width: 273px; diff --git a/dmp-frontend/src/app/ui/auth/login/login.component.ts b/dmp-frontend/src/app/ui/auth/login/login.component.ts index c15aced02..6c329587e 100644 --- a/dmp-frontend/src/app/ui/auth/login/login.component.ts +++ b/dmp-frontend/src/app/ui/auth/login/login.component.ts @@ -58,6 +58,10 @@ export class LoginComponent extends BaseComponent implements OnInit, AfterViewIn this.router.navigate(['/login/external/orcid']); } + public openaireLogin() { + this.router.navigate(['/login/openaire']); + } + public hasFacebookOauth(): boolean { return this.hasProvider(AuthProvider.Facebook); } @@ -82,6 +86,10 @@ export class LoginComponent extends BaseComponent implements OnInit, AfterViewIn return this.hasProvider(AuthProvider.ORCID); } + public hasOpenAireOauth(): boolean { + return this.hasProvider(AuthProvider.OpenAire); + } + public initProviders() { if (this.hasProvider(AuthProvider.Google)) { this.initializeGoogleOauth(); } if (this.hasProvider(AuthProvider.Facebook)) { this.initializeFacebookOauth(); } @@ -102,6 +110,7 @@ export class LoginComponent extends BaseComponent implements OnInit, AfterViewIn case AuthProvider.Twitter: return this.hasAllRequiredFieldsConfigured(environment.loginProviders.twitterConfiguration); case AuthProvider.B2Access: return this.hasAllRequiredFieldsConfigured(environment.loginProviders.b2accessConfiguration); case AuthProvider.ORCID: return this.hasAllRequiredFieldsConfigured(environment.loginProviders.orcidConfiguration); + case AuthProvider.OpenAire: return this.hasAllRequiredFieldsConfigured(environment.loginProviders.openAireConfiguration); default: throw new Error('Unsupported Provider Type'); } } diff --git a/dmp-frontend/src/app/ui/auth/login/login.module.ts b/dmp-frontend/src/app/ui/auth/login/login.module.ts index de4b22391..8eaa9ba92 100644 --- a/dmp-frontend/src/app/ui/auth/login/login.module.ts +++ b/dmp-frontend/src/app/ui/auth/login/login.module.ts @@ -9,6 +9,7 @@ import { LoginService } from './utilities/login.service'; import { B2AccessLoginComponent } from './b2access/b2access-login.component'; import { OrcidLoginComponent } from './orcid-login/orcid-login.component'; import { EmailConfirmation } from './email-confirmation/email-confirmation.component'; +import { OpenAireLoginComponent } from "./openaire-login/openaire-login.component"; @NgModule({ imports: [ @@ -22,7 +23,8 @@ import { EmailConfirmation } from './email-confirmation/email-confirmation.compo TwitterLoginComponent, B2AccessLoginComponent, OrcidLoginComponent, - EmailConfirmation + EmailConfirmation, + OpenAireLoginComponent ], providers: [LoginService] }) diff --git a/dmp-frontend/src/app/ui/auth/login/login.routing.ts b/dmp-frontend/src/app/ui/auth/login/login.routing.ts index 88c7fc0b4..e1bec1f77 100644 --- a/dmp-frontend/src/app/ui/auth/login/login.routing.ts +++ b/dmp-frontend/src/app/ui/auth/login/login.routing.ts @@ -6,6 +6,7 @@ import { LinkedInLoginComponent } from './linkedin-login/linkedin-login.componen import { LoginComponent } from './login.component'; import { OrcidLoginComponent } from './orcid-login/orcid-login.component'; import { TwitterLoginComponent } from './twitter-login/twitter-login.component'; +import { OpenAireLoginComponent } from "./openaire-login/openaire-login.component"; const routes: Routes = [ { path: '', component: LoginComponent }, @@ -14,7 +15,8 @@ const routes: Routes = [ { path: 'external/orcid', component: OrcidLoginComponent }, { path: 'external/b2access', component: B2AccessLoginComponent }, { path: 'confirmation/:token', component: EmailConfirmation }, - { path: 'confirmation', component: EmailConfirmation } + { path: 'confirmation', component: EmailConfirmation }, + { path: 'openaire', component: OpenAireLoginComponent} ]; @NgModule({ diff --git a/dmp-frontend/src/app/ui/auth/login/openaire-login/openaire-login.component.html b/dmp-frontend/src/app/ui/auth/login/openaire-login/openaire-login.component.html new file mode 100644 index 000000000..e69de29bb diff --git a/dmp-frontend/src/app/ui/auth/login/openaire-login/openaire-login.component.ts b/dmp-frontend/src/app/ui/auth/login/openaire-login/openaire-login.component.ts new file mode 100644 index 000000000..14754d688 --- /dev/null +++ b/dmp-frontend/src/app/ui/auth/login/openaire-login/openaire-login.component.ts @@ -0,0 +1,61 @@ +import { Component, OnInit } from "@angular/core"; +import { BaseComponent } from "../../../../core/common/base/base.component"; +import { ActivatedRoute, Router, Params } from "@angular/router"; +import { LoginService } from "../utilities/login.service"; +import { AuthService } from "../../../../core/services/auth/auth.service"; +import { HttpClient } from "@angular/common/http"; +import { takeUntil } from "rxjs/operators"; +import { environment } from "../../../../../environments/environment"; +import { AuthProvider } from "../../../../core/common/enum/auth-provider"; + +@Component({ + selector: 'app-openaire-login', + templateUrl: './openaire-login.component.html', +}) +export class OpenAireLoginComponent extends BaseComponent implements OnInit { + private returnUrl: string; + + constructor( + private route: ActivatedRoute, + private loginService: LoginService, + private authService: AuthService, + private router: Router, + private httpClient: HttpClient + ) { + super(); + } + + ngOnInit(): void { + this.route.queryParams + .pipe(takeUntil(this._destroyed)) + .subscribe((params: Params) => { + const returnUrlFromParams = params['returnUrl']; + if (returnUrlFromParams) { this.returnUrl = returnUrlFromParams; } + if (!params['code']) { this.openaireAuthorize(); } else { this.openaireLoginUser(params['code'], params['state']) } + }) + } + + public openaireAuthorize() { + window.location.href = environment.loginProviders.openAireConfiguration.oauthUrl + + '?response_type=code&client_id=' + environment.loginProviders.openAireConfiguration.clientId + + '&redirect_uri=' + environment.loginProviders.openAireConfiguration.redirectUri + + '&state=' + environment.loginProviders.openAireConfiguration.state + + '&scope=openid profile email'; + } + + public openaireLoginUser(code: string, state: string) { + if (state !== environment.loginProviders.openAireConfiguration.state) { + this.router.navigate(['/login']) + } + this.httpClient.post(environment.Server + 'auth/openAireRequestToken', { code: code, provider: AuthProvider.OpenAire }) + .pipe(takeUntil(this._destroyed)) + .subscribe((data: any) => { + this.authService.login({ ticket: data.payload.accessToken, provider: AuthProvider.OpenAire, data: null }) + .pipe(takeUntil(this._destroyed)) + .subscribe( + res => this.loginService.onLogInSuccess(res, this.returnUrl), + error => this.loginService.onLogInError(error) + ); + }); + } +} diff --git a/dmp-frontend/src/environments/environment.ts b/dmp-frontend/src/environments/environment.ts index ba3d6d89d..1e079ce43 100644 --- a/dmp-frontend/src/environments/environment.ts +++ b/dmp-frontend/src/environments/environment.ts @@ -8,7 +8,7 @@ export const environment = { }, defaultCulture: 'en-US', loginProviders: { - enabled: [1, 2, 3, 4, 5, 6, 7], + enabled: [1, 2, 3, 4, 5, 6, 7, 8], facebookConfiguration: { clientId: '' }, googleConfiguration: { clientId: '' }, linkedInConfiguration: { @@ -31,6 +31,12 @@ export const environment = { clientId: 'APP-766DI5LP8T75FC4R', oauthUrl: 'https://orcid.org/oauth/authorize', redirectUri: 'http://localhost:4200/login/external/orcid' + }, + openAireConfiguration: { + clientId: '', + oauthUrl: '', + redirectUri: '', + state: '987654321' } }, logging: {