Skip to content

Latest commit

 

History

History
644 lines (475 loc) · 96 KB

README.md

File metadata and controls

644 lines (475 loc) · 96 KB

eng-lollipop-consumer-java-sdk

This repository contains the code that composes the eng-lollipop-consumer-java-sdk, containing the features to enable a LolliPoP validation inside a Consumer project using the JVM environment. It contains:

  • a main core module that defines the base structure for the validation process using the library
  • several default implementations for the underlying integrations/functionalities
  • samples using the sdk and the default implementations

Modules

The repository contains the following Gradle modules, to be used within other projects:

Module Artifact ID Module Name Description
core Core Module Core Library, containing the base services for LolliPop validation, and all references to the interfaces to be used.
http-verifier Http Verifier Module Implementation of the core HttpMessageVerifier for the http-signature using eng-http-signatures.
identity-service-rest-client-native Simple IdP Rest Client Module Implementation of IdpCertClientProvider, defining a Rest client for IDP data recovery using JDK 11 standard functionalities of Identity Services OpenAPI specs
assertion-rest-client-native Simple Assertion Rest Client Module Implementation of AssertionClientProvider, defining a Rest client for Assertions recovery using JDK 11 standard functionalities of Assertion OpenAPI specs
redis-storage Redis Storage Module Contains implementation of the storage interfaces using Redis Cache.
spring-impl Spring Implementation Module Contains an implementation of a Spring Interceptor using the core modules validation commands, and provides a defined configuration for the core classes using Spring @Configuration and @ConfigurationProperties
servlet-impl Servlet Implementation Module Contains an implementation of a servlet filter using the core modules validation commands

Samples

Sample Name Description
Simple Simple Application running default configurations and mocked services to test executing instances of LollipopConsumerCommand for validation
Simple with Typesafe Simple Application running default configurations and mocked services to test executing instances of LollipopConsumerCommand for validation, configured with custom properties using LollipopTypesafeConfig utility class
Spring with Interceptor Spring Boot Application sample defining Spring configurations of the standard modules through application.properties, using the spring-impl interceptor to validate request on the provided controller endpoint. Used in the Dockerfile in order to create an usable image
Simple with Servlet Simple Application sample running default configurations and mocked services, using the servlet filter to validate request on the provided servlet exposed through embedded Tomcat server

Use the SDK as dependency

The gradle modules contained in the repository (except the sources contained in the sample directory) will be available on GitHub Packages. In order to include a dependency, use the Maven dependency

<dependency>
    <groupId>it.pagopa.tech.lollipop-consumer-java-sdk</groupId>
    <artifactId>MODULE_NAME</artifactId>
    <version>RELEASE_VERSION</version>
</dependency>

Or, in Gradle:

implementation 'it.pagopa.tech.lollipop-consumer-java-sdk:MODULE_NAME:RELEASE_VERSION'

Where MODULE_NAME is one of the modules to be used for the SDK (Described in the paragraph above), and RELEASE_VERSION is the version available on GitHub Packages (or the version installed locally).

Local Installation

Prerequisites

In order to work with the eng-lollipop-consumer-java-sdk locally the following are required to be installed:

  • JDK 11
  • Gradle 7.4+

Maven Dependencies

In order to use maven it is required to have it installed locally, suggested to have it at least on version 3.8.5+.

Github Packages Dependencies

This library uses some dependencies available through GitHub Packages. It is required to have the following information, in order to obtain them:

  • gpr.user project property, or the GITHUB_ACTOR environment variable, containing the GitHub handle to be used for package recovery
  • gpr.key project property, or the GITHUB_TOKEN environment variable, containing the GitHub token to be used for package recovery. The token must contain the permissions to retrieve GitHub Packages. See the Official Guidelines

Build Locally

In order to build the library source locally it is suggested to run the .\gradlew build --refresh-dependecies. Ensure that the properties regarding GitHub credentials have been defined beforehand.

Metadata Verification

This repository uses the Gradle verification process on dependency checksums, using the file provided under gradle\verification-metadata.xml. Whenever the dependency check does exit with a failure locally, it might be necessary to update the file. Gradle does provide the command .\gradlew --write-verification-metadata [algorithm] help where the algorithm could be sha256, or whenever it is not available for a particular dependency sha1. An already known problem with the verification process and file update may not intercept all internal dependencies, obtaining a different result from the automated checks within the GitHub workflow. Whenever an update is required, and the provided cli command does not automatically update the file, it is required to introduce the checksum values manually. See the official Gradle Docs for troubleshooting of the metadata verification.

Publish to Maven local repository

In order to publish the modules on the local maven repository the command to be used is .\gradlew publishToMavenLocal

Native Build

In order to compile the modules contained in this repository in a native form, the graalvm plugin is applied. In order to execute a native build it is required that an instance of the GraalVM JDK is installed and configured.

In order to compile natively execute this command:

.\gradlew nativeCompile

The result will be found under the module build/native directory.

Note that currently a native version of the SDK is not automatically published on the GitHub Package.

Utilization

Configurations

The core module contains defined parameters to configure the provided services. Within each of the configuration classes provided in this module, that are not directly related to an implementation of a specific library or framework does not contain any functionality for property loading. The choice of the preferred method to apply the configuration properties is defined by the library user. The configuration classes are defined as follows:

This configuration class contains the standard configuration properties for the SDK core functionalities:

Property Description Default
strictDigestVerify Flag to define if the digest validation is applied in strict-mode. when false if the content-digest header isn't present in the signature-input parameters to validate, it won't be checked false
signatureHeader Header expected to contain the signatures to be validated signature
signatureInputHeader Header expected to contain the signature-input to be used in signature validation signature-input
contentEncodingHeader Header expected to contain the content encoding to be used when the request body is present. content-encoding
contentDigestHeader Header expected to contain the content digest to be validated content-digest
originalMethodHeader Header expected to contain the original method calling the API x-pagopa-lollipop-original-method
originalURLHeader Header expected to contain the original url calling the API x-pagopa-lollipop-original-url
assertionRefHeader Header expected to contain the assertion-ref to be used in order to retrieve the SAML Assertion to validate x-pagopa-lollipop-assertion-ref
assertionTypeHeader Header expected to contain the assertion type x-pagopa-lollipop-assertion-type
userIdHeader Header expected to contain the user-id to be used in SAML validation x-pagopa-lollipop-user-id
publicKeyHeader Header expected to contain the LolliPop public key to be used for the validation process x-pagopa-lollipop-public-key
authJWTHeader Header expected to contain the JWT to be used in SAML Assertion retrieval x-pagopa-lollipop-auth-jwt
expectedFirstLcOriginalMethod The expected value within the originalMethodHeader, used in formal validation of the request to be processed POST
expectedFirsxtLcOriginalUrl The expected value within the originalURLHeader, used in formal validation of the request to be processed https://api-app.io.pagopa.it/first-lollipop/sign
assertionExpireInDays Number of days to be consider when checking if the difference between the current date and the NotBefore value in the SAML Assertion 30
assertionNotBeforeDateFormat Date format to be used for parsing the NotBeforeDate in the SAML Assertion yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
assertionInstantDateFormat Date format to be used for parsing the InstantDate in the SAML Assertion yyy-MM-dd'T'HH:mm:ss.SSS'Z'
samlNamespaceAssertion SAML Namespace of the Assertion urn:oasis:names:tc:SAML:2.0:assertion
assertionNotBeforeTag Tag containing the NotBefore value in the SAML Assertion Conditions
assertionFiscalCodeTag Tag containing the FiscalCode value in the SAML Assertion Attribute
assertionInResponseToTag Tag containing the InResponseTo value in the SAML Assertion SubjectConfirmationData
assertionEntityIdTag Tag containing the EntityId value in the SAML Assertion Issuer
assertionInstantTag Tag containing the Instant value in the SAML Assertion Assertion
enableConsumerLogging Flag enabling the logging of the request validation, using the implementation of the provided interface true
enableAssertionLogging Flag enabling the logging the retrieved SAML Assertion for audit purposes, using the implementation of the provided interface true
enableIdpCertDataLogging Flag enabling the logging the retrieved IdP certificates for audit purposes, using the implementation of the provided interface true

This configuration contains the standard properties regarding the storage interface for the SAML Assertion data:

Property Description Default
assertionStorageEnabled Flag to determine if the implementation of the storage interface regarding the SAML Assertion will be used for retrieval/storage true
storageEvictionDelay Eviction delay value 1
storageEvictionDelayTimeUnit Time unit to be used when defining the delay regarding the eviction MINUTES
maxNumberOfElements Maximum number of Assertion allows to be stored 100

This configuration contains the standard properties regarding the storage interface for the IdP certificates:

Property Description Default
idpCertDataStorageEnabled Flag to determine if the implementation of the storage interface regarding the IdP Certificates will be used for retrieval/storage true
storageEvictionDelay Eviction delay value 1
storageEvictionDelayTimeUnit Time unit to be used when defining the delay regarding the eviction MINUTES

Other Configs

Inside the modules with the default implementations of the core interfaces regarding storage, rest clients and signature validation functionalities, are contained configuration classes specific for the provided implementations, the description of which are defined in the respective Readme files.

Implementations Usage

Each service inside the core SDK is defined by an interface and a related Factory to generate an instance of the service, using the related configurations. The repository contains default implementations for each one of the interfaces to be used. The following steps should be followed to ensure the usage of the SDK:

The baseline for the SDK configuration is in this configuration class. As for any of the config files within the core SDK there is no reference to a particular method to be used for loading properties from an external source, leaving the possibility and responsibility to implement a proper loading method in the service utilizing the library (See for example the SpringLollipopConsumerRequestConfig extension, using annotations to load properties from the application context).

Whenever is required to define a new instance of the configuration class programmatically, it may be used a builder to setup the required parameters to be changed (not that otherwise the default values are applied):

lollipopConsumerRequestConfig = LollipopConsumerRequestConfig.builder()
        .assertionNotBeforeDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
        .assertionInstantDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
        .expectedFirstLcOriginalMethod('POST')
        .expectedFirstLcOriginalUrl('http://validurl:8080')
        .build();

Having defined the general configuration we can initialize the single instances of services (or related factories) to be used in the validation process.

An instance of the service to be used in order to verify the content digest and signatures related to the http request, through an implementation of the HttpMessageVerifier interface. The standard library does provide a factory interface to be used for the creation of a particular instance of the message verifier.

Whenever the factory helper class is not used and the generation of new instance of the service is required, we may use the following to generate an instance using the factory interface:

HttpMessageVerifier verifier = httpMessageVerifierFactory.create();

The repository provides a standard implementation of the service, and related factory. In order to initialize the factory the lollipopConsumerRequestConfig is required, as well as the value of the expected encoding. Note that the latter does not have a specific configuration file:

HttpMessageVerifierFactory messageVerifierFactory = new VismaHttpMessageVerifierFactory("UTF-8", LollipopConsumerRequestConfig);

An instance of this service is used to apply formal validation a LollipopConsumerRequest instance. In order to use the provided implementation lollipopConsumerRequestConfig is required, as it is used to search for the headers using the name defined in the configuration class. We may define a new validation service as follows:

LollipopConsumerRequestValidationService lollipopConsumerRequestValidationService = new LollipopConsumerRequestValidationServiceImpl(lollipopConsumerRequestConfig);

An instance of the LollipopLoggerService is used to apply a form of logging in pre-defined portions of the SDK core services, in order to audit request validations, and if enabled the retrieval of Assertions and IdP Cert Data. The standard library does provide a factory interface to be used for the creation of a particular instance of the logger service.

Whenever the factory helper class is not used and the generation of new instance of the service is required, we may use the following to generate an instance using the factory interface:

LollipopLoggerService lollipopLoggerService = lollipopLoggerServiceFactory.create();

The repository provides a standard implementation of the service, and related factory, using a standard logback implementation. In order to initialize the factory use the following snippet:

LollipopLoggerServiceFactory lollipopLoggerServiceFactory = new LollipopLogbackLoggerServiceFactory();

The SDK provides a default.xml logback include, as well as a default logback.xml file. The default may be used as a portion of other logback configuration, as an example see the spring implementation default logback-spring.xml.

An instance of the service to be used in order to enable the possibility to retrieve or store already recovered SAML Assertions from a cache or storage, through an implementation of the AssertionStorage interface. The standard library does provide a factory interface to be used for the creation of a particular instance of the storage.

Whenever the factory helper class is not used and the generation of new instance of the service is required, we may use the following to generate an instance using the factory interface, using an instance of the StorageConfig class (described in the configuration paragraph):

AssertionStorage assertionStorage = assertionStorageProvider.provideStorage(storageConfig);

The repository provides a standard implementation of the service, and related factory. that defines a simple in-memory cache storage for limited use, in order to initialize it, it is required to use the SimpleAssertionStorageProvider.

An instance of the service to be used in order to enable the possibility to retrieve or store already recovered IdP Certificates from a cache or storage, through an implementation of the IdpCertStorage interface. The standard library does provide a factory interface to be used for the creation of a particular instance of the storage.

Whenever the factory helper class is not used and the generation of new instance of the service is required, we may use the following to generate an instance using the factory interface, using an instance of the IdpCertStorageConfig class (described in the configuration paragraph):

IdpCertStorage idpCertStorage = idpCertStorageProvider.provideStorage(idpCertStorageConfig);

The repository provides a standard implementation of the service, and related factory. that defines a simple in-memory cache storage for limited use, in order to initialize it, it is required to use the SimpleIdpCertStorageProvider.

Note that currently the storage is required only if applied directly to the default provider of IdP certificates data, as it is directly used in the Identity Services implementation. In case other implementations are used, this storage service may not be in use.

An instance of the service to be used in order to enable the possibility to retrieve SAML Assertions through an implementation of the AssertionClient interface. The standard library does provide a factory interface to be used for the creation of a particular instance of the client.

Whenever the factory helper class is not used and the generation of new instance of the service is required, we may use the following to generate an instance using the factory interface:

AssertionClient assertionClient = assertionClientProvider.provideClient();

The repository provides a standard implementation of the service, and related factory, that defines a Rest Client using the available functionalities in the JDK 11 environment, available in the assertion-rest-client-native module.

See the related README.md for further information about the usage of this implementation.

An instance of the service to be used in order to enable the possibility to retrieve IdPCert data through an implementation of the IdpCertClient interface. The standard library does provide a factory interface to be used for the creation of a particular instance of the client.

Whenever the factory helper class is not used and the generation of new instance of the service is required, we may use the following to generate an instance using the factory interface:

IdpCertClient idpCertClient = idpCertClientProvider.provideClient();

The repository provides a standard implementation of the service, and related factory, that defines a Rest Client using the available functionalities in the JDK 11 environment, available in the identity-service-rest-client-native module.

See the related README.md for further information about the usage of this implementation.

Once we have defined the necessary services to be used for the retrieval of the IdP certificates, we can use an implementation of the IdpCertProvider interface, in order to provide a transparent functionality inside the SDK library.

Whenever the factory helper class is not used and the generation of new instance of the service is required, we may use the following to generate an instance using the factory interface:

IdpCertProvider idpCertProvider = idpCertProviderFactory.create();

The repository provides a standard implementation of the service, and related factory. In order to initialize the factory an instance of the IdpCertClientProvider is required:

IdpCertProviderFactory idpCertProviderFactory = new IdpCertProviderFactoryImpl(idpCertClientProvider);

Once we have defined the necessary services to be used for the retrieval of the SAML Assertion data, we can use an implementation of the AssertionService interface, in order to provide a transparent functionality inside the SDK library.

Whenever the factory helper class is not used and the generation of new instance of the service is required, we may use the following to generate an instance using the factory interface:

AssertionService assertionService = assertionServiceFactory.create();

The repository provides a standard implementation of the service, and related factory. In order to initialize the factory an instance of the AssertionClientProvider, AssertionStorageProvider, and StorageConfig are required:

AssertionServiceFactory assertionServiceFactory = new AssertionServiceFactoryImpl(
                          assertionStorageProvider, assertionClientProvider, assertionStorageConfig);

In order to execute a validation of the SAML Assertions starting form a LollipopConsumerRequest an interface of the AssertionVerifierService has to be used.

The standard implementation of this interface expects to have instances of the previously described interfaces, to be used for SAML Assertion retrieval and storage. Whenever we are using the factory helper it is not necessary to directly manage in any part the service startup, as it will be managed by the helper class itsefl if an implementation is missing.

In case it is necessary an instance of the standard implementation of the service can be applied with the following snippet, provided that the required services have been produced by the respective factory methods (or directly):

AssertionServiceFactory assertionServiceFactory = new AssertionVerifierServiceImpl(
                                   lollipopLoggerService,
                                   idpCertProvider,
                                   assertionService,
                                   lollipopRequestConfig);

Factory Helper Startup

The LollipopFactoryHelper is a singleton class to be used by the LollipopCommandBuilder implementation, that provides (and creates if unavailable) the required services, through the provided implementations of the factory classes for the single components. It is not mandatory to be used in order to use the services, if the dependencies are injected using a dedicated library.

It requires an instance of a LollipopConsumerRequestConfig, HttpMessageVerifierFactory, AssertionStorageProvider, IdpCertProviderFactory, AssertionServiceFactory, LollipopLoggerServiceFactory. LollipopConsumerRequestValidationService

And related configs and sub-dependencies defined by the factory implementation.

LollipopConsumerFactoryHelper lollipopFactoryHelper = new LollipopConsumerFactoryHelper(lollipopLoggerServiceFactory,
                                                                      messageVerifierFactory, idpCertProviderFactory,
                                                                      assertionServiceFactory,
                                                                      lollipopConsumerRequestValidationService,
                                                                      lollipopConsumerRequestConfig);

Example

The following examples provides the complete setup method with default configurations created directly into the method. For a simple usage of the library the following can be used with minimal setup changes in configuration related to the expect origin method and url, and the rest client url to be used for Assertions retrieval. In a normal usage case each factory implementation and related configurations should be treated with an implementation for the related frameworks and libraries used for the application (As an example, defining Beans and configurations within a Spring context, such as in the provided spring-impl module, and within the spring sample):

lollipopConsumerRequestConfig = LollipopConsumerRequestConfig.builder()
        .assertionNotBeforeDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
        .assertionInstantDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
        .build();
HttpMessageVerifierFactory messageVerifierFactory = new VismaHttpMessageVerifierFactory("UTF-8",
        LollipopConsumerRequestConfig.builder().build());
LollipopConsumerRequestValidationServiceImpl lollipopConsumerRequestValidationService = 
        new LollipopConsumerRequestValidationServiceImpl(lollipopConsumerRequestConfig);        
AssertionStorageProvider assertionStorageProvider = new SimpleAssertionStorageProvider();
IdpCertProviderFactory idpCertProviderFactory = new IdpCertProviderFactoryImpl(
        new IdpCertSimpleClientProvider(IdpCertSimpleClientConfig.builder().baseUri("http://localhost:3001").build(),
                new SimpleIdpCertStorageProvider(), new IdpCertStorageConfig()));
AssertionClientProvider assertionClientProvider =
        new AssertionSimpleClientProvider(AssertionSimpleClientConfig.builder().build());
AssertionServiceFactory assertionServiceFactory = new AssertionServiceFactoryImpl(
        assertionStorageProvider, assertionClientProvider, new StorageConfig());
LollipopLoggerServiceFactory lollipopLoggerServiceFactory = new LollipopLogbackLoggerServiceFactory();
LollipopConsumerFactoryHelper lollipopFactoryHelper = new LollipopConsumerFactoryHelper(lollipopLoggerServiceFactory,
                                         messageVerifierFactory, idpCertProviderFactory,
                                         assertionServiceFactory, lollipopConsumerRequestValidationService ,
                                         lollipopConsumerRequestConfig);

Execute Validation Command

In order to execute a validation of an instance of LollipopConsumerRequest, after an instance of a LollipopConsumerFactoryHelper we could create an instance of the LollipopCommandBuilder interface as in the following snippet, directly into the execution method, or as the part of the application context (As an example, as a Spring Bean):

LollipopConsumerCommandBuilder commandBuilder = new LollipopConsumerCommandBuilderImpl(lollipopConsumerFactoryHelper);

With an existing builder we could provide a new instance of a command to execute using the following:

CommandResult result = commandBuilder.createCommand(lollipopConsumerRequest).doExecute();

A new LollipopConsumerCommand could be defined without the help of the FactoryHelper and the CommandBuilder, provided instances of an implementation of the required services are available, directly in the class requiring the new instance, or throughout the application context capable of enabling the usage of the @Inject annotations within the implemented command. In the case of a direct creation of a command to execute, use the following:

LollipopConsumerCommand command = new LollipopConsumerCommandImpl(
                                    lollipopConsumerRequestConfig, httpMessageVerifierService,
                                    assertionVerifierService, lollipopConsumerRequestValidationService,
                                    lollipopLoggerService, lollipopConsumerRequest);
CommandResult commandResult = command.doExecute();                                    

Defining LollipopRequestCommand instance

In order to define an instance of the LollipopRequestCommand, to be used in the validation process it is required to setup the following parameters:

  • requestBody, contains the request body to be used for the digest validation
  • headerParams, Map containing the list of parameters to be used within the validation process
  • requestParams, Map containing the list of parameters to be used with the validation process (actually not in use, defined for possible use in other implementations)

The following snippet defines the conversion from an HttpServletRequest instance, to a new LollipopConsumerRequest

LollipopConsumerRequest.builder()
  .requestBody(requestBody != null ? new String(requestBody) : null)
  .headerParams(
          Collections.list(httpServletRequest.getHeaderNames()).stream()
                  .collect(Collectors.toMap(h -> h, httpServletRequest::getHeader)))
  .requestParams(httpServletRequest.getParameterMap())
  .build();

Using CommandResult instances

Whenever a validation command is executed, a CommandResult will be produced, abstracting the exceptions or validation errors produced by the services regarding the validation process for the http message, and the SAML assertion. The CommandResult has properties indicating:

  • A result code to indicate if successful or not (in case of a valid request the SUCCESS code has to be expected)
  • A message containing details on the result, usually to be used for errors

The following snippet shows an example of how the CommandResult could be used to define the HttpServletRespons status and response body whenever the CommandResult is not ending in a successful state:

if (!commandResult.getResultCode().equals(VERIFICATION_SUCCESS_CODE)) {
    httpResponse.setStatus(401);
    httpResponse.getWriter().write(commandResult.getResultMessage());
}

Utility classes

LollipopConsumerConverter

Class that implements Javax Servlet library with two utility methods:

Examples of its usage can be found in the Spring Interceptor.

LollipopTypesafeConfig

Class that implements Lightbend's Config library, used to define configuration parameters.

The class' constructor retrieve from a Config object the parameters that can be used as configuration in the application, if the path to the parameter is not found (it hasn't been configured) a default value will be set.

Examples of its usage can be found in the Simple Typesafe sample, where the Config object is generated with the library's class ConfigFactory using as source for the configuration the sample's application.properties.

Testing

Testing of the repository functionalities is conducted by unit test, integration and e2e testing.

Collecting Test Coverage

This repository contains a module dedicated to collecting the test coverage of all the modules within the repository through the usage of a dedicated gradle plugin.

In order to obtain a centralized report of the repository test coverage, the following command can be used on the test-coverage module:

.\gradlew testCodeCoverageReport                                

Afterwards, the report is found at /test-coverage/build/reports/jacoco/testCodeCoverageReport.

E2E

This repository contains a collection and docker-compose file to be used for the purpose of an integrated testing. See the related README.md for further information.

Generate new Rest Clients

The standard Rest Clients available in the repository are defined without a specific dependency, and relates to the standard services available (For example, the IdP Data Provider is referred to the existing Pagopa Identity Services).

In case a new implementation of the client (for example, using Feign), or one of the clients has a different specification from the one that has been used as a default, a tool may be used to generate the internal structure of the client using OpenApi generation tool or gradle plugin. For the latter the following steps may be used to produce the internals of the Rest Client implementation:

Introduce in your module the following plugin:

id("org.openapi.generator") version "6.5.0"

Afterwards define the following task structure in your module:

compileJava.dependsOn tasks.openApiGenerate

openApiGenerate {
    generatorName = "java"
    inputSpec = "$projectDir/openapi/openapi-spec.yml"
    outputDir = "$projectDir/generated"
    configOptions = [
        dataLibrary: "java8",
        library: "native",
        useRuntimeException: "true",
        sourceFolder: "build/generated/sources/"
    ]
}

Where the dataLibrary config option defines the java version to be used, and the library defines witch implementation to be used. (For example library: "feign" will generate a Feign Rest Client).

In order to execute the task run the following command:

.\gradlew openApiGenerate

The default openApi specs for the two services already implemented are found in the respective modules under the openApi folder.

See the OpenAPITools/openapi-generator repository for further information about the generation toolkit.

Having the Rest Client code generated, the output should be introduced inside the expected package within the module, and an instance of the core SDK interfaces should be implemented in order to handle the data retrieval through the generated client.

For example, in order to enable the usage of a new Rest Client regarding the IdP certificates retrieval an implementation of the IdpCertClient and IdpCertClientProvider should be defined. See for reference the IdpCertSimpleClient implementation.