Controller (7 tests): signup, login, logout, GET/PATCH me. Standalone MockMvc setup (Boot 4 removed @WebMvcTest). Service (11 tests): signup with conflict check, login with password/active validation, getCurrentUser with household info, updateProfile with password change flow. Repository (4 tests): save/find, case-insensitive email via IgnoreCase queries (citext + Hibernate needs explicit IgnoreCase), existsByEmail. Also includes: - SecurityConfig: session auth, CSRF, role-based authorization - CustomUserDetailsService: loads UserAccount for Spring Security - UserAccount, Household, HouseholdMember JPA entities - spring-boot-flyway dependency (Boot 4 requires explicit module) - ddl-auto=none (Flyway owns schema, validate fails on citext) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
36 lines
1.4 KiB
Java
36 lines
1.4 KiB
Java
package com.recipeapp.auth;
|
|
|
|
import com.recipeapp.auth.entity.UserAccount;
|
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
|
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.core.userdetails.UsernameNotFoundException;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
import java.util.List;
|
|
|
|
@Service
|
|
public class CustomUserDetailsService implements UserDetailsService {
|
|
|
|
private final UserAccountRepository userAccountRepository;
|
|
|
|
public CustomUserDetailsService(UserAccountRepository userAccountRepository) {
|
|
this.userAccountRepository = userAccountRepository;
|
|
}
|
|
|
|
@Override
|
|
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
|
|
UserAccount account = userAccountRepository.findByEmailIgnoreCase(email)
|
|
.orElseThrow(() -> new UsernameNotFoundException("User not found: " + email));
|
|
|
|
if (!account.isActive()) {
|
|
throw new UsernameNotFoundException("Account is deactivated: " + email);
|
|
}
|
|
|
|
var authorities = List.of(new SimpleGrantedAuthority("ROLE_" + account.getSystemRole().toUpperCase()));
|
|
|
|
return new User(account.getEmail(), account.getPasswordHash(), authorities);
|
|
}
|
|
}
|