Improved Zenodo Account Integration

This commit is contained in:
George Kalampokis 2020-04-10 17:16:37 +03:00
parent 417ee02087
commit 982aea0cbf
24 changed files with 281 additions and 37 deletions

View File

@ -95,6 +95,14 @@ public class Users extends BaseController {
userManager.registerDOIToken(doiRequest, principal);
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<UserProfile>().status(ApiMessageCode.NO_MESSAGE));
}
@Transactional
@RequestMapping(method = RequestMethod.DELETE, value = {"/deleteDOIToken"}, consumes = "application/json", produces = "application/json")
public @ResponseBody
ResponseEntity<ResponseItem<UserProfile>> deleteDOIToken(Principal principal) throws NullEmailException, IOException {
userManager.deleteDOIToken(principal);
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<UserProfile>().status(ApiMessageCode.NO_MESSAGE));
}
}

View File

@ -25,6 +25,8 @@ public class PrincipalBuilder extends Builder<Principal> {
private String timezone;
private String zenodoToken;
private Instant zenodoDuration;
private String zenodoEmail;
private String zenodoRefresh;
public PrincipalBuilder id(UUID id) {
this.id = id;
@ -81,6 +83,16 @@ public class PrincipalBuilder extends Builder<Principal> {
return this;
}
public PrincipalBuilder zenodoEmail(String zenodoEmail) {
this.zenodoEmail = zenodoEmail;
return this;
}
public PrincipalBuilder zenodoRefresh(String zenodoRefresh) {
this.zenodoRefresh = zenodoRefresh;
return this;
}
@Override
public Principal build() {
Principal principal = new Principal();
@ -95,6 +107,8 @@ public class PrincipalBuilder extends Builder<Principal> {
principal.setTimezone(timezone);
principal.setZenodoToken(zenodoToken);
principal.setZenodoDuration(zenodoDuration);
principal.setZenodoEmail(zenodoEmail);
principal.setZenodoRefresh(zenodoRefresh);
return principal;
}
}

View File

@ -13,6 +13,7 @@ import eu.eudat.exceptions.security.NullEmailException;
import eu.eudat.exceptions.security.UnauthorisedException;
import eu.eudat.logic.builders.entity.UserRoleBuilder;
import eu.eudat.logic.builders.model.models.DataTableDataBuilder;
import eu.eudat.logic.security.customproviders.Zenodo.ZenodoAccessType;
import eu.eudat.logic.security.customproviders.Zenodo.ZenodoCustomProvider;
import eu.eudat.logic.security.validators.zenodo.helpers.ZenodoResponseToken;
import eu.eudat.logic.services.ApiContext;
@ -129,21 +130,38 @@ public class UserManager {
if (Instant.now().isBefore(principal.getZenodoDuration())) {
return true;
}
Map<String, Object> settings = Collections.singletonMap("zenodoToken", "");
this.updateSettings(settings, principal);
throw new ExpiredTokenException("Zenodo Token is expired");
try {
this.updateDOIToken(ZenodoAccessType.REFRESH_TOKEN, principal.getZenodoRefresh(), this.environment.getProperty("zenodo.login.redirect_uri"), principal);
}catch (IOException e) {
throw new ExpiredTokenException("Zenodo Token is expired.");
}
}
throw new NonValidTokenException("This account has no Zenodo Token");
}
public void registerDOIToken(DOIRequest doiRequest, Principal principal) throws IOException {
ZenodoResponseToken responseToken = this.zenodoCustomProvider.getAccessToken(doiRequest.getZenodoRequest().getCode()
this.updateDOIToken(ZenodoAccessType.AUTHORIZATION_CODE, doiRequest.getZenodoRequest().getCode(), doiRequest.getRedirectUri(), principal);
}
private void updateDOIToken(ZenodoAccessType accessType, String code, String redirectUri, Principal principal) throws IOException {
ZenodoResponseToken responseToken = this.zenodoCustomProvider.getAccessToken(accessType, code
, this.environment.getProperty("zenodo.login.client_id")
, this.environment.getProperty("zenodo.login.client_secret")
, doiRequest.getRedirectUri());
, redirectUri);
Map<String, Object> settings = new HashMap<>();
settings.put("zenodoEmail", responseToken.getEmail());
settings.put("zenodoRefresh", responseToken.getRefreshToken());
settings.put("zenodoToken", responseToken.getAccessToken());
settings.put("expirationDate", Instant.now().plusSeconds(responseToken.getExpiresIn()).toEpochMilli());
this.updateSettings(settings, principal);
}
public void deleteDOIToken(Principal principal) throws IOException {
Map<String, Object> settings = new HashMap<>();
settings.put("zenodoEmail", "");
settings.put("zenodoRefresh", "");
settings.put("zenodoToken", "");
settings.put("expirationDate", 0);
this.updateSettings(settings, principal);
}
}

View File

@ -0,0 +1,22 @@
package eu.eudat.logic.security.customproviders.Zenodo;
public enum ZenodoAccessType {
AUTHORIZATION_CODE("authorization_code", "code"),
REFRESH_TOKEN("refresh_token", "refresh_token");
private final String grantType;
private final String property;
ZenodoAccessType(String grantType, String property) {
this.grantType = grantType;
this.property = property;
}
public String getGrantType() {
return grantType;
}
public String getProperty() {
return property;
}
}

View File

@ -4,5 +4,5 @@ import eu.eudat.logic.security.validators.orcid.helpers.ORCIDResponseToken;
import eu.eudat.logic.security.validators.zenodo.helpers.ZenodoResponseToken;
public interface ZenodoCustomProvider {
ZenodoResponseToken getAccessToken(String code, String clientId, String clientSecret, String redirectUri);
ZenodoResponseToken getAccessToken(ZenodoAccessType accessType, String code, String clientId, String clientSecret, String redirectUri);
}

View File

@ -32,7 +32,7 @@ public class ZenodoCustomProviderImpl implements ZenodoCustomProvider {
}
@Override
public ZenodoResponseToken getAccessToken(String code, String clientId, String clientSecret, String redirectUri) {
public ZenodoResponseToken getAccessToken(ZenodoAccessType accessType, String code, String clientId, String clientSecret, String redirectUri) {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
@ -41,8 +41,8 @@ public class ZenodoCustomProviderImpl implements ZenodoCustomProvider {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("client_id", clientId);
map.add("client_secret", clientSecret);
map.add("grant_type", "authorization_code");
map.add("code", code);
map.add("grant_type", accessType.getGrantType());
map.add(accessType.getProperty(), code);
map.add("redirect_uri", redirectUri);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
@ -54,6 +54,7 @@ public class ZenodoCustomProviderImpl implements ZenodoCustomProvider {
zenodoResponseToken.setEmail((String) user.get("email"));
zenodoResponseToken.setExpiresIn((Integer) values.get("expires_in"));
zenodoResponseToken.setAccessToken((String) values.get("access_token"));
zenodoResponseToken.setRefreshToken((String) values.get("refresh_token"));
return zenodoResponseToken;
} catch (HttpClientErrorException ex) {

View File

@ -7,6 +7,7 @@ public class ZenodoUser {
private String email;
private String accessToken;
private Integer expiresIn;
private String refreshToken;
public String getUserId() {
return userId;
@ -39,11 +40,20 @@ public class ZenodoUser {
this.expiresIn = expiresIn;
}
public String getRefreshToken() {
return refreshToken;
}
public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}
public ZenodoUser getZenodoUser(Object data) {
this.userId = (String) ((Map) data).get("userId");
this.email = (String) ((Map) data).get("email");
this.accessToken = (String) ((Map) data).get("accessToken");
this.expiresIn = (Integer) ((Map) data).get("expiresIn");
this.refreshToken = (String) ((Map) data).get("refreshToken");
return this;
}
}

View File

@ -4,6 +4,7 @@ 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.customproviders.Zenodo.ZenodoAccessType;
import eu.eudat.logic.security.customproviders.Zenodo.ZenodoCustomProvider;
import eu.eudat.logic.security.customproviders.Zenodo.ZenodoUser;
import eu.eudat.logic.security.validators.TokenValidator;
@ -43,13 +44,14 @@ public class ZenodoTokenValidator implements TokenValidator {
user.setEmail(zenodoUser.getEmail());
user.setZenodoId(zenodoUser.getAccessToken());
user.setZenodoExpire(zenodoUser.getExpiresIn());
user.setZenodoRefresh(zenodoUser.getRefreshToken());
user.setProvider(credentials.getProvider());
user.setSecret(credentials.getTicket());
return this.nonVerifiedUserAuthenticationService.Touch(user);
}
public ZenodoResponseToken getAccessToken(ZenodoRequest zenodoRequest) {
return this.zenodoCustomProvider.getAccessToken(zenodoRequest.getCode()
return this.zenodoCustomProvider.getAccessToken(ZenodoAccessType.AUTHORIZATION_CODE, zenodoRequest.getCode()
, this.environment.getProperty("zenodo.login.client_id")
, this.environment.getProperty("zenodo.login.client_secret")
, this.environment.getProperty("zenodo.login.redirect_uri"));

View File

@ -5,6 +5,7 @@ public class ZenodoResponseToken {
private String email;
private Integer expiresIn;
private String accessToken;
private String refreshToken;
public String getUserId() {
return userId;
@ -35,4 +36,12 @@ public class ZenodoResponseToken {
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public String getRefreshToken() {
return refreshToken;
}
public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}
}

View File

@ -133,7 +133,11 @@ public abstract class AbstractAuthenticationService implements AuthenticationSer
userInfo = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserInfoBuilder.class)
.name(profile.getName()).verified_email(profile.getIsVerified())
.email(profile.getEmail()).created(new Date()).lastloggedin(new Date())
.additionalinfo("{\"data\":{\"avatar\":{\"url\":\"" + profile.getAvatarUrl() + "\"}},{\"zenodoToken\":\"" + profile.getZenodoId() + "\", \"expirationDate\": \"" + Instant.now().plusSeconds(profile.getZenodoExpire()).toEpochMilli() + "\"}")
.additionalinfo("{\"data\":{\"avatar\":{\"url\":\"" + profile.getAvatarUrl()
+ "\"}},{\"zenodoToken\":\"" + profile.getZenodoId()
+ "\", \"expirationDate\": \"" + Instant.now().plusSeconds(profile.getZenodoExpire()).toEpochMilli()
+ "\", \"zenodoRefresh\": \"" + profile.getZenodoRefresh()
+ (profile.getProvider() == TokenValidatorFactoryImpl.LoginProvider.ZENODO ? "\", \"zenodoEmail\": \"" + profile.getEmail() : "") +"\"}")
.authorization_level((short) 1).usertype((short) 1)
.build();
@ -159,6 +163,12 @@ public abstract class AbstractAuthenticationService implements AuthenticationSer
if (profile.getZenodoExpire() != null) {
additionalInfo.put("expirationDate", Instant.now().plusSeconds(profile.getZenodoExpire()).toEpochMilli());
}
if (profile.getZenodoRefresh() != null) {
additionalInfo.put("zenodoRefresh", profile.getZenodoRefresh());
}
if (profile.getProvider() == TokenValidatorFactoryImpl.LoginProvider.ZENODO) {
additionalInfo.put("zenodoEmail", profile.getEmail());
}
userInfo.setLastloggedin(new Date());
userInfo.setAdditionalinfo(new JSONObject(additionalInfo).toString());
Set<Credential> credentials = userInfo.getCredentials();

View File

@ -46,6 +46,18 @@ public class NonVerifiedUserEmailAuthenticationService extends AbstractAuthentic
} catch (Exception e) {
zenodoDuration = Instant.now();
}
String zenodoEmail;
try {
zenodoEmail = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("zenodoEmail").asText() : "";
} catch (Exception e) {
zenodoEmail = "";
}
String zenodoRefresh;
try {
zenodoRefresh = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("zenodoRefresh").asText() : "";
} catch (Exception e) {
zenodoRefresh = "";
}
String culture;
try {
culture = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("culture").get("name").asText() : "";
@ -73,6 +85,8 @@ public class NonVerifiedUserEmailAuthenticationService extends AbstractAuthentic
.timezone(timezone)
.zenodoToken(zenodoToken)
.zenodoDuration(zenodoDuration)
.zenodoEmail(zenodoEmail)
.zenodoRefresh(zenodoRefresh)
.build();
List<UserRole> userRoles = apiContext.getOperationsContext().getDatabaseRepository().getUserRoleDao().getUserRoles(user);

View File

@ -55,6 +55,18 @@ public class VerifiedUserAuthenticationService extends AbstractAuthenticationSer
} catch (Exception e) {
zenodoDuration = Instant.now();
}
String zenodoEmail;
try {
zenodoEmail = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("zenodoEmail").asText() : "";
} catch (Exception e) {
zenodoEmail = "";
}
String zenodoRefresh;
try {
zenodoRefresh = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("zenodoRefresh").asText() : "";
} catch (Exception e) {
zenodoRefresh = "";
}
String culture;
try {
culture = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("culture").get("name").asText() : "";
@ -82,6 +94,8 @@ public class VerifiedUserAuthenticationService extends AbstractAuthenticationSer
.timezone(timezone)
.zenodoToken(zenodoToken)
.zenodoDuration(zenodoDuration)
.zenodoEmail(zenodoEmail)
.zenodoRefresh(zenodoRefresh)
.build();
List<UserRole> userRoles = apiContext.getOperationsContext().getDatabaseRepository().getUserRoleDao().getUserRoles(user);

View File

@ -13,6 +13,7 @@ public class LoginProviderUser {
private TokenValidatorFactoryImpl.LoginProvider provider;
private String zenodoId;
private Integer zenodoExpire;
private String zenodoRefresh;
public String getId() {
return id;
@ -85,4 +86,12 @@ public class LoginProviderUser {
public void setZenodoExpire(Integer zenodoExpire) {
this.zenodoExpire = zenodoExpire;
}
public String getZenodoRefresh() {
return zenodoRefresh;
}
public void setZenodoRefresh(String zenodoRefresh) {
this.zenodoRefresh = zenodoRefresh;
}
}

View File

@ -20,6 +20,8 @@ public class Principal {
private String timezone;
private String zenodoToken;
private Instant zenodoDuration;
private String zenodoRefresh;
private String zenodoEmail;
public UUID getId() {
return id;
@ -105,6 +107,22 @@ public class Principal {
this.zenodoDuration = zenodoDuration;
}
public String getZenodoRefresh() {
return zenodoRefresh;
}
public void setZenodoRefresh(String zenodoRefresh) {
this.zenodoRefresh = zenodoRefresh;
}
public String getZenodoEmail() {
return zenodoEmail;
}
public void setZenodoEmail(String zenodoEmail) {
this.zenodoEmail = zenodoEmail;
}
@JsonIgnore
public Set<Authorities> getAuthz() {
return this.authorities;

View File

@ -10,4 +10,5 @@ export interface Principal {
timezone: string;
language: string;
culture: string;
zenodoEmail: string;
}

View File

@ -3,5 +3,8 @@ import { AppRole } from "../../common/enum/app-role";
export interface UserListingModel {
id: String;
name: String;
email: string;
appRoles: AppRole[];
additionalinfo: any;
associatedDmps: any[];
}

View File

@ -3,4 +3,5 @@ export class ZenodoToken {
expiresIn: number;
accessToken:string;
email: string;
refreshToken: string;
}

View File

@ -57,4 +57,9 @@ export class UserService {
const url = this.actionUrl + 'registerDOIToken';
return this.http.post(url, {zenodoRequest: {code: code}, redirectUri: redirectUri}, { headers: this.headers });
}
public deleteDOIToken(): Observable<any> {
const url = this.actionUrl + 'deleteDOIToken';
return this.http.delete(url, { headers: this.headers });
}
}

View File

@ -64,6 +64,7 @@ export class ZenodoLoginComponent extends BaseComponent implements OnInit {
this.zenodoToken.expiresIn = responseData.payload.expiresIn;
this.accessToken = this.zenodoToken.accessToken = responseData.payload.accessToken;
this.zenodoToken.email = responseData.payload.email;
this.zenodoToken.refreshToken = responseData.payload.refreshToken;
this.authService.login({ ticket: this.accessToken, provider: AuthProvider.Zenodo, data: this.zenodoToken })
.pipe(takeUntil(this._destroyed))
.subscribe(

View File

@ -45,6 +45,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
breadCrumbs: Observable<BreadcrumbItem[]> = observableOf();
isUserOwner: boolean;
expand = false;
hasDOIToken = false;
constructor(
private route: ActivatedRoute,
@ -149,14 +150,14 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
this.expand = !this.expand;
}
checkOverflow (element) {
checkOverflow(element) {
if (this.expand || (element.offsetHeight < element.scrollHeight ||
element.offsetWidth < element.scrollWidth)) {
return true;
return true;
} else {
return false;
return false;
}
}
}
datasetClicked(datasetId: String) {
if (this.isPublicView) {
@ -334,26 +335,29 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
getAccessUrl(): string {
const redirectUri = this.configurationService.app + 'oauth2';
const url = this.configurationService.loginProviders.zenodoConfiguration.oauthUrl
+ '?client_id=' + this.configurationService.loginProviders.zenodoConfiguration.clientId
+ '&response_type=code&scope=deposit:write+deposit:actions&state=astate&redirect_uri='
+ redirectUri;
+ '?client_id=' + this.configurationService.loginProviders.zenodoConfiguration.clientId
+ '&response_type=code&scope=deposit:write+deposit:actions+user:email&state=astate&redirect_uri='
+ redirectUri;
return url;
}
getDoi(dmp: DmpOverviewModel) {
this.userService.hasDOIToken().subscribe(response => {
this.hasDOIToken = true;
this.showConfirmationDOIDialog(dmp);
}, error => {
this.hasDOIToken = false;
this.showErrorConfirmationDOIDialog(error.error.message, dmp);
});
}
showConfirmationDOIDialog(dmp: DmpOverviewModel) {
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
maxWidth: '600px',
restoreFocus: false,
data: {
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ZENODO-DOI'),
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ZENODO-DOI', { 'username': this.hasDOIToken ? this.authentication.current().zenodoEmail : 'default'}),
confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'),
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
}
@ -379,7 +383,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
restoreFocus: false,
data: {
message: message,
titles: [ this.language.instant('DMP-OVERVIEW.MULTIPLE-DIALOG.ZENODO-LOGIN'), this.language.instant('DMP-OVERVIEW.MULTIPLE-DIALOG.USE-DEFAULT')]
titles: [this.language.instant('DMP-OVERVIEW.MULTIPLE-DIALOG.ZENODO-LOGIN'), this.language.instant('DMP-OVERVIEW.MULTIPLE-DIALOG.USE-DEFAULT')]
}
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
@ -398,14 +402,17 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
showOauth2Dialog(url: string, dmp: DmpOverviewModel) {
this.oauth2DialogService.login(url)
.pipe(takeUntil(this._destroyed))
.subscribe(code => {
if (!isNullOrUndefined(code)) {
this.userService.registerDOIToken(code, this.configurationService.app + 'oauth2')
.pipe(takeUntil(this._destroyed))
.subscribe(() => this.showConfirmationDOIDialog(dmp));
}
});
.pipe(takeUntil(this._destroyed))
.subscribe(code => {
if (!isNullOrUndefined(code)) {
this.userService.registerDOIToken(code, this.configurationService.app + 'oauth2')
.pipe(takeUntil(this._destroyed))
.subscribe(() => {
this.hasDOIToken = true;
this.showConfirmationDOIDialog(dmp);
});
}
});
}
onDOICallbackSuccess(): void {

View File

@ -63,7 +63,7 @@
</div>
</mat-card-title>
</mat-card-header>
<mat-card-content>
<mat-card-content disabled="false">
<div class="container">
<div class="row" [formGroup]="formGroup">
<mat-form-field class="col-md-4">
@ -98,6 +98,29 @@
</div>
</mat-card-content>
</mat-card>
<mat-card class="col-12 profile-card">
<mat-card-header>
<mat-card-title>
<div class="row">
<h4 class="settings col-auto">{{ 'USER-PROFILE.ZENODO.TITLE' | translate}}</h4>
</div>
</mat-card-title>
</mat-card-header>
<mat-card-content>
<div class="container">
<div class="row">
<div class="col-md-4" *ngIf="!hasZenodo()">
<button mat-raised-button type="button" (click)="loginToZenodo()" class="confirm">{{'USER-PROFILE.ZENODO.LOGIN' | translate}}</button>
</div>
<div class="col-md-4" *ngIf="hasZenodo()">
<div><label class="zenodo-email">{{ 'USER-PROFILE.ZENODO.DESCRIPTION' | translate}}</label></div>
<label class="zenodo-email">{{zenodoEmail}}</label>
<div><button mat-raised-button type="button" (click)="RemoveZenodo()" class="confirm">{{'USER-PROFILE.ZENODO.LOGOUT' | translate}}</button></div>
</div>
</div>
</div>
</mat-card-content>
</mat-card>
</div>
<ng-template #loading>
</ng-template>

View File

@ -25,3 +25,7 @@
.settings {
line-height: 2.4em !important;
}
.zenodo-email {
color: black;
}

View File

@ -13,6 +13,9 @@ import * as moment from 'moment-timezone';
import { Observable, of } from 'rxjs';
import { map, takeUntil } from 'rxjs/operators';
import { LanguageService } from '@app/core/services/language/language.service';
import { isNullOrUndefined } from 'util';
import { Oauth2DialogService } from '../misc/oauth2-dialog/service/oauth2-dialog.service';
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
const availableLanguages: any[] = require('../../../assets/resources/language.json');
@ -29,6 +32,8 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
timezones: Observable<any[]>;
editMode = false;
languages = availableLanguages;
zenodoToken: string;
zenodoEmail: string;
formGroup: FormGroup;
constructor(
@ -39,7 +44,9 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
private language: TranslateService,
private cultureService: CultureService,
private authentication: AuthService,
private languageService: LanguageService
private languageService: LanguageService,
private configurationService: ConfigurationService,
private oauth2DialogService: Oauth2DialogService
) { super(); }
ngOnInit() {
@ -50,6 +57,8 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
const userId = !params['id'] ? 'me' : params['id'];
this.user = this.userService.getUser(userId).pipe(map(result => {
result['additionalinfo'] = JSON.parse(result['additionalinfo']);
this.zenodoToken = result['additionalinfo']['zenodoToken'];
this.zenodoEmail = result['additionalinfo']['zenodoEmail'];
this.formGroup = new FormBuilder().group({
language: new FormControl(result['additionalinfo']['language'] ? availableLanguages.filter(x => x.value === result['additionalinfo']['language']['value']).pop() : '', [Validators.required]),
timezone: new FormControl(result['additionalinfo']['timezone'], [Validators.required]),
@ -78,10 +87,10 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
getUserRole(dmp: DmpModel) {
if (dmp.creator.id === this.currentUserId) {
return this.language.instant('USER-PROFILE.DMPS.CREATOR');
} else if (dmp.associatedUsers.map(x => x.id).indexOf(this.currentUserId) !== -1) {
return this.language.instant('USER-PROFILE.DMPS.MEMBER');
}
return this.language.instant('USER-PROFILE.DMPS.CREATOR');
} else if (dmp.associatedUsers.map(x => x.id).indexOf(this.currentUserId) !== -1) {
return this.language.instant('USER-PROFILE.DMPS.MEMBER');
}
}
showAllDmps() {
@ -147,4 +156,39 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
(ev.target as HTMLImageElement).src = 'assets/images/profile-placeholder.png';
}
public hasZenodo(): boolean {
return !isNullOrUndefined(this.zenodoToken) && this.zenodoToken !== "";
}
public loginToZenodo() {
this.showOauth2Dialog(this.getAccessUrl());
}
getAccessUrl(): string {
const redirectUri = this.configurationService.app + 'oauth2';
const url = this.configurationService.loginProviders.zenodoConfiguration.oauthUrl
+ '?client_id=' + this.configurationService.loginProviders.zenodoConfiguration.clientId
+ '&response_type=code&scope=deposit:write+deposit:actions+user:email&state=astate&redirect_uri='
+ redirectUri;
return url;
}
showOauth2Dialog(url: string) {
this.oauth2DialogService.login(url)
.pipe(takeUntil(this._destroyed))
.subscribe(code => {
if (!isNullOrUndefined(code)) {
this.userService.registerDOIToken(code, this.configurationService.app + 'oauth2')
.pipe(takeUntil(this._destroyed))
.subscribe(() => this.router.navigate(['/reload']).then(() => this.router.navigate(['/profile'])));
}
});
}
public RemoveZenodo() {
this.userService.deleteDOIToken()
.pipe(takeUntil(this._destroyed))
.subscribe(() => this.router.navigate(['/reload']).then(() => this.router.navigate(['/profile'])));
}
}

View File

@ -52,7 +52,7 @@
"FINALIZE-ITEM": "Finalize this item?",
"PUBLISH-ITEM": "Publish this item?",
"ADD-DATASET": "Do you want to continue by adding a Dataset Description to your DMP? You can always add more Dataset Descriptions using \"Add Dataset Description (Wizard)\" menu.",
"ZENODO-DOI": "Would you like to create digital object identifier (DOI) for the DMP?",
"ZENODO-DOI": "Would you like to create digital object identifier (DOI) with {{username}} account for the DMP?",
"LEAVE-PAGE": "If you leave, your changes will be lost.",
"LEAVE-WARNING": "You have unsaved changes!",
"PRIVACY-POLICY-NAMES": "The names of all people involved into this DMP will be publicly visible. Do you agree with that?",
@ -218,7 +218,7 @@
"DATASET-TEMPLATES": "Dataset Description Templates",
"DMP-TEMPLATES": "DMP Templates",
"USERS": "Users",
"LANGUAGE-EDITOR":"Language Editor",
"LANGUAGE-EDITOR": "Language Editor",
"GUIDE-EDITOR": "User Guide Editor"
},
"DATASET-PROFILE-EDITOR": {
@ -431,7 +431,7 @@
"TITLE": "Published Data Management Plans",
"OWNER": "Owner",
"MEMBER": "Member",
"CREATOR":"Creator",
"CREATOR": "Creator",
"VIEW-ONLY": "View Only",
"TOOLTIP": {
"PUBLISHED": "Public access - Closed DMP",
@ -1090,6 +1090,12 @@
"SHOW-ALL": "Show All",
"CREATOR": "Creator",
"MEMBER": "Member"
},
"ZENODO": {
"LOGIN": "Login to Zenodo",
"LOGOUT": "Remove Zenodo",
"TITLE": "Zenodo Account",
"DESCRIPTION": "Linked Zenodo Account:"
}
},
"DATASET-REFERENCED-MODELS": {