Files
mealprep/backend/src/main/java/com/recipeapp/auth/CustomUserDetailsService.java
Marcel Raddatz 3253dcfec2 Implement auth domain with outside-in TDD (22 tests)
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>
2026-04-01 21:24:26 +02:00

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);
}
}