Skip to content

Commit 6400581

Browse files
committed
add better logging
1 parent 907430c commit 6400581

23 files changed

+235
-103
lines changed

backend/spring-boot/pom.xml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,7 @@
4949
<groupId>org.springframework.boot</groupId>
5050
<artifactId>spring-boot-starter-actuator</artifactId>
5151
</dependency>
52-
<dependency>
53-
<groupId>org.springframework.boot</groupId>
54-
<artifactId>spring-boot-starter-aspectj</artifactId>
55-
</dependency>
52+
5653
<dependency>
5754
<groupId>org.springframework.boot</groupId>
5855
<artifactId>spring-boot-starter-data-jpa</artifactId>

backend/spring-boot/src/main/java/org/bugzkit/api/admin/service/impl/UserServiceImpl.java

Lines changed: 67 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.util.HashSet;
44
import java.util.Set;
5+
import lombok.extern.slf4j.Slf4j;
56
import org.bugzkit.api.admin.payload.request.PatchUserRequest;
67
import org.bugzkit.api.admin.payload.request.UserRequest;
78
import org.bugzkit.api.admin.service.UserService;
@@ -24,6 +25,7 @@
2425
import org.springframework.stereotype.Service;
2526
import org.springframework.transaction.annotation.Transactional;
2627

28+
@Slf4j
2729
@Service("adminUserService")
2830
@PreAuthorize("hasAuthority('ADMIN')")
2931
public class UserServiceImpl implements UserService {
@@ -49,10 +51,14 @@ public UserServiceImpl(
4951
@Override
5052
@Transactional
5153
public UserDTO create(UserRequest userRequest) {
52-
if (userRepository.existsByUsername(userRequest.username()))
54+
if (userRepository.existsByUsername(userRequest.username())) {
55+
log.warn("Admin user creation failed: username '{}' already exists", userRequest.username());
5356
throw new ConflictException("user.usernameExists");
54-
if (userRepository.existsByEmail(userRequest.email()))
57+
}
58+
if (userRepository.existsByEmail(userRequest.email())) {
59+
log.warn("Admin user creation failed: email '{}' already exists", userRequest.email());
5560
throw new ConflictException("user.emailExists");
61+
}
5662
final var user =
5763
User.builder()
5864
.username(userRequest.username())
@@ -62,7 +68,9 @@ public UserDTO create(UserRequest userRequest) {
6268
.lock(userRequest.lock())
6369
.roles(new HashSet<>(roleRepository.findAllByNameIn(userRequest.roleNames())))
6470
.build();
65-
return UserMapper.INSTANCE.userToAdminUserDTO(userRepository.save(user));
71+
final var saved = userRepository.save(user);
72+
log.info("Admin created user '{}' (id={})", saved.getUsername(), saved.getId());
73+
return UserMapper.INSTANCE.userToAdminUserDTO(saved);
6674
}
6775

6876
/*
@@ -87,7 +95,11 @@ public UserDTO findById(Long id) {
8795
return userRepository
8896
.findWithRolesById(id)
8997
.map(UserMapper.INSTANCE::userToAdminUserDTO)
90-
.orElseThrow(() -> new ResourceNotFoundException("user.notFound"));
98+
.orElseThrow(
99+
() -> {
100+
log.warn("Admin user lookup failed: no user found with id '{}'", id);
101+
return new ResourceNotFoundException("user.notFound");
102+
});
91103
}
92104

93105
@Override
@@ -96,7 +108,11 @@ public UserDTO update(Long id, UserRequest userRequest) {
96108
final var user =
97109
userRepository
98110
.findWithRolesById(id)
99-
.orElseThrow(() -> new ResourceNotFoundException("user.notFound"));
111+
.orElseThrow(
112+
() -> {
113+
log.warn("Admin user update failed: no user found with id '{}'", id);
114+
return new ResourceNotFoundException("user.notFound");
115+
});
100116

101117
setUsername(user, userRequest.username());
102118
setEmail(user, userRequest.email());
@@ -108,7 +124,9 @@ public UserDTO update(Long id, UserRequest userRequest) {
108124
setRoles(user, userRequest.roleNames());
109125
}
110126

111-
return UserMapper.INSTANCE.userToAdminUserDTO(userRepository.save(user));
127+
final var updated = userRepository.save(user);
128+
log.info("Admin updated user '{}' (id={})", updated.getUsername(), id);
129+
return UserMapper.INSTANCE.userToAdminUserDTO(updated);
112130
}
113131

114132
@Override
@@ -117,7 +135,11 @@ public UserDTO patch(Long id, PatchUserRequest patchUserRequest) {
117135
final var user =
118136
userRepository
119137
.findWithRolesById(id)
120-
.orElseThrow(() -> new ResourceNotFoundException("user.notFound"));
138+
.orElseThrow(
139+
() -> {
140+
log.warn("Admin user patch failed: no user found with id '{}'", id);
141+
return new ResourceNotFoundException("user.notFound");
142+
});
121143

122144
if (patchUserRequest.username() != null) setUsername(user, patchUserRequest.username());
123145
if (patchUserRequest.email() != null) setEmail(user, patchUserRequest.email());
@@ -129,7 +151,9 @@ public UserDTO patch(Long id, PatchUserRequest patchUserRequest) {
129151
if (patchUserRequest.roleNames() != null) setRoles(user, patchUserRequest.roleNames());
130152
}
131153

132-
return UserMapper.INSTANCE.userToAdminUserDTO(userRepository.save(user));
154+
final var updated = userRepository.save(user);
155+
log.info("Admin patched user '{}' (id={})", updated.getUsername(), id);
156+
return UserMapper.INSTANCE.userToAdminUserDTO(updated);
133157
}
134158

135159
private boolean isSelf(Long id) {
@@ -143,16 +167,19 @@ private void deleteAuthTokens(Long userId) {
143167

144168
private void setUsername(User user, String username) {
145169
if (username.equals(user.getUsername())) return;
146-
if (userRepository.existsByUsername(username))
170+
if (userRepository.existsByUsername(username)) {
171+
log.warn("Admin user update failed: username '{}' already exists", username);
147172
throw new ConflictException("user.usernameExists");
148-
173+
}
149174
user.setUsername(username);
150175
}
151176

152177
private void setEmail(User user, String email) {
153178
if (email.equals(user.getEmail())) return;
154-
if (userRepository.existsByEmail(email)) throw new ConflictException("user.emailExists");
155-
179+
if (userRepository.existsByEmail(email)) {
180+
log.warn("Admin user update failed: email '{}' already exists", email);
181+
throw new ConflictException("user.emailExists");
182+
}
156183
user.setEmail(email);
157184
}
158185

@@ -161,36 +188,56 @@ private void setPassword(User user, String password) {
161188
return;
162189

163190
user.setPassword(bCryptPasswordEncoder.encode(password));
164-
if (user.getId() != null) deleteAuthTokens(user.getId());
191+
if (user.getId() != null) {
192+
deleteAuthTokens(user.getId());
193+
log.info(
194+
"Password changed for user '{}' (id={}), all tokens invalidated",
195+
user.getUsername(),
196+
user.getId());
197+
}
165198
}
166199

167200
private void setActive(User user, Boolean active) {
168201
if (user.getActive().equals(active)) return;
169-
170202
user.setActive(active);
171-
if (Boolean.FALSE.equals(active)) deleteAuthTokens(user.getId());
203+
if (Boolean.FALSE.equals(active)) {
204+
deleteAuthTokens(user.getId());
205+
log.info(
206+
"User '{}' (id={}) deactivated, all tokens invalidated",
207+
user.getUsername(),
208+
user.getId());
209+
}
172210
}
173211

174212
private void setLock(User user, Boolean lock) {
175213
if (user.getLock().equals(lock)) return;
176-
177214
user.setLock(lock);
178-
if (Boolean.TRUE.equals(lock)) deleteAuthTokens(user.getId());
215+
if (Boolean.TRUE.equals(lock)) {
216+
deleteAuthTokens(user.getId());
217+
log.info(
218+
"User '{}' (id={}) locked, all tokens invalidated", user.getUsername(), user.getId());
219+
}
179220
}
180221

181222
private void setRoles(User user, Set<RoleName> roleNames) {
182-
if (roleNames.isEmpty()) throw new BadRequestException("user.rolesEmpty");
183-
223+
if (roleNames.isEmpty()) {
224+
log.warn("Admin role update failed for user '{}': role list is empty", user.getId());
225+
throw new BadRequestException("user.rolesEmpty");
226+
}
184227
final var roles = new HashSet<>(roleRepository.findAllByNameIn(roleNames));
185228
if (user.getRoles().equals(roles)) return;
186-
187229
user.setRoles(roles);
188230
deleteAuthTokens(user.getId());
231+
log.info(
232+
"Roles updated for user '{}' (id={}), all tokens invalidated",
233+
user.getUsername(),
234+
user.getId());
189235
}
190236

191237
@Override
192238
public void delete(Long id) {
193239
deleteAuthTokens(id);
194240
userRepository.deleteById(id);
241+
log.info("Admin deleted user with id '{}'", id);
195242
}
196243
}

backend/spring-boot/src/main/java/org/bugzkit/api/auth/controller/AuthController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import org.bugzkit.api.auth.util.AuthUtil;
1919
import org.bugzkit.api.auth.util.JwtUtil;
2020
import org.bugzkit.api.shared.constants.Path;
21-
import org.bugzkit.api.shared.ratelimit.RateLimit;
21+
import org.bugzkit.api.shared.interceptor.RateLimit;
2222
import org.bugzkit.api.user.payload.dto.UserDTO;
2323
import org.springframework.beans.factory.annotation.Value;
2424
import org.springframework.http.HttpHeaders;

backend/spring-boot/src/main/java/org/bugzkit/api/auth/oauth2/OAuth2SuccessHandler.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ public void onAuthenticationSuccess(
6666
response.addHeader(HttpHeaders.SET_COOKIE, accessTokenCookie.toString());
6767
response.addHeader(HttpHeaders.SET_COOKIE, refreshTokenCookie.toString());
6868
response.sendRedirect(uiUrl);
69-
log.info("OAuth finished");
69+
log.info(
70+
"OAuth2 login successful for user '{}' on device '{}'", userPrincipal.getId(), deviceId);
7071
MDC.clear();
7172
}
7273
}

backend/spring-boot/src/main/java/org/bugzkit/api/auth/oauth2/OAuth2UserService.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,20 @@ public OAuth2UserService(UserRepository userRepository, RoleRepository roleRepos
3030
@Override
3131
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
3232
MDC.put("REQUEST_ID", UUID.randomUUID().toString());
33-
log.info("OAuth called");
3433
final var oAuthUser = super.loadUser(userRequest);
3534
final String email = oAuthUser.getAttribute("email");
3635
final boolean emailVerified = Boolean.TRUE.equals(oAuthUser.getAttribute("email_verified"));
3736
if (!emailVerified) throw new DisabledException("user.notActive");
38-
final var user = userRepository.findWithRolesByEmail(email).orElseGet(() -> createUser(email));
37+
final var provider = userRequest.getClientRegistration().getRegistrationId();
38+
final var user =
39+
userRepository.findWithRolesByEmail(email).orElseGet(() -> createUser(email, provider));
3940
if (user.getUsername() == null) user.setUsername(email);
41+
log.info("OAuth2 login via '{}' for '{}'", provider, email);
4042
return new OAuth2UserPrincipal(UserPrincipal.create(user), oAuthUser.getAttributes());
4143
}
4244

43-
private User createUser(String email) {
45+
private User createUser(String email, String provider) {
46+
log.info("Provisioning new OAuth2 user via '{}' for '{}'", provider, email);
4447
final var roles =
4548
roleRepository
4649
.findByName(RoleName.USER)

backend/spring-boot/src/main/java/org/bugzkit/api/auth/service/impl/AccessTokenServiceImpl.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.time.Instant;
55
import java.util.Set;
66
import java.util.UUID;
7+
import lombok.extern.slf4j.Slf4j;
78
import org.bugzkit.api.auth.redis.model.AccessTokenBlacklist;
89
import org.bugzkit.api.auth.redis.model.UserBlacklist;
910
import org.bugzkit.api.auth.redis.repository.AccessTokenBlacklistRepository;
@@ -16,6 +17,7 @@
1617
import org.springframework.beans.factory.annotation.Value;
1718
import org.springframework.stereotype.Service;
1819

20+
@Slf4j
1921
@Service
2022
public class AccessTokenServiceImpl implements AccessTokenService {
2123
private static final JwtPurpose PURPOSE = JwtPurpose.ACCESS_TOKEN;
@@ -59,22 +61,27 @@ private void verifyToken(String token) {
5961
try {
6062
JwtUtil.verify(token, secret, PURPOSE);
6163
} catch (RuntimeException e) {
64+
log.warn("Access token verification failed: {}", e.getMessage());
6265
throw new UnauthorizedException("auth.tokenInvalid");
6366
}
6467
}
6568

6669
private void isInAccessTokenBlacklist(String token) {
67-
if (accessTokenBlacklistRepository.existsById(JwtUtil.getJwtId(token)))
70+
if (accessTokenBlacklistRepository.existsById(JwtUtil.getJwtId(token))) {
71+
log.warn("Access token '{}' is blacklisted", JwtUtil.getJwtId(token));
6872
throw new UnauthorizedException("auth.tokenInvalid");
73+
}
6974
}
7075

7176
private void isInUserBlacklist(String token) {
7277
final var userId = JwtUtil.getUserId(token);
7378
final var issuedAt = JwtUtil.getIssuedAt(token);
7479
final var userInBlacklist = userBlacklistRepository.findById(userId);
7580
if (userInBlacklist.isEmpty()) return;
76-
if (issuedAt.isBefore(userInBlacklist.get().getUpdatedAt()))
81+
if (issuedAt.isBefore(userInBlacklist.get().getUpdatedAt())) {
82+
log.warn("Access token for user '{}' was issued before the user blacklist entry", userId);
7783
throw new UnauthorizedException("auth.tokenInvalid");
84+
}
7885
}
7986

8087
@Override

0 commit comments

Comments
 (0)