Skip to content

Commit

Permalink
feat: P4ADEV-791-P4PA-AUTH-API-censimento-client-id (#80)
Browse files Browse the repository at this point in the history
  • Loading branch information
macacia authored Oct 7, 2024
1 parent c78802e commit 31c7d7f
Show file tree
Hide file tree
Showing 22 changed files with 751 additions and 38 deletions.
1 change: 1 addition & 0 deletions helm/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ microservice-chart:
MYPIVOT_DB_PASSWORD: db-mypay-login-password

DATA_CIPHER_P4PA_AUTH_HASH_KEY: p4pa-auth-hash-key
DATA_CIPHER_P4PA_AUTH_ENCRYPT_PSW: p4pa-auth-encrypt-psw
# nodeSelector: {}

# tolerations: []
Expand Down
86 changes: 85 additions & 1 deletion openapi/p4pa-auth.openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ paths:
required: true
schema:
enum: [
"urn:ietf:params:oauth:grant-type:token-exchange"
"urn:ietf:params:oauth:grant-type:token-exchange",
"client_credentials"
]
type: string
- name: subject_token
Expand Down Expand Up @@ -154,6 +155,66 @@ paths:
description: Invalid request
'401':
description: Invalid client_id
/auth/clients/{organizationIpaCode}:
get:
tags:
- authz
operationId: getClients
parameters:
- name: organizationIpaCode
in: path
required: true
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/ClientDTO'
'400':
description: Invalid request
'401':
description: Unauthorized
'403':
description: Forbidden
'412':
description: ToS acceptance missing
'429':
description: Too Many Requests
post:
tags:
- authz
operationId: registerClient
parameters:
- name: organizationIpaCode
in: path
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CreateClientRequest'
required: true
responses:
'200':
description: OK
content:
application/json:
schema:
type: array
$ref: '#/components/schemas/ClientDTO'
'400':
description: Invalid request
'401':
description: Unauthorized
'403':
description: Forbidden
'429':
description: Too Many Requests
/am/users:
post:
tags:
Expand Down Expand Up @@ -351,6 +412,29 @@ components:
default: Bearer
expires_in:
type: integer
ClientDTO:
type: object
required:
- clientId
- clientName
- organizationIpaCode
- clientSecret
properties:
clientId:
type: string
clientName:
type: string
organizationIpaCode:
type: string
clientSecret:
type: string
CreateClientRequest:
type: object
required:
- clientName
properties:
clientName:
type: string
UserDTO:
type: object
required:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@
import it.gov.pagopa.payhub.auth.service.AuthzService;
import it.gov.pagopa.payhub.auth.utils.SecurityUtils;
import it.gov.pagopa.payhub.controller.generated.AuthzApi;
import it.gov.pagopa.payhub.model.generated.CreateOperatorRequest;
import it.gov.pagopa.payhub.model.generated.OperatorDTO;
import it.gov.pagopa.payhub.model.generated.OperatorsPage;
import it.gov.pagopa.payhub.model.generated.UserDTO;
import it.gov.pagopa.payhub.model.generated.*;
import it.gov.pagopa.payhub.model.generated.UserInfo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
Expand Down Expand Up @@ -99,4 +96,12 @@ public ResponseEntity<UserDTO> createUser(UserDTO user) {
}
return ResponseEntity.ok(authzService.createUser(user));
}

@Override
public ResponseEntity<ClientDTO> registerClient(String organizationIpaCode, CreateClientRequest createClientRequest) {
if(!SecurityUtils.isPrincipalAdmin(organizationIpaCode)){
throw new UserUnauthorizedException("User not allowed to create client");
}
return ResponseEntity.ok(authzService.registerClient(organizationIpaCode, createClientRequest));
}
}
35 changes: 35 additions & 0 deletions src/main/java/it/gov/pagopa/payhub/auth/mapper/ClientMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package it.gov.pagopa.payhub.auth.mapper;

import it.gov.pagopa.payhub.auth.model.Client;
import it.gov.pagopa.payhub.auth.service.DataCipherService;
import it.gov.pagopa.payhub.model.generated.ClientDTO;
import org.springframework.stereotype.Service;

@Service
public class ClientMapper {

private final DataCipherService dataCipherService;

public ClientMapper(DataCipherService dataCipherService) {
this.dataCipherService = dataCipherService;
}

public ClientDTO mapToDTO(Client client) {
return ClientDTO.builder()
.clientId(client.getClientId())
.clientName(client.getClientName())
.organizationIpaCode(client.getOrganizationIpaCode())
.clientSecret(dataCipherService.decrypt(client.getClientSecret()))
.build();
}

public Client mapToModel(ClientDTO clientDTO) {
return Client.builder()
.clientId(clientDTO.getClientId())
.clientName(clientDTO.getClientName())
.organizationIpaCode(clientDTO.getOrganizationIpaCode())
.clientSecret(dataCipherService.encrypt(clientDTO.getClientSecret()))
.build();
}

}
24 changes: 24 additions & 0 deletions src/main/java/it/gov/pagopa/payhub/auth/model/Client.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package it.gov.pagopa.payhub.auth.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.FieldNameConstants;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Data
@Document("clients")
@NoArgsConstructor
@AllArgsConstructor
@Builder
@FieldNameConstants
public class Client {

@Id
private String clientId;
private String clientName;
private String organizationIpaCode;
private byte[] clientSecret;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package it.gov.pagopa.payhub.auth.repository;

import it.gov.pagopa.payhub.auth.model.Client;
import org.springframework.data.mongodb.repository.MongoRepository;

public interface ClientRepository extends MongoRepository<Client, String> {

}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package it.gov.pagopa.payhub.auth.service;

import it.gov.pagopa.payhub.model.generated.CreateOperatorRequest;
import it.gov.pagopa.payhub.model.generated.OperatorDTO;
import it.gov.pagopa.payhub.model.generated.UserDTO;
import it.gov.pagopa.payhub.model.generated.*;
import it.gov.pagopa.payhub.model.generated.UserInfo;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
Expand All @@ -15,4 +13,5 @@ public interface AuthzService {
OperatorDTO createOrganizationOperator(String organizationIpaCode, CreateOperatorRequest createOperatorRequest);
UserDTO createUser(UserDTO user);
UserInfo getUserInfoFromMappedExternalUserId(String mappedExternalUserId);
ClientDTO registerClient(String organizationIpaCode, CreateClientRequest createClientRequest);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@
import it.gov.pagopa.payhub.auth.model.User;
import it.gov.pagopa.payhub.auth.repository.OperatorsRepository;
import it.gov.pagopa.payhub.auth.repository.UsersRepository;
import it.gov.pagopa.payhub.auth.service.a2a.ClientService;
import it.gov.pagopa.payhub.auth.service.user.UserService;
import it.gov.pagopa.payhub.auth.service.user.retrieve.Operator2UserInfoMapper;
import it.gov.pagopa.payhub.auth.service.user.retrieve.OperatorDTOMapper;
import it.gov.pagopa.payhub.auth.service.user.retrieve.UserDTOMapper;
import it.gov.pagopa.payhub.model.generated.CreateOperatorRequest;
import it.gov.pagopa.payhub.model.generated.OperatorDTO;
import it.gov.pagopa.payhub.model.generated.UserDTO;
import it.gov.pagopa.payhub.model.generated.*;
import it.gov.pagopa.payhub.model.generated.UserInfo;
import jakarta.transaction.Transactional;
import java.util.HashSet;
Expand All @@ -28,17 +27,19 @@
public class AuthzServiceImpl implements AuthzService {

private final UserService userService;
private final ClientService clientService;
private final UsersRepository usersRepository;
private final OperatorsRepository operatorsRepository;
private final OperatorDTOMapper operatorDTOMapper;
private final UserDTOMapper userDTOMapper;
private final Operator2UserInfoMapper operator2UserInfoMapper;
private static final String MYPAYIAMISSUERS = "MYPAY";

public AuthzServiceImpl(UserService userService, UsersRepository usersRepository,
OperatorsRepository operatorsRepository, OperatorDTOMapper operatorDTOMapper,
UserDTOMapper userDTOMapper, Operator2UserInfoMapper operator2UserInfoMapper) {
public AuthzServiceImpl(UserService userService, ClientService clientService, UsersRepository usersRepository,
OperatorsRepository operatorsRepository, OperatorDTOMapper operatorDTOMapper, UserDTOMapper userDTOMapper,
Operator2UserInfoMapper operator2UserInfoMapper) {
this.userService = userService;
this.clientService = clientService;
this.usersRepository = usersRepository;
this.operatorsRepository = operatorsRepository;
this.operatorDTOMapper = operatorDTOMapper;
Expand Down Expand Up @@ -101,4 +102,9 @@ public UserInfo getUserInfoFromMappedExternalUserId(String mappedExternalUserId)
List<Operator> operators = operatorsRepository.findAllByUserId(user.getUserId());
return operator2UserInfoMapper.apply(user, operators);
}

@Override
public ClientDTO registerClient(String organizationIpaCode, CreateClientRequest createClientRequest) {
return clientService.registerClient(createClientRequest.getClientName(), organizationIpaCode);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package it.gov.pagopa.payhub.auth.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import it.gov.pagopa.payhub.auth.utils.AESUtils;
import it.gov.pagopa.payhub.auth.utils.HashAlgorithm;
import java.util.Base64;
import org.springframework.beans.factory.annotation.Value;
Expand All @@ -8,10 +11,43 @@
@Service
public class DataCipherService {

private final String encryptPsw;
private final HashAlgorithm hashAlgorithm;
private final ObjectMapper objectMapper;

public DataCipherService(@Value("${data-cipher.p4pa-auth-hash-key}") String hashPepper) {
hashAlgorithm = new HashAlgorithm("SHA-256", Base64.getUrlDecoder().decode(hashPepper));
public DataCipherService(
@Value("${p4pa-auth-encrypt-psw}") String encryptPsw,
@Value("${p4pa-auth-hash-pepper}") String hashPepper,
ObjectMapper objectMapper
) {
this.encryptPsw = encryptPsw;
this.objectMapper = objectMapper;

hashAlgorithm = new HashAlgorithm("SHA-256", Base64.getDecoder().decode(hashPepper));
}

public byte[] encrypt(String plainText){
return AESUtils.encrypt(encryptPsw, plainText);
}

public String decrypt(byte[] cipherData){
return AESUtils.decrypt(encryptPsw, cipherData);
}

public <T> byte[] encryptObj(T obj){
try {
return encrypt(objectMapper.writeValueAsString(obj));
} catch (JsonProcessingException e) {
throw new IllegalStateException("Cannot serialize object as JSON", e);
}
}

public <T> T decryptObj(byte[] cipherData, Class<T> clazz) {
try {
return objectMapper.readValue(decrypt(cipherData), clazz);
} catch (JsonProcessingException e) {
throw new IllegalStateException("Cannot deserialize object as JSON", e);
}
}

public byte[] hash(String value) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package it.gov.pagopa.payhub.auth.service.a2a;

import it.gov.pagopa.payhub.model.generated.ClientDTO;

public interface ClientService {

ClientDTO registerClient(String clientName, String organizationIpaCode);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package it.gov.pagopa.payhub.auth.service.a2a;

import it.gov.pagopa.payhub.auth.model.Client;
import it.gov.pagopa.payhub.auth.service.a2a.registration.ClientRegistrationService;
import it.gov.pagopa.payhub.auth.mapper.ClientMapper;
import it.gov.pagopa.payhub.model.generated.ClientDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class ClientServiceImpl implements ClientService {

private final ClientRegistrationService clientRegistrationService;

private final ClientMapper clientMapper;

public ClientServiceImpl(ClientRegistrationService clientRegistrationService, ClientMapper clientMapper) {
this.clientRegistrationService = clientRegistrationService;
this.clientMapper = clientMapper;
}

@Override
public ClientDTO registerClient(String clientName, String organizationIpaCode) {
Client client = clientRegistrationService.registerClient(clientName, organizationIpaCode);
return clientMapper.mapToDTO(client);
}
}
Loading

0 comments on commit 31c7d7f

Please sign in to comment.