// Path: src/main/java/com/lyubenblagoev/postfixrest/security/CustomUserDetailsPasswordService.java
// @Service
// public class CustomUserDetailsPasswordService implements UserDetailsPasswordService {
// 
//     private static final Logger logger = LoggerFactory.getLogger(CustomUserDetailsPasswordService.class);
// 
//     private final UserRepository userRepository;
//     private final UserDetailsService userDetailsService;
// 
//     public CustomUserDetailsPasswordService(UserRepository userRepository,
//                                             CustomUserDetailsService userDetailsService) {
//         this.userRepository = userRepository;
//         this.userDetailsService = userDetailsService;
//     }
// 
//     @Override
//     public UserDetails updatePassword(UserDetails user, String newPassword) {
//         return userRepository.findByEmail(user.getUsername())
//                 .map(u -> {
//                     logger.debug("Upgrading password for user " + user.getUsername());
//                     u.setPassword(newPassword);
//                     userRepository.save(u);
//                     return userDetailsService.loadUserByUsername(user.getUsername());
//                 })
//                 .orElseThrow(() -> new UsernameNotFoundException("No user found for " + user.getUsername()));
//     }
// }
// 
// Path: src/main/java/com/lyubenblagoev/postfixrest/security/CustomUserDetailsService.java
// @Service
// public class CustomUserDetailsService implements UserDetailsService {
// 
//     private final UserRepository userRepository;
// 
//     public CustomUserDetailsService(UserRepository userRepository) {
//         this.userRepository = userRepository;
//     }
// 
//     @Override
//     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//         return userRepository.findByEmail(username)
//                 .map(u -> new UserPrincipal(u))
//                 .orElseThrow(() -> new UsernameNotFoundException("No user found for " + username));
//     }
// }
// 
// Path: src/main/java/com/lyubenblagoev/postfixrest/security/JwtAuthenticationFilter.java
// @Component
// public class JwtAuthenticationFilter extends OncePerRequestFilter {
// 
//     private static final Logger logger = LoggerFactory.getLogger(JwtAuthenticationFilter.class);
// 
//     private final JwtAuthenticationConverter authenticationConverter = new JwtAuthenticationConverter();
//     private final JwtAuthenticationProvider authenticationProvider;
// 
//     public JwtAuthenticationFilter(JwtAuthenticationProvider authenticationProvider) {
//         this.authenticationProvider = authenticationProvider;
//     }
// 
//     @Override
//     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
//             throws ServletException, IOException {
//         try {
//             Authentication authRequest = authenticationConverter.convert(request);
//             if (authRequest == null || !(authRequest instanceof JwtAuthenticationToken)) {
//                 logger.trace("Did not process authentication request since failed to find "
//                         + "JWT in Bearer Authorization header");
//                 filterChain.doFilter(request, response);
//                 return;
//             }
//             String token = ((JwtAuthenticationToken) authRequest).getToken();
//             if (token != null) {
//                 Authentication authentication = authenticationProvider.authenticate(authRequest);
//                 SecurityContextHolder.getContext().setAuthentication(authentication);
//             }
//         } catch (AuthenticationException e) {
//             SecurityContextHolder.clearContext();
//             logger.debug("Failed to process authentication request: " + e.getMessage());
//             response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase());
//             return;
//         }
//         filterChain.doFilter(request, response);
//     }
// 
// }


import com.lyubenblagoev.postfixrest.security.CustomUserDetailsPasswordService;
import com.lyubenblagoev.postfixrest.security.CustomUserDetailsService;
import com.lyubenblagoev.postfixrest.security.JwtAuthenticationFilter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsPasswordService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
package com.lyubenblagoev.postfixrest.configuration;


@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

// Path: src/main/java/com/lyubenblagoev/postfixrest/security/CustomUserDetailsPasswordService.java
// @Service
// public class CustomUserDetailsPasswordService implements UserDetailsPasswordService {
// 
//     private static final Logger logger = LoggerFactory.getLogger(CustomUserDetailsPasswordService.class);
// 
//     private final UserRepository userRepository;
//     private final UserDetailsService userDetailsService;
// 
//     public CustomUserDetailsPasswordService(UserRepository userRepository,
//                                             CustomUserDetailsService userDetailsService) {
//         this.userRepository = userRepository;
//         this.userDetailsService = userDetailsService;
//     }
// 
//     @Override
//     public UserDetails updatePassword(UserDetails user, String newPassword) {
//         return userRepository.findByEmail(user.getUsername())
//                 .map(u -> {
//                     logger.debug("Upgrading password for user " + user.getUsername());
//                     u.setPassword(newPassword);
//                     userRepository.save(u);
//                     return userDetailsService.loadUserByUsername(user.getUsername());
//                 })
//                 .orElseThrow(() -> new UsernameNotFoundException("No user found for " + user.getUsername()));
//     }
// }
// 
// Path: src/main/java/com/lyubenblagoev/postfixrest/security/CustomUserDetailsService.java
// @Service
// public class CustomUserDetailsService implements UserDetailsService {
// 
//     private final UserRepository userRepository;
// 
//     public CustomUserDetailsService(UserRepository userRepository) {
//         this.userRepository = userRepository;
//     }
// 
//     @Override
//     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//         return userRepository.findByEmail(username)
//                 .map(u -> new UserPrincipal(u))
//                 .orElseThrow(() -> new UsernameNotFoundException("No user found for " + username));
//     }
// }
// 
// Path: src/main/java/com/lyubenblagoev/postfixrest/security/JwtAuthenticationFilter.java
// @Component
// public class JwtAuthenticationFilter extends OncePerRequestFilter {
// 
//     private static final Logger logger = LoggerFactory.getLogger(JwtAuthenticationFilter.class);
// 
//     private final JwtAuthenticationConverter authenticationConverter = new JwtAuthenticationConverter();
//     private final JwtAuthenticationProvider authenticationProvider;
// 
//     public JwtAuthenticationFilter(JwtAuthenticationProvider authenticationProvider) {
//         this.authenticationProvider = authenticationProvider;
//     }
// 
//     @Override
//     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
//             throws ServletException, IOException {
//         try {
//             Authentication authRequest = authenticationConverter.convert(request);
//             if (authRequest == null || !(authRequest instanceof JwtAuthenticationToken)) {
//                 logger.trace("Did not process authentication request since failed to find "
//                         + "JWT in Bearer Authorization header");
//                 filterChain.doFilter(request, response);
//                 return;
//             }
//             String token = ((JwtAuthenticationToken) authRequest).getToken();
//             if (token != null) {
//                 Authentication authentication = authenticationProvider.authenticate(authRequest);
//                 SecurityContextHolder.getContext().setAuthentication(authentication);
//             }
//         } catch (AuthenticationException e) {
//             SecurityContextHolder.clearContext();
//             logger.debug("Failed to process authentication request: " + e.getMessage());
//             response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase());
//             return;
//         }
//         filterChain.doFilter(request, response);
//     }
// 
// }


// Path: src/main/java/com/lyubenblagoev/postfixrest/configuration/SecurityConfiguration.java
import com.lyubenblagoev.postfixrest.security.CustomUserDetailsPasswordService;
import com.lyubenblagoev.postfixrest.security.CustomUserDetailsService;
import com.lyubenblagoev.postfixrest.security.JwtAuthenticationFilter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsPasswordService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

package com.lyubenblagoev.postfixrest.configuration;


@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    private final CustomUserDetailsService userDetailsService;