From 9ab8a9d241da0aa1e1c32a17b0b2e7fe911e3ac2 Mon Sep 17 00:00:00 2001
From: migudel <miguel.moras@estudiantes.uva.es>
Date: Wed, 25 Dec 2024 13:47:26 +0100
Subject: [PATCH 1/4] =?UTF-8?q?Correcci=C3=B3n=20sobre=20puertos=20y=20fal?=
 =?UTF-8?q?los=20en=20el=20compose?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 docker-compose.yml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/docker-compose.yml b/docker-compose.yml
index 57fc680..92124a4 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -15,7 +15,7 @@ services:
   # Postgres: The database used by Kong
   kong-database:
     image: postgres:9.6
-    container_DATABASE: kong-postgres
+    container_name: kong-postgres
     restart: on-failure
     networks:
       - kong-net
@@ -108,7 +108,7 @@ services:
       kong-database:
         condition: service_healthy
     ports:
-      - 1337:133
+      - 1337:1337
 
   #######################################
   # APIs
@@ -124,10 +124,10 @@ services:
     networks:
       - kong-net
     environment:
-      # TODO Meter kid y secret key
-      KID: ${JWT_KID}
-      SECRET_KEY: ${JWT_KID}
-      EXTERNAL_SERVICE_USERS_URL: ${API_USERS_URL}${API_USERS_ENDPOINT}
+      SECURITY_JWT_EXPIRATION: 3600000
+      SECURITY_JWT_KID: ${JWT_KID:-9L8RmLEKMFd54WrR06CE9zoRSAGpCWeu}
+      SECURITY_JWT_SECRET_KEY: ${JWT_KEY:-MiClaveDeSeguridadMuyLargaParaQueNoFalleSpringBoot}
+      EXTERNAL_SERVICES_USERS_URL: ${API_USERS_URL}
     depends_on:
       - Users-API
 
@@ -135,7 +135,7 @@ services:
     image: users-api-image
     hostname: ${API_USERS_HOSTNAME}
     build:
-      context: ./java/services/user
+      context: ./java/services/users
       dockerfile: Dockerfile
     restart: unless-stopped
     networks:
-- 
GitLab


From a00f340ae732ab8c404588abacfbfcd5a0c9177d Mon Sep 17 00:00:00 2001
From: migudel <miguel.moras@estudiantes.uva.es>
Date: Wed, 25 Dec 2024 21:16:17 +0100
Subject: [PATCH 2/4] =?UTF-8?q?Configuraci=C3=B3n=20e=20integraci=C3=B3n?=
 =?UTF-8?q?=20de=20kong,=20alineamiento=20de=20los=20metadatos=20de=20los?=
 =?UTF-8?q?=20microservicios?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .env                                          | 34 +++++---
 .gitignore                                    |  5 +-
 angular/RestClient/src/mocks/users.ts         | 18 -----
 docker-compose.yml                            | 78 +++++++++++++------
 .../src/main/resources/application.properties |  4 +-
 .../com/uva/api/bookings/api/UserApi.java     | 11 ++-
 .../src/main/resources/application.properties |  6 +-
 .../src/main/resources/application.properties |  8 +-
 .../src/main/resources/application.properties |  5 --
 kong_config.json                              |  1 +
 poblate/Dockerfile                            | 11 +++
 poblate/index.js                              | 46 ++++++-----
 12 files changed, 136 insertions(+), 91 deletions(-)
 delete mode 100644 angular/RestClient/src/mocks/users.ts
 create mode 100644 kong_config.json
 create mode 100644 poblate/Dockerfile

diff --git a/.env b/.env
index a77b201..8244fc7 100644
--- a/.env
+++ b/.env
@@ -2,31 +2,39 @@
 # Environment
 #######################################
 
-## Meter aquí cosas sobre las keys del token y esas mierdas
-
 #######################################
 # APIs
 #######################################
 ## AUTH
-API_AUTH_ENDPOINT=/users
 API_AUTH_HOSTNAME=auth-api
 API_AUTH_PORT=8101
-API_AUTH_URL=http://$API_AUTH_HOSTNAME:$API_AUTH_PORT$API_AUTH_ENDPOINT
+API_AUTH_URL=http://$API_AUTH_HOSTNAME:$API_AUTH_PORT 
+API_AUTH_TOKEN_URL=$API_AUTH_URL/token
 ## Bookings
-API_BOOKINGS_ENDPOINT=/bookings
 API_BOOKINGS_HOSTNAME=bookings-api
 API_BOOKINGS_PORT=8401
-API_BOOKINGS_URL=http://$API_BOOKINGS_HOSTNAME:$API_BOOKINGS_PORT$API_BOOKINGS_ENDPOINT
+API_BOOKINGS_URL=http://$API_BOOKINGS_HOSTNAME:$API_BOOKINGS_PORT 
 ## Hotels
-API_HOTELS_ENDPOINT=/hotels
 API_HOTELS_HOSTNAME=hotels-api
 API_HOTELS_PORT=8301
-API_HOTELS_URL=http://$API_HOTELS_HOSTNAME:$API_HOTELS_PORT$API_HOTELS_ENDPOINT
+API_HOTELS_URL=http://$API_HOTELS_HOSTNAME:$API_HOTELS_PORT 
 ## Users
-API_USERS_ENDPOINT=/users
 API_USERS_HOSTNAME=users-api
 API_USERS_PORT=8201
-API_USERS_URL=http://$API_USERS_HOSTNAME:$API_USERS_PORT$API_USERS_ENDPOINT
+API_USERS_URL=http://$API_USERS_HOSTNAME:$API_USERS_PORT 
+## Kong
+# Kong configuration
+API_KONG_HOSTNAME=kong
+API_KONG_PORT=8000
+API_KONG_URL=http://$API_KONG_HOSTNAME:$API_KONG_PORT 
+API_KONG_GATEWAY=$API_KONG_URL/api
+# Kong Routes
+API_KONG_ROUTE_AUTH_URL=$API_KONG_GATEWAY/auth 
+API_KONG_ROUTE_BOOKINGS_URL=$API_KONG_GATEWAY/bookings
+API_KONG_ROUTE_CLIENTS_URL=$API_KONG_GATEWAY/users/clients
+API_KONG_ROUTE_HOTELS_URL=$API_KONG_GATEWAY/hotels
+API_KONG_ROUTE_MANAGERS_URL=$API_KONG_GATEWAY/users/managers
+API_KONG_ROUTE_USERS_URL=$API_KONG_GATEWAY/users
 #
 #######################################
 # Databases
@@ -40,3 +48,9 @@ DB_HOTELS_HOSTNAME=HotelsDB
 ## DB Users
 DB_USERS_DATABASE=Users
 DB_USERS_HOSTNAME=UsersDB
+#
+#######################################
+# JWT
+#######################################
+JWT_KEY=MiClaveDeSeguridadMuyLargaParaQueNoFalleSpringBoot
+JWT_KID=9L8RmLEKMFd54WrR06CE9zoRSAGpCWeu
diff --git a/.gitignore b/.gitignore
index 9d69baa..734c0ce 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,10 +1,9 @@
 ### Own ###
-taller
+.trunk/
 *.pdf
 **/target/
 **/.vscode
 **/tmp
 **/*.tmp
 *.ln
-*.log
-
+*.log
\ No newline at end of file
diff --git a/angular/RestClient/src/mocks/users.ts b/angular/RestClient/src/mocks/users.ts
deleted file mode 100644
index c21e671..0000000
--- a/angular/RestClient/src/mocks/users.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { Client, User } from '../app/core/models';
-
-export const users: Client[] = [
-  {
-    id: 1,
-    name: 'John Doe',
-    email: 'jon@com',
-    rol: 'CLIENT',
-    status: 'NO_BOOKINGS',
-  },
-  {
-    id: 2,
-    name: 'Angela Doe',
-    email: 'angle@com',
-    rol: 'CLIENT',
-    status: 'NO_BOOKINGS',
-  },
-];
diff --git a/docker-compose.yml b/docker-compose.yml
index 92124a4..2244d32 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -8,6 +8,26 @@ networks: #Red interna para comunicar los servicios
   kong-net:
 
 services:
+  #######################################
+  # Cliente Angular
+  #######################################
+  # RoomsBooking-Web:
+  #   image: roomsbooking-web-image
+  #   build:
+  #     context: ./angular/RestClient
+  #     dockerfile: ./Dockerfile
+  #   restart: unless-stopped
+  #   ports:
+  #     - 4200:80
+  #   networks:
+  #     - kong-net
+  #   depends_on:
+  #     - kong
+  #     - Auth-API
+  #     - Users-API
+  #     - Hotels-API
+  #     - Bookings-API
+
   #######################################
   # Kong
   #######################################
@@ -110,6 +130,25 @@ services:
     ports:
       - 1337:1337
 
+  #######################################
+  # Generate Data
+  #######################################
+
+  Generate-APIs-Data:
+    image: gen-apis-data
+    build:
+      context: ./poblate
+      dockerfile: Dockerfile
+    networks:
+      - kong-net
+    restart: on-failure
+    depends_on:
+      - kong
+      - Auth-API
+      - Users-API
+      - Hotels-API
+      - Bookings-API
+
   #######################################
   # APIs
   #######################################
@@ -124,10 +163,11 @@ services:
     networks:
       - kong-net
     environment:
-      SECURITY_JWT_EXPIRATION: 3600000
-      SECURITY_JWT_KID: ${JWT_KID:-9L8RmLEKMFd54WrR06CE9zoRSAGpCWeu}
-      SECURITY_JWT_SECRET_KEY: ${JWT_KEY:-MiClaveDeSeguridadMuyLargaParaQueNoFalleSpringBoot}
-      EXTERNAL_SERVICES_USERS_URL: ${API_USERS_URL}
+      SECURITY_JWT_SECRET-KEY: ${JWT_KEY}
+      SECURITY_JWT_KID: ${JWT_KID}
+      SECURITY_JWT_EXTERNAL_EXPIRATION: ${JWT_EXTERNAL_EXPIRATION:-3600}
+      SECURITY_JWT_INTERNAL_EXPIRATION: ${JWT_INTERNAL_EXPIRATION:-600}
+      SERVICES_EXTERNAL_USERS_URL: ${API_KONG_ROUTE_USERS_URL}
     depends_on:
       - Users-API
 
@@ -142,7 +182,9 @@ services:
       - kong-net
     environment:
       SPRING_DATASOURCE_URL: jdbc:mysql://${DB_USERS_HOSTNAME}:${DB_USERS_PORT:-3306}/${DB_USERS_DATABASE}?createDatabaseIfNotExist=true
-      EXTERNAL_SERVICE_USERS_URL: ${API_USERS_URL}${API_USERS_ENDPOINT}
+      SERVICES_INTERNAL_TOKEN_URL: ${API_AUTH_TOKEN_URL}
+      SERVICES_EXTERNAL_HOTELS_URL: ${API_KONG_ROUTE_HOTELS_URL}
+      SERVICES_EXTERNAL_BOOKINGS_URL: ${API_KONG_ROUTE_BOOKINGS_URL}
     depends_on:
       - Users-DB
 
@@ -157,6 +199,9 @@ services:
       - kong-net
     environment:
       SPRING_DATASOURCE_URL: jdbc:mysql://${DB_HOTELS_HOSTNAME}:${DB_HOTELS_PORT:-3306}/${DB_HOTELS_DATABASE}?createDatabaseIfNotExist=true
+      SERVICES_INTERNAL_TOKEN_URL: ${API_AUTH_TOKEN_URL}
+      SERVICES_EXTERNAL_MANAGERS_URL: ${API_KONG_ROUTE_MANAGERS_URL}
+      SERVICES_EXTERNAL_BOOKINGS_URL: ${API_KONG_ROUTE_BOOKINGS_URL}
     depends_on:
       - Hotels-DB
 
@@ -171,6 +216,11 @@ services:
       - kong-net
     environment:
       SPRING_DATASOURCE_URL: jdbc:mysql://${DB_BOOKINGS_HOSTNAME}:${DB_BOOKINGS_PORT:-3306}/${DB_BOOKINGS_DATABASE}?createDatabaseIfNotExist=true
+      SERVICES_INTERNAL_TOKEN_URL: ${API_AUTH_TOKEN_URL}
+      SERVICES_EXTERNAL_CLIENTS_URL: ${API_KONG_ROUTE_CLIENTS_URL}
+      SERVICES_EXTERNAL_MANAGERS_URL: ${API_KONG_ROUTE_MANAGERS_URL}
+      SERVICES_EXTERNAL_HOTELS_URL: ${API_KONG_ROUTE_HOTELS_URL}
+
     depends_on:
       - Users-API
       - Hotels-API
@@ -223,26 +273,10 @@ services:
     networks:
       - kong-net
     volumes:
-      - hotels_data:/var/lib/mysql
+      - bookings_data:/var/lib/mysql
     environment:
       MYSQL_ROOT_PASSWORD: ${DB_CREDENTIALS_ROOT_PASSWORD:-ClaveRoot}
       MYSQL_USER: ${DB_CREDENTIALS_USER:-user}
       MYSQL_PASSWORD: ${DB_CREDENTIALS_PASSWORD:-password}
       MYSQL_DATABASE: ${DB_BOOKINGS_DATABASE}
       MYSQL_ROOT_HOST: "%"
-
-  #######################################
-  # Cliente Angular
-  #######################################
-  RoomsBooking-Web:
-    image: roomsbooking-web-image
-    build:
-      context: ./angular/RestClient
-      dockerfile: ./Dockerfile
-    restart: unless-stopped
-    ports:
-      - 4200:80
-    networks:
-      - kong-net
-    depends_on:
-      - RoomsBooking-database
diff --git a/java/services/auth/src/main/resources/application.properties b/java/services/auth/src/main/resources/application.properties
index 992556c..14e05dd 100644
--- a/java/services/auth/src/main/resources/application.properties
+++ b/java/services/auth/src/main/resources/application.properties
@@ -2,9 +2,9 @@ spring.application.name=authentication
 server.port=8101
 
 security.jwt.secret-key=MiClaveDeSeguridadMuyLargaParaQueNoFalleSpringBoot
-# 1h in seconds
+# Tiempo de validez para tokens para usuarios (externos) 1h in seconds
 security.jwt.external.expiration=3600 
-# 10min in seconds
+# Tiempo de validez para tokens para servicios (internos) 10min in seconds
 security.jwt.internal.expiration=600
 security.jwt.kid=cYz3kNRLAirxVhHXQ5rh5xKrOwHwZVui
 
diff --git a/java/services/bookings/src/main/java/com/uva/api/bookings/api/UserApi.java b/java/services/bookings/src/main/java/com/uva/api/bookings/api/UserApi.java
index 6e91634..a17bf87 100644
--- a/java/services/bookings/src/main/java/com/uva/api/bookings/api/UserApi.java
+++ b/java/services/bookings/src/main/java/com/uva/api/bookings/api/UserApi.java
@@ -14,12 +14,15 @@ public class UserApi {
   @Autowired
   private RestTemplate restTemplate;
 
-  @Value("${services.external.users.url}")
-  private String USERS_API_URL;
+  @Value("${services.external.clients.url}")
+  private String CLIENTS_API_URL;
+
+  @Value("${services.external.managers.url}")
+  private String MANAGERS_API_URL;
 
   public boolean existsClientById(int id) {
     try {
-      String url = USERS_API_URL + "/clients/{id}";
+      String url = CLIENTS_API_URL + "/{id}";
       ResponseEntity<Void> response = restTemplate.getForEntity(url, Void.class, id);
       return response.getStatusCode() == HttpStatus.OK;
     } catch (HttpClientErrorException ex) {
@@ -32,7 +35,7 @@ public class UserApi {
 
   public boolean existsManagerById(int id) {
     try {
-      String url = USERS_API_URL + "/managers/{id}";
+      String url = MANAGERS_API_URL + "/{id}";
       ResponseEntity<Void> response = restTemplate.getForEntity(url, Void.class, id);
       return response.getStatusCode() == HttpStatus.OK;
     } catch (HttpClientErrorException ex) {
diff --git a/java/services/bookings/src/main/resources/application.properties b/java/services/bookings/src/main/resources/application.properties
index 1c5908a..9198f97 100644
--- a/java/services/bookings/src/main/resources/application.properties
+++ b/java/services/bookings/src/main/resources/application.properties
@@ -7,8 +7,10 @@ spring.datasource.username=user
 spring.datasource.password=password
 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
 
-spring.security.user.enabled=false
+spring.security.user.name=user
+spring.security.user.password=password
 
 services.internal.token.url=http://localhost:8101/token
-services.external.users.url=http://localhost:8201/users
+services.external.clients.url=http://localhost:8201/users/clients
+services.external.managers.url=http://localhost:8201/users/managers
 services.external.hotels.url=http://localhost:8301/hotels
\ No newline at end of file
diff --git a/java/services/hotels/src/main/resources/application.properties b/java/services/hotels/src/main/resources/application.properties
index c607a84..f382a5d 100644
--- a/java/services/hotels/src/main/resources/application.properties
+++ b/java/services/hotels/src/main/resources/application.properties
@@ -7,12 +7,8 @@ spring.datasource.username=user
 spring.datasource.password=password
 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
 
-spring.security.user.enabled=false
-
-security.jwt.secret-key=MiClaveDeSeguridadMuyLargaParaQueNoFalleSpringBoot
-# 1h in millisecond
-security.jwt.expiration-time=3600000 
-security.jwt.kid=cYz3kNRLAirxVhHXQ5rh5xKrOwHwZVui
+spring.security.user.name=user
+spring.security.user.password=password
 
 services.internal.token.url=http://localhost:8101/token
 services.external.managers.url=http://localhost:8201/users/managers
diff --git a/java/services/users/src/main/resources/application.properties b/java/services/users/src/main/resources/application.properties
index 6ad30a8..c680e76 100644
--- a/java/services/users/src/main/resources/application.properties
+++ b/java/services/users/src/main/resources/application.properties
@@ -10,11 +10,6 @@ spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
 spring.security.user.name=user
 spring.security.user.password=password
 
-security.jwt.secret-key=MiClaveDeSeguridadMuyLargaParaQueNoFalleSpringBoot
-# 1h in millisecond
-security.jwt.expiration-time=3600000 
-security.jwt.kid=cYz3kNRLAirxVhHXQ5rh5xKrOwHwZVui
-
 services.internal.token.url=http://localhost:8101/token/
 services.external.hotels.url=http://localhost:8301/hotels
 services.external.bookings.url=http://localhost:8401/bookings
\ No newline at end of file
diff --git a/kong_config.json b/kong_config.json
new file mode 100644
index 0000000..2754ccc
--- /dev/null
+++ b/kong_config.json
@@ -0,0 +1 @@
+{"createdUser":null,"updatedUser":null,"id":1,"name":"Practica","kong_node_name":"Kong","kong_node_url":"http://kong:8001","kong_version":"3.9.0","data":{"services":[{"retries":5,"tags":[],"created_at":1735150914,"updated_at":1735150914,"name":"Users","port":8201,"id":"1d1ce8d9-aa4b-4576-8d91-00326d00c26e","client_certificate":null,"write_timeout":60000,"connect_timeout":60000,"read_timeout":60000,"protocol":"http","enabled":true,"ca_certificates":null,"tls_verify":null,"path":"/users","tls_verify_depth":null,"host":"users-api","extras":{"id":1,"service_id":"1d1ce8d9-aa4b-4576-8d91-00326d00c26e","kong_node_id":"1","description":null,"tags":null,"createdAt":"2024-12-25T18:21:54.000Z","updatedAt":"2024-12-25T18:21:54.000Z","createdUser":null,"updatedUser":null}},{"retries":5,"tags":[],"created_at":1735151821,"updated_at":1735151821,"name":"Hotels","port":8301,"id":"37407f92-1d9f-4d88-b80f-0bc9a3fb57fd","client_certificate":null,"write_timeout":60000,"connect_timeout":60000,"read_timeout":60000,"protocol":"http","enabled":true,"ca_certificates":null,"tls_verify":null,"path":"/hotels","tls_verify_depth":null,"host":"hotels-api","extras":{"id":3,"service_id":"37407f92-1d9f-4d88-b80f-0bc9a3fb57fd","kong_node_id":"1","description":null,"tags":null,"createdAt":"2024-12-25T18:37:01.000Z","updatedAt":"2024-12-25T18:37:01.000Z","createdUser":null,"updatedUser":null}},{"retries":5,"tags":[],"created_at":1735151037,"updated_at":1735151134,"name":"Auth","port":8101,"id":"60e76e38-63f1-4fd7-b10c-51456722a312","client_certificate":null,"write_timeout":60000,"connect_timeout":60000,"read_timeout":60000,"protocol":"http","enabled":true,"ca_certificates":null,"tls_verify":null,"path":"/auth","tls_verify_depth":null,"host":"auth-api","extras":{"id":2,"service_id":"60e76e38-63f1-4fd7-b10c-51456722a312","kong_node_id":"1","description":null,"tags":null,"createdAt":"2024-12-25T18:23:57.000Z","updatedAt":"2024-12-25T18:25:34.000Z","createdUser":null,"updatedUser":null}},{"retries":5,"tags":[],"created_at":1735151922,"updated_at":1735151922,"name":"Bookings","port":8401,"id":"ae250c19-10c3-4ed2-8cdb-d62497721da2","client_certificate":null,"write_timeout":60000,"connect_timeout":60000,"read_timeout":60000,"protocol":"http","enabled":true,"ca_certificates":null,"tls_verify":null,"path":"/bookings","tls_verify_depth":null,"host":"bookings-api","extras":{"id":4,"service_id":"ae250c19-10c3-4ed2-8cdb-d62497721da2","kong_node_id":"1","description":null,"tags":null,"createdAt":"2024-12-25T18:38:42.000Z","updatedAt":"2024-12-25T18:38:42.000Z","createdUser":null,"updatedUser":null}}],"routes":[{"tags":null,"created_at":1735151865,"updated_at":1735151865,"name":"hotels","destinations":null,"strip_path":true,"hosts":null,"methods":["GET","POST","PUT","PATCH","DELETE","OPTIONS"],"service":{"id":"37407f92-1d9f-4d88-b80f-0bc9a3fb57fd"},"preserve_host":false,"regex_priority":0,"headers":null,"paths":["/api/hotels"],"request_buffering":true,"response_buffering":true,"protocols":["http","https"],"sources":null,"id":"17bc07be-9af8-499f-9ec6-716504cd801f","path_handling":"v1","https_redirect_status_code":426,"snis":null},{"tags":null,"created_at":1735151081,"updated_at":1735151965,"name":"Auth","destinations":null,"strip_path":true,"hosts":null,"methods":["OPTIONS","POST","DELETE"],"service":{"id":"60e76e38-63f1-4fd7-b10c-51456722a312"},"preserve_host":false,"regex_priority":0,"headers":null,"paths":["/api/auth"],"request_buffering":true,"response_buffering":true,"protocols":["http","https"],"sources":null,"id":"4f7e698c-aed6-4919-8d72-a24ce6a2a333","path_handling":"v1","https_redirect_status_code":426,"snis":null},{"tags":null,"created_at":1735151945,"updated_at":1735151945,"name":"Bookings","destinations":null,"strip_path":true,"hosts":null,"methods":["GET","POST","PATCH","PUT","DELETE","OPTIONS"],"service":{"id":"ae250c19-10c3-4ed2-8cdb-d62497721da2"},"preserve_host":false,"regex_priority":0,"headers":null,"paths":["/api/bookings"],"request_buffering":true,"response_buffering":true,"protocols":["http","https"],"sources":null,"id":"810bbb6d-a10d-416d-b5db-a121762981fa","path_handling":"v1","https_redirect_status_code":426,"snis":null},{"tags":null,"created_at":1735150976,"updated_at":1735150976,"name":"Usuarios","destinations":null,"strip_path":true,"hosts":null,"methods":["OPTIONS","GET","POST","DELETE","PUT","PATCH"],"service":{"id":"1d1ce8d9-aa4b-4576-8d91-00326d00c26e"},"preserve_host":false,"regex_priority":0,"headers":null,"paths":["/api/users"],"request_buffering":true,"response_buffering":true,"protocols":["http","https"],"sources":null,"id":"df0fefa6-7df8-4ae3-baed-ae58add42bbf","path_handling":"v1","https_redirect_status_code":426,"snis":null}],"consumers":[{"id":"c012b84f-63af-461f-8a8d-b8f99a2bd006","tags":[],"created_at":1735155577,"updated_at":1735155577,"custom_id":null,"username":"JWT","credentials":{"jwts":[{"rsa_public_key":null,"algorithm":"HS256","tags":null,"created_at":1735155689,"key":"9L8RmLEKMFd54WrR06CE9zoRSAGpCWeu","consumer":{"id":"c012b84f-63af-461f-8a8d-b8f99a2bd006"},"id":"493ad0f9-23e7-4e5f-b6e1-6982677ba0d6","secret":"MiClaveDeSeguridadMuyLargaParaQueNoFalleSpringBoot"}]}}],"plugins":[{"config":{"secret_is_base64":false,"key_claim_name":"kid","claims_to_verify":["exp"],"maximum_expiration":0,"uri_param_names":["jwt"],"cookie_names":[],"header_names":["Authorization"],"realm":null,"run_on_preflight":true,"anonymous":null},"tags":null,"created_at":1735155843,"updated_at":1735155843,"name":"jwt","route":{"id":"810bbb6d-a10d-416d-b5db-a121762981fa"},"consumer":null,"id":"3e302549-c51f-469d-a71d-98f30f2ddcab","protocols":["grpc","grpcs","http","https"],"instance_name":null,"service":null,"enabled":true},{"config":{"secret_is_base64":false,"key_claim_name":"kid","claims_to_verify":["exp"],"maximum_expiration":0,"uri_param_names":["jwt"],"cookie_names":[],"header_names":["Authorization"],"realm":null,"run_on_preflight":true,"anonymous":null},"tags":null,"created_at":1735156525,"updated_at":1735156585,"name":"jwt","route":{"id":"df0fefa6-7df8-4ae3-baed-ae58add42bbf"},"consumer":null,"id":"8386bf54-ede1-4f34-bb87-989ce4276e8a","protocols":["grpc","grpcs","http","https"],"instance_name":null,"service":null,"enabled":true},{"config":{"secret_is_base64":false,"key_claim_name":"kid","claims_to_verify":["exp"],"maximum_expiration":0,"uri_param_names":["jwt"],"cookie_names":[],"header_names":["Authorization"],"realm":null,"run_on_preflight":true,"anonymous":null},"tags":null,"created_at":1735156492,"updated_at":1735156600,"name":"jwt","route":{"id":"17bc07be-9af8-499f-9ec6-716504cd801f"},"consumer":null,"id":"9ac23748-1964-4038-8cdc-b2db799010a6","protocols":["grpc","grpcs","http","https"],"instance_name":null,"service":null,"enabled":true}],"acls":[],"upstreams":[],"certificates":[],"snis":[]},"createdAt":"2024-12-25T19:59:28.000Z","updatedAt":"2024-12-25T19:59:28.000Z"}
\ No newline at end of file
diff --git a/poblate/Dockerfile b/poblate/Dockerfile
new file mode 100644
index 0000000..29f6ea7
--- /dev/null
+++ b/poblate/Dockerfile
@@ -0,0 +1,11 @@
+FROM node:20
+
+# Establecer el directorio de trabajo
+WORKDIR /app
+
+COPY package*.json ./
+RUN npm install
+
+COPY . .
+
+CMD ["npm", "run", "prod", "--", "-d"]
\ No newline at end of file
diff --git a/poblate/index.js b/poblate/index.js
index 1a3b339..1a95be4 100644
--- a/poblate/index.js
+++ b/poblate/index.js
@@ -10,6 +10,7 @@ const args = process.argv;
 const isProduction = args.includes("--prod");
 const DEBUG = args.includes("--debug") || args.includes("-d");
 const FORCE = args.includes("--force") || args.includes("-f");
+const ERROR = args.includes("--error") || args.includes("-e");
 
 const env = (isProduction ? prod : dev).env;
 const { authApi, hotelsApi, bookingsApi } = env;
@@ -33,7 +34,7 @@ function genDates(ref = new Date()) {
 
 	// After
 	const afterStart = new Date(ref);
-	afterStart.setDate(ref.getDate() + 14); // Restar 2 semanas
+	afterStart.setDate(ref.getDate() + 14); // Sumar 2 semanas
 
 	const afterEnd = new Date(afterStart);
 	afterEnd.setDate(afterStart.getDate() + 2);
@@ -57,18 +58,23 @@ function getRandomItem(a = []) {
 const savePost = async (data, first, second = "") => {
 	try {
 		try {
+			debug("Trying to register user", data);
 			return await axios.post(first, data);
 		} catch (error) {
-			console.error("ERROR Al REGISTRO, SE PROCEDE A INTENTAR ACCEDER");
+			debug("Trying to log user", data);
+			debug("ERROR:", ERROR ? error : error.data ?? error.cause);
+			debug("ERROR Al REGISTRO, SE PROCEDE A INTENTAR ACCEDER");
+			const response = await axios.post(second, data);
 			if (!FORCE) {
 				console.log("Parece que ya hay datos en el sistema");
 				process.exit(0);
 			}
-			return await axios.post(second, data);
+			return response;
 		}
 	} catch (error) {
 		console.error("ERROR Al LOGIN");
 		console.error("\nNo se ha podido comunicar con el servicio de auth");
+		debug("ERROR:", ERROR ? error : error.data ?? error.cause);
 		process.exit(-1);
 	}
 };
@@ -79,6 +85,7 @@ async function register(user) {
 		`${authApi}/register`,
 		`${authApi}/login`
 	);
+	debug("User identified successful");
 	const decoded = jwtDecode(data.token);
 	user.id = decoded.id;
 	user.token = data.token;
@@ -100,22 +107,21 @@ const addUsers = async () => {
 
 const insertHotel = async ({ manager, hotel }) => {
 	try {
-		const { data } = await axios.post(
-			hotelsApi,
-			{
-				...hotel,
-				managerId: manager.id,
+		const body = {
+			...hotel,
+			managerId: manager.id,
+		};
+		debug("Trying to add booking", body);
+		const { data } = await axios.post(hotelsApi, body, {
+			headers: {
+				Authorization: `Bearer ${manager.token}`,
 			},
-			{
-				headers: {
-					Authorization: `Bearer ${manager.token}`,
-				},
-			}
-		);
+		});
+		debug("Hotel added successful");
 		return data;
-	} catch (e) {
-		// console.error(e);
+	} catch (error) {
 		console.error("ERROR Al INSERTAR HOTEL");
+		debug("ERROR:", ERROR ? error : error.data ?? error.cause);
 		process.exit(-1);
 	}
 };
@@ -131,15 +137,17 @@ async function addHotels(managers) {
 
 const insertBookings = async (booking, token) => {
 	try {
+		debug("Trying to add booking", booking);
 		const { data } = await axios.post(bookingsApi, booking, {
 			headers: {
 				Authorization: `Bearer ${token}`,
 			},
 		});
+		debug("Booking added successful");
 		return data;
-	} catch (e) {
-		// console.error(e);
-		console.error("ERROR Al INSERTAR HOTEL");
+	} catch (error) {
+		console.error("ERROR Al INSERTAR RESERVA");
+		debug("ERROR:", ERROR ? error : error.data ?? error.cause);
 		process.exit(-1);
 	}
 };
-- 
GitLab


From 364a6ee65ae6ca8574b313fa1451d67353d42aad Mon Sep 17 00:00:00 2001
From: hugcubi <hugo.cubino@estudiantes.uva.es>
Date: Wed, 25 Dec 2024 23:11:13 +0100
Subject: [PATCH 3/4] Mejora del manejo de errores en users y auth

---
 .../java/com/uva/api/auth/api/UserAPI.java    | 14 +++----
 .../api/auth/controllers/AuthController.java  | 19 +---------
 .../exceptions/GlobalExceptionHandler.java    | 32 ++++++++++++++++
 .../uva/api/auth/services/AuthService.java    | 38 +++++++++----------
 .../exceptions/GlobalExceptionHandler.java    | 10 +++++
 .../users/repositories/UserRepository.java    |  2 +
 .../api/users/services/ManagerService.java    |  1 -
 .../uva/api/users/services/UserService.java   |  5 +++
 8 files changed, 76 insertions(+), 45 deletions(-)
 create mode 100644 java/services/auth/src/main/java/com/uva/api/auth/exceptions/GlobalExceptionHandler.java

diff --git a/java/services/auth/src/main/java/com/uva/api/auth/api/UserAPI.java b/java/services/auth/src/main/java/com/uva/api/auth/api/UserAPI.java
index 57f661e..b41d97f 100644
--- a/java/services/auth/src/main/java/com/uva/api/auth/api/UserAPI.java
+++ b/java/services/auth/src/main/java/com/uva/api/auth/api/UserAPI.java
@@ -55,14 +55,14 @@ public class UserAPI {
    */
   public User registerUser(RegisterRequest registerRequest) {
     String url = USER_API_URL;
-    System.out.println(url + " " + registerRequest);
-    ResponseEntity<User> userResponse = restTemplate.postForEntity(url, registerRequest, User.class);
-    if (!userResponse.getStatusCode().is2xxSuccessful()) {
-      String errorMessage = "Failed to register user: " + userResponse.getStatusCode() + ". " + userResponse.getBody();
-      throw new HttpClientErrorException(userResponse.getStatusCode(), errorMessage);
+    try {
+      ResponseEntity<User> userResponse = restTemplate.postForEntity(url, registerRequest, User.class);
+      return userResponse.getBody();
+    } catch (HttpClientErrorException ex) {
+      if (ex.getStatusCode() == HttpStatus.BAD_REQUEST)
+        throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Register failed");
+      throw ex;
     }
-
-    return userResponse.getBody();
   }
 
   /**
diff --git a/java/services/auth/src/main/java/com/uva/api/auth/controllers/AuthController.java b/java/services/auth/src/main/java/com/uva/api/auth/controllers/AuthController.java
index ceda96e..f84a840 100644
--- a/java/services/auth/src/main/java/com/uva/api/auth/controllers/AuthController.java
+++ b/java/services/auth/src/main/java/com/uva/api/auth/controllers/AuthController.java
@@ -6,7 +6,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
-import org.springframework.web.client.HttpClientErrorException;
 
 import com.uva.api.auth.models.auth.LoginRequest;
 import com.uva.api.auth.models.auth.RegisterRequest;
@@ -25,26 +24,12 @@ public class AuthController {
 
     @PostMapping("/login")
     public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) {
-        try {
-            return authService.login(loginRequest);
-        } catch (HttpClientErrorException e) {
-            if (e.getStatusCode() == HttpStatus.FORBIDDEN) {
-                return new ResponseEntity<>(e.getMessage(), HttpStatus.FORBIDDEN);
-            }
-        }
-        return new ResponseEntity<>("Algo no fue bien", HttpStatus.UNAUTHORIZED);
+        return authService.login(loginRequest);
     }
 
     @PostMapping("/register")
     public ResponseEntity<?> register(@RequestBody RegisterRequest registerRequest) {
-        try {
-            return authService.register(registerRequest);
-        } catch (HttpClientErrorException e) {
-            if (e.getStatusCode() == HttpStatus.CONFLICT)
-                return new ResponseEntity<>(e.getMessage(), HttpStatus.CONFLICT);
-        }
-
-        return new ResponseEntity<>("Algo no fue bien", HttpStatus.UNAUTHORIZED);
+        return authService.register(registerRequest);
     }
 
     @PostMapping("/password")
diff --git a/java/services/auth/src/main/java/com/uva/api/auth/exceptions/GlobalExceptionHandler.java b/java/services/auth/src/main/java/com/uva/api/auth/exceptions/GlobalExceptionHandler.java
new file mode 100644
index 0000000..f82af24
--- /dev/null
+++ b/java/services/auth/src/main/java/com/uva/api/auth/exceptions/GlobalExceptionHandler.java
@@ -0,0 +1,32 @@
+package com.uva.api.auth.exceptions;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.client.HttpClientErrorException;
+
+import java.time.LocalDateTime;
+import java.util.HashMap;
+import java.util.Map;
+
+@ControllerAdvice
+public class GlobalExceptionHandler {
+  @ExceptionHandler(HttpClientErrorException.class)
+  public ResponseEntity<Map<String, Object>> handleHttpClientErrorException(HttpClientErrorException ex) {
+    Map<String, Object> body = new HashMap<>();
+    body.put("timestamp", LocalDateTime.now());
+    body.put("message", ex.getMessage());
+
+    return new ResponseEntity<>(body, ex.getStatusCode());
+  }
+
+  @ExceptionHandler(Exception.class)
+  public ResponseEntity<Map<String, Object>> handleGeneralException(Exception ex) {
+    Map<String, Object> body = new HashMap<>();
+    body.put("timestamp", LocalDateTime.now());
+    body.put("message", "An unexpected error occurred: " + ex.getMessage());
+
+    return new ResponseEntity<>(body, HttpStatus.INTERNAL_SERVER_ERROR);
+  }
+}
diff --git a/java/services/auth/src/main/java/com/uva/api/auth/services/AuthService.java b/java/services/auth/src/main/java/com/uva/api/auth/services/AuthService.java
index 1449758..5cf22ae 100644
--- a/java/services/auth/src/main/java/com/uva/api/auth/services/AuthService.java
+++ b/java/services/auth/src/main/java/com/uva/api/auth/services/AuthService.java
@@ -79,7 +79,7 @@ public class AuthService {
   public ResponseEntity<?> changePassword(String token, String actualPass, String newPass) {
     JwtData decoded = jwtUtil.decodeToken(token);
     if (decoded == null)
-      return new ResponseEntity<>(HttpStatus.FORBIDDEN);
+      throw new HttpClientErrorException(HttpStatus.FORBIDDEN);
 
     String email = decoded.getEmail();
     User user = getUser(email, actualPass);
@@ -87,23 +87,22 @@ public class AuthService {
     boolean changePasswordAllowed = decoded.isAdmin() || user != null;
 
     if (user != null && !validStrings(actualPass, newPass))
-      return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
-
-    if (changePasswordAllowed) {
-      // Actualizamos la nueva
-      String hashPass = SecurityUtils.encrypt(newPass);
-      userAPI.changePassword(user, hashPass);
-      // Hacemos un login con los nuevos datos
-      return login(new LoginRequest(email, newPass));
-    } else {
-      return new ResponseEntity<>("Invalid credentials", HttpStatus.FORBIDDEN);
-    }
+      throw new HttpClientErrorException(HttpStatus.BAD_REQUEST);
+
+    if (!changePasswordAllowed)
+      throw new HttpClientErrorException(HttpStatus.FORBIDDEN, "Invalid credentials");
+
+    // Actualizamos la nueva
+    String hashPass = SecurityUtils.encrypt(newPass);
+    userAPI.changePassword(user, hashPass);
+    // Hacemos un login con los nuevos datos
+    return login(new LoginRequest(email, newPass));
   }
 
   public ResponseEntity<?> deleteUser(String token, int id, String password) {
     JwtData decoded = jwtUtil.decodeToken(token);
     if (decoded == null)
-      return new ResponseEntity<>(HttpStatus.FORBIDDEN);
+      throw new HttpClientErrorException(HttpStatus.FORBIDDEN);
 
     String email = decoded.getEmail();
     User user = getUser(email, password);
@@ -112,13 +111,12 @@ public class AuthService {
         || (user != null && user.getId() == id);
 
     if (user != null && !validStrings(password))
-      return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
+      throw new HttpClientErrorException(HttpStatus.BAD_REQUEST);
 
-    if (changePasswordAllowed) {
-      userAPI.deleteUser(user);
-      return new ResponseEntity<>(HttpStatus.OK);
-    } else {
-      return new ResponseEntity<>("Invalid credentials", HttpStatus.FORBIDDEN);
-    }
+    if (!changePasswordAllowed)
+      throw new HttpClientErrorException(HttpStatus.FORBIDDEN, "Invalid credentials");
+
+    userAPI.deleteUser(user);
+    return ResponseEntity.ok(user);
   }
 }
diff --git a/java/services/users/src/main/java/com/uva/api/users/exceptions/GlobalExceptionHandler.java b/java/services/users/src/main/java/com/uva/api/users/exceptions/GlobalExceptionHandler.java
index 4241b4d..f7e1e6f 100644
--- a/java/services/users/src/main/java/com/uva/api/users/exceptions/GlobalExceptionHandler.java
+++ b/java/services/users/src/main/java/com/uva/api/users/exceptions/GlobalExceptionHandler.java
@@ -4,6 +4,7 @@ import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.ControllerAdvice;
 import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.client.HttpClientErrorException;
 
 import java.time.LocalDateTime;
 import java.util.HashMap;
@@ -21,6 +22,15 @@ public class GlobalExceptionHandler {
         return new ResponseEntity<>(body, HttpStatus.NOT_FOUND);
     }
 
+    @ExceptionHandler(HttpClientErrorException.class)
+    public ResponseEntity<Map<String, Object>> handleHttpClientErrorException(HttpClientErrorException ex) {
+        Map<String, Object> body = new HashMap<>();
+        body.put("timestamp", LocalDateTime.now());
+        body.put("message", ex.getMessage());
+
+        return new ResponseEntity<>(body, ex.getStatusCode());
+    }
+
     @ExceptionHandler(Exception.class)
     public ResponseEntity<Map<String, Object>> handleGeneralException(Exception ex) {
         Map<String, Object> body = new HashMap<>();
diff --git a/java/services/users/src/main/java/com/uva/api/users/repositories/UserRepository.java b/java/services/users/src/main/java/com/uva/api/users/repositories/UserRepository.java
index 94c7526..bf5e152 100644
--- a/java/services/users/src/main/java/com/uva/api/users/repositories/UserRepository.java
+++ b/java/services/users/src/main/java/com/uva/api/users/repositories/UserRepository.java
@@ -8,4 +8,6 @@ import com.uva.api.users.models.User;
 
 public interface UserRepository extends JpaRepository<User, Integer> {
   Optional<User> findByEmail(String email);
+
+  Boolean existsByEmail(String email);
 }
diff --git a/java/services/users/src/main/java/com/uva/api/users/services/ManagerService.java b/java/services/users/src/main/java/com/uva/api/users/services/ManagerService.java
index 9c9dba2..bc776e6 100644
--- a/java/services/users/src/main/java/com/uva/api/users/services/ManagerService.java
+++ b/java/services/users/src/main/java/com/uva/api/users/services/ManagerService.java
@@ -5,7 +5,6 @@ import java.util.List;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
-
 import com.uva.api.users.api.HotelApi;
 import com.uva.api.users.models.Manager;
 import com.uva.api.users.models.User;
diff --git a/java/services/users/src/main/java/com/uva/api/users/services/UserService.java b/java/services/users/src/main/java/com/uva/api/users/services/UserService.java
index bf2d04f..1a7cd8b 100644
--- a/java/services/users/src/main/java/com/uva/api/users/services/UserService.java
+++ b/java/services/users/src/main/java/com/uva/api/users/services/UserService.java
@@ -4,8 +4,10 @@ import java.util.List;
 
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
+import org.springframework.web.client.HttpClientErrorException;
 
 import com.uva.api.users.models.AuthDTO;
 import com.uva.api.users.models.User;
@@ -47,6 +49,9 @@ public class UserService {
   }
 
   public ResponseEntity<User> registerNewUser(AuthDTO request) {
+    if (userRepository.existsByEmail(request.getEmail()))
+      throw new HttpClientErrorException(HttpStatus.BAD_REQUEST);
+
     User user = new User();
     BeanUtils.copyProperties(request, user);
 
-- 
GitLab


From eaf26664a565d0641c7a25603d3c87f893f8b7a9 Mon Sep 17 00:00:00 2001
From: hugcubi <hugo.cubino@estudiantes.uva.es>
Date: Thu, 26 Dec 2024 15:52:22 +0100
Subject: [PATCH 4/4] Diagramas

---
 angular/RestClient/src/mocks/users.ts         |  18 ++++++++++++++++++
 diagramas/practica.asta                       | Bin 0 -> 31103 bytes
 .../uva/api/users/services/ClientService.java |   5 +----
 .../api/users/services/ManagerService.java    |   8 ++------
 .../uva/api/users/services/UserService.java   |  10 ++++++++--
 5 files changed, 29 insertions(+), 12 deletions(-)
 create mode 100644 angular/RestClient/src/mocks/users.ts
 create mode 100644 diagramas/practica.asta

diff --git a/angular/RestClient/src/mocks/users.ts b/angular/RestClient/src/mocks/users.ts
new file mode 100644
index 0000000..c21e671
--- /dev/null
+++ b/angular/RestClient/src/mocks/users.ts
@@ -0,0 +1,18 @@
+import { Client, User } from '../app/core/models';
+
+export const users: Client[] = [
+  {
+    id: 1,
+    name: 'John Doe',
+    email: 'jon@com',
+    rol: 'CLIENT',
+    status: 'NO_BOOKINGS',
+  },
+  {
+    id: 2,
+    name: 'Angela Doe',
+    email: 'angle@com',
+    rol: 'CLIENT',
+    status: 'NO_BOOKINGS',
+  },
+];
diff --git a/diagramas/practica.asta b/diagramas/practica.asta
new file mode 100644
index 0000000000000000000000000000000000000000..78f91509c528f8268b56577e3bdff74384871e02
GIT binary patch
literal 31103
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

literal 0
HcmV?d00001

diff --git a/java/services/users/src/main/java/com/uva/api/users/services/ClientService.java b/java/services/users/src/main/java/com/uva/api/users/services/ClientService.java
index 6f5a8af..a0a1975 100644
--- a/java/services/users/src/main/java/com/uva/api/users/services/ClientService.java
+++ b/java/services/users/src/main/java/com/uva/api/users/services/ClientService.java
@@ -3,7 +3,6 @@ package com.uva.api.users.services;
 import java.time.LocalDate;
 import java.util.List;
 
-import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
@@ -42,9 +41,7 @@ public class ClientService {
     return client;
   }
 
-  public Client save(User request) {
-    Client client = new Client();
-    BeanUtils.copyProperties(request, client);
+  public Client save(Client client) {
     // Default rol
     client.setRol(UserRol.CLIENT);
     return clientRepository.save(client);
diff --git a/java/services/users/src/main/java/com/uva/api/users/services/ManagerService.java b/java/services/users/src/main/java/com/uva/api/users/services/ManagerService.java
index bc776e6..cf9e952 100644
--- a/java/services/users/src/main/java/com/uva/api/users/services/ManagerService.java
+++ b/java/services/users/src/main/java/com/uva/api/users/services/ManagerService.java
@@ -2,12 +2,10 @@ package com.uva.api.users.services;
 
 import java.util.List;
 
-import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.uva.api.users.api.HotelApi;
 import com.uva.api.users.models.Manager;
-import com.uva.api.users.models.User;
 import com.uva.api.users.repositories.ManagerRepository;
 import com.uva.api.users.utils.Utils;
 
@@ -20,10 +18,8 @@ public class ManagerService {
   @Autowired
   private ManagerRepository managerRepository;
 
-  public Manager save(User request) {
-    Manager hm = new Manager();
-    BeanUtils.copyProperties(request, hm);
-    return managerRepository.save(hm);
+  public Manager save(Manager manager) {
+    return managerRepository.save(manager);
   }
 
   public List<Manager> findAll() {
diff --git a/java/services/users/src/main/java/com/uva/api/users/services/UserService.java b/java/services/users/src/main/java/com/uva/api/users/services/UserService.java
index 1a7cd8b..23125b3 100644
--- a/java/services/users/src/main/java/com/uva/api/users/services/UserService.java
+++ b/java/services/users/src/main/java/com/uva/api/users/services/UserService.java
@@ -10,6 +10,8 @@ import org.springframework.stereotype.Service;
 import org.springframework.web.client.HttpClientErrorException;
 
 import com.uva.api.users.models.AuthDTO;
+import com.uva.api.users.models.Client;
+import com.uva.api.users.models.Manager;
 import com.uva.api.users.models.User;
 import com.uva.api.users.models.UserRol;
 import com.uva.api.users.repositories.UserRepository;
@@ -67,12 +69,16 @@ public class UserService {
         break;
 
       case HOTEL_ADMIN:
-        user = managerService.save(user);
+        Manager manager = new Manager();
+        BeanUtils.copyProperties(request, manager);
+        user = managerService.save(manager);
         break;
 
       case CLIENT: // By default
       default:
-        user = clientService.save(user);
+        Client client = new Client();
+        BeanUtils.copyProperties(request, client);
+        user = clientService.save(client);
         break;
     }
     return ResponseEntity.ok(user);
-- 
GitLab