diff --git a/src/main/java/com/example/proyectofinal/component/CustomAuth.java b/src/main/java/com/example/proyectofinal/component/CustomAuth.java new file mode 100644 index 0000000..82ebcfe --- /dev/null +++ b/src/main/java/com/example/proyectofinal/component/CustomAuth.java @@ -0,0 +1,37 @@ +package com.example.proyectofinal.component; +import com.example.proyectofinal.models.login.Usuario; +import com.example.proyectofinal.servicios.user.UsuarioService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; + +@Component +public class CustomAuth implements AuthenticationProvider{ + @Autowired + private UsuarioService usuarioService; + + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + String nombreLogIn = authentication.getName(); + String password = authentication.getCredentials().toString(); + + Usuario usuario = usuarioService.login(nombreLogIn, password); + + if (usuario != null) { + return new UsernamePasswordAuthenticationToken(nombreLogIn, password, new ArrayList<>()); + } else { + throw new BadCredentialsException("External system authentication failed"); + } + } + + @Override + public boolean supports(Class authentication) { + return authentication.equals(UsernamePasswordAuthenticationToken.class); + } +} diff --git a/src/main/java/com/example/proyectofinal/configuration/seguridad/CustomAuthenticacionHandler.java b/src/main/java/com/example/proyectofinal/configuration/CustomAuthenticacionHandler.java similarity index 87% rename from src/main/java/com/example/proyectofinal/configuration/seguridad/CustomAuthenticacionHandler.java rename to src/main/java/com/example/proyectofinal/configuration/CustomAuthenticacionHandler.java index a6d55cc..4d135b0 100644 --- a/src/main/java/com/example/proyectofinal/configuration/seguridad/CustomAuthenticacionHandler.java +++ b/src/main/java/com/example/proyectofinal/configuration/CustomAuthenticacionHandler.java @@ -1,8 +1,7 @@ -package com.example.proyectofinal.configuration.seguridad; +package com.example.proyectofinal.configuration; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import org.springframework.context.annotation.Bean; import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; diff --git a/src/main/java/com/example/proyectofinal/configuration/PasswordEcodingConf.java b/src/main/java/com/example/proyectofinal/configuration/PasswordEcodingConf.java new file mode 100644 index 0000000..3b166e9 --- /dev/null +++ b/src/main/java/com/example/proyectofinal/configuration/PasswordEcodingConf.java @@ -0,0 +1,14 @@ +package com.example.proyectofinal.configuration; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +public class PasswordEcodingConf { + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } +} diff --git a/src/main/java/com/example/proyectofinal/configuration/SecurityConfig.java b/src/main/java/com/example/proyectofinal/configuration/SecurityConfig.java new file mode 100644 index 0000000..e224d64 --- /dev/null +++ b/src/main/java/com/example/proyectofinal/configuration/SecurityConfig.java @@ -0,0 +1,93 @@ +package com.example.proyectofinal.configuration; + +import com.example.proyectofinal.component.CustomAuth; +import com.example.proyectofinal.servicios.user.UsuarioService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.web.SecurityFilterChain; + +@Configuration +public class SecurityConfig { + + @Autowired + private JdbcTemplate jdbcTemplate; + @Autowired + private UsuarioService usuarioService; + + @Autowired + private CustomAuth customAuth; + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth.authenticationProvider(customAuth); + } + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http + .sessionManagement(sessionManagement -> sessionManagement + .invalidSessionUrl("/logout") // Redirect to /logout when session is invalid + .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) + .sessionFixation().migrateSession() + .maximumSessions(1).expiredUrl("/logout")) // Redirect to /logout when session expires + .authorizeRequests(authorize -> authorize + .anyRequest().authenticated() + ) + .formLogin(formLogin -> formLogin + .successHandler(customAuthenticacionHandler()) + ) + .logout(logout -> logout + .logoutUrl("/logout") + .logoutSuccessUrl("/login?logout") + .invalidateHttpSession(true) + .deleteCookies("JSESSIONID") + .addLogoutHandler((request, response, authentication) -> { + if (authentication != null) { + String nombreLogIn = authentication.getName(); + usuarioService.logout(nombreLogIn); + } + }) + ); + return http.build(); + } + + @Bean + public CustomAuthenticacionHandler customAuthenticacionHandler() { + return new CustomAuthenticacionHandler(); + } + + private void initializeAutoridadAndRolTables() { + // Check if the autoridad table is empty + Integer autoridadCount = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM autoridad", Integer.class); + if (autoridadCount != null && autoridadCount == 0) { + // If the table is empty, insert 'READ', 'WRITE', and 'DELETE' + jdbcTemplate.execute("INSERT INTO autoridad (nombre) VALUES ('READ'), ('WRITE'), ('DELETE')"); + } + + // Check if the rol table is empty + Integer rolCount = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM rol", Integer.class); + if (rolCount != null && rolCount == 0) { + // If the table is empty, insert roles and establish many-to-many relationship with autoridad + jdbcTemplate.execute("INSERT INTO rol (nombre) VALUES ('ADMIN'), ('USER')"); + } + + // Check if the rol_autoridad table is empty + Integer rolAutoridadCount = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM rol_autoridad", Integer.class); + if (rolAutoridadCount != null && rolAutoridadCount == 0) { + // If the table is empty, establish many-to-many relationship between roles and autoridades + // Manually insert authorities for 'ADM' role + jdbcTemplate.update("INSERT INTO rol_autoridad (fk_rol, fk_autoridad) VALUES (1, 1)"); // 'ADM' - 'READ' + jdbcTemplate.update("INSERT INTO rol_autoridad (fk_rol, fk_autoridad) VALUES (1, 2)"); // 'ADM' - 'WRITE' + jdbcTemplate.update("INSERT INTO rol_autoridad (fk_rol, fk_autoridad) VALUES (1, 3)"); // 'ADM' - 'DELETE' + + // Manually insert authorities for 'ALU' role + jdbcTemplate.update("INSERT INTO rol_autoridad (fk_rol, fk_autoridad) VALUES (2, 1)"); // 'ALU' - 'READ' + jdbcTemplate.update("INSERT INTO rol_autoridad (fk_rol, fk_autoridad) VALUES (2, 2)"); // 'ALU' - 'EDIT' + } + } + +} diff --git a/src/main/java/com/example/proyectofinal/configuration/seguridad/SecurityConfig.java b/src/main/java/com/example/proyectofinal/configuration/seguridad/SecurityConfig.java deleted file mode 100644 index 32c427e..0000000 --- a/src/main/java/com/example/proyectofinal/configuration/seguridad/SecurityConfig.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.example.proyectofinal.configuration.seguridad; - -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.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.provisioning.InMemoryUserDetailsManager; -import org.springframework.security.web.SecurityFilterChain; - -@Configuration -public class SecurityConfig { - @Bean - public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { - http - .authorizeRequests(authorize -> authorize - .anyRequest().authenticated() - ) - .formLogin(formLogin -> formLogin - .successHandler(customAuthenticacionHandler()) - ); - return http.build(); - } - @Bean - public UserDetailsService userDetailsService() { - var userDetailsService= new InMemoryUserDetailsManager(); - UserDetails user1 = User.builder() - .username("user") - .password(this.passwordEncoder().encode("1234")) - .authorities("read","write","delete") - .build(); - - userDetailsService.createUser(user1); - return userDetailsService; - } - @Bean - public PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); - } - @Bean - public CustomAuthenticacionHandler customAuthenticacionHandler() { - return new CustomAuthenticacionHandler(); - } -} diff --git a/src/main/java/com/example/proyectofinal/controllers/BuscadorController.java b/src/main/java/com/example/proyectofinal/controllers/BuscadorController.java index 635260d..3ea2740 100644 --- a/src/main/java/com/example/proyectofinal/controllers/BuscadorController.java +++ b/src/main/java/com/example/proyectofinal/controllers/BuscadorController.java @@ -5,6 +5,7 @@ import com.example.proyectofinal.models.empresas.*; import com.example.proyectofinal.repositories.empresas.*; import com.example.proyectofinal.servicios.*; import com.example.proyectofinal.interfaces.IPagination; +import org.springframework.context.annotation.Role; import org.springframework.data.domain.Page; import org.springframework.http.ResponseEntity; import org.springframework.ui.Model; diff --git a/src/main/java/com/example/proyectofinal/controllers/LogOutController.java b/src/main/java/com/example/proyectofinal/controllers/LogOutController.java new file mode 100644 index 0000000..5cffd8e --- /dev/null +++ b/src/main/java/com/example/proyectofinal/controllers/LogOutController.java @@ -0,0 +1,32 @@ +package com.example.proyectofinal.controllers; + +import com.example.proyectofinal.servicios.user.UsuarioService; +import jakarta.servlet.http.HttpServletRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +public class LogOutController { + + @Autowired + private UsuarioService usuarioService; + + private static final Logger logger = LoggerFactory.getLogger(LogOutController.class); + @RequestMapping("/logout") + public String logout(HttpServletRequest request) { + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + if (auth != null) { + String nombreLogIn = auth.getName(); + logger.info("Logging out user: " + nombreLogIn); + usuarioService.logout(nombreLogIn); + new SecurityContextLogoutHandler().logout(request, null, null); + } + return "redirect:/login?logout"; + } +} \ No newline at end of file diff --git a/src/main/java/com/example/proyectofinal/models/login/Autoridad.java b/src/main/java/com/example/proyectofinal/models/login/Autoridad.java new file mode 100644 index 0000000..27994f4 --- /dev/null +++ b/src/main/java/com/example/proyectofinal/models/login/Autoridad.java @@ -0,0 +1,26 @@ +package com.example.proyectofinal.models.login; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Set; + +@Entity +@AllArgsConstructor +@NoArgsConstructor +@Data +@Table(name = "autoridad") +public class Autoridad { + + @Id + @GeneratedValue (strategy = GenerationType.IDENTITY) + private long id; + + @Column(length = 70) + private String nombre; + + @ManyToMany(mappedBy = "autoridades",fetch = FetchType.EAGER) + private Set roles; +} diff --git a/src/main/java/com/example/proyectofinal/models/login/Autoridades.java b/src/main/java/com/example/proyectofinal/models/login/Autoridades.java deleted file mode 100644 index d1caa9a..0000000 --- a/src/main/java/com/example/proyectofinal/models/login/Autoridades.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.example.proyectofinal.models.login; - -public class Autoridades { -} diff --git a/src/main/java/com/example/proyectofinal/models/login/Rol.java b/src/main/java/com/example/proyectofinal/models/login/Rol.java new file mode 100644 index 0000000..6a6de09 --- /dev/null +++ b/src/main/java/com/example/proyectofinal/models/login/Rol.java @@ -0,0 +1,31 @@ +package com.example.proyectofinal.models.login; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.OnDelete; +import org.hibernate.annotations.OnDeleteAction; + +import java.util.Set; + +@Entity +@AllArgsConstructor +@NoArgsConstructor +@Data +@Table(name = "rol") +public class Rol { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String nombre; + + @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, fetch = FetchType.EAGER) + @JoinTable(name = "rol_autoridad", + joinColumns = @JoinColumn(name = "fk_rol", referencedColumnName = "id") , + inverseJoinColumns = @JoinColumn(name = "fk_autoridad", referencedColumnName = "id")) + @OnDelete(action = OnDeleteAction.CASCADE) + private Setautoridades; +} diff --git a/src/main/java/com/example/proyectofinal/models/login/Usuario.java b/src/main/java/com/example/proyectofinal/models/login/Usuario.java index 6fc9615..5a24a8b 100644 --- a/src/main/java/com/example/proyectofinal/models/login/Usuario.java +++ b/src/main/java/com/example/proyectofinal/models/login/Usuario.java @@ -1,4 +1,40 @@ package com.example.proyectofinal.models.login; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.OnDelete; +import org.hibernate.annotations.OnDeleteAction; + +@Entity +@Data +@AllArgsConstructor +@NoArgsConstructor +@Table(name = "usuario") public class Usuario { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(length = 250) + private String nombreUsuario; + + @Column(length = 70) + private String nombreLogIn; + + @Column(length = 100) + private String email; + + @Column(length = 60) + private String password; + + + private boolean logedIn; + + @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, fetch = FetchType.EAGER) + @JoinColumn(name = "fk_rol", referencedColumnName = "id") + @OnDelete(action = OnDeleteAction.CASCADE) + private Rol rol; } diff --git a/src/main/java/com/example/proyectofinal/repositories/empresas/OfertaRepository.java b/src/main/java/com/example/proyectofinal/repositories/empresas/OfertaRepository.java index 2108667..279684e 100644 --- a/src/main/java/com/example/proyectofinal/repositories/empresas/OfertaRepository.java +++ b/src/main/java/com/example/proyectofinal/repositories/empresas/OfertaRepository.java @@ -85,9 +85,9 @@ public interface OfertaRepository extends JpaRepository { @Query("SELECT o FROM Oferta o WHERE o.fecha > :query") Collection ofertasByFechaDespuesCust(@Param("query") Date query); - @Query(value = "SELECT o FROM Oferta o WHERE YEAR(o.fecha) = :query", nativeQuery = true) - Collection ofertasByAnoCust(@Param("query") int query); - @Query("SELECT o FROM Oferta o JOIN o.skills s WHERE s.nombre LIKE %:query%") Collection ofertasBySkillCust(@Param("query") String query); + + @Query(value = "SELECT * FROM ofertas o WHERE YEAR(o.fecha) = YEAR(:dateQuery)", nativeQuery = true) + Collection ofertasByFechaAnyoCust(Date dateQuery); } diff --git a/src/main/java/com/example/proyectofinal/repositories/login/AutoridadesRepository.java b/src/main/java/com/example/proyectofinal/repositories/login/AutoridadesRepository.java index a328c67..c6f200d 100644 --- a/src/main/java/com/example/proyectofinal/repositories/login/AutoridadesRepository.java +++ b/src/main/java/com/example/proyectofinal/repositories/login/AutoridadesRepository.java @@ -1,7 +1,17 @@ package com.example.proyectofinal.repositories.login; -import com.example.proyectofinal.models.login.Autoridades; +import com.example.proyectofinal.models.login.Autoridad; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; -public interface AutoridadesRepository /*extends JpaRepository */{ -} +import java.util.Collection; + +public interface AutoridadesRepository extends JpaRepository { + + @Query("SELECT a FROM Autoridad a WHERE a.nombre = ?1") + Autoridad findByNombre(String read); + + @Query(value = "SELECT COUNT(a.id) FROM autoridad a JOIN rol_autoridad ra ON a.id = ra.fk_autoridad WHERE ra.fk_rol = ?1", nativeQuery = true) + int countAutoridadesByRolId(Long rolId); + +} \ No newline at end of file diff --git a/src/main/java/com/example/proyectofinal/repositories/login/RolRepository.java b/src/main/java/com/example/proyectofinal/repositories/login/RolRepository.java new file mode 100644 index 0000000..719ef65 --- /dev/null +++ b/src/main/java/com/example/proyectofinal/repositories/login/RolRepository.java @@ -0,0 +1,21 @@ +package com.example.proyectofinal.repositories.login; + +import com.example.proyectofinal.models.login.Autoridad; +import com.example.proyectofinal.models.login.Rol; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.ArrayList; +import java.util.Optional; + +public interface RolRepository extends JpaRepository { + + @Query("SELECT r FROM Rol r WHERE r.nombre = ?1") + Rol findByName(String name); + + @Query("SELECT r FROM Rol r WHERE r.id = ?1") + Rol findRolById(Long rolId); + + @Query(value = "SELECT a.* FROM autoridad a JOIN rol_autoridad ra ON a.id = ra.fk_autoridad WHERE ra.fk_rol = ?1", nativeQuery = true) + ArrayList findAutoridadesByRolId(Long rolId); +} diff --git a/src/main/java/com/example/proyectofinal/repositories/login/UserRepository.java b/src/main/java/com/example/proyectofinal/repositories/login/UserRepository.java index f8de0ee..0e02776 100644 --- a/src/main/java/com/example/proyectofinal/repositories/login/UserRepository.java +++ b/src/main/java/com/example/proyectofinal/repositories/login/UserRepository.java @@ -1,7 +1,23 @@ package com.example.proyectofinal.repositories.login; -import org.apache.catalina.User; +import com.example.proyectofinal.models.login.Usuario; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; -public interface UserRepository /*extends JpaRepository */{ +import java.util.Optional; + +public interface UserRepository extends JpaRepository{ + + + @Query("SELECT u FROM Usuario u WHERE u.nombreLogIn = ?1") + Optional findByNombreUsuario(String nombreLogIn); + + @Modifying + @Query("UPDATE Usuario u SET u.logedIn = true WHERE u.id = ?1") + void updateLogedIn(Long id); + + @Modifying + @Query("UPDATE Usuario u SET u.logedIn = false WHERE u.id = ?1") + void resetLogedIn(Long id); } diff --git a/src/main/java/com/example/proyectofinal/servicios/OfertaService.java b/src/main/java/com/example/proyectofinal/servicios/OfertaService.java index be71d1b..8f66dd6 100644 --- a/src/main/java/com/example/proyectofinal/servicios/OfertaService.java +++ b/src/main/java/com/example/proyectofinal/servicios/OfertaService.java @@ -176,6 +176,28 @@ public class OfertaService implements IOferta { listEmpPrime.addAll(ofertaRepository.ofertasByEmpresaCust(query)); } else if (secondaryOption.equals("Skill")) { listEmpPrime.addAll(ofertaRepository.ofertasBySkillCust(query)); + }else if(secondaryOption.equals("Fecha antes")){ + try { + Date dateQuery = new SimpleDateFormat("yyyy-MM-dd").parse(query); + listEmpPrime.addAll(ofertaRepository.ofertasByFechaAntesCust(dateQuery)); + } catch (ParseException e) { + e.printStackTrace(); + } + }else if(secondaryOption.equals("Fecha despues")){ + try { + Date dateQuery = new SimpleDateFormat("yyyy-MM-dd").parse(query); + listEmpPrime.addAll(ofertaRepository.ofertasByFechaDespuesCust(dateQuery)); + } catch (ParseException e) { + e.printStackTrace(); + + } + }else if(secondaryOption.equals("Año")){ + try { + Date dateQuery = new SimpleDateFormat("yyyy-MM-dd").parse(query); + listEmpPrime.addAll(ofertaRepository.ofertasByFechaAnyoCust(dateQuery)); + } catch (ParseException e) { + e.printStackTrace(); + } } } } diff --git a/src/main/java/com/example/proyectofinal/servicios/user/RolAutoService.java b/src/main/java/com/example/proyectofinal/servicios/user/RolAutoService.java new file mode 100644 index 0000000..4d84600 --- /dev/null +++ b/src/main/java/com/example/proyectofinal/servicios/user/RolAutoService.java @@ -0,0 +1,24 @@ +package com.example.proyectofinal.servicios.user; + +import com.example.proyectofinal.models.login.Autoridad; +import com.example.proyectofinal.models.login.Rol; +import com.example.proyectofinal.repositories.login.AutoridadesRepository; +import com.example.proyectofinal.repositories.login.RolRepository; +import jakarta.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.HashSet; +import java.util.Set; + +@Service +public class RolAutoService { + + @Autowired + private RolRepository rolRepository; + + @Autowired + private AutoridadesRepository autoridadRepository; + + +} diff --git a/src/main/java/com/example/proyectofinal/servicios/user/UsuarioService.java b/src/main/java/com/example/proyectofinal/servicios/user/UsuarioService.java new file mode 100644 index 0000000..1f8fdfb --- /dev/null +++ b/src/main/java/com/example/proyectofinal/servicios/user/UsuarioService.java @@ -0,0 +1,115 @@ +package com.example.proyectofinal.servicios.user; + +import com.example.proyectofinal.models.login.Autoridad; +import com.example.proyectofinal.models.login.Usuario; +import com.example.proyectofinal.models.login.Rol; +import com.example.proyectofinal.repositories.login.AutoridadesRepository; +import com.example.proyectofinal.repositories.login.UserRepository; +import com.example.proyectofinal.repositories.login.RolRepository; +import jakarta.annotation.PostConstruct; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +public class UsuarioService { + + @Autowired + private UserRepository userRepository; + + @Autowired + private RolRepository rolRepository; + + @Autowired + private AutoridadesRepository autoridadRepository; + + private PasswordEncoder passwordEncoder; + + @Autowired + JdbcTemplate jdbcTemplate; + private static final Logger logger = LoggerFactory.getLogger(UsuarioService.class); + @Autowired + public void setPasswordEncoder(PasswordEncoder passwordEncoder) { + this.passwordEncoder = passwordEncoder; + } + + @Transactional + public Usuario login(String nombreLogIn, String password) { + Usuario usuario = userRepository.findByNombreUsuario(nombreLogIn) + .orElseThrow(() -> new UsernameNotFoundException("Usuario no encontrado")); + if (usuario.isLogedIn()) { + throw new AlreadyLoggedInException("User is already logged in"); + } + if (passwordEncoder.matches(password, usuario.getPassword())) { + userRepository.updateLogedIn( usuario.getId()); + return usuario; + } else { + throw new BadCredentialsException("Invalid password"); + } + } + private static class AlreadyLoggedInException extends RuntimeException { + public AlreadyLoggedInException(String message) { + super(message); + } + } + + @Transactional + public void logout(String nombreLogIn) { + Usuario usuario = userRepository.findByNombreUsuario(nombreLogIn) + .orElseThrow(() -> new UsernameNotFoundException("Usuario no encontrado")); + logger.info("Resetting loggedIn status for user: " + nombreLogIn); + userRepository.resetLogedIn(usuario.getId()); + } + + @PostConstruct + @Transactional + public void createDefaultRolesAuthoritiesAndAdmin() { + try { + if (userRepository.findByNombreUsuario("admin").isEmpty()) { + Rol adminRole = rolRepository.findByName("ADMIN"); + createUsuario("admin", "admin", + "admin@example.com", + "$2a$10$uTJY6B1H7MzEFrv2MX9K2uBgk1crVMtnuHgUgbTaQ/Cv7O.k0kUi2", + false, adminRole.getId()); + } + } catch (Exception e) { + System.out.println("Exception in createDefaultRolesAuthoritiesAndAdmin: " + e.getMessage()); + e.printStackTrace(); + } + } + + public Usuario createUsuario(String nombreUsuario, String nombreLogIn, String email, String password, boolean loged, Long rolId) { + // Insert into usuario table + String insertUsuarioSql = "INSERT INTO usuario (nombre_usuario, nombre_log_in, email, password, loged_in, fk_rol) VALUES (?, ?, ?, ?, ?, ?)"; + jdbcTemplate.update(insertUsuarioSql, nombreUsuario, nombreLogIn, email, password, loged, rolId); + + // Get the last inserted id + Long usuarioId = jdbcTemplate.queryForObject("SELECT LAST_INSERT_ID()", Long.class); + + // Get all autoridades + List autoridadList = autoridadRepository.findAll(); + + // For each autoridad, check if it's already associated with the rol + for (Autoridad autoridad : autoridadList) { + String checkSql = "SELECT COUNT(*) FROM rol_autoridad WHERE fk_rol = ? AND fk_autoridad = ?"; + Integer count = jdbcTemplate.queryForObject(checkSql, Integer.class, rolId, autoridad.getId()); + + // If not associated, insert into rol_autoridad table + if (count == 0) { + String insertRolAutoridadSql = "INSERT INTO rol_autoridad (fk_rol, fk_autoridad) VALUES (?, ?)"; + jdbcTemplate.update(insertRolAutoridadSql, rolId, autoridad.getId()); + } + } + Usuario usuario = userRepository.findById(usuarioId).orElse(null); + + return usuario; + } +} \ No newline at end of file diff --git a/src/main/java/com/example/proyectofinal/temp b/src/main/java/com/example/proyectofinal/temp index e4af756..a23f55f 100644 --- a/src/main/java/com/example/proyectofinal/temp +++ b/src/main/java/com/example/proyectofinal/temp @@ -1,7 +1 @@ -listEmpPrime: TEST[Empresa(id=4, nombre=Keytara, cif=123456789W4, correo=keytara@example.com, telefono=12345678904, - keywords=programador, sector=Sector(id=4, nombre=Musica)), - Empresa(id=9, nombre=FinTrack, cif=123456789W9, correo=fintrack@example.com, telefono=12345678909, - keywords=finance,investment, sector=Sector(id=4, nombre=Musica)), - Empresa(id=14, nombre=WealthTrack, cif=123456789W9, correo=wealthtrack@example.com, telefono=12345678909, - keywords=finance,investment, sector=Sector(id=4, nombre=Musica))] -listEmpSec: TEST[] \ No newline at end of file +currently for the login I'm using the default and not recomened way of creating user, and log in witht the default ligin provided by spring. Can I rework my login to a more complex level with the clases Autoridad, wich has the authorities \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8e2b0d8..60ac4f6 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -16,3 +16,4 @@ server.port=8080 #Dialecto spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect + diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index e69de29..98a41d0 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -0,0 +1,7 @@ +-- Insert 'READ', 'WRITE', and 'DELETE' into the autoridad table if the table is empty +INSERT INTO autoridad (nombre) +SELECT 'READ' WHERE NOT EXISTS (SELECT 1 FROM autoridad); +INSERT INTO autoridad (nombre) +SELECT 'WRITE' WHERE NOT EXISTS (SELECT 1 FROM autoridad); +INSERT INTO autoridad (nombre) +SELECT 'DELETE' WHERE NOT EXISTS (SELECT 1 FROM autoridad); \ No newline at end of file diff --git a/src/main/resources/templates/firt_admin_user.html b/src/main/resources/templates/firt_admin_user.html new file mode 100644 index 0000000..9bd087e --- /dev/null +++ b/src/main/resources/templates/firt_admin_user.html @@ -0,0 +1,10 @@ + + + + + Primer Usuario + + + + + \ No newline at end of file