Code development platform for open source projects from the European Union institutions :large_blue_circle: EU Login authentication by SMS has been phased out. To see alternatives please check here

Skip to content
Snippets Groups Projects
Commit 17741d9d authored by Marco Amoia's avatar Marco Amoia
Browse files

Merge branch 'release' into 'main'

Create release 0.5.0

See merge request !72
parents f8d9424a 28112f14
No related branches found
No related tags found
2 merge requests!83Create,!72Create release 0.5.0
Pipeline #212082 failed
Showing
with 887 additions and 371 deletions
FROM openjdk:17-jdk-alpine
FROM eclipse-temurin:21-jdk-alpine
RUN adduser -S -u 1001 1001
COPY target/*.jar app.jar
RUN chown 1001 /app.jar
USER 1001
ENTRYPOINT ["java","-jar","/app.jar"]
......@@ -9,45 +9,41 @@ The environment variables listed below are used to define the connection details
## Environment Variables
### Database Configuration
- **PostgreSQL**
- `SPRING_DATASOURCE_URL`: The JDBC URL for connecting to the PostgreSQL database.
- Format: `jdbc:postgresql://postgresql.<namespace>.svc.cluster.local:5432/usersroles`
- `SPRING_DATASOURCE_USERNAME`: The username for the PostgreSQL database.
- Default value: `usersroles`
- `SPRING_DATASOURCE_PASSWORD`: The password for the PostgreSQL database.
- Default value: `usersroles`
### Redis Configuration
- `SPRING_DATA_REDIS_HOST`: The host address for the Redis service.
- Format: `redis-master.<namespace>.svc.cluster.local`
- `SPRING_DATA_REDIS_PORT`: The port on which Redis is running.
- Default value: `6379`
- `SPRING_DATA_REDIS_USERNAME`: The username for connecting to Redis.
- Default value: `default`
- `SPRING_DATA_REDIS_PASSWORD`: The password for connecting to Redis.
- Default value: `admin`
### Ephemeral Proof Issuer Configuration
- `SIMPL_EPHEMERAL_PROOF_ISSUER_URL`: The URL for the Ephemeral Proof Issuer service.
- This value is generated using the `tls.gateway.url` Helm template.
- `SIMPL_CERTIFICATE_PASSWORD`: The password for the certificate used by the service.
- Value is derived from `global.keystore.password` specified in the Helm values.
-
- 'SIMPL_EPHEMERAL_PROOF_EXPIRE_AFTER' : The time to Live of the ephemeral proof in redis
- Default value: `3D`, follow the spring standard of the Duration class.
### DataSource Configuration
- `SPRING_DATASOURCE_URL`: The URL for the datasource connection.
- Value is derived from `db.url` specified in the Helm values.
- `SPRING_DATASOURCE_USERNAME`: The username for the datasource.
- Value is derived from `db.username` specified in the Helm values.
- `SPRING_DATASOURCE_PASSWORD`: The password for the datasource.
- Value is derived from `db.password` specified in the Helm values.
### Microservices Configuration
- `MICROSERVICE_IDENTITY_PROVIDER_URL`: The URL for the Identity Provider microservice.
- Value is derived from `microservices.identityProviderUrl` specified in the Helm values.
## Usage
To use these environment variables, define them in your Kubernetes manifests or Helm chart. The values for URLs and passwords will be dynamically generated based on the namespace and other configuration values.
### Example `values.yaml`
### Example `values-common.yaml`
```yaml
global:
keystore:
password: "your-keystore-password"
```
### Example `values-authority.yaml`
```yaml
db:
url: "jdbc:postgresql://postgresql.{{ .Release.Namespace }}.svc.cluster.local:5432/securityattributesprovider"
username: "securityattributesprovider"
password: "securityattributesprovider"
microservices:
identityProviderUrl: http://identity-provider.{{ .Release.Namespace }}.svc.cluster.local:8080
```
......@@ -3,8 +3,8 @@ kind: ConfigMap
metadata:
name: {{ .Chart.Name }}-configmap
data:
{{- with .Values.env }}
{{- toYaml . | nindent 2 }}
{{- end }}
SIMPL_EPHEMERAL_PROOF_ISSUER_URL: "{{- include "tls.gateway.url" . }}"
SIMPL_CERTIFICATE_PASSWORD: "{{ .Values.global.keystore.password }}"
\ No newline at end of file
SPRING_DATASOURCE_URL: "{{ .Values.db.url }}"
SPRING_DATASOURCE_USERNAME: "{{ .Values.db.username }}"
SPRING_DATASOURCE_PASSWORD: "{{ .Values.db.password }}"
MICROSERVICE_IDENTITY_PROVIDER_URL: "{{ .Values.microservices.identityProviderUrl }}"
......@@ -9,7 +9,7 @@ spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include "microservices.fullname" . }}
name: {{ .Chart.Name }}
minReplicas: {{ .Values.autoscaling.minReplicas }}
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
metrics:
......
......@@ -24,13 +24,14 @@ podLabels: {}
podSecurityContext: {}
# fsGroup: 2000
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
securityContext:
capabilities:
drop:
- ALL
readOnlyRootFilesystem: false
runAsNonRoot: true
runAsUser: 1001
service:
type: ClusterIP
......@@ -108,13 +109,11 @@ tolerations: []
affinity: {}
env:
SPRING_DATASOURCE_URL: jdbc:postgresql://postgresql.{{ .Release.Namespace }}.svc.cluster.local:5432/securityattributesprovider
SPRING_DATASOURCE_USERNAME: "securityattributesprovider"
SPRING_DATASOURCE_PASSWORD: "securityattributesprovider"
SPRING_DATA_REDIS_HOST: "redis-master.{{ .Release.Namespace }}.svc.cluster.local"
SPRING_DATA_REDIS_PORT: "6379"
SPRING_DATA_REDIS_USERNAME: "default"
SPRING_DATA_REDIS_PASSWORD: "admin"
MICROSERVICE_USERS_ROLES_URL: http://users-roles.{{ .Release.Namespace }}.svc.cluster.local:8080
MICROSERVICE_ONBOARDING_URL: http://onboarding.{{ .Release.Namespace }}.svc.cluster.local:8080
SIMPL_EPHEMERAL_PROOF_EXPIRE_AFTER: "3D"
db:
url: "jdbc:postgresql://postgresql.{{ .Release.Namespace }}.svc.cluster.local:5432/securityattributesprovider"
username: "securityattributesprovider"
password: "securityattributesprovider"
microservices:
identityProviderUrl: http://identity-provider.{{ .Release.Namespace }}.svc.cluster.local:8080
{
"openapi": "3.0.1",
"info": {
"title": "OpenAPI definition",
"version": "v0"
},
"servers": [
{
"url": "http://localhost:8082",
"description": "Generated server url"
}
],
"paths": {
"/identity-attribute/{id}": {
"get": {
"tags": [
"identity-attribute-controller"
],
"operationId": "findById",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"409": {
"description": "Conflict",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/ErrorDTO"
}
}
}
},
"200": {
"description": "OK",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/IdentityAttributeDTO"
}
}
}
}
}
},
"put": {
"tags": [
"identity-attribute-controller"
],
"operationId": "updateAttributes",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/IdentityAttributeDTO"
}
}
},
"required": true
},
"responses": {
"409": {
"description": "Conflict",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/ErrorDTO"
}
}
}
},
"204": {
"description": "No Content"
}
}
},
"delete": {
"tags": [
"identity-attribute-controller"
],
"operationId": "delete",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"409": {
"description": "Conflict",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/ErrorDTO"
}
}
}
},
"204": {
"description": "No Content"
}
}
}
},
"/identity-attribute/assignable/{value}": {
"put": {
"tags": [
"identity-attribute-controller"
],
"operationId": "updateAssignableParameter",
"parameters": [
{
"name": "value",
"in": "path",
"required": true,
"schema": {
"type": "boolean"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
}
}
},
"required": true
},
"responses": {
"409": {
"description": "Conflict",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/ErrorDTO"
}
}
}
},
"200": {
"description": "OK"
}
}
}
},
"/identity-attribute/assign-participant/{userId}": {
"put": {
"tags": [
"identity-attribute-controller"
],
"operationId": "assign",
"parameters": [
{
"name": "userId",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
}
}
},
"required": true
},
"responses": {
"409": {
"description": "Conflict",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/ErrorDTO"
}
}
}
},
"204": {
"description": "No Content"
}
}
}
},
"/identity-attribute/add-participant-type/{participantType}": {
"put": {
"tags": [
"identity-attribute-controller"
],
"operationId": "addParticipantType",
"parameters": [
{
"name": "participantType",
"in": "path",
"required": true,
"schema": {
"type": "string",
"enum": [
"CONSUMER",
"APPLICATION_PROVIDER",
"DATA_PROVIDER",
"INFRASTRUCTURE_PROVIDER",
"GOVERNANCE_AUTHORITY"
]
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
}
}
},
"required": true
},
"responses": {
"409": {
"description": "Conflict",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/ErrorDTO"
}
}
}
},
"200": {
"description": "OK"
}
}
}
},
"/identity-attribute": {
"post": {
"tags": [
"identity-attribute-controller"
],
"operationId": "create",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/IdentityAttributeDTO"
}
}
},
"required": true
},
"responses": {
"409": {
"description": "Conflict",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/ErrorDTO"
}
}
}
},
"201": {
"description": "Created",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/IdentityAttributeDTO"
}
}
}
}
}
}
},
"/mtls/identity-attribute": {
"get": {
"tags": [
"mtls-controller"
],
"operationId": "getIdentityAttributesWithOwnership",
"parameters": [
{
"name": "Participant-Id",
"in": "header",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"409": {
"description": "Conflict",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/ErrorDTO"
}
}
}
},
"200": {
"description": "OK",
"content": {
"*/*": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/IdentityAttributeWithOwnershipDTO"
}
}
}
}
}
}
}
},
"/mtls/identity-attribute/{certificateId}": {
"get": {
"tags": [
"mtls-controller"
],
"operationId": "getIdentityAttributesByCertificateIdInUri",
"parameters": [
{
"name": "certificateId",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"409": {
"description": "Conflict",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/ErrorDTO"
}
}
}
},
"200": {
"description": "OK",
"content": {
"*/*": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/IdentityAttributeDTO"
}
}
}
}
}
}
}
},
"/identity-attribute/search": {
"get": {
"tags": [
"identity-attribute-controller"
],
"operationId": "search",
"parameters": [
{
"name": "code",
"in": "query",
"required": false,
"schema": {
"type": "string"
}
},
{
"name": "name",
"in": "query",
"required": false,
"schema": {
"type": "string"
}
},
{
"name": "enabled",
"in": "query",
"required": false,
"schema": {
"type": "boolean"
}
},
{
"name": "participantTypeIn",
"in": "query",
"required": false,
"schema": {
"type": "string",
"enum": [
"CONSUMER",
"APPLICATION_PROVIDER",
"DATA_PROVIDER",
"INFRASTRUCTURE_PROVIDER",
"GOVERNANCE_AUTHORITY"
]
}
},
{
"name": "participantTypeNotIn",
"in": "query",
"required": false,
"schema": {
"type": "string",
"enum": [
"CONSUMER",
"APPLICATION_PROVIDER",
"DATA_PROVIDER",
"INFRASTRUCTURE_PROVIDER",
"GOVERNANCE_AUTHORITY"
]
}
},
{
"name": "participantIdIn",
"in": "query",
"required": false,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "participantIdNotIn",
"in": "query",
"required": false,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "updateTimestampFrom",
"in": "query",
"required": false,
"schema": {
"type": "string",
"format": "date-time"
}
},
{
"name": "updateTimestampTo",
"in": "query",
"required": false,
"schema": {
"type": "string",
"format": "date-time"
}
},
{
"name": "page",
"in": "query",
"description": "Zero-based page index (0..N)",
"required": false,
"schema": {
"minimum": 0,
"type": "integer",
"default": 0
}
},
{
"name": "size",
"in": "query",
"description": "The size of the page to be returned",
"required": false,
"schema": {
"minimum": 1,
"type": "integer",
"default": 10
}
},
{
"name": "sort",
"in": "query",
"description": "Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.",
"required": false,
"schema": {
"type": "array",
"items": {
"type": "string"
},
"default": [
"id,ASC"
]
}
}
],
"responses": {
"409": {
"description": "Conflict",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/ErrorDTO"
}
}
}
},
"200": {
"description": "OK",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/PageResponseIdentityAttributeDTO"
}
}
}
}
}
}
},
"/identity-attribute/unassign-participant/{userId}": {
"delete": {
"tags": [
"identity-attribute-controller"
],
"operationId": "unassign",
"parameters": [
{
"name": "userId",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
}
}
},
"required": true
},
"responses": {
"409": {
"description": "Conflict",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/ErrorDTO"
}
}
}
},
"204": {
"description": "No Content"
}
}
}
}
},
"components": {
"schemas": {
"ErrorDTO": {
"type": "object",
"properties": {
"error": {
"type": "string"
},
"elementName": {
"type": "string"
}
}
},
"IdentityAttributeDTO": {
"required": [
"assignableToRoles",
"code",
"enabled",
"name"
],
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"code": {
"type": "string"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"assignableToRoles": {
"type": "boolean"
},
"enabled": {
"type": "boolean"
},
"creationTimestamp": {
"type": "string",
"format": "date-time"
},
"updateTimestamp": {
"type": "string",
"format": "date-time"
},
"participantTypes": {
"uniqueItems": true,
"type": "array",
"items": {
"type": "string",
"enum": [
"CONSUMER",
"APPLICATION_PROVIDER",
"DATA_PROVIDER",
"INFRASTRUCTURE_PROVIDER",
"GOVERNANCE_AUTHORITY"
]
}
},
"used": {
"type": "boolean",
"readOnly": true
}
}
},
"IdentityAttributeWithOwnershipDTO": {
"required": [
"assignableToRoles",
"code",
"enabled",
"name"
],
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"code": {
"type": "string"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"assignableToRoles": {
"type": "boolean"
},
"enabled": {
"type": "boolean"
},
"creationTimestamp": {
"type": "string",
"format": "date-time"
},
"updateTimestamp": {
"type": "string",
"format": "date-time"
},
"participantTypes": {
"uniqueItems": true,
"type": "array",
"items": {
"type": "string",
"enum": [
"CONSUMER",
"APPLICATION_PROVIDER",
"DATA_PROVIDER",
"INFRASTRUCTURE_PROVIDER",
"GOVERNANCE_AUTHORITY"
]
}
},
"used": {
"type": "boolean",
"readOnly": true
},
"assignedToParticipant": {
"type": "boolean"
}
}
},
"PageMetadata": {
"type": "object",
"properties": {
"size": {
"type": "integer",
"format": "int64"
},
"number": {
"type": "integer",
"format": "int64"
},
"totalElements": {
"type": "integer",
"format": "int64"
},
"totalPages": {
"type": "integer",
"format": "int64"
}
}
},
"PageResponseIdentityAttributeDTO": {
"type": "object",
"properties": {
"content": {
"type": "array",
"items": {
"$ref": "#/components/schemas/IdentityAttributeDTO"
}
},
"page": {
"$ref": "#/components/schemas/PageMetadata"
},
"empty": {
"type": "boolean"
}
}
}
}
}
}
\ No newline at end of file
PROJECT_VERSION_NUMBER="0.0.4"
PROJECT_VERSION_NUMBER="0.5.0"
......@@ -5,7 +5,7 @@
<parent>
<groupId>com.aruba.simpl</groupId>
<artifactId>simpl-parent</artifactId>
<version>0.0.4-SNAPSHOT</version>
<version>0.5.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
......@@ -15,6 +15,8 @@
<properties>
<instancio.version>4.8.1</instancio.version>
<sonar.coverage.exclusions>**/model/*,**/model/**/*,**/exceptions/*,**/exceptions/**/*,**/configurations/*,**/configurations/**/*</sonar.coverage.exclusions>
<sonar.exclusions>**/model/*,**/model/**/*,**/exceptions/*,**/exceptions/**/*,**/configurations/*,**/configurations/**/*</sonar.exclusions>
</properties>
<dependencies>
......@@ -30,10 +32,6 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
......
package com.aruba.simpl.securityattributesprovider.configurations;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import org.springframework.web.multipart.MultipartFile;
public class ByteArrayMultipartFile implements MultipartFile {
private final byte[] bytes;
public ByteArrayMultipartFile(byte[] bytes) {
this.bytes = bytes;
}
@Override
public String getName() {
return "credentials.p12";
}
@Override
public String getOriginalFilename() {
return "credentials.p12";
}
@Override
public String getContentType() {
return null;
}
@Override
public boolean isEmpty() {
return bytes == null || bytes.length == 0;
}
@Override
public long getSize() {
return bytes.length;
}
@Override
public byte[] getBytes() {
return bytes;
}
@Override
public InputStream getInputStream() {
return new ByteArrayInputStream(bytes);
}
@Override
public void transferTo(File dest) throws IOException, IllegalStateException {
Files.write(Paths.get(dest.getPath()), bytes);
}
}
package com.aruba.simpl.securityattributesprovider.configurations;
import com.aruba.simpl.common.exchanges.AttachmentExchange;
import com.aruba.simpl.common.exchanges.CertificateExchange;
import com.aruba.simpl.common.exchanges.CredentialExchange;
import com.aruba.simpl.common.exchanges.UserExchange;
import com.aruba.simpl.common.messageconverters.StreamingResponseBodyMessageConverter;
import com.aruba.simpl.securityattributesprovider.exceptions.CertificateNotFoundException;
import com.aruba.simpl.securityattributesprovider.exceptions.CredentialsNotFoundException;
import java.util.Objects;
import com.aruba.simpl.common.argumentresolvers.PageableArgumentResolver;
import com.aruba.simpl.common.argumentresolvers.QueryParamsArgumentResolver;
import com.aruba.simpl.common.exchanges.identityprovider.ParticipantExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.support.RestClientAdapter;
import org.springframework.web.service.invoker.HttpServiceProxyFactory;
@Configuration
public class ClientConfig {
@Bean
public UserExchange userExchange(MicroserviceProperties properties, RestClient.Builder restClientBuilder) {
return buildExchange(properties.usersRoles().url(), restClientBuilder, UserExchange.class);
}
@Bean
public CredentialExchange credentialExchange(
MicroserviceProperties properties, RestClient.Builder restClientBuilder) {
return buildExchange(
properties.usersRoles().url(),
restClientBuilder
.messageConverters(l -> l.add(new StreamingResponseBodyMessageConverter()))
.defaultStatusHandler(
statusCode -> Objects.equals(statusCode, HttpStatus.NOT_FOUND), (request, response) -> {
throw new CredentialsNotFoundException();
}),
CredentialExchange.class);
}
@Bean
public CertificateExchange certificateExchange(
MicroserviceProperties properties, RestClient.Builder restClientBuilder) {
return buildExchange(
properties.onboarding().url(),
restClientBuilder
.messageConverters(l -> l.add(new StreamingResponseBodyMessageConverter()))
.defaultStatusHandler(
statusCode -> Objects.equals(statusCode, HttpStatus.NOT_FOUND), (request, response) -> {
throw new CertificateNotFoundException();
}),
CertificateExchange.class);
}
@Bean
public AttachmentExchange attachmentExchange(
public ParticipantExchange participantExchange(
MicroserviceProperties properties, RestClient.Builder restClientBuilder) {
return buildExchange(properties.onboarding().url(), restClientBuilder, AttachmentExchange.class);
return buildExchange(properties.identityProvider().url(), restClientBuilder, ParticipantExchange.class);
}
private <E> E buildExchange(String baseurl, RestClient.Builder restClientBuilder, Class<E> clazz) {
var restClient = restClientBuilder.baseUrl(baseurl).build();
var adapter = RestClientAdapter.create(restClient);
var factory = HttpServiceProxyFactory.builderFor(adapter).build();
var factory = HttpServiceProxyFactory.builderFor(adapter)
.customArgumentResolver(new PageableArgumentResolver())
.customArgumentResolver(new QueryParamsArgumentResolver())
.build();
return factory.createClient(clazz);
}
}
......@@ -3,9 +3,7 @@ package com.aruba.simpl.securityattributesprovider.configurations;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "microservice")
public record MicroserviceProperties(UsersRoles usersRoles, Onboarding onboarding) {
public record MicroserviceProperties(IdentityProvider identityProvider) {
public record UsersRoles(String url) {}
public record Onboarding(String url) {}
public record IdentityProvider(String url) {}
}
......@@ -12,8 +12,8 @@ public class SecurityConfig {
@Bean
public DefaultSecurityAutoConfiguration.PublicUrlCustomizer publicUrlCustomizer() {
return publicUrl -> {
publicUrl.add(AntPathRequestMatcher.antMatcher(HttpMethod.POST, "/participant"));
publicUrl.add(AntPathRequestMatcher.antMatcher("/mtls/**"));
publicUrl.add(AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/identity-attribute/search"));
};
}
}
package com.aruba.simpl.securityattributesprovider.configurations;
import java.time.Duration;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "simpl")
public record SimplProperties(EphemeralProof ephemeralProof, Certificate certificate) {
public record EphemeralProof(String issuerUrl, Duration expireAfter) {}
public record Certificate(String password) {}
}
package com.aruba.simpl.securityattributesprovider.controllers;
import com.aruba.simpl.common.exchanges.SapCliExchange;
import com.aruba.simpl.common.exchanges.securityattributeprovider.SapCliExchange;
import com.aruba.simpl.common.model.dto.IdentityAttributeDTO;
import com.aruba.simpl.common.model.dto.ParticipantExtendedDTO;
import com.aruba.simpl.securityattributesprovider.services.CliService;
import io.swagger.v3.oas.annotations.Hidden;
import jakarta.validation.Valid;
import java.util.List;
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import lombok.extern.log4j.Log4j2;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.*;
@Log4j2
@RestController
@Hidden
public class CliController implements SapCliExchange {
private final CliService cliService;
private final Logger log = LoggerFactory.getLogger(CliController.class);
public CliController(CliService cliService) {
this.cliService = cliService;
}
@Override
public UUID createParticipant(@RequestBody @Valid ParticipantExtendedDTO participantDTO, HttpHeaders token) {
log.info("Creating participant from CLI");
return cliService.createParticipant(participantDTO);
}
@Override
public void initializeIdentityAttributes(@RequestBody List<IdentityAttributeDTO> list, HttpHeaders token) {
log.info("Initializing identity attributes from CLI");
......
package com.aruba.simpl.securityattributesprovider.controllers;
import com.aruba.simpl.common.exchanges.securityattributeprovider.IdentityAttributeExchange;
import com.aruba.simpl.common.model.dto.IdentityAttributeDTO;
import com.aruba.simpl.common.model.enums.ParticipantType;
import com.aruba.simpl.common.model.filters.IdentityAttributeFilter;
import com.aruba.simpl.common.model.validators.CreateOperation;
import com.aruba.simpl.common.model.responses.PageResponse;
import com.aruba.simpl.common.model.validators.UpdateOperation;
import com.aruba.simpl.securityattributesprovider.services.IdentityAttributeService;
import java.util.List;
import java.util.UUID;
import lombok.extern.log4j.Log4j2;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@Log4j2
@RestController
@RequestMapping("identity-attribute")
public class IdentityAttributeController {
public class IdentityAttributeController implements IdentityAttributeExchange {
private final IdentityAttributeService service;
public IdentityAttributeController(IdentityAttributeService service) {
this.service = service;
}
@PreAuthorize("hasRole('IATTR_M')")
@ResponseStatus(HttpStatus.CREATED)
@PostMapping
public IdentityAttributeDTO create(@RequestBody @Validated(CreateOperation.class) IdentityAttributeDTO attribute) {
@Override
public IdentityAttributeDTO create(@RequestBody IdentityAttributeDTO attribute) {
return service.create(attribute);
}
@PreAuthorize("hasRole('IATTR_M')")
@GetMapping("{id}")
@Override
public IdentityAttributeDTO findById(@PathVariable UUID id) {
return service.findById(id);
}
@PreAuthorize("hasRole('IATTR_M')")
@ResponseStatus(HttpStatus.NO_CONTENT)
@PutMapping("{id}")
@Override
public void updateAttributes(
@PathVariable UUID id, @RequestBody @Validated(UpdateOperation.class) IdentityAttributeDTO attribute) {
attribute.setId(id);
service.update(id, attribute);
}
@PreAuthorize("hasRole('IATTR_M')")
@ResponseStatus(HttpStatus.NO_CONTENT)
@DeleteMapping("{id}")
@Override
public void delete(@PathVariable UUID id) {
service.delete(id);
}
@PreAuthorize("hasAnyRole('IATTR_M', 'NOTARY')")
@GetMapping("search")
public Page<IdentityAttributeDTO> search(
@ParameterObject IdentityAttributeFilter filter,
@Override
public PageResponse<IdentityAttributeDTO> search(
@ParameterObject @ModelAttribute IdentityAttributeFilter filter,
@PageableDefault(sort = "id") @ParameterObject Pageable pageable) {
return service.search(filter, pageable);
return new PageResponse<>(service.search(filter, pageable));
}
@PreAuthorize("hasRole('IATTR_M')")
@ResponseStatus(HttpStatus.OK)
@PutMapping("/assignable/{value}")
@Override
public void updateAssignableParameter(@RequestBody List<UUID> body, @PathVariable boolean value) {
service.updateAssignableParameter(body, value);
}
@PreAuthorize("hasRole('IATTR_M')")
@ResponseStatus(HttpStatus.OK)
@PutMapping("/addParticipantType/{participantType}")
@Override
public void addParticipantType(@RequestBody UUID[] body, @PathVariable ParticipantType participantType) {
service.addParticipantType(body, participantType);
}
@Override
public void unassign(UUID userId, List<UUID> identityAttributes) {
service.unassign(userId, identityAttributes);
}
@Override
public void assign(UUID userId, List<UUID> identityAttributes) {
service.assign(userId, identityAttributes);
}
@Override
public void assignSnapshot(ParticipantType participantType, UUID userId, List<UUID> excludedAttributes) {
service.assignLastSnapshot(participantType, userId, excludedAttributes);
}
}
......@@ -3,9 +3,7 @@ package com.aruba.simpl.securityattributesprovider.controllers;
import com.aruba.simpl.common.model.constants.HttpHeaders;
import com.aruba.simpl.common.model.dto.IdentityAttributeDTO;
import com.aruba.simpl.common.model.dto.IdentityAttributeWithOwnershipDTO;
import com.aruba.simpl.common.model.dto.ParticipantWithIdentityAttributesDTO;
import com.aruba.simpl.securityattributesprovider.services.IdentityAttributeService;
import com.aruba.simpl.securityattributesprovider.services.ParticipantService;
import java.util.List;
import java.util.UUID;
import org.springframework.web.bind.annotation.*;
......@@ -14,17 +12,9 @@ import org.springframework.web.bind.annotation.*;
@RequestMapping("mtls")
public class MtlsController {
private final IdentityAttributeService identityAttributeService;
private final ParticipantService participantService;
public MtlsController(IdentityAttributeService identityAttributeService, ParticipantService participantService) {
public MtlsController(IdentityAttributeService identityAttributeService) {
this.identityAttributeService = identityAttributeService;
this.participantService = participantService;
}
@GetMapping("echo-t2")
public ParticipantWithIdentityAttributesDTO getParticipantWithIdentityAttributesWithEchoT2(
@RequestHeader(HttpHeaders.PARTICIPANT_ID) UUID participantId) {
return participantService.getParticipantWithIdentityAttributesByParticipantId(participantId);
}
@GetMapping("identity-attribute")
......
package com.aruba.simpl.securityattributesprovider.controllers;
import com.aruba.simpl.common.model.constants.HttpHeaders;
import com.aruba.simpl.securityattributesprovider.services.EphemeralProofService;
import java.util.UUID;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("mtls/token")
public class MtlsEphemeralProofController {
private final EphemeralProofService ephemeralProofService;
public MtlsEphemeralProofController(EphemeralProofService ephemeralProofService) {
this.ephemeralProofService = ephemeralProofService;
}
@PostMapping
public String getEphemeralProof(@RequestHeader(HttpHeaders.PARTICIPANT_ID) UUID participantId) {
return ephemeralProofService.generateEphemeralProof(participantId);
}
}
package com.aruba.simpl.securityattributesprovider.controllers;
import com.aruba.simpl.common.model.dto.ParticipantDTO;
import com.aruba.simpl.common.model.dto.ParticipantExtendedDTO;
import com.aruba.simpl.common.model.validators.CreateOperation;
import com.aruba.simpl.securityattributesprovider.model.entities.Participant_;
import com.aruba.simpl.securityattributesprovider.model.filters.ParticipantFilter;
import com.aruba.simpl.securityattributesprovider.model.requests.InitializeAuthorityRequest;
import com.aruba.simpl.securityattributesprovider.services.ParticipantService;
import jakarta.validation.Valid;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@RestController
@RequestMapping(value = "participant")
public class ParticipantController {
private final ParticipantService participantService;
public ParticipantController(ParticipantService participantService) {
this.participantService = participantService;
}
@ResponseStatus(HttpStatus.CREATED)
@PostMapping
public UUID create(@RequestBody @Validated(CreateOperation.class) ParticipantExtendedDTO participantDTO) {
return participantService.create(participantDTO);
}
@ResponseStatus(HttpStatus.CREATED)
@PostMapping(path = "attachment", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public void uploadAttachment(@RequestPart MultipartFile attachment) {
participantService.uploadAttachment(attachment);
}
@PreAuthorize("hasRole('NOTARY')")
@PutMapping(path = "{userId}")
public void outcome(
@PathVariable UUID userId,
@RequestParam boolean approve,
@RequestBody List<UUID> identityAttributesExcluded) {
participantService.outcome(userId, approve, identityAttributesExcluded);
}
@GetMapping
public ParticipantDTO currentUser() {
return participantService.currentUser();
}
@PreAuthorize("hasRole('NOTARY')")
@GetMapping("search")
public Page<ParticipantDTO> search(
@ParameterObject @Valid ParticipantFilter filter, @ParameterObject Pageable pageable) {
var defaultSort = pageable.getSort().and(Sort.by(Participant_.ID));
var pageRequest = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), defaultSort);
return participantService.search(filter, pageRequest);
}
@ResponseStatus(HttpStatus.NO_CONTENT)
@PreAuthorize("hasRole('NOTARY')")
@DeleteMapping("{userId}/identity-attributes")
public void unassignIdentityAttributes(@PathVariable UUID userId, @RequestBody List<UUID> identityAttributes) {
participantService.unassign(userId, identityAttributes);
}
@ResponseStatus(HttpStatus.NO_CONTENT)
@PreAuthorize("hasRole('NOTARY')")
@PutMapping("{userId}/identity-attributes")
public void assignIdentityAttributes(@PathVariable UUID userId, @RequestBody UUID[] identityAttributes) {
participantService.assign(userId, identityAttributes);
}
@PreAuthorize("hasRole('T2IAA_M')")
@PostMapping("initialize")
public void initializeAuthority(@RequestBody InitializeAuthorityRequest initializeAuthorityRequest)
throws IOException {
participantService.initializeAuthority(initializeAuthorityRequest);
}
}
package com.aruba.simpl.securityattributesprovider.exceptions;
import com.aruba.simpl.common.exceptions.StatusException;
import java.util.UUID;
import org.springframework.http.HttpStatus;
public class AttachmentAlreadyUploadedException extends StatusException {
public AttachmentAlreadyUploadedException(UUID id) {
super(HttpStatus.CONFLICT, "User %s as already an attachment uploaded".formatted(id));
}
}
package com.aruba.simpl.securityattributesprovider.exceptions;
import com.aruba.simpl.common.exceptions.StatusException;
import org.springframework.http.HttpStatus;
public class AuthorityAlreadyInitializedException extends StatusException {
public AuthorityAlreadyInitializedException() {
super(HttpStatus.CONFLICT, "Authority already initialized.");
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment