Skip to content

Commit a81e645

Browse files
authored
add c transaction code (#53)
* add c transaction code * delete package-lock.json * update build gradle * add validation of the credential status * update tests * add logs * add logs * add logs * add switchIfEmpty for getProcedureIdByTransactionCode * fix cache problem * solve merge conflicts
1 parent 2f2a41e commit a81e645

21 files changed

+312
-62
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [v1.2.1](https://github.com/in2workspace/in2-issuer-api/releases/tag/v1.1.4)
8+
### Added
9+
- Add support for requesting a fresh QR code if the previous one has expired or was an error during the proccess of
10+
711
## [v1.2.0](https://github.com/in2workspace/in2-issuer-api/releases/tag/v1.2.0)
812
### Added
913
- Validation of authentication for issuance against the verifier.

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ plugins {
1111
}
1212

1313
group = 'es.in2'
14-
version = '1.2.0'
14+
version = '1.2.1'
1515

1616
java {
1717
sourceCompatibility = '17'

package-lock.json

Lines changed: 0 additions & 6 deletions
This file was deleted.
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package es.in2.issuer.application.workflow;
22

3+
import es.in2.issuer.domain.model.dto.CredentialOfferUriResponse;
34
import es.in2.issuer.domain.model.dto.CustomCredentialOffer;
45
import reactor.core.publisher.Mono;
56

67
public interface CredentialOfferIssuanceWorkflow {
7-
Mono<String> buildCredentialOfferUri(String processId, String transactionCode);
8+
Mono<CredentialOfferUriResponse> buildCredentialOfferUri(String processId, String transactionCode);
9+
Mono<CredentialOfferUriResponse> buildNewCredentialOfferUri(String processId, String cTransactionCode);
810
Mono<CustomCredentialOffer> getCustomCredentialOffer(String nonce);
911
}

src/main/java/es/in2/issuer/application/workflow/impl/CredentialOfferIssuanceWorkflowImpl.java

Lines changed: 70 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import es.in2.issuer.application.workflow.CredentialOfferIssuanceWorkflow;
55
import es.in2.issuer.domain.exception.ParseErrorException;
66
import es.in2.issuer.domain.exception.PreAuthorizationCodeGetException;
7+
import es.in2.issuer.domain.model.dto.CredentialOfferUriResponse;
78
import es.in2.issuer.domain.model.dto.CustomCredentialOffer;
89
import es.in2.issuer.domain.model.dto.PreAuthCodeResponse;
910
import es.in2.issuer.domain.service.*;
@@ -34,22 +35,60 @@ public class CredentialOfferIssuanceWorkflowImpl implements CredentialOfferIssua
3435
private final IssuerApiClientTokenService issuerApiClientTokenService;
3536

3637
@Override
37-
public Mono<String> buildCredentialOfferUri(String processId, String transactionCode) {
38+
public Mono<CredentialOfferUriResponse> buildCredentialOfferUri(String processId, String transactionCode) {
3839
return deferredCredentialMetadataService.validateTransactionCode(transactionCode)
39-
.then(deferredCredentialMetadataService.getProcedureIdByTransactionCode(transactionCode))
40-
.flatMap(procedureId -> credentialProcedureService.getCredentialTypeByProcedureId(procedureId)
41-
.flatMap(credentialType -> getPreAuthorizationCodeFromIam()
42-
.flatMap(preAuthCodeResponse ->
43-
deferredCredentialMetadataService.updateAuthServerNonceByTransactionCode(transactionCode, preAuthCodeResponse.grant().preAuthorizedCode())
44-
.then(credentialProcedureService.getMandateeEmailFromDecodedCredentialByProcedureId(procedureId))
45-
.flatMap(email -> credentialOfferService.buildCustomCredentialOffer(credentialType, preAuthCodeResponse.grant(),email,preAuthCodeResponse.pin())
46-
.flatMap(credentialOfferCacheStorageService::saveCustomCredentialOffer)
47-
.flatMap(credentialOfferService::createCredentialOfferUri))
40+
.then(Mono.just(transactionCode))
41+
.flatMap(this::buildCredentialOfferUriInternal);
42+
}
43+
44+
@Override
45+
public Mono<CredentialOfferUriResponse> buildNewCredentialOfferUri(String processId, String cTransactionCode) {
46+
return deferredCredentialMetadataService.validateCTransactionCode(cTransactionCode)
47+
.flatMap(this::buildCredentialOfferUriInternal);
48+
}
49+
50+
// Add logs to debug the process
51+
private Mono<CredentialOfferUriResponse> buildCredentialOfferUriInternal(String transactionCode) {
52+
return deferredCredentialMetadataService.getProcedureIdByTransactionCode(transactionCode)
53+
.flatMap(procedureId ->
54+
credentialProcedureService.getCredentialTypeByProcedureId(procedureId)
55+
.flatMap(credentialType ->
56+
getPreAuthorizationCodeFromIam()
57+
.flatMap(preAuthCodeResponse ->
58+
deferredCredentialMetadataService.updateAuthServerNonceByTransactionCode(
59+
transactionCode,
60+
preAuthCodeResponse.grant().preAuthorizedCode()
61+
)
62+
.then(
63+
credentialProcedureService.getMandateeEmailFromDecodedCredentialByProcedureId(procedureId)
64+
)
65+
.flatMap(email ->
66+
credentialOfferService.buildCustomCredentialOffer(
67+
credentialType,
68+
preAuthCodeResponse.grant(),
69+
email,
70+
preAuthCodeResponse.pin()
71+
)
72+
.flatMap(credentialOfferCacheStorageService::saveCustomCredentialOffer)
73+
.flatMap(credentialOfferService::createCredentialOfferUriResponse)
74+
)
75+
)
76+
.flatMap(credentialOfferUri ->
77+
deferredCredentialMetadataService.updateCacheStoreForCTransactionCode(transactionCode)
78+
.flatMap(cTransactionCode ->
79+
Mono.just(
80+
CredentialOfferUriResponse.builder()
81+
.credentialOfferUri(credentialOfferUri)
82+
.cTransactionCode(cTransactionCode)
83+
.build()
84+
)
85+
)
4886
)
4987
)
5088
);
5189
}
5290

91+
5392
@Override
5493
public Mono<CustomCredentialOffer> getCustomCredentialOffer(String nonce) {
5594
return credentialOfferCacheStorageService.getCustomCredentialOffer(nonce)
@@ -66,27 +105,27 @@ private Mono<PreAuthCodeResponse> getPreAuthorizationCodeFromIam() {
66105
return issuerApiClientTokenService.getClientToken()
67106
.flatMap(
68107
token ->
69-
webClient.commonWebClient()
70-
.get()
71-
.uri(url)
72-
.accept(MediaType.APPLICATION_JSON)
73-
.header(HttpHeaders.AUTHORIZATION, BEARER_PREFIX + token)
74-
.exchangeToMono(response -> {
75-
if (response.statusCode().is4xxClientError() || response.statusCode().is5xxServerError()) {
76-
return Mono.error(new PreAuthorizationCodeGetException("There was an error during pre-authorization code retrieval, error: " + response));
77-
} else {
78-
log.info("Pre Authorization code response: {}", response);
79-
return response.bodyToMono(String.class);
80-
}
81-
})
82-
// Parsing response
83-
.flatMap(response -> {
84-
try {
85-
return Mono.just(objectMapper.readValue(response, PreAuthCodeResponse.class));
86-
} catch (com.fasterxml.jackson.core.JsonProcessingException e) {
87-
return Mono.error(new ParseErrorException("Error parsing JSON response"));
88-
}
89-
})
108+
webClient.commonWebClient()
109+
.get()
110+
.uri(url)
111+
.accept(MediaType.APPLICATION_JSON)
112+
.header(HttpHeaders.AUTHORIZATION, BEARER_PREFIX + token)
113+
.exchangeToMono(response -> {
114+
if (response.statusCode().is4xxClientError() || response.statusCode().is5xxServerError()) {
115+
return Mono.error(new PreAuthorizationCodeGetException("There was an error during pre-authorization code retrieval, error: " + response));
116+
} else {
117+
log.info("Pre Authorization code response: {}", response);
118+
return response.bodyToMono(String.class);
119+
}
120+
})
121+
// Parsing response
122+
.flatMap(response -> {
123+
try {
124+
return Mono.just(objectMapper.readValue(response, PreAuthCodeResponse.class));
125+
} catch (com.fasterxml.jackson.core.JsonProcessingException e) {
126+
return Mono.error(new ParseErrorException("Error parsing JSON response"));
127+
}
128+
})
90129
);
91130
}
92131

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package es.in2.issuer.domain.exception;
2+
3+
public class CredentialAlreadyIssuedException extends RuntimeException {
4+
public CredentialAlreadyIssuedException(String message) {
5+
super(message);
6+
}
7+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package es.in2.issuer.domain.model.dto;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import lombok.Builder;
5+
6+
@Builder
7+
public record CredentialOfferUriResponse(
8+
@JsonProperty("credential_offer_uri")
9+
String credentialOfferUri,
10+
@JsonProperty("c_transaction_code")
11+
String cTransactionCode
12+
) {
13+
}

src/main/java/es/in2/issuer/domain/service/CredentialOfferService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66

77
public interface CredentialOfferService {
88
Mono<CredentialOfferData> buildCustomCredentialOffer(String credentialType, Grant grant, String employeeEmail, String pin);
9-
Mono<String> createCredentialOfferUri(String nonce);
9+
Mono<String> createCredentialOfferUriResponse(String nonce);
1010
}

src/main/java/es/in2/issuer/domain/service/DeferredCredentialMetadataService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
public interface DeferredCredentialMetadataService {
77
Mono<String> createDeferredCredentialMetadata(String procedureId, String operationMode, String responseUri);
8+
Mono<String> updateCacheStoreForCTransactionCode(String transactionCode);
9+
Mono<String> validateCTransactionCode(String cTransactionCode);
810
Mono<String> updateTransactionCodeInDeferredCredentialMetadata(String procedureId);
911
Mono<String> getProcedureIdByTransactionCode(String transactionCode);
1012
Mono<String> getProcedureIdByAuthServerNonce(String authServerNonce);

src/main/java/es/in2/issuer/domain/service/impl/CredentialOfferCacheStorageServiceImpl.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,15 @@ public Mono<String> saveCustomCredentialOffer(CredentialOfferData credentialOffe
2626
@Override
2727
public Mono<CredentialOfferData> getCustomCredentialOffer(String nonce) {
2828
return cacheStore.get(nonce)
29-
.doOnSuccess(customCredentialOffer -> {
30-
if (customCredentialOffer != null) {
31-
log.debug("CustomCredentialOffer found for nonce: {}", nonce);
32-
cacheStore.delete(nonce);
33-
}
34-
})
35-
.switchIfEmpty(Mono.error(new CustomCredentialOfferNotFoundException("CustomCredentialOffer not found for nonce: " + nonce)));
29+
.switchIfEmpty(Mono.error(
30+
new CustomCredentialOfferNotFoundException(
31+
"CustomCredentialOffer not found for nonce: " + nonce))
32+
)
33+
.doOnNext(customCredentialOffer ->
34+
log.debug("CustomCredentialOffer found for nonce: {}", nonce)
35+
)
36+
.flatMap(customCredentialOffer ->
37+
cacheStore.delete(nonce).thenReturn(customCredentialOffer)
38+
);
3639
}
37-
3840
}

0 commit comments

Comments
 (0)