auth listo y contador terminados
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
package com.example.fercoganbackend;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class FercoganbackendApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(FercoganbackendApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.example.fercoganbackend.component;
|
||||
|
||||
// ContadorWebSocketHandler.java
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.socket.*;
|
||||
import org.springframework.web.socket.handler.TextWebSocketHandler;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
@Component
|
||||
public class ContadorWebSocketHandler extends TextWebSocketHandler {
|
||||
private final List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();
|
||||
|
||||
@Override
|
||||
public void afterConnectionEstablished(WebSocketSession session) {
|
||||
sessions.add(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
|
||||
sessions.remove(session);
|
||||
}
|
||||
|
||||
public void broadcast(String message) {
|
||||
for (WebSocketSession session : sessions) {
|
||||
try {
|
||||
session.sendMessage(new TextMessage(message));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.example.fercoganbackend.configuration;
|
||||
|
||||
import com.example.fercoganbackend.service.UsuarioDetailsService;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
|
||||
@Configuration
|
||||
public class SecurityConfig {
|
||||
|
||||
private final UsuarioDetailsService usuarioDetailsService;
|
||||
|
||||
public SecurityConfig(UsuarioDetailsService usuarioDetailsService) {
|
||||
this.usuarioDetailsService = usuarioDetailsService;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
|
||||
return authConfig.getAuthenticationManager();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.csrf(AbstractHttpConfigurer::disable)
|
||||
.authorizeHttpRequests(auth -> auth
|
||||
.requestMatchers("/auth/**").permitAll()
|
||||
.requestMatchers("/admin/**").hasAnyAuthority("SUPER_USUARIO","ADMIN")
|
||||
.anyRequest().authenticated()
|
||||
)
|
||||
.httpBasic(httpBasic -> httpBasic
|
||||
.authenticationEntryPoint((request, response, authException) -> {
|
||||
// Log del fallo de autenticación
|
||||
System.out.println("Fallo de autenticación: " + authException.getMessage());
|
||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage());
|
||||
})
|
||||
);
|
||||
return http.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.example.fercoganbackend.configuration;
|
||||
|
||||
// WebSocketConfig.java
|
||||
import com.example.fercoganbackend.component.ContadorWebSocketHandler;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.socket.config.annotation.*;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSocket
|
||||
public class WebSocketConfig implements WebSocketConfigurer {
|
||||
private final ContadorWebSocketHandler handler;
|
||||
|
||||
public WebSocketConfig(ContadorWebSocketHandler handler) {
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
|
||||
registry.addHandler(handler, "/ws/contador").setAllowedOrigins("*");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.example.fercoganbackend.controller;
|
||||
|
||||
import com.example.fercoganbackend.component.ContadorWebSocketHandler;
|
||||
import com.example.fercoganbackend.entity.Rol;
|
||||
import com.example.fercoganbackend.entity.Usuario;
|
||||
import com.example.fercoganbackend.service.ContadorService;
|
||||
import com.example.fercoganbackend.service.UsuarioService;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
public class AppController {
|
||||
|
||||
private final UsuarioService usuarioService;
|
||||
private final ContadorService contadorService;
|
||||
private final ContadorWebSocketHandler webSocketHandler;
|
||||
|
||||
public AppController(UsuarioService usuarioService, ContadorService contadorService, ContadorWebSocketHandler webSocketHandler) {
|
||||
this.usuarioService = usuarioService;
|
||||
this.contadorService = contadorService;
|
||||
this.webSocketHandler = webSocketHandler;
|
||||
}
|
||||
|
||||
// Registro
|
||||
@PostMapping("/auth/registrar")
|
||||
public String registrar(@RequestParam String username,
|
||||
@RequestParam String password,
|
||||
@RequestParam Set<Rol> roles) {
|
||||
usuarioService.registrarUsuario(username, password, roles);
|
||||
return "Usuario registrado, pendiente de aprobación";
|
||||
}
|
||||
|
||||
// Verificar si aprobado
|
||||
@GetMapping("/auth/verificar/{username}")
|
||||
public String verificar(@PathVariable String username) {
|
||||
boolean aprobado = usuarioService.estaAprobado(username);
|
||||
return aprobado ? "Usuario aprobado ✅" : "Usuario pendiente ❌";
|
||||
}
|
||||
|
||||
// Listar pendientes (solo admin/super)
|
||||
@GetMapping("/admin/pendientes")
|
||||
public List<Usuario> pendientes() {
|
||||
return usuarioService.listarPendientes();
|
||||
}
|
||||
|
||||
// Aceptar usuario (solo admin/super)
|
||||
@PostMapping("/admin/aceptar/{id}")
|
||||
public String aceptar(@PathVariable Long id) {
|
||||
usuarioService.aceptarUsuario(id);
|
||||
return "Usuario aprobado ✅";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.example.fercoganbackend.controller;
|
||||
|
||||
// ContadorController.java (REST API)
|
||||
import com.example.fercoganbackend.component.ContadorWebSocketHandler;
|
||||
import com.example.fercoganbackend.service.ContadorService;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/contador")
|
||||
public class ContadorController {
|
||||
private final ContadorService contadorService;
|
||||
private final ContadorWebSocketHandler webSocketHandler;
|
||||
|
||||
public ContadorController(ContadorService contadorService, ContadorWebSocketHandler webSocketHandler) {
|
||||
this.contadorService = contadorService;
|
||||
this.webSocketHandler = webSocketHandler;
|
||||
}
|
||||
|
||||
@PostMapping("/incrementar")
|
||||
public int incrementar() {
|
||||
int nuevoValor = contadorService.incrementar();
|
||||
webSocketHandler.broadcast(String.valueOf(nuevoValor));
|
||||
return nuevoValor;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public int getContador() {
|
||||
return contadorService.getContador();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.example.fercoganbackend.entity;
|
||||
|
||||
|
||||
public enum Rol {
|
||||
SUPER_USUARIO, ADMIN, COLABORADOR, CLIENTE
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.example.fercoganbackend.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import java.util.Set;
|
||||
|
||||
@Entity
|
||||
public class Usuario {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
@Column(nullable = false)
|
||||
private Boolean aprobado = false;
|
||||
|
||||
@ElementCollection(fetch = FetchType.EAGER)
|
||||
@Enumerated(EnumType.STRING)
|
||||
private Set<Rol> roles; // aquí consumes el enum
|
||||
|
||||
// getters y setters
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public boolean isAprobado() {
|
||||
return aprobado;
|
||||
}
|
||||
|
||||
public void setAprobado(boolean aprobado) {
|
||||
this.aprobado = aprobado;
|
||||
}
|
||||
|
||||
public Set<Rol> getRoles() {
|
||||
return roles;
|
||||
}
|
||||
|
||||
public void setRoles(Set<Rol> roles) {
|
||||
this.roles = roles;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.example.fercoganbackend.otros;
|
||||
|
||||
import com.example.fercoganbackend.entity.Usuario;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class UsuarioPrincipal implements UserDetails {
|
||||
private final Usuario usuario;
|
||||
|
||||
public UsuarioPrincipal(Usuario usuario) {
|
||||
this.usuario = usuario;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||
return usuario.getRoles().stream()
|
||||
.map(r -> new SimpleGrantedAuthority("ROLE_" + r.name()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return usuario.getPassword();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return usuario.getUsername();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccountNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccountNonLocked() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCredentialsNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return usuario.isAprobado(); // aquí usamos tu booleano
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.example.fercoganbackend.repository;
|
||||
|
||||
import com.example.fercoganbackend.entity.Usuario;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface UsuarioRepository extends JpaRepository<Usuario, Long> {
|
||||
Optional<Usuario> findByUsername(String username);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.example.fercoganbackend.service;
|
||||
|
||||
// ContadorService.java
|
||||
import org.springframework.stereotype.Service;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@Service
|
||||
public class ContadorService {
|
||||
private final AtomicInteger contador = new AtomicInteger(200);
|
||||
private boolean sw = true;
|
||||
|
||||
public int incrementar() {
|
||||
int valorActual = contador.get();
|
||||
int incremento;
|
||||
if (valorActual < 300) {
|
||||
incremento = sw ? 20 : 30;
|
||||
sw = !sw; // alterna el booleano
|
||||
} else if (valorActual < 1000) {
|
||||
incremento = 50;
|
||||
} else if (valorActual < 2000) {
|
||||
incremento = 100;
|
||||
} else {
|
||||
incremento = 500;
|
||||
}
|
||||
return contador.getAndAdd(incremento);
|
||||
}
|
||||
|
||||
|
||||
public int getContador() {
|
||||
return contador.get();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.example.fercoganbackend.service;
|
||||
|
||||
import com.example.fercoganbackend.entity.Usuario;
|
||||
import com.example.fercoganbackend.otros.UsuarioPrincipal;
|
||||
import com.example.fercoganbackend.repository.UsuarioRepository;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
@Service
|
||||
public class UsuarioDetailsService implements UserDetailsService {
|
||||
|
||||
private final UsuarioRepository usuarioRepository;
|
||||
private final Logger logger = LoggerFactory.getLogger(UsuarioDetailsService.class);
|
||||
|
||||
public UsuarioDetailsService(UsuarioRepository usuarioRepository) {
|
||||
this.usuarioRepository = usuarioRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
logger.info("Intentando autenticar usuario: {}", username);
|
||||
|
||||
Usuario usuario = usuarioRepository.findByUsername(username)
|
||||
.orElseThrow(() -> {
|
||||
logger.warn("Usuario no encontrado: {}", username);
|
||||
return new UsernameNotFoundException("Usuario no encontrado");
|
||||
});
|
||||
|
||||
logger.info("Usuario encontrado: {}, aprobado: {}", usuario.getUsername(), usuario.isAprobado());
|
||||
logger.info("Roles del usuario: {}", usuario.getRoles());
|
||||
|
||||
return new org.springframework.security.core.userdetails.User(
|
||||
usuario.getUsername(),
|
||||
usuario.getPassword(),
|
||||
usuario.isAprobado(), true, true, true,
|
||||
usuario.getRoles().stream()
|
||||
.map(r -> new SimpleGrantedAuthority(r.name()))
|
||||
.toList()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.example.fercoganbackend.service;
|
||||
import com.example.fercoganbackend.entity.Rol;
|
||||
import com.example.fercoganbackend.entity.Usuario;
|
||||
import com.example.fercoganbackend.repository.UsuarioRepository;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Service
|
||||
public class UsuarioService {
|
||||
private final UsuarioRepository repo;
|
||||
private final PasswordEncoder encoder;
|
||||
|
||||
public UsuarioService(UsuarioRepository repo, PasswordEncoder encoder) {
|
||||
this.repo = repo;
|
||||
this.encoder = encoder;
|
||||
}
|
||||
|
||||
public Usuario registrarUsuario(String username, String password, Set<Rol> roles) {
|
||||
Usuario u = new Usuario();
|
||||
u.setUsername(username);
|
||||
u.setPassword(encoder.encode(password));
|
||||
u.setRoles(roles);
|
||||
u.setAprobado(false); // no aprobado hasta aceptación
|
||||
return repo.save(u);
|
||||
}
|
||||
|
||||
public List<Usuario> listarPendientes() {
|
||||
return repo.findAll().stream().filter(u -> !u.isAprobado()).toList();
|
||||
}
|
||||
|
||||
public Usuario aceptarUsuario(Long id) {
|
||||
Usuario u = repo.findById(id).orElseThrow();
|
||||
u.setAprobado(true);
|
||||
return repo.save(u);
|
||||
}
|
||||
|
||||
public boolean estaAprobado(String username) {
|
||||
return repo.findByUsername(username).map(Usuario::isAprobado).orElse(false);
|
||||
}
|
||||
}
|
||||
13
src/main/resources/application.properties
Normal file
13
src/main/resources/application.properties
Normal file
@@ -0,0 +1,13 @@
|
||||
spring.application.name=fercoganbackend
|
||||
spring.datasource.url=jdbc:mysql://localhost:3306/testdb
|
||||
spring.datasource.username=andre
|
||||
spring.datasource.password=andre
|
||||
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.jpa.show-sql=true
|
||||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
|
||||
# Nivel de log para Spring Security
|
||||
logging.level.org.springframework.security=DEBUG
|
||||
logging.level.org.hibernate.SQL=DEBUG
|
||||
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.example.fercoganbackend;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class FercoganbackendApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user