diff --git a/.gitignore b/.gitignore index 73cfdb62c0d09ddc5671811621d994cd2271da64..b82c94fbe7dec8073b73fe9914d08b263803dfaf 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,8 @@ taller *.pdf **/target/ -**/.vscode \ No newline at end of file +**/.vscode +*.ln +*.tmp +**/tmp +*.log \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 40484328bc7cb6aa6b3d94b2616393b3e0cab264..85641c264792a1c3cafb824d8b0b4337f2764ad1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,7 +8,7 @@ networks: services: Auth-API: image: auth-api-image - hostname: ${AUTH_SERVICE_HOSTNAME} + hostname: $${AUTH_SERVICE_HOSTNAME} build: context: ./java/services/auth dockerfile: Dockerfile @@ -18,13 +18,13 @@ services: networks: - kong-net environment: - SPRING_DATASOURCE_URL: jdbc:mysql://${DB_SERVICE_HOSTNAME}:3306/${DB_DATABASE_NAME}?createDatabaseIfNotExist=true + SPRING_DATASOURCE_URL: jdbc:mysql://$${DB_SERVICE_HOSTNAME}:3306/$${DB_DATABASE_NAME}?createDatabaseIfNotExist=true depends_on: - RoomsBooking-database Users-API: image: users-api-image - hostname: "${USERS_SERVICE_HOSTNAME}" + hostname: "$${USERS_SERVICE_HOSTNAME}" build: context: ./java/services/users dockerfile: Dockerfile @@ -34,13 +34,13 @@ services: networks: - kong-net environment: - SPRING_DATASOURCE_URL: jdbc:mysql://${DB_SERVICE_HOSTNAME}:3306/${DB_DATABASE_NAME}?createDatabaseIfNotExist=true + SPRING_DATASOURCE_URL: jdbc:mysql://$${DB_SERVICE_HOSTNAME}:3306/$${DB_DATABASE_NAME}?createDatabaseIfNotExist=true depends_on: - RoomsBooking-database Hotels-API: image: hotels-api-image - hostname: ${HOTELS_SERVICE_HOSTNAME} + hostname: $${HOTELS_SERVICE_HOSTNAME} build: context: ./java/services/hotels dockerfile: Dockerfile @@ -50,16 +50,16 @@ services: networks: - kong-net environment: - SPRING_DATASOURCE_URL: jdbc:mysql://${DB_SERVICE_HOSTNAME}:3306/${DB_DATABASE_NAME}?createDatabaseIfNotExist=true - SPRING_DATASOURCE_USER: ${USER_DATABASE} - SPRING_DATASOURCE_PASSWORD: ${} + SPRING_DATASOURCE_URL: jdbc:mysql://$${DB_SERVICE_HOSTNAME}:3306/$${DB_DATABASE_NAME}?createDatabaseIfNotExist=true + SPRING_DATASOURCE_USER: $${USER_DATABASE} + SPRING_DATASOURCE_PASSWORD: $${} depends_on: - RoomsBooking-database - Bookings-API Bookings-API: image: bookings-api-image - hostname: ${BOOKINGS_SERVICE_HOSTNAME} + hostname: $${BOOKINGS_SERVICE_HOSTNAME} build: context: ./java/services/bookings dockerfile: Dockerfile @@ -69,13 +69,13 @@ services: networks: - kong-net environment: - SPRING_DATASOURCE_URL: jdbc:mysql://${DB_SERVICE_HOSTNAME}:3306/${DB_DATABASE_NAME}?createDatabaseIfNotExist=true + SPRING_DATASOURCE_URL: jdbc:mysql://$${DB_SERVICE_HOSTNAME}:3306/$${DB_DATABASE_NAME}?createDatabaseIfNotExist=true depends_on: - RoomsBooking-database RoomsBooking-database: image: mysql - hostname: ${DB_SERVICE_HOSTNAME} + hostname: $${DB_SERVICE_HOSTNAME} cap_add: - SYS_NICE restart: unless-stopped @@ -103,6 +103,6 @@ services: networks: - kong-net environment: - SPRING_DATASOURCE_URL: jdbc:mysql://${DB_SERVICE_HOSTNAME}:3306/${DB_DATABASE_NAME}?createDatabaseIfNotExist=true + SPRING_DATASOURCE_URL: jdbc:mysql://$${DB_SERVICE_HOSTNAME}:3306/$${DB_DATABASE_NAME}?createDatabaseIfNotExist=true depends_on: - RoomsBooking-database diff --git a/java/roomBooking/pom.xml b/java/roomBooking/pom.xml index 476f735b695a459292a258d72d89261c89dca993..f6fa75bdb21b812320db5afa07b770891fb9bd95 100644 --- a/java/roomBooking/pom.xml +++ b/java/roomBooking/pom.xml @@ -49,6 +49,32 @@ <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-security</artifactId> + </dependency> + <dependency> + <groupId>io.jsonwebtoken</groupId> + <artifactId>jjwt-api</artifactId> + <version>0.11.5</version> + </dependency> + <dependency> + <groupId>io.jsonwebtoken</groupId> + <artifactId>jjwt-impl</artifactId> + <version>0.11.5</version> + <scope>runtime</scope> + </dependency> + <dependency> + <groupId>io.jsonwebtoken</groupId> + <artifactId>jjwt-jackson</artifactId> + <version>0.11.5</version> + <scope>runtime</scope> + </dependency> + <dependency> + <groupId>jakarta.servlet</groupId> + <artifactId>jakarta.servlet-api</artifactId> + <scope>provided</scope> + </dependency> </dependencies> <build> @@ -60,4 +86,4 @@ </plugins> </build> -</project> +</project> \ No newline at end of file diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/auth/AuthController.java b/java/roomBooking/src/main/java/com/uva/monolith/services/auth/AuthController.java new file mode 100644 index 0000000000000000000000000000000000000000..c47ba890b6d67fd87fb23f809ffa5ea3c69fc99a --- /dev/null +++ b/java/roomBooking/src/main/java/com/uva/monolith/services/auth/AuthController.java @@ -0,0 +1,47 @@ +package com.uva.monolith.services.auth; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.server.ResponseStatusException; +import com.uva.monolith.services.users.controllers.UserService; +import com.uva.monolith.services.users.models.User; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import javax.crypto.spec.SecretKeySpec; +import java.security.Key; +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; + +@RestController +@RequestMapping("/api/auth") +public class AuthController { + + private final String SECRET_KEY = "clave_secreta"; + + @Autowired + private UserService userService; + + @PostMapping("/login") + public Map<String, String> login(@RequestBody LoginRequest loginRequest) { + User user = userService.findByEmail(loginRequest.getEmail()); + + if (user != null && userService.verifyPassword(loginRequest.getPassword(), user.getPassword())) { + String token = Jwts.builder() + .setSubject(user.getEmail()) + .signWith(new SecretKeySpec(SECRET_KEY.getBytes(), SignatureAlgorithm.HS256.getJcaName())) + .claim("email", user.getEmail()) + .setExpiration(new Date(System.currentTimeMillis() + 3600000)) // 1 hora + .compact(); + + Map<String, String> response = new HashMap<>(); + response.put("token", token); + return response; + } + + throw new ResponseStatusException(HttpStatus.FORBIDDEN, "Credenciales inválidas"); + } +} diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/auth/JwtAuthenticationFilter.java b/java/roomBooking/src/main/java/com/uva/monolith/services/auth/JwtAuthenticationFilter.java new file mode 100644 index 0000000000000000000000000000000000000000..23137977cbb2f748b6885234d9e64f0dd0de2992 --- /dev/null +++ b/java/roomBooking/src/main/java/com/uva/monolith/services/auth/JwtAuthenticationFilter.java @@ -0,0 +1,121 @@ +package com.uva.monolith.services.auth; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.MalformedJwtException; +import io.jsonwebtoken.UnsupportedJwtException; +import io.jsonwebtoken.io.Decoders; +import io.jsonwebtoken.security.Keys; +import io.jsonwebtoken.security.SignatureException; + +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.stereotype.Component; + +import com.uva.monolith.services.users.models.UserRol; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.Filter; +import java.io.IOException; +import java.security.Key; +import java.util.Collections; +import java.util.Date; + +@Component +public class JwtAuthenticationFilter implements Filter { + + private final String SECRET_KEY = "3cfa76ef14937c1c0ea519f8fc057a80fcd04a7420f8e8bcd0a7567c272e007b"; + + private Key getSignInKey() { + byte[] keyBytes = Decoders.BASE64.decode(SECRET_KEY); + return Keys.hmacShaKeyFor(keyBytes); + } + + private String getTokenFromRequest(HttpServletRequest request) { + String authHeader = request.getHeader("Authorization"); + if (authHeader == null || !authHeader.startsWith("Bearer ")) + return null; + return authHeader.substring(7); + } + + private Claims getClaimsFromToken(String token) { + return Jwts.parserBuilder() + .setSigningKey(getSignInKey()) + .build() + .parseClaimsJws(token) + .getBody(); + } + + private boolean validateToken(String token) { + if (token == null) + return false;// no token + try { + // Verifica y analiza el token + Claims claims = getClaimsFromToken(token); + + // Verifica que el token no esté expirado + return claims.getExpiration().after(new Date()); + } catch (ExpiredJwtException e) { + System.out.println("Token expirado: " + e.getMessage()); + } catch (UnsupportedJwtException e) { + System.out.println("Token no soportado: " + e.getMessage()); + } catch (MalformedJwtException e) { + System.out.println("Token malformado: " + e.getMessage()); + } catch (SignatureException e) { + System.out.println("Firma inválida: " + e.getMessage()); + } catch (IllegalArgumentException e) { + System.out.println("Token vacío o nulo: " + e.getMessage()); + } + return false; // Si ocurre cualquier excepción, el token es inválido + + } + + private String getEmailFromToken(String token) { + return getClaimsFromToken(token).getSubject(); + } + + private UserRol getRoleFromToken(String token) { + String rol = getClaimsFromToken(token).get("rol", String.class); + return UserRol.valueOf(rol); + } + + public static String getRol(UserRol rol) { + return String.format("ROLE_%s", rol.toString()); + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + HttpServletRequest httpRequest = (HttpServletRequest) request; + String token = getTokenFromRequest(httpRequest); + + if (validateToken(token)) { + + String email = getEmailFromToken(token); + UserRol role = getRoleFromToken(token); // Extraer el rol del token + + if (email != null && SecurityContextHolder.getContext().getAuthentication() == null) { + UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken( + email, null, null); + authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest)); + SecurityContextHolder.getContext().setAuthentication(authentication); + } + + // Agregar el rol como autoridad + SimpleGrantedAuthority authority = new SimpleGrantedAuthority(getRol(role)); + UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(email, null, + Collections.singletonList(authority)); + SecurityContextHolder.getContext().setAuthentication(authentication); + } + + chain.doFilter(request, response); + } + +} diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/auth/LoginRequest.java b/java/roomBooking/src/main/java/com/uva/monolith/services/auth/LoginRequest.java new file mode 100644 index 0000000000000000000000000000000000000000..62f9cb9e8bbb6a8b05489e4e3ec3024a7aff51b2 --- /dev/null +++ b/java/roomBooking/src/main/java/com/uva/monolith/services/auth/LoginRequest.java @@ -0,0 +1,23 @@ +package com.uva.monolith.services.auth; + +public class LoginRequest { + + private String email; + private String password; + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } +} diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/auth/SecurityConfig.java b/java/roomBooking/src/main/java/com/uva/monolith/services/auth/SecurityConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..e115ffbaeb43990960790c4a49dbbe4d5b237e88 --- /dev/null +++ b/java/roomBooking/src/main/java/com/uva/monolith/services/auth/SecurityConfig.java @@ -0,0 +1,44 @@ +package com.uva.monolith.services.auth; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +import com.uva.monolith.services.users.models.UserRol; + +@Configuration +@EnableWebSecurity +public class SecurityConfig { + + private final JwtAuthenticationFilter jwtAuthenticationFilter; + + public SecurityConfig(JwtAuthenticationFilter jwtAuthenticationFilter) { + this.jwtAuthenticationFilter = jwtAuthenticationFilter; + } + + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http.csrf(csrf -> csrf.disable()) + .authorizeHttpRequests(authorize -> authorize + // Permitir todas las conexiones + .requestMatchers("").permitAll() + // Acceso restringido a usuarios y administradores + .requestMatchers("users", "users/**") + .hasAnyRole(UserRol.ADMIN.toString(), UserRol.CLIENT.toString()) + // Acceso restringido a gestores de hoteles y administradores + .requestMatchers("hotels", "hotels/**") + .hasAnyRole(UserRol.ADMIN.toString(), UserRol.HOTEL_ADMIN.toString()) + // Acceso restringido a cualquier usuario del sistema + .requestMatchers("bookings", "bookings/**") + .hasAnyRole(UserRol.ADMIN.toString(), UserRol.HOTEL_ADMIN.toString(), UserRol.CLIENT.toString()) + // Rechazar el resto + .anyRequest().denyAll()) + // Registra el filtro antes del filtro estándar de autenticación + .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); + + return http.build(); + } +} diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/Hotel.java b/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/Hotel.java index 7400dfa789c29c788e497e23393827bca10298aa..0616ff81afa74cb1ce6c2289137f6fe95305126b 100644 --- a/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/Hotel.java +++ b/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/Hotel.java @@ -1,14 +1,21 @@ package com.uva.monolith.services.hotels.models; import java.util.List; + +import org.hibernate.annotations.ManyToAny; + +import com.uva.monolith.services.users.models.HotelManager; + import jakarta.persistence.Basic; import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; import jakarta.persistence.OneToMany; import jakarta.persistence.OneToOne; import jakarta.persistence.Table; @@ -34,14 +41,19 @@ public class Hotel { @OneToMany(mappedBy = "hotel", fetch = FetchType.EAGER, cascade = CascadeType.ALL) private List<Room> rooms; + @ManyToOne(optional = false) + @JoinColumn(name = "hotel_manager", referencedColumnName = "id") + private HotelManager hotelManager; + public Hotel() { } - public Hotel(int id, String name, Address address, List<Room> rooms) { + public Hotel(int id, String name, Address address, List<Room> rooms, HotelManager hotelManager) { setId(id); setName(name); setAddress(address); setRooms(rooms); + setHotelManager(hotelManager); } public int getId() { @@ -77,4 +89,11 @@ public class Hotel { rooms.forEach(room -> room.setHotel(this)); } + public void setHotelManager(HotelManager hotelManager) { + this.hotelManager = hotelManager; + } + + public HotelManager getHotelManager() { + return hotelManager; + } } diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/users/controllers/UserController.java b/java/roomBooking/src/main/java/com/uva/monolith/services/users/controllers/UserController.java index c097ef7d7c26443ff82da3860e1cf54362df94d2..166922605ed07e3a9dcc87c6b38ea8af23ea7899 100644 --- a/java/roomBooking/src/main/java/com/uva/monolith/services/users/controllers/UserController.java +++ b/java/roomBooking/src/main/java/com/uva/monolith/services/users/controllers/UserController.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.CrossOrigin; @@ -18,22 +19,26 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.server.ResponseStatusException; import com.uva.monolith.services.bookings.models.Booking; +import com.uva.monolith.services.users.models.Client; import com.uva.monolith.services.users.models.User; import com.uva.monolith.services.users.models.UserRol; import com.uva.monolith.services.users.models.UserStatus; +import com.uva.monolith.services.users.repositories.ClientRepository; import com.uva.monolith.services.users.repositories.UserRepository; @RestController @RequestMapping("users") @CrossOrigin(origins = "*") public class UserController { - private final UserRepository userRepository; - public UserController(UserRepository userRepository) { - this.userRepository = userRepository; - } + @Autowired + private UserRepository userRepository; + + @Autowired + private ClientRepository clientRepository; @GetMapping public List<User> getAllUsers() { @@ -51,9 +56,9 @@ public class UserController { @PostMapping public User addUser(@RequestBody User user) { - user.setStatus(UserStatus.NO_BOOKINGS); + // user.setStatus(UserStatus.NO_BOOKINGS); if (user.getRol() == null) // Rol por defecto - user.setRol(UserRol.CONSUMER); + user.setRol(UserRol.CLIENT); return userRepository.save(user); } @@ -76,7 +81,7 @@ public class UserController { @PatchMapping("/{id}") public User updateUserState(@PathVariable int id, @RequestBody Map<String, String> json) { - User target = userRepository.findById(id).orElseThrow(); + Client target = clientRepository.findById(id).orElseThrow(); String strStatus = json.get("status"); if (strStatus == null) { // TODO cambiar manejo @@ -125,7 +130,8 @@ public class UserController { @GetMapping("/{id}/bookings") public List<Booking> getUserBookingsById(@PathVariable int id) { - User user = userRepository.findById(id).orElseThrow(); + Client user = clientRepository.findById(id).orElseThrow(); return user.getBookings(); } + } diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/users/controllers/UserService.java b/java/roomBooking/src/main/java/com/uva/monolith/services/users/controllers/UserService.java new file mode 100644 index 0000000000000000000000000000000000000000..bdaf5acec3769e9c13893c9fd83f4ad17173a3d0 --- /dev/null +++ b/java/roomBooking/src/main/java/com/uva/monolith/services/users/controllers/UserService.java @@ -0,0 +1,36 @@ +package com.uva.monolith.services.users.controllers; + +import org.springframework.stereotype.Service; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.server.ResponseStatusException; + +import com.uva.monolith.services.users.models.User; + +import org.springframework.http.HttpStatus; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; + +import org.springframework.beans.factory.annotation.Autowired; +import com.uva.monolith.services.users.repositories.UserRepository; + +@Service +public class UserService { + + @Autowired + private UserRepository userRepository; + + private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + + public boolean verifyPassword(String rawPassword, String encodedPassword) { + return passwordEncoder.matches(rawPassword, encodedPassword); + } + + public String encodePassword(String password) { + return passwordEncoder.encode(password); + } + + public User findByEmail(@RequestParam String email) { + return userRepository.findByEmail(email) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Usuario no encontrado")); +} +} diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/Client.java b/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/Client.java new file mode 100644 index 0000000000000000000000000000000000000000..e106ecd3789a0237602e3194feacab7ddcbf4dfd --- /dev/null +++ b/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/Client.java @@ -0,0 +1,65 @@ +package com.uva.monolith.services.users.models; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.uva.monolith.services.bookings.models.Booking; + +import jakarta.persistence.Basic; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.FetchType; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; + +@Entity +@Table(name = "user_client") +public class Client extends User { + + @Basic(optional = false) + @Column(nullable = false) + @Enumerated(EnumType.STRING) + private UserStatus status; + + @JsonIgnore + @OneToMany(mappedBy = "userId", fetch = FetchType.EAGER, cascade = CascadeType.ALL) + private List<Booking> bookings; + + public Client() { + super(); + bookings = new ArrayList<>(); + status = UserStatus.NO_BOOKINGS; + } + + public Client(int id, String name, String email, String password, UserStatus status, + List<Booking> bookings) { + super(id, name, email, password, UserRol.CLIENT); + setStatus(status); + setBookings(bookings); + } + + public UserStatus getStatus() { + if (getBookings() == null || getBookings().isEmpty()) + return UserStatus.NO_BOOKINGS; + boolean activeBookings = getBookings().stream() + .anyMatch(booking -> !booking.getEndDate().isBefore(LocalDate.now())); // reserva >= ahora + return activeBookings ? UserStatus.WITH_ACTIVE_BOOKINGS : UserStatus.WITH_INACTIVE_BOOKINGS; + } + + public void setStatus(UserStatus status) { + this.status = status; + } + + public List<Booking> getBookings() { + return this.bookings; + } + + public void setBookings(List<Booking> bookings) { + this.bookings = bookings; + } +} diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/HotelManager.java b/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/HotelManager.java new file mode 100644 index 0000000000000000000000000000000000000000..0e6f4b0aafa35ab8b23d202814c1fabefdcf86ed --- /dev/null +++ b/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/HotelManager.java @@ -0,0 +1,38 @@ +package com.uva.monolith.services.users.models; + +import java.util.ArrayList; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.uva.monolith.services.hotels.models.Hotel; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; + +@Entity +@Table(name = "hotel_manager_user") +public class HotelManager extends User { + + @JsonIgnore + @OneToMany(mappedBy = "hotelManager", fetch = FetchType.EAGER, cascade = CascadeType.ALL) + private List<Hotel> hotels; + + public HotelManager() { + super(); + hotels = new ArrayList<>(); + } + + public HotelManager(int id, String name, String email, String password, List<Hotel> hotels) { + super(id, name, email, password, UserRol.HOTEL_ADMIN); + setHotels(hotels); + } + + public List<Hotel> getHotels() { + return this.hotels; + } + + public void setHotels(List<Hotel> hotels) { + this.hotels = hotels; + } +} diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/User.java b/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/User.java index 5c1f928c0bf0f273f27d890739801c89bdd9c9be..45decd686b3972058eb920f6c2e07cd4293f1e05 100644 --- a/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/User.java +++ b/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/User.java @@ -1,64 +1,56 @@ package com.uva.monolith.services.users.models; -import java.time.LocalDate; -import java.util.List; - import com.fasterxml.jackson.annotation.JsonIgnore; -import com.uva.monolith.services.bookings.models.Booking; import jakarta.persistence.Basic; -import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; -import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; -import jakarta.persistence.OneToMany; +import jakarta.persistence.Inheritance; +import jakarta.persistence.InheritanceType; import jakarta.persistence.Table; @Entity +@Inheritance(strategy = InheritanceType.JOINED) @Table(name = "users") public class User { - // TODO extraer a dos clases hijas, una por cada tipo + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Basic(optional = false) + @Column(nullable = false) private int id; @Basic(optional = false) + @Column(nullable = false) private String name; @Basic(optional = false) + @Column(nullable = false, unique = true) private String email; + @JsonIgnore @Basic(optional = false) + @Column(nullable = false) private String password; @Basic(optional = false) + @Column(nullable = false) @Enumerated(EnumType.STRING) - private UserRol rol = UserRol.CONSUMER; - - @Basic(optional = false) - @Enumerated(EnumType.STRING) - private UserStatus status; - - @JsonIgnore - @OneToMany(mappedBy = "userId", fetch = FetchType.EAGER, cascade = CascadeType.ALL) - private List<Booking> bookings; + private UserRol rol = UserRol.CLIENT; public User() { } - public User(int id, String name, String email, String password, UserRol rol, UserStatus status, - List<Booking> bookings) { + public User(int id, String name, String email, String password, UserRol rol) { setId(id); setName(name); setEmail(email); setRol(rol); - setStatus(status); - setBookings(bookings); } public int getId() { @@ -89,8 +81,8 @@ public class User { return password; } - public void setPassword(String password) { - this.password = password; + public void setPassword(String rawPassword) { + this.password = rawPassword; } public UserRol getRol() { @@ -100,24 +92,4 @@ public class User { public void setRol(UserRol rol) { this.rol = rol; } - - public UserStatus getStatus() { - if (getBookings() == null || getBookings().isEmpty()) - return UserStatus.NO_BOOKINGS; - boolean activeBookings = getBookings().stream() - .anyMatch(booking -> !booking.getEndDate().isBefore(LocalDate.now())); // reserva >= ahora - return activeBookings ? UserStatus.WITH_ACTIVE_BOOKINGS : UserStatus.WITH_INACTIVE_BOOKINGS; - } - - public void setStatus(UserStatus status) { - this.status = status; - } - - public List<Booking> getBookings() { - return this.bookings; - } - - public void setBookings(List<Booking> bookings) { - this.bookings = bookings; - } } diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/UserRol.java b/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/UserRol.java index 0abe595a154a10347b4eb63a818e72a51ea616f9..f408ba5ef9d34d96c32d3c42a6c2c51b1c6f22b1 100644 --- a/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/UserRol.java +++ b/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/UserRol.java @@ -1,5 +1,5 @@ package com.uva.monolith.services.users.models; public enum UserRol { - HOTEL_ADMIN, CONSUMER + ADMIN, HOTEL_ADMIN, CLIENT } diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/users/repositories/ClientRepository.java b/java/roomBooking/src/main/java/com/uva/monolith/services/users/repositories/ClientRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..1c1b46fbe665075b8f817367ff14ee65cf69ff76 --- /dev/null +++ b/java/roomBooking/src/main/java/com/uva/monolith/services/users/repositories/ClientRepository.java @@ -0,0 +1,10 @@ +package com.uva.monolith.services.users.repositories; + +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; + +import com.uva.monolith.services.users.models.Client; + +public interface ClientRepository extends JpaRepository<Client, Integer> { + Optional<Client> findByEmail(String email); +} \ No newline at end of file diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/users/repositories/HotelManagerRepository.java b/java/roomBooking/src/main/java/com/uva/monolith/services/users/repositories/HotelManagerRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..092a251b199fdecd80a2654fc3e6c96d1b7eb7f4 --- /dev/null +++ b/java/roomBooking/src/main/java/com/uva/monolith/services/users/repositories/HotelManagerRepository.java @@ -0,0 +1,10 @@ +package com.uva.monolith.services.users.repositories; + +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; + +import com.uva.monolith.services.users.models.HotelManager; + +public interface HotelManagerRepository extends JpaRepository<HotelManager, Integer> { + Optional<HotelManager> findByEmail(String email); +} \ No newline at end of file diff --git a/java/services/auth/pom.xml b/java/services/auth/pom.xml index 2838a0e84212291636783be15f1dec8706cf285f..ab9de31eb2707016bf0997d538e82b1ac3e525d5 100644 --- a/java/services/auth/pom.xml +++ b/java/services/auth/pom.xml @@ -49,6 +49,10 @@ <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-security</artifactId> + </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> diff --git a/java/services/auth/src/main/java/com/uva/authentication/api/UserAPI.java b/java/services/auth/src/main/java/com/uva/authentication/api/UserAPI.java index 03e44c8462a69bf143876c62eed3a751735a6c3c..a2df673233a774d4afc0228b798f0e1b6ba295ac 100644 --- a/java/services/auth/src/main/java/com/uva/authentication/api/UserAPI.java +++ b/java/services/auth/src/main/java/com/uva/authentication/api/UserAPI.java @@ -1,7 +1,11 @@ +// TODO eliminar si realmente no necesitamos comunicar un servicio con otro package com.uva.authentication.api; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; @@ -10,6 +14,8 @@ import org.springframework.web.client.RestTemplate; import com.uva.authentication.models.RegisterRequest; import com.uva.authentication.models.User; +import com.uva.authentication.models.UserRol; +import com.uva.authentication.utils.JwtUtil; @Component public class UserAPI { @@ -20,10 +26,30 @@ public class UserAPI { @Value("${external.services.users.baseurl}") private String USER_API_URL; + @Autowired + private JwtUtil jwtUtil; + + private String token; + private final User USER = new User(-1, "admin", null, null, UserRol.ADMIN); + + private String getAccessToken() { + if (token == null || token.isEmpty() || jwtUtil.isTokenValid(token, USER)) { + token = jwtUtil.generateToken(USER); + } + return token; + } + public User getUserByEmail(String email) { - String url = USER_API_URL + "?email={email}"; + + String token = getAccessToken(); + HttpHeaders headers = new HttpHeaders(); + headers.set("Authorization", "Bearer " + token); + HttpEntity<Void> entity = new HttpEntity<>(headers); + + String url = USER_API_URL + "?email={" + email + "}"; try { ResponseEntity<User> userResponse = restTemplate.getForEntity(url, User.class, email); + // restTemplate.exchange(url, HttpMethod.GET, entity, User.class); return userResponse.getBody(); } catch (HttpClientErrorException e) { if (e.getStatusCode() != HttpStatus.NOT_FOUND) @@ -33,8 +59,13 @@ public class UserAPI { } public User registerUser(RegisterRequest registerRequest) { + + String token = getAccessToken(); + HttpHeaders headers = new HttpHeaders(); + headers.set("Authorization", "Bearer " + token); + String url = USER_API_URL; - ResponseEntity<User> userResponse = restTemplate.postForEntity(url, registerRequest, User.class); + ResponseEntity<User> userResponse = restTemplate.postForEntity(url, registerRequest, User.class, headers); if (!userResponse.getStatusCode().is2xxSuccessful()) throw new RuntimeException("Failed to register user"); diff --git a/java/services/auth/src/main/java/com/uva/authentication/config/SecurityConfig.java b/java/services/auth/src/main/java/com/uva/authentication/config/SecurityConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..99715b0c854bd997e35fdde1e3cf76afa28f4f9e --- /dev/null +++ b/java/services/auth/src/main/java/com/uva/authentication/config/SecurityConfig.java @@ -0,0 +1,17 @@ +package com.uva.authentication.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.web.SecurityFilterChain; + +@Configuration +public class SecurityConfig { + + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http.csrf(crsf -> crsf.disable()) + .authorizeHttpRequests(auth -> auth.anyRequest().permitAll()); + return http.build(); + } +} diff --git a/java/services/auth/src/main/java/com/uva/authentication/controllers/AuthController.java b/java/services/auth/src/main/java/com/uva/authentication/controllers/AuthController.java index 08ad46a807354a557e2bd5f6f6f9d5fc94a79949..b9434db06eb6b092331f29353b8d9079139f4c42 100644 --- a/java/services/auth/src/main/java/com/uva/authentication/controllers/AuthController.java +++ b/java/services/auth/src/main/java/com/uva/authentication/controllers/AuthController.java @@ -9,6 +9,7 @@ import com.uva.authentication.models.*; import com.uva.authentication.services.AuthService; @RestController +@CrossOrigin(origins = "*") public class AuthController { @Autowired @@ -42,6 +43,7 @@ public class AuthController { // return new ResponseEntity<Void>(HttpStatus.FORBIDDEN); return new ResponseEntity<String>(e.getMessage(), HttpStatus.CONFLICT); } + e.fillInStackTrace(); } return new ResponseEntity<String>("Algo no fue bien", HttpStatus.UNAUTHORIZED); diff --git a/java/services/auth/src/main/java/com/uva/authentication/models/Client.java b/java/services/auth/src/main/java/com/uva/authentication/models/Client.java new file mode 100644 index 0000000000000000000000000000000000000000..896fe932aed9f3bcccc0cc783a9d230f5879a597 --- /dev/null +++ b/java/services/auth/src/main/java/com/uva/authentication/models/Client.java @@ -0,0 +1,60 @@ +package com.uva.authentication.models; + +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +import jakarta.persistence.Basic; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.FetchType; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; + +@Entity +@Table(name = "user_client") +public class Client extends User { + + @Basic(optional = false) + @Column(nullable = false) + @Enumerated(EnumType.STRING) + private UserStatus status; + + // @JsonIgnore + // @OneToMany(mappedBy = "userId", fetch = FetchType.EAGER, cascade = + // CascadeType.ALL) + // private List<?> bookings; + + public Client() { + super(); + // bookings = new ArrayList<>(); + status = UserStatus.NO_BOOKINGS; + } + + public Client(int id, String name, String email, String password, UserStatus status) { + // , List<?> bookings) { + super(id, name, email, password, UserRol.CLIENT); + setStatus(status); + // setBookings(bookings); + } + + public UserStatus getStatus() { + return this.status; + } + + public void setStatus(UserStatus status) { + this.status = status; + } + + // public List<?> getBookings() { + // return this.bookings; + // } + + // public void setBookings(List<?> bookings) { + // this.bookings = bookings; + // } +} diff --git a/java/services/auth/src/main/java/com/uva/authentication/models/HotelManager.java b/java/services/auth/src/main/java/com/uva/authentication/models/HotelManager.java new file mode 100644 index 0000000000000000000000000000000000000000..5cc75cb14d6402371cd5e61c82b2c50018a9981e --- /dev/null +++ b/java/services/auth/src/main/java/com/uva/authentication/models/HotelManager.java @@ -0,0 +1,40 @@ +package com.uva.authentication.models; + +import java.util.ArrayList; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; + +@Entity +@Table(name = "hotel_manager_user") +public class HotelManager extends User { + + // TODO tener en cuenta que esto hay que tener un control adecuado + // @JsonIgnore + // @OneToMany(mappedBy = "userId", fetch = FetchType.EAGER, cascade = + // CascadeType.ALL) + // private List<?> hotels; + + public HotelManager() { + super(); + // hotels = new ArrayList<>(); + } + + public HotelManager(int id, String name, String email, String password) { // , List<?> hotels) { + super(id, name, email, password, UserRol.HOTEL_ADMIN); + // setHotels(hotels); + } + + // public List<?> getHotels() { + // return this.hotels; + // } + + // public void setHotels(List<?> hotels) { + // this.hotels = hotels; + // } +} diff --git a/java/services/auth/src/main/java/com/uva/authentication/models/User.java b/java/services/auth/src/main/java/com/uva/authentication/models/User.java index 4a8ceb643989c16cd53e90717035c0fa31d09c8d..ae4981ae99984bc58ee01b196fb7c0e8ca93f0f4 100644 --- a/java/services/auth/src/main/java/com/uva/authentication/models/User.java +++ b/java/services/auth/src/main/java/com/uva/authentication/models/User.java @@ -1,12 +1,58 @@ package com.uva.authentication.models; -public class User extends RegisterRequest { +import com.fasterxml.jackson.annotation.JsonIgnore; + +import jakarta.persistence.Basic; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Inheritance; +import jakarta.persistence.InheritanceType; +import jakarta.persistence.Table; + +@Entity +@Inheritance(strategy = InheritanceType.JOINED) +@Table(name = "users") +public class User { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Basic(optional = false) + @Column(nullable = false) private int id; - private UserStatus status; + + @Basic(optional = false) + @Column(nullable = false) + private String name; + + @Basic(optional = false) + @Column(nullable = false, unique = true) + private String email; + + @JsonIgnore + @Basic(optional = false) + @Column(nullable = false) + private String password; + + @Basic(optional = false) + @Column(nullable = false) + @Enumerated(EnumType.STRING) + private UserRol rol = UserRol.CLIENT; public User() { } + public User(int id, String name, String email, String password, UserRol rol) { + setId(id); + setName(name); + setEmail(email); + setRol(rol); + } + public int getId() { return this.id; } @@ -15,11 +61,35 @@ public class User extends RegisterRequest { this.id = id; } - public UserStatus getStatus() { - return this.status; + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return this.email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPassword() { + return password; + } + + public void setPassword(String rawPassword) { + this.password = rawPassword; + } + + public UserRol getRol() { + return this.rol; } - public void setStatus(UserStatus status) { - this.status = status; + public void setRol(UserRol rol) { + this.rol = rol; } } diff --git a/java/services/auth/src/main/java/com/uva/authentication/models/UserRol.java b/java/services/auth/src/main/java/com/uva/authentication/models/UserRol.java index 80bc5a008c2b7ebf990f2416162d756fb61f5597..5944a6845b11b3dbbf0796f7b7d28641ff98fb75 100644 --- a/java/services/auth/src/main/java/com/uva/authentication/models/UserRol.java +++ b/java/services/auth/src/main/java/com/uva/authentication/models/UserRol.java @@ -1,5 +1,5 @@ package com.uva.authentication.models; public enum UserRol { - HOTEL_ADMIN, CONSUMER + ADMIN, HOTEL_ADMIN, CLIENT } diff --git a/java/services/auth/src/main/java/com/uva/authentication/repositories/ClientRepository.java b/java/services/auth/src/main/java/com/uva/authentication/repositories/ClientRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..11e4c125110b7b6505e3321fc6e92434e639bf22 --- /dev/null +++ b/java/services/auth/src/main/java/com/uva/authentication/repositories/ClientRepository.java @@ -0,0 +1,11 @@ +package com.uva.authentication.repositories; + +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; + +import com.uva.authentication.models.Client; +import com.uva.authentication.models.User; + +public interface ClientRepository extends JpaRepository<User, Integer> { + Optional<Client> findByEmail(String email); +} \ No newline at end of file diff --git a/java/services/auth/src/main/java/com/uva/authentication/repositories/HotelManagerRepository.java b/java/services/auth/src/main/java/com/uva/authentication/repositories/HotelManagerRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..a1e0ba81f6f380e670e67a42435506b28a09a7e7 --- /dev/null +++ b/java/services/auth/src/main/java/com/uva/authentication/repositories/HotelManagerRepository.java @@ -0,0 +1,11 @@ +package com.uva.authentication.repositories; + +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; + +import com.uva.authentication.models.HotelManager; +import com.uva.authentication.models.User; + +public interface HotelManagerRepository extends JpaRepository<User, Integer> { + Optional<HotelManager> findByEmail(String email); +} \ No newline at end of file diff --git a/java/services/auth/src/main/java/com/uva/authentication/repositories/UserRepository.java b/java/services/auth/src/main/java/com/uva/authentication/repositories/UserRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..c0695df1aae2f7640ee1d38e2cf0b449e7d40baa --- /dev/null +++ b/java/services/auth/src/main/java/com/uva/authentication/repositories/UserRepository.java @@ -0,0 +1,9 @@ +package com.uva.authentication.repositories; + +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; +import com.uva.authentication.models.User; + +public interface UserRepository extends JpaRepository<User, Integer> { + Optional<User> findByEmail(String email); +} \ No newline at end of file diff --git a/java/services/auth/src/main/java/com/uva/authentication/services/AuthService.java b/java/services/auth/src/main/java/com/uva/authentication/services/AuthService.java index 872aa3bd27e6635786c9effb6873118fefbad2d7..0ed199965af0f0423236ee79ae4bcae406d3f643 100644 --- a/java/services/auth/src/main/java/com/uva/authentication/services/AuthService.java +++ b/java/services/auth/src/main/java/com/uva/authentication/services/AuthService.java @@ -1,17 +1,25 @@ package com.uva.authentication.services; -import java.util.Objects; +import java.util.Optional; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import org.springframework.web.client.HttpClientErrorException; import com.uva.authentication.api.UserAPI; -import com.uva.authentication.jwt.JwtUtil; +import com.uva.authentication.models.Client; +import com.uva.authentication.models.HotelManager; import com.uva.authentication.models.LoginRequest; import com.uva.authentication.models.RegisterRequest; import com.uva.authentication.models.User; +import com.uva.authentication.models.UserRol; +import com.uva.authentication.repositories.ClientRepository; +import com.uva.authentication.repositories.HotelManagerRepository; +import com.uva.authentication.repositories.UserRepository; +import com.uva.authentication.utils.JwtUtil; +import com.uva.authentication.utils.SecurityUtils; @Service public class AuthService { @@ -19,25 +27,29 @@ public class AuthService { @Autowired private JwtUtil jwtUtil; + @Autowired + private HotelManagerRepository hotelManagerRepository; + + @Autowired + private ClientRepository clientRepository; + @Autowired private UserAPI userAPI; - private String hashPass(String password) { - return String.valueOf(Objects.hashCode(password)); - } + @Autowired + private UserRepository userRepository; private boolean authenticateUser(LoginRequest request, User user) { - System.err.println(user); if (user == null) return false; - String hashPass = hashPass(request.getPassword()); - System.err.println(request.getPassword() + " -> " + hashPass + " == " + - user.getPassword()); - return hashPass.equals(user.getPassword()); + return SecurityUtils.checkPassword(request.getPassword(), user.getPassword()); } public String login(LoginRequest loginRequest) { - User user = userAPI.getUserByEmail(loginRequest.getEmail()); + // User user = userAPI.getUserByEmail(loginRequest.getEmail()); + User user = userRepository.findByEmail(loginRequest.getEmail()) + .orElseThrow(() -> new HttpClientErrorException(HttpStatus.FORBIDDEN, + "Invalid credentials")); boolean isAuthenticated = authenticateUser(loginRequest, user); if (!isAuthenticated) { @@ -51,13 +63,32 @@ public class AuthService { } public User register(RegisterRequest registerRequest) { - User user = userAPI.getUserByEmail(registerRequest.getEmail()); - if (user != null) + // User user = userAPI.getUserByEmail(registerRequest.getEmail()); + Optional<User> user = userRepository.findByEmail(registerRequest.getEmail()); + if (user.isPresent()) throw new HttpClientErrorException(HttpStatus.CONFLICT, "Email already in use"); - String hashPass = hashPass(registerRequest.getPassword()); - registerRequest.setPassword(hashPass); - return userAPI.registerUser(registerRequest); + String hashPass = SecurityUtils.encrypt(registerRequest.getPassword()); + // return userAPI.registerUser(registerRequest); + User newUser; + if (registerRequest.getRol() == UserRol.HOTEL_ADMIN) { + HotelManager hm = new HotelManager(); + // hm.setName(registerRequest.getName()); + // hm.setEmail(registerRequest.getEmail()); + // hm.setRol(registerRequest.getRol()); + BeanUtils.copyProperties(registerRequest, hm); + hm.setPassword(hashPass); + newUser = hotelManagerRepository.save(hm); + } else { + Client client = new Client(); + // client.setName(registerRequest.getName()); + // client.setEmail(registerRequest.getEmail()); + BeanUtils.copyProperties(registerRequest, client); + client.setRol(UserRol.CLIENT); + client.setPassword(hashPass); + newUser = clientRepository.save(client); + } + return newUser; } } diff --git a/java/services/auth/src/main/java/com/uva/authentication/jwt/JwtUtil.java b/java/services/auth/src/main/java/com/uva/authentication/utils/JwtUtil.java similarity index 96% rename from java/services/auth/src/main/java/com/uva/authentication/jwt/JwtUtil.java rename to java/services/auth/src/main/java/com/uva/authentication/utils/JwtUtil.java index 6c596112fd7c80984099225b35199d9e887bf313..2e22fae815270d51bebd7e5da1c2d7d35861779f 100644 --- a/java/services/auth/src/main/java/com/uva/authentication/jwt/JwtUtil.java +++ b/java/services/auth/src/main/java/com/uva/authentication/utils/JwtUtil.java @@ -1,4 +1,4 @@ -package com.uva.authentication.jwt; +package com.uva.authentication.utils; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; @@ -41,8 +41,8 @@ public class JwtUtil { public String generateToken(User user) { Map<String, Object> extraClaims = new HashMap<>(); - // extraClaims.put("role", user.getRole()); extraClaims.put("email", user.getEmail()); + extraClaims.put("rol", user.getRol()); extraClaims.put("user", user); long expiration = jwtExpiration; diff --git a/java/services/auth/src/main/java/com/uva/authentication/utils/SecurityUtils.java b/java/services/auth/src/main/java/com/uva/authentication/utils/SecurityUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..2df069eabbe53bdeaccbdbd58094bf8022ff35c7 --- /dev/null +++ b/java/services/auth/src/main/java/com/uva/authentication/utils/SecurityUtils.java @@ -0,0 +1,18 @@ +package com.uva.authentication.utils; + +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; + +public class SecurityUtils { + + private static BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); + + public static String encrypt(String value) { + return encoder.encode(value); + } + + // Método para comparar la contraseña ingresada con el hash almacenado + public static boolean checkPassword(String rawPassword, String encodedPassword) { + return encoder.matches(rawPassword, encodedPassword); // Comparar la contraseña con el hash + } + +}