Skip to content

Commit

Permalink
feat: #72 implement accept-terms endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
emilianapali committed Jul 31, 2024
1 parent caf6116 commit 6087e1e
Show file tree
Hide file tree
Showing 15 changed files with 394 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@
package io.github.genomicdatainfrastructure.daam.api;

import io.github.genomicdatainfrastructure.daam.model.*;
import io.github.genomicdatainfrastructure.daam.services.AttachFileToApplicationService;
import io.github.genomicdatainfrastructure.daam.services.CreateApplicationService;
import io.github.genomicdatainfrastructure.daam.services.SaveApplicationService;
import io.github.genomicdatainfrastructure.daam.services.SubmitApplicationService;
import io.github.genomicdatainfrastructure.daam.services.*;
import io.quarkus.oidc.runtime.OidcJwtCallerPrincipal;
import io.quarkus.security.identity.SecurityIdentity;
import jakarta.ws.rs.core.Response;
Expand All @@ -25,13 +22,7 @@ public class ApplicationCommandApiImpl implements ApplicationCommandApi {
private final CreateApplicationService createApplicationService;
private final SubmitApplicationService submitApplicationService;
private final AttachFileToApplicationService attachFileToApplicationService;

@Override
public Response acceptApplicationTermsV1(Long id) {
throw new UnsupportedOperationException(
"Unimplemented method 'acceptApplicationTermsV1'"
);
}
private final AcceptTermsService acceptTermsService;

@Override
public Response addEventToApplicationV1(Long id, AddApplicationEvent addApplicationEvent) {
Expand Down Expand Up @@ -114,4 +105,17 @@ private String userId() {
var principal = (OidcJwtCallerPrincipal) identity.getPrincipal();
return principal.getClaim(USER_ID_CLAIM);
}

@Override
public Response acceptApplicationTermsV1(Long id, AcceptLicensesCommand acceptLicensesCommand) {
String userId = userId();

io.github.genomicdatainfrastructure.daam.remote.rems.model.AcceptLicensesCommand remoteAcceptLicensesCommand = new io.github.genomicdatainfrastructure.daam.remote.rems.model.AcceptLicensesCommand();
remoteAcceptLicensesCommand.setApplicationId(acceptLicensesCommand.getApplicationId());
remoteAcceptLicensesCommand.setAcceptedLicenses(acceptLicensesCommand
.getAcceptedLicenses());

acceptTermsService.acceptTerms(id, userId, remoteAcceptLicensesCommand);
return Response.noContent().build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.Optional;
import java.util.Comparator;
import java.util.Objects;
import java.util.stream.Collectors;

@ApplicationScoped
public class RemsApplicationMapper {
Expand Down Expand Up @@ -282,15 +283,17 @@ private List<RetrievedApplicationLicense> toLicences(Application application) {
private RetrievedApplicationLicense toLicense(V2License license) {
var potentialLicense = ofNullable(license);

return new RetrievedApplicationLicense(
potentialLicense.map(this::toLicenseType)
.orElse(null),
potentialLicense.map(l -> toLabelObject(l.getLicenseTitle()))
.orElse(null),
potentialLicense.map(V2License::getLicenseEnabled)
.orElse(null),
potentialLicense.map(V2License::getLicenseArchived)
.orElse(null));
return RetrievedApplicationLicense.builder()
.type(potentialLicense.map(this::toLicenseType).orElse(null))
.title(potentialLicense.map(l -> toLabelObject(l.getLicenseTitle())).orElse(null))
.enabled(potentialLicense.map(V2License::getLicenseEnabled).orElse(null))
.archived(potentialLicense.map(V2License::getLicenseArchived).orElse(null))
.description(potentialLicense.map(l -> convertMapToString(l
.getLicenseDescription())).orElse(null))
.url(potentialLicense.map(V2License::getLicenseUrl).orElse(null))
.version(potentialLicense.map(V2License::getLicenseVersion).orElse(null))
.terms(potentialLicense.map(V2License::getLicenseTerms).orElse(null))
.build();
}

private String toLicenseType(V2License license) {
Expand Down Expand Up @@ -319,4 +322,14 @@ private List<Label> toLabelObject(Map<String, String> map) {
.map(entry -> new Label(entry.getKey(), entry.getValue()))
.toList();
}

private String convertMapToString(Map<String, String> map) {
if (map == null) {
return null;
}
return map.entrySet()
.stream()
.map(entry -> entry.getKey() + "=" + entry.getValue())
.collect(Collectors.joining(", "));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// SPDX-FileCopyrightText: 2024 PNED G.I.E.
//
// SPDX-License-Identifier: Apache-2.0

package io.github.genomicdatainfrastructure.daam.services;

import io.github.genomicdatainfrastructure.daam.exceptions.ApplicationNotInCorrectStateException;
import io.github.genomicdatainfrastructure.daam.exceptions.UserNotApplicantException;
import io.github.genomicdatainfrastructure.daam.exceptions.ApplicationNotFoundException;
import io.github.genomicdatainfrastructure.daam.gateways.RemsApiQueryGateway;
import io.github.genomicdatainfrastructure.daam.remote.rems.api.RemsApplicationCommandApi;
import io.github.genomicdatainfrastructure.daam.remote.rems.model.AcceptLicensesCommand;
import io.github.genomicdatainfrastructure.daam.remote.rems.model.Application;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.Response.Status;

@ApplicationScoped
public class AcceptTermsService {

private final String remsApiKey;
private final RemsApplicationCommandApi remsApplicationCommandApi;
private final RemsApiQueryGateway remsApiQueryGateway;

@Inject
public AcceptTermsService(
@ConfigProperty(name = "quarkus.rest-client.rems_yaml.api-key") String remsApiKey,
@RestClient RemsApplicationCommandApi remsApplicationCommandApi,
RemsApiQueryGateway remsApiQueryGateway
) {
this.remsApiKey = remsApiKey;
this.remsApplicationCommandApi = remsApplicationCommandApi;
this.remsApiQueryGateway = remsApiQueryGateway;
}

public void acceptTerms(Long id, String userId, AcceptLicensesCommand acceptLicensesCommand) {
Application application = remsApiQueryGateway.retrieveApplication(id, userId);
if (!application.getApplicationApplicant().getUserid().equals(userId)) {
throw new UserNotApplicantException(id, userId);
}

try {
remsApplicationCommandApi.apiApplicationsAcceptLicensesPost(remsApiKey, userId,
acceptLicensesCommand);
} catch (WebApplicationException e) {
if (e.getResponse().getStatus() == Status.NOT_FOUND.getStatusCode()) {
throw new ApplicationNotFoundException(id);
}
if (e.getResponse().getStatus() == Status.FORBIDDEN.getStatusCode()) {
throw new UserNotApplicantException(id, userId);
}
if (e.getResponse().getStatus() == Status.PRECONDITION_REQUIRED.getStatusCode()) {
throw new ApplicationNotInCorrectStateException(id,
"Application not in submittable state");
}
throw e;
}
}
}
59 changes: 59 additions & 0 deletions src/main/openapi/daam.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -268,9 +268,41 @@ paths:
schema:
type: integer
format: int64
requestBody:
description: Accept terms data
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/AcceptLicensesCommand"
responses:
"204":
description: Successful Response (no content)
"400":
description: Bad Request
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"404":
description: Application not found
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"403":
description: Application does not belong to applicant
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"428":
description: Application not in submittable state
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"

security:
- daam_auth:
- write:applications
Expand Down Expand Up @@ -896,6 +928,19 @@ components:
archived:
type: boolean
title: License archived
description:
type: string
title: License description
url:
type: string
format: uri
title: License URL
version:
type: string
title: License version
terms:
type: string
title: License terms
ListedBasket:
properties:
id:
Expand Down Expand Up @@ -1021,3 +1066,17 @@ components:
format: date-time
required:
- entitlements
AcceptLicensesCommand:
type: object
required:
- application-id
- accepted-licenses
properties:
application-id:
type: integer
format: int64
accepted-licenses:
type: array
items:
type: integer
format: int64
68 changes: 64 additions & 4 deletions src/main/openapi/rems.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,38 @@ paths:
type: array
items:
$ref: "#/components/schemas/Entitlement"
/api/applications/accept-licenses:
post:
tags:
- rems-application-command
summary: "Submit an 'accept-licenses' command for an application. (roles: logged-in)"
parameters:
- name: x-rems-api-key
required: true
in: header
description: REMS API-Key (optional for UI, required for API)
schema:
type: string
- name: x-rems-user-id
required: true
in: header
description: user (optional for UI, required for API). This can be a REMS internal or an external user identity attribute (specified in config.edn).
schema:
type: string
requestBody:
description: Accept licenses data
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/AcceptLicensesCommand"
responses:
"200":
description: Accept Licenses successful
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
components:
schemas:
CatalogueItem:
Expand Down Expand Up @@ -1077,6 +1109,9 @@ components:
- license/id
- license/enabled
- license/archived
- license/description
- license/version
- license/terms
properties:
license/type:
type: string
Expand All @@ -1093,6 +1128,18 @@ components:
type: boolean
license/archived:
type: boolean
license/description:
$ref: "#/components/schemas/LocalizedString"
license/url:
type: string
format: uri
description: URL to the license document
license/version:
type: string
description: Version of the license
license/terms:
type: string
description: Terms and conditions of the license
Form:
required:
- form/id
Expand Down Expand Up @@ -1203,7 +1250,7 @@ components:
$ref: "#/components/schemas/CreateApplicationError"
warnings:
type: array
items: { }
items: {}
application-id:
type: integer
format: int64
Expand Down Expand Up @@ -1264,18 +1311,17 @@ components:
error:
type: string
title: error description

AttachFileResponse:
type: object
properties:
success:
type: boolean
errors:
type: array
items: { }
items: {}
warnings:
type: array
items: { }
items: {}
id:
type: integer
format: int64
Expand Down Expand Up @@ -1407,3 +1453,17 @@ components:
properties:
organization/id:
type: string
AcceptLicensesCommand:
type: object
required:
- application-id
- accepted-licenses
properties:
application-id:
type: integer
format: int64
accepted-licenses:
type: array
items:
type: integer
format: int64
Loading

0 comments on commit 6087e1e

Please sign in to comment.