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 620af62e authored by Flavio Ferraioli's avatar Flavio Ferraioli
Browse files

Merge branch 'release' into 'main'

Release

See merge request !55
parents ed1cfb37 1c360f16
Branches
Tags v0.0.3
2 merge requests!83Create,!55Release
Pipeline #197985 passed
Showing
with 193 additions and 175 deletions
PROJECT_VERSION_NUMBER="0.0.2"
PROJECT_VERSION_NUMBER="0.0.3"
......@@ -13,11 +13,19 @@
<name>Security Attributes Provider</name>
<description>Security Attributes Provider Microservice for SIMPL project</description>
<properties>
<instancio.version>4.8.1</instancio.version>
</properties>
<dependencies>
<dependency>
<groupId>com.aruba.simpl</groupId>
<artifactId>simpl-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.aruba.simpl</groupId>
<artifactId>simpl-test-lib</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
......@@ -67,6 +75,22 @@
<groupId>com.fasterxml.uuid</groupId>
<artifactId>java-uuid-generator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.instancio</groupId>
<artifactId>instancio-junit</artifactId>
<version>${instancio.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
......
package com.aruba.simpl.securityattributesprovider;
import com.aruba.simpl.securityattributesprovider.model.dto.ParticipantExtendedDTO;
import com.aruba.simpl.common.model.dto.IdentityAttributeWithOwnershipDTO;
import com.aruba.simpl.common.model.dto.ParticipantExtendedDTO;
import org.springdoc.core.utils.SpringDocUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
......@@ -10,7 +11,10 @@ import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
@ConfigurationPropertiesScan
public class SecurityAttributesProviderApplication {
public static void main(String[] args) {
SpringDocUtils.getConfig().addParentType(ParticipantExtendedDTO.class.getSimpleName());
SpringDocUtils.getConfig()
.addParentType(
ParticipantExtendedDTO.class.getSimpleName(),
IdentityAttributeWithOwnershipDTO.class.getSimpleName());
SpringApplication.run(SecurityAttributesProviderApplication.class, args);
}
}
......@@ -11,6 +11,9 @@ public class SecurityConfig {
@Bean
public DefaultSecurityAutoConfiguration.PublicUrlCustomizer publicUrlCustomizer() {
return publicUrl -> publicUrl.add(AntPathRequestMatcher.antMatcher(HttpMethod.POST, "/participant"));
return publicUrl -> {
publicUrl.add(AntPathRequestMatcher.antMatcher(HttpMethod.POST, "/participant"));
publicUrl.add(AntPathRequestMatcher.antMatcher("/mtls/**"));
};
}
}
package com.aruba.simpl.securityattributesprovider.controllers;
import com.aruba.simpl.securityattributesprovider.model.dto.ParticipantExtendedDTO;
import com.aruba.simpl.common.model.dto.IdentityAttributeDTO;
import com.aruba.simpl.common.model.dto.ParticipantExtendedDTO;
import com.aruba.simpl.common.model.validators.CreateOperation;
import com.aruba.simpl.securityattributesprovider.services.CliService;
import io.swagger.v3.oas.annotations.Hidden;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import java.util.List;
import java.util.UUID;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.UriComponentsBuilder;
......@@ -34,4 +38,11 @@ public class CliController {
.buildAndExpand(uuid)
.toUriString();
}
@ResponseStatus(HttpStatus.CREATED)
@PostMapping("identity-attributes")
public void initializeIdentityAttributes(
@RequestBody @Validated(value = CreateOperation.class) List<IdentityAttributeDTO> list) {
cliService.createAttributes(list);
}
}
package com.aruba.simpl.securityattributesprovider.controllers;
import com.aruba.simpl.common.exchanges.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.validators.UpdateOperation;
import com.aruba.simpl.securityattributesprovider.services.IdentityAttributeService;
import jakarta.validation.Valid;
import java.util.List;
import java.util.UUID;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.data.domain.Page;
......@@ -12,10 +14,12 @@ 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.*;
@RestController
public class IdentityAttributeController implements IdentityAttributeExchange {
@RequestMapping("identity-attribute")
public class IdentityAttributeController {
private final IdentityAttributeService service;
public IdentityAttributeController(IdentityAttributeService service) {
......@@ -25,7 +29,7 @@ public class IdentityAttributeController implements IdentityAttributeExchange {
@PreAuthorize("hasRole('IATTR_M')")
@ResponseStatus(HttpStatus.CREATED)
@PostMapping
public IdentityAttributeDTO create(@RequestBody @Valid IdentityAttributeDTO attribute) {
public IdentityAttributeDTO create(@RequestBody @Validated(CreateOperation.class) IdentityAttributeDTO attribute) {
return service.create(attribute);
}
......@@ -38,7 +42,8 @@ public class IdentityAttributeController implements IdentityAttributeExchange {
@PreAuthorize("hasRole('IATTR_M')")
@ResponseStatus(HttpStatus.NO_CONTENT)
@PutMapping("{id}")
public void updateAttributes(@PathVariable UUID id, @RequestBody @Valid IdentityAttributeDTO attribute) {
public void updateAttributes(
@PathVariable UUID id, @RequestBody @Validated(UpdateOperation.class) IdentityAttributeDTO attribute) {
attribute.setId(id);
service.update(id, attribute);
}
......@@ -51,10 +56,24 @@ public class IdentityAttributeController implements IdentityAttributeExchange {
}
@PreAuthorize("hasAnyRole('IATTR_M', 'NOTARY')")
@Override
@GetMapping("search")
public Page<IdentityAttributeDTO> search(
@ParameterObject @Valid IdentityAttributeFilter filter,
@ParameterObject IdentityAttributeFilter filter,
@PageableDefault(sort = "id") @ParameterObject Pageable pageable) {
return service.search(filter, pageable);
}
@PreAuthorize("hasRole('IATTR_M')")
@ResponseStatus(HttpStatus.OK)
@PutMapping("/assignable/{value}")
public void updateAssignableParameter(@RequestBody List<UUID> body, @PathVariable boolean value) {
service.updateAssignableParameter(body, value);
}
@PreAuthorize("hasRole('IATTR_M')")
@ResponseStatus(HttpStatus.OK)
@PutMapping("/addParticipantType/{participantType}")
public void addParticipantType(@RequestBody UUID[] body, @PathVariable ParticipantType participantType) {
service.addParticipantType(body, participantType);
}
}
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.*;
@RestController
@RequestMapping("mtls")
public class MtlsController {
private final IdentityAttributeService identityAttributeService;
private final ParticipantService participantService;
public MtlsController(IdentityAttributeService identityAttributeService, ParticipantService participantService) {
this.identityAttributeService = identityAttributeService;
this.participantService = participantService;
}
@GetMapping("echo-t2")
public ParticipantWithIdentityAttributesDTO getParticipantWithIdentityAttributesWithEchoT2(
@RequestHeader(HttpHeaders.PARTICIPANT_ID) UUID participantId) {
return participantService.getParticipantWithIdentityAttributesByParticipantId(participantId);
}
@PostMapping("token")
public String getEphemeralProf(@RequestHeader(HttpHeaders.PARTICIPANT_ID) UUID participantId) {
// TODO implement handler logic for ephemeral proof
return "null";
}
@GetMapping("identity-attribute")
public List<IdentityAttributeWithOwnershipDTO> getIdentityAttributesWithOwnership(
@RequestHeader(HttpHeaders.PARTICIPANT_ID) UUID participantId) {
return identityAttributeService.getIdentityAttributesWithOwnership(participantId);
}
@GetMapping("identity-attribute/{certificateId}")
public List<IdentityAttributeDTO> getIdentityAttributesByCertificateIdInUri(@PathVariable String certificateId) {
return identityAttributeService.getIdentityAttributesByCertificateId(certificateId);
}
}
package com.aruba.simpl.securityattributesprovider.controllers;
import com.aruba.simpl.securityattributesprovider.model.dto.ParticipantDTO;
import com.aruba.simpl.securityattributesprovider.model.dto.ParticipantExtendedDTO;
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.services.ParticipantService;
......@@ -16,6 +17,7 @@ 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;
......@@ -30,7 +32,7 @@ public class ParticipantController {
@ResponseStatus(HttpStatus.CREATED)
@PostMapping
public UUID create(@RequestBody @Valid ParticipantExtendedDTO participantDTO) {
public UUID create(@RequestBody @Validated(CreateOperation.class) ParticipantExtendedDTO participantDTO) {
return participantService.create(participantDTO);
}
......@@ -62,4 +64,18 @@ public class ParticipantController {
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);
}
}
......@@ -3,12 +3,10 @@ package com.aruba.simpl.securityattributesprovider.exceptions;
import com.aruba.simpl.common.exceptions.StatusException;
import java.util.UUID;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.CONFLICT)
public class AttachmentAlreadyUploadedException extends StatusException {
public AttachmentAlreadyUploadedException(UUID id) {
super("User %s as already an attachment uploaded".formatted(id));
super(HttpStatus.CONFLICT, "User %s as already an attachment uploaded".formatted(id));
}
}
......@@ -2,11 +2,18 @@ package com.aruba.simpl.securityattributesprovider.exceptions;
import com.aruba.simpl.common.exceptions.StatusException;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.CONFLICT)
public class IdentityAttributeAlreadyExistException extends StatusException {
protected IdentityAttributeAlreadyExistException(HttpStatus status, String code, String name) {
super(status, "Identity attribute with code [ %s ] or name [ %s ] already exist".formatted(code, name));
}
public IdentityAttributeAlreadyExistException() {
super(HttpStatus.CONFLICT, "Identity attributes already stored in the database.");
}
public IdentityAttributeAlreadyExistException(String code, String name) {
super("Identity attribute with code [ %s ] or name [ %s ] already exist".formatted(code, name));
this(HttpStatus.CONFLICT, code, name);
}
}
package com.aruba.simpl.securityattributesprovider.exceptions;
import com.aruba.simpl.common.exceptions.StatusException;
import org.springframework.http.HttpStatus;
public class IdentityAttributeAssignedException extends StatusException {
public IdentityAttributeAssignedException() {
super(HttpStatus.FORBIDDEN, "The deletion of an assigned identity attribute is not allowed.");
}
}
......@@ -8,6 +8,10 @@ import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NOT_FOUND)
public class IdentityAttributeNotFoundException extends StatusException {
public IdentityAttributeNotFoundException(UUID id) {
super("Identity attribute with id [ %s ] not found".formatted(id.toString()));
this(HttpStatus.NOT_FOUND, id);
}
public IdentityAttributeNotFoundException(HttpStatus status, UUID id) {
super(status, "Identity attribute with id [ %s ] not found".formatted(id.toString()));
}
}
......@@ -3,12 +3,10 @@ package com.aruba.simpl.securityattributesprovider.exceptions;
import com.aruba.simpl.common.exceptions.StatusException;
import java.util.UUID;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.CONFLICT)
public class OutcomeAlreadyGivenException extends StatusException {
public OutcomeAlreadyGivenException(UUID id) {
super("Onboarding request of user %s has already an outcome".formatted(id));
super(HttpStatus.CONFLICT, "Onboarding request of user %s has already an outcome".formatted(id));
}
}
......@@ -3,15 +3,13 @@ package com.aruba.simpl.securityattributesprovider.exceptions;
import com.aruba.simpl.common.exceptions.StatusException;
import java.util.UUID;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NOT_FOUND)
public class UserNotFoundException extends StatusException {
public UserNotFoundException(String userEmail) {
super("User with userEmail [ %s ] not found".formatted(userEmail));
super(HttpStatus.NOT_FOUND, "User with userEmail [ %s ] not found".formatted(userEmail));
}
public UserNotFoundException(UUID id) {
super("User with id [ %s ] not found".formatted(id));
super(HttpStatus.NOT_FOUND, "User with id [ %s ] not found".formatted(id));
}
}
package com.aruba.simpl.securityattributesprovider.model.dto;
import com.aruba.simpl.common.model.enums.ParticipantType;
import com.aruba.simpl.common.model.enums.Status;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.time.ZonedDateTime;
import java.util.UUID;
public class ParticipantDTO {
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private UUID id;
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private String userEmail;
private ParticipantType participantType;
private String organization;
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private Status status;
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private ZonedDateTime creationTimestamp;
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private ZonedDateTime updateTimestamp;
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private String outcomeUserEmail;
public UUID getId() {
return id;
}
public ParticipantDTO setId(UUID id) {
this.id = id;
return this;
}
public String getUserEmail() {
return userEmail;
}
public ParticipantDTO setUserEmail(String userEmail) {
this.userEmail = userEmail;
return this;
}
public ParticipantType getParticipantType() {
return participantType;
}
public ParticipantDTO setParticipantType(ParticipantType participantType) {
this.participantType = participantType;
return this;
}
public String getOrganization() {
return organization;
}
public ParticipantDTO setOrganization(String organization) {
this.organization = organization;
return this;
}
public Status getStatus() {
return status;
}
public ParticipantDTO setStatus(Status status) {
this.status = status;
return this;
}
public ZonedDateTime getCreationTimestamp() {
return creationTimestamp;
}
public ParticipantDTO setCreationTimestamp(ZonedDateTime creationTimestamp) {
this.creationTimestamp = creationTimestamp;
return this;
}
public ZonedDateTime getUpdateTimestamp() {
return updateTimestamp;
}
public ParticipantDTO setUpdateTimestamp(ZonedDateTime updateTimestamp) {
this.updateTimestamp = updateTimestamp;
return this;
}
public String getOutcomeUserEmail() {
return outcomeUserEmail;
}
public ParticipantDTO setOutcomeUserEmail(String outcomeUserEmail) {
this.outcomeUserEmail = outcomeUserEmail;
return this;
}
}
package com.aruba.simpl.securityattributesprovider.model.dto;
import com.aruba.simpl.common.model.dto.KeycloakUserDTO;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import jakarta.validation.Valid;
public class ParticipantExtendedDTO {
@JsonUnwrapped
@Valid
private ParticipantDTO participant;
@JsonUnwrapped
@Valid
private KeycloakUserDTO keycloakUser;
public ParticipantDTO getParticipant() {
return participant;
}
public ParticipantExtendedDTO setParticipant(ParticipantDTO participant) {
this.participant = participant;
return this;
}
public KeycloakUserDTO getKeycloakUser() {
return keycloakUser;
}
public ParticipantExtendedDTO setKeycloakUser(KeycloakUserDTO keycloakUser) {
this.keycloakUser = keycloakUser;
return this;
}
}
......@@ -4,10 +4,7 @@ import com.aruba.simpl.common.model.entity.annotations.UUIDv7Generator;
import com.aruba.simpl.common.model.enums.ParticipantType;
import jakarta.persistence.*;
import java.time.ZonedDateTime;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.*;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.Formula;
import org.hibernate.annotations.UpdateTimestamp;
......
......@@ -42,6 +42,9 @@ public class Participant {
@Column(name = "outcome_user_email")
private String outcomeUserEmail;
@Column(name = "certificate_id")
private String certificateId;
@ManyToMany
@JoinTable(
name = "participant_identity_attribute",
......@@ -121,12 +124,21 @@ public class Participant {
return this;
}
public List<IdentityAttribute> getIdentityAttributes() {
return identityAttributes;
public String getCertificateId() {
return certificateId;
}
public Participant setCertificateId(String certificateId) {
this.certificateId = certificateId;
return this;
}
public Participant setIdentityAttributes(List<IdentityAttribute> identityAttributes) {
this.identityAttributes = identityAttributes;
return this;
}
public List<IdentityAttribute> getIdentityAttributes() {
return identityAttributes;
}
}
package com.aruba.simpl.securityattributesprovider.model.mappers;
import com.aruba.simpl.common.model.dto.IdentityAttributeDTO;
import com.aruba.simpl.common.model.dto.IdentityAttributeWithOwnershipDTO;
import com.aruba.simpl.securityattributesprovider.model.entities.IdentityAttribute;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import com.aruba.simpl.securityattributesprovider.model.projection.IdentityAttributeWithOwnership;
import org.mapstruct.*;
@Mapper
public interface IdentityAttributeMapper {
......@@ -13,6 +13,10 @@ public interface IdentityAttributeMapper {
IdentityAttributeDTO toDto(IdentityAttribute entity);
@Mapping(target = "identityAttribute")
IdentityAttributeWithOwnershipDTO toDtoWithOwnership(IdentityAttributeWithOwnership projection);
@Named("light")
@Mapping(target = "participantTypes", ignore = true)
IdentityAttributeDTO toLightDto(IdentityAttribute entity);
......
package com.aruba.simpl.securityattributesprovider.model.mappers;
import com.aruba.simpl.securityattributesprovider.model.dto.ParticipantDTO;
import com.aruba.simpl.common.model.dto.ParticipantDTO;
import com.aruba.simpl.securityattributesprovider.model.entities.Participant;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.NullValueCheckStrategy;
@Mapper
@Mapper(nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS)
public interface ParticipantMapper {
ParticipantDTO toDto(Participant entity);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment