Merge branch 'dmp-refactoring' of https://code-repo.d4science.org/MaDgiK-CITE/argos into dmp-refactoring

This commit is contained in:
Diamantis Tziotzios 2024-09-19 11:29:17 +03:00
commit 2fb1178350
22 changed files with 180 additions and 27 deletions

View File

@ -544,4 +544,34 @@ public class ErrorThesaurusProperties {
public ErrorDescription getUserProfileInactive() { return userProfileInactive; }
public void setUserProfileInactive(ErrorDescription userProfileInactive) {this.userProfileInactive = userProfileInactive; }
private ErrorDescription planInvitationAlreadyConfirmed;
public ErrorDescription getPlanInvitationAlreadyConfirmed() {
return planInvitationAlreadyConfirmed;
}
public void setPlanInvitationAlreadyConfirmed(ErrorDescription planInvitationAlreadyConfirmed) {
this.planInvitationAlreadyConfirmed = planInvitationAlreadyConfirmed;
}
private ErrorDescription anotherUserToken;
public ErrorDescription getAnotherUserToken() {
return anotherUserToken;
}
public void setAnotherUserToken(ErrorDescription anotherUserToken) {
this.anotherUserToken = anotherUserToken;
}
private ErrorDescription tokenNotExist;
public ErrorDescription getTokenNotExist() {
return tokenNotExist;
}
public void setTokenNotExist(ErrorDescription tokenNotExist) {
this.tokenNotExist = tokenNotExist;
}
}

View File

@ -52,7 +52,7 @@ public interface PlanService {
void inviteUserOrAssignUsers(UUID id, List<PlanUserPersist> users) throws InvalidApplicationException, JAXBException, IOException;
void planInvitationAccept(String token) throws InvalidApplicationException, IOException;
UUID planInvitationAccept(String token) throws InvalidApplicationException, IOException;
PlanImportExport exportXmlEntity(UUID id, boolean ignoreAuthorize, boolean isPublic) throws MyForbiddenException, MyNotFoundException, JAXBException, ParserConfigurationException, IOException, InstantiationException, IllegalAccessException, SAXException, InvalidApplicationException;

View File

@ -1979,21 +1979,28 @@ public class PlanServiceImpl implements PlanService {
return persist.getToken();
}
public void planInvitationAccept(String token) throws InvalidApplicationException {
public UUID planInvitationAccept(String token) throws InvalidApplicationException {
ActionConfirmationEntity action = this.queryFactory.query(ActionConfirmationQuery.class).tokens(token).types(ActionConfirmationType.PlanInvitation).isActive(IsActive.Active).first();
if (action == null){
throw new MyApplicationException("Token does not exist!");
throw new MyValidationException(this.errors.getTokenNotExist().getCode(), this.errors.getTokenNotExist().getMessage());
}
if (action.getStatus().equals(ActionConfirmationStatus.Accepted)){
throw new MyApplicationException("Invitation is already confirmed!");
throw new MyValidationException(this.errors.getPlanInvitationAlreadyConfirmed().getCode(), this.errors.getPlanInvitationAlreadyConfirmed().getMessage());
}
if (action.getExpiresAt().compareTo(Instant.now()) < 0){
throw new MyApplicationException("Token has expired!");
throw new MyValidationException(this.errors.getRequestHasExpired().getCode(), this.errors.getRequestHasExpired().getMessage());
}
PlanInvitationEntity planInvitation = this.xmlHandlingService.fromXmlSafe(PlanInvitationEntity.class, action.getData());
if (planInvitation == null) {
throw new MyApplicationException("plan invitation don't exist");
}
UserContactInfoEntity contactInfoEntity = this.queryFactory.query(UserContactInfoQuery.class).disableTracking().userIds(this.userScope.getUserId()).values(planInvitation.getEmail()).types(ContactInfoType.Email).first();
if (contactInfoEntity == null){
throw new MyValidationException(this.errors.getAnotherUserToken().getCode(), this.errors.getAnotherUserToken().getMessage());
}
PlanUserEntity data = new PlanUserEntity();
data.setId(UUID.randomUUID());
data.setIsActive(IsActive.Active);
@ -2008,6 +2015,7 @@ public class PlanServiceImpl implements PlanService {
this.entityManager.merge(action);
this.annotationEntityTouchedIntegrationEventHandler.handlePlan(planInvitation.getPlanId());
return planInvitation.getPlanId();
}
//region Export

View File

@ -1051,7 +1051,7 @@ public class UserServiceImpl implements UserService {
this.entityManager.reloadTenantFilters();
}
if (action == null)
throw new MyNotFoundException(this.messageSource.getMessage("General_ItemNotFound", new Object[]{token, ActionConfirmationEntity.class.getSimpleName()}, LocaleContextHolder.getLocale()));
throw new MyValidationException(this.errors.getTokenNotExist().getCode(), this.errors.getTokenNotExist().getMessage());
this.checkActionState(action, true);
UserInviteToTenantRequestEntity userInviteToTenantRequest = this.xmlHandlingService.fromXmlSafe(UserInviteToTenantRequestEntity.class, action.getData());

View File

@ -483,20 +483,20 @@ public class PlanController {
return true;
}
@GetMapping("{id}/token/{token}/invite-accept")
@OperationWithTenantHeader(summary = "Accept an invitation token for a plan by id")
@GetMapping("token/{token}/invite-accept")
@OperationWithTenantHeader(summary = "Accept an invitation token for a plan by token")
@Transactional
@Hidden
public boolean acceptInvitation(@PathVariable("id") UUID id, @PathVariable("token") String token) throws InvalidApplicationException, JAXBException, IOException {
logger.debug(new MapLogEntry("inviting users to plan").And("id", id));
public UUID acceptInvitation(@PathVariable("token") String token) throws InvalidApplicationException, JAXBException, IOException {
logger.debug(new MapLogEntry("inviting users to plan").And("token", token));
this.planService.planInvitationAccept(token);
UUID planId = this.planService.planInvitationAccept(token);
this.auditService.track(AuditableAction.Plan_Invite_Accept, Map.ofEntries(
new AbstractMap.SimpleEntry<String, Object>("token", token)
));
return true;
return planId;
}
@RequestMapping(method = RequestMethod.GET, value = "/xml/export/{id}", produces = "application/xml")

View File

@ -170,3 +170,12 @@ error-thesaurus:
userProfileInactive:
code: 160
message: User account has not been activated
planInvitationAlreadyConfirmed:
code: 161
message: Plan invitation already confirmed
anotherUserToken:
code: 162
message: This token is for another user
tokenNotExist:
code: 163
message: This token does not exist

View File

@ -56,6 +56,9 @@ export enum ResponseErrorCode {
missingTenantRole = 158,
missingGlobalRole = 159,
userProfileInactive = 160,
planInvitationAlreadyConfirmed = 161,
anotherUserToken = 162,
tokenNotExist = 163,
// Notification & Annotation Errors
InvalidApiKey = 200,
@ -199,7 +202,13 @@ export class ResponseErrorCodeHelper {
case ResponseErrorCode.missingGlobalRole:
return language.instant("GENERAL.BACKEND-ERRORS.MISSING-GLOBAL-ROLE");
case ResponseErrorCode.userProfileInactive:
return language.instant("GENERAL.BACKEND-ERRORS.CANNOT-PERFORM-ACTION-ON-USER")
return language.instant("GENERAL.BACKEND-ERRORS.CANNOT-PERFORM-ACTION-ON-USER");
case ResponseErrorCode.planInvitationAlreadyConfirmed:
return language.instant("GENERAL.BACKEND-ERRORS.PLAN-INVITATION-ALREADY-CONFIRMED");
case ResponseErrorCode.anotherUserToken:
return language.instant("GENERAL.BACKEND-ERRORS.ANOTHER-USER-TOKEN");
case ResponseErrorCode.tokenNotExist:
return language.instant("GENERAL.BACKEND-ERRORS.TOKEN-NOT-EXIST");
default:
return language.instant("GENERAL.SNACK-BAR.NOT-FOUND");
}

View File

@ -172,10 +172,10 @@ export class PlanService {
catchError((error: any) => throwError(error)));
}
acceptInvitation(PlanId: Guid, token: string): Observable<any> {
const url = `${this.apiBase}/${PlanId}/token/${token}/invite-accept`;
acceptInvitation(token: string): Observable<Guid> {
const url = `${this.apiBase}/token/${token}/invite-accept`;
return this.http.get<any>(url).pipe(catchError((error: any) => throwError(error)));
return this.http.get<Guid>(url).pipe(catchError((error: any) => throwError(error)));
}
downloadXML(id: Guid): Observable<HttpResponse<Blob>> {

View File

@ -0,0 +1,63 @@
import { HttpErrorResponse } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { AuthService } from '@app/core/services/auth/auth.service';
import { SnackBarNotificationLevel } from '@app/core/services/notification/ui-notification-service';
import { PlanService } from '@app/core/services/plan/plan.service';
import { RouterUtilsService } from '@app/core/services/router/router-utils.service';
import { BaseComponent } from '@common/base/base.component';
import { HttpError, HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
import { takeUntil } from 'rxjs/operators';
@Component({
selector: 'app-plan-invitation-accepted-component',
templateUrl: 'plan-invitation-accepted.component.html',
})
export class InvitationAcceptedComponent extends BaseComponent implements OnInit {
constructor(
private planService: PlanService,
private route: ActivatedRoute,
private router: Router,
private authentication: AuthService,
protected routerUtils: RouterUtilsService,
private httpErrorHandlingService: HttpErrorHandlingService
) { super(); }
ngOnInit(): void {
this.route.params
.pipe(takeUntil(this._destroyed))
.subscribe(params => {
const token = params['token'];
if(this.isAuthenticated()){
this.planService.acceptInvitation(token)
.pipe(takeUntil(this._destroyed))
.subscribe(result => {
this.router.navigate([this.routerUtils.generateUrl('plans/edit/' + result)]);
},
error => this.onCallbackError(error));
}else{
let returnUrl = `plans/invitation/${token}`;
this.router.navigate([this.routerUtils.generateUrl('login')], {queryParams:{returnUrl: this.routerUtils.generateUrl(returnUrl)}});
}
});
}
public isAuthenticated(): boolean {
return this.authentication.currentAccountIsAuthenticated();
}
onCallbackError(errorResponse: HttpErrorResponse) {
this.httpErrorHandlingService.handleBackedRequestError(errorResponse, null, SnackBarNotificationLevel.Error)
const error: HttpError = this.httpErrorHandlingService.getError(errorResponse);
if (error.statusCode === 302) {
this.router.navigate([this.routerUtils.generateUrl('home')]);
}
this.router.navigate([this.routerUtils.generateUrl('home')]);
}
}

View File

@ -3,6 +3,7 @@ import { FormattingModule } from '@app/core/formatting.module';
import { PlanRoutingModule, PublicPlanRoutingModule } from '@app/ui/plan/plan.routing';
import { CommonFormsModule } from '@common/forms/common-forms.module';
import { CommonUiModule } from '@common/ui/common-ui.module';
import { InvitationAcceptedComponent } from './invitation/accepted/plan-invitation-accepted.component';
@NgModule({
imports: [
@ -12,6 +13,7 @@ import { CommonUiModule } from '@common/ui/common-ui.module';
PlanRoutingModule,
],
declarations: [
InvitationAcceptedComponent
],
exports: [
]

View File

@ -2,6 +2,7 @@ import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { BreadcrumbService } from '../misc/breadcrumb/breadcrumb.service';
import { AuthGuard } from '@app/core/auth-guard.service';
import { InvitationAcceptedComponent } from './invitation/accepted/plan-invitation-accepted.component';
const routes: Routes = [
{
@ -47,6 +48,7 @@ const routes: Routes = [
breadcrumb: true
},
},
{ path: 'invitation/:token', component: InvitationAcceptedComponent },
];
const publicRoutes: Routes = [

View File

@ -95,7 +95,10 @@
"PLAN-BLUEPRINT-IMPORT-DRAFT": "Plan Blueprint with code '{{planBlueprintCode}}' is not finalized yet.",
"MISSING-TENANT-ROLE": "Υou must also select a tenant role",
"MISSING-GLOBAL-ROLE": "Υou must also select a global role",
"CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated"
"CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated",
"PLAN-INVITATION-ALREADY-CONFIRMED": "Plan invitation has alreay confirmed",
"ANOTHER-USER-TOKEN": "This token is for another user",
"TOKEN-NOT-EXIST": "This token does not exist"
},
"FORM-VALIDATION-DISPLAY-DIALOG": {
"WARNING": "Warnung!",

View File

@ -95,7 +95,10 @@
"PLAN-BLUEPRINT-IMPORT-DRAFT": "Plan Blueprint with code '{{planBlueprintCode}}' is not finalized yet.",
"MISSING-TENANT-ROLE": "Υou must also select a tenant role",
"MISSING-GLOBAL-ROLE": "Υou must also select a global role",
"CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated"
"CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated",
"PLAN-INVITATION-ALREADY-CONFIRMED": "Plan invitation has alreay confirmed",
"ANOTHER-USER-TOKEN": "This token is for another user",
"TOKEN-NOT-EXIST": "This token does not exist"
},
"FORM-VALIDATION-DISPLAY-DIALOG": {
"WARNING": "Warning!",

View File

@ -95,7 +95,10 @@
"PLAN-BLUEPRINT-IMPORT-DRAFT": "Plan Blueprint with code '{{planBlueprintCode}}' is not finalized yet.",
"MISSING-TENANT-ROLE": "Υou must also select a tenant role",
"MISSING-GLOBAL-ROLE": "Υou must also select a global role",
"CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated"
"CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated",
"PLAN-INVITATION-ALREADY-CONFIRMED": "Plan invitation has alreay confirmed",
"ANOTHER-USER-TOKEN": "This token is for another user",
"TOKEN-NOT-EXIST": "This token does not exist"
},
"FORM-VALIDATION-DISPLAY-DIALOG": {
"WARNING": "Atención!",

View File

@ -95,7 +95,10 @@
"PLAN-BLUEPRINT-IMPORT-DRAFT": "Plan Blueprint with code '{{planBlueprintCode}}' is not finalized yet.",
"MISSING-TENANT-ROLE": "Υou must also select a tenant role",
"MISSING-GLOBAL-ROLE": "Υou must also select a global role",
"CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated"
"CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated",
"PLAN-INVITATION-ALREADY-CONFIRMED": "Plan invitation has alreay confirmed",
"ANOTHER-USER-TOKEN": "This token is for another user",
"TOKEN-NOT-EXIST": "This token does not exist"
},
"FORM-VALIDATION-DISPLAY-DIALOG": {
"WARNING": "Προσοχή!",

View File

@ -95,7 +95,10 @@
"PLAN-BLUEPRINT-IMPORT-DRAFT": "Plan Blueprint with code '{{planBlueprintCode}}' is not finalized yet.",
"MISSING-TENANT-ROLE": "Υou must also select a tenant role",
"MISSING-GLOBAL-ROLE": "Υou must also select a global role",
"CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated"
"CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated",
"PLAN-INVITATION-ALREADY-CONFIRMED": "Plan invitation has alreay confirmed",
"ANOTHER-USER-TOKEN": "This token is for another user",
"TOKEN-NOT-EXIST": "This token does not exist"
},
"FORM-VALIDATION-DISPLAY-DIALOG": {
"WARNING": "Oprez!",

View File

@ -95,7 +95,10 @@
"PLAN-BLUEPRINT-IMPORT-DRAFT": "Plan Blueprint with code '{{planBlueprintCode}}' is not finalized yet.",
"MISSING-TENANT-ROLE": "Υou must also select a tenant role",
"MISSING-GLOBAL-ROLE": "Υou must also select a global role",
"CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated"
"CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated",
"PLAN-INVITATION-ALREADY-CONFIRMED": "Plan invitation has alreay confirmed",
"ANOTHER-USER-TOKEN": "This token is for another user",
"TOKEN-NOT-EXIST": "This token does not exist"
},
"FORM-VALIDATION-DISPLAY-DIALOG": {
"WARNING": "Ostrzeżenie!",

View File

@ -95,7 +95,10 @@
"PLAN-BLUEPRINT-IMPORT-DRAFT": "Plan Blueprint with code '{{planBlueprintCode}}' is not finalized yet.",
"MISSING-TENANT-ROLE": "Υou must also select a tenant role",
"MISSING-GLOBAL-ROLE": "Υou must also select a global role",
"CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated"
"CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated",
"PLAN-INVITATION-ALREADY-CONFIRMED": "Plan invitation has alreay confirmed",
"ANOTHER-USER-TOKEN": "This token is for another user",
"TOKEN-NOT-EXIST": "This token does not exist"
},
"FORM-VALIDATION-DISPLAY-DIALOG": {
"WARNING": "Atenção!",

View File

@ -95,7 +95,10 @@
"PLAN-BLUEPRINT-IMPORT-DRAFT": "Plan Blueprint with code '{{planBlueprintCode}}' is not finalized yet.",
"MISSING-TENANT-ROLE": "Υou must also select a tenant role",
"MISSING-GLOBAL-ROLE": "Υou must also select a global role",
"CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated"
"CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated",
"PLAN-INVITATION-ALREADY-CONFIRMED": "Plan invitation has alreay confirmed",
"ANOTHER-USER-TOKEN": "This token is for another user",
"TOKEN-NOT-EXIST": "This token does not exist"
},
"FORM-VALIDATION-DISPLAY-DIALOG": {
"WARNING": "Upozornenie!",

View File

@ -95,7 +95,10 @@
"PLAN-BLUEPRINT-IMPORT-DRAFT": "Plan Blueprint with code '{{planBlueprintCode}}' is not finalized yet.",
"MISSING-TENANT-ROLE": "Υou must also select a tenant role",
"MISSING-GLOBAL-ROLE": "Υou must also select a global role",
"CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated"
"CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated",
"PLAN-INVITATION-ALREADY-CONFIRMED": "Plan invitation has alreay confirmed",
"ANOTHER-USER-TOKEN": "This token is for another user",
"TOKEN-NOT-EXIST": "This token does not exist"
},
"FORM-VALIDATION-DISPLAY-DIALOG": {
"WARNING": "Oprez!",

View File

@ -95,7 +95,10 @@
"PLAN-BLUEPRINT-IMPORT-DRAFT": "Plan Blueprint with code '{{planBlueprintCode}}' is not finalized yet.",
"MISSING-TENANT-ROLE": "Υou must also select a tenant role",
"MISSING-GLOBAL-ROLE": "Υou must also select a global role",
"CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated"
"CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated",
"PLAN-INVITATION-ALREADY-CONFIRMED": "Plan invitation has alreay confirmed",
"ANOTHER-USER-TOKEN": "This token is for another user",
"TOKEN-NOT-EXIST": "This token does not exist"
},
"FORM-VALIDATION-DISPLAY-DIALOG": {
"WARNING": "Uyarı!",