This repository was archived by the owner on Jul 6, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAuthenticationApplicationService.java
More file actions
107 lines (86 loc) · 4.88 KB
/
AuthenticationApplicationService.java
File metadata and controls
107 lines (86 loc) · 4.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package com.zenfulcode.commercify.auth.application.service;
import com.zenfulcode.commercify.auth.application.command.LoginCommand;
import com.zenfulcode.commercify.auth.domain.event.UserAuthenticatedEvent;
import com.zenfulcode.commercify.auth.domain.model.AuthenticatedUser;
import com.zenfulcode.commercify.auth.domain.service.AuthenticationDomainService;
import com.zenfulcode.commercify.auth.infrastructure.security.TokenService;
import com.zenfulcode.commercify.shared.domain.event.DomainEventPublisher;
import com.zenfulcode.commercify.user.application.command.CreateUserCommand;
import com.zenfulcode.commercify.user.application.service.UserApplicationService;
import com.zenfulcode.commercify.user.domain.exception.UserAlreadyExistsException;
import com.zenfulcode.commercify.user.domain.exception.UserNotFoundException;
import com.zenfulcode.commercify.user.domain.model.User;
import com.zenfulcode.commercify.user.domain.model.UserRole;
import com.zenfulcode.commercify.user.domain.repository.UserRepository;
import com.zenfulcode.commercify.user.domain.valueobject.UserId;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
@Slf4j
@Service
@AllArgsConstructor
public class AuthenticationApplicationService {
private final AuthenticationManager authenticationManager;
private final AuthenticationDomainService authenticationDomainService;
private final UserRepository userRepository;
private final TokenService tokenService;
private final DomainEventPublisher eventPublisher;
private final UserApplicationService userApplicationService;
@Transactional
public AuthenticationResult authenticate(LoginCommand command) {
String email = command.email();
String password = command.password();
UserId userId;
if (!command.isGuest()) {
User user = userRepository.findByEmail(command.email()).orElseThrow(() -> new UserNotFoundException(command.email()));
userId = user.getId();
} else {
Optional<User> user = userRepository.findByEmail(command.email());
if (user.isPresent()) {
throw new UserAlreadyExistsException("There is already a user with this email");
}
email = "guest-" + System.currentTimeMillis() + "@commercify.com";
password = UUID.randomUUID().toString();
CreateUserCommand createUserCommand = new CreateUserCommand(email, "Guest", "User", password, Set.of(UserRole.GUEST), null);
userId = userApplicationService.createUser(createUserCommand);
}
Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(email, password));
AuthenticatedUser authenticatedUser = (AuthenticatedUser) authentication.getPrincipal();
User user = userApplicationService.getUser(userId);
// Generate tokens
String accessToken = tokenService.generateAccessToken(authenticatedUser);
String refreshToken = tokenService.generateRefreshToken(authenticatedUser);
// Publish domain event
eventPublisher.publish(new UserAuthenticatedEvent(this, userId, email, command.isGuest()));
return new AuthenticationResult(accessToken, refreshToken, authenticatedUser, user);
}
@Transactional(readOnly = true)
public AuthenticatedUser validateAccessToken(String token) {
String userId = tokenService.validateTokenAndGetUserId(token);
log.info("Validating access token for user: '{}'", userId);
User user = userRepository.findById(UserId.of(userId)).orElseThrow();
return authenticationDomainService.createAuthenticatedUser(user);
}
@Transactional
public AuthenticationResult refreshToken(String refreshToken) {
String userId = tokenService.validateTokenAndGetUserId(refreshToken);
User user = userRepository.findById(UserId.of(userId)).orElseThrow();
AuthenticatedUser authenticatedUser = authenticationDomainService.createAuthenticatedUser(user);
String newAccessToken = tokenService.generateAccessToken(authenticatedUser);
String newRefreshToken = tokenService.generateRefreshToken(authenticatedUser);
return new AuthenticationResult(newAccessToken, newRefreshToken, authenticatedUser, user);
}
public Optional<String> extractTokenFromHeader(String authHeader) {
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
return Optional.empty();
}
return Optional.of(authHeader.substring(7));
}
}