feat: add whitelist register mode

This commit is contained in:
Tim
2025-07-14 21:32:07 +08:00
parent c9c96edcb0
commit 609156f4e5
21 changed files with 161 additions and 36 deletions

View File

@@ -43,16 +43,16 @@ public class CommentService {
comment.setContent(content);
comment = commentRepository.save(comment);
if (!author.getId().equals(post.getAuthor().getId())) {
notificationService.createNotification(post.getAuthor(), NotificationType.COMMENT_REPLY, post, comment, null);
notificationService.createNotification(post.getAuthor(), NotificationType.COMMENT_REPLY, post, comment, null, null, null, null);
}
for (User u : subscriptionService.getPostSubscribers(postId)) {
if (!u.getId().equals(author.getId())) {
notificationService.createNotification(u, NotificationType.POST_UPDATED, post, comment, null);
notificationService.createNotification(u, NotificationType.POST_UPDATED, post, comment, null, null, null, null);
}
}
for (User u : subscriptionService.getSubscribers(author.getUsername())) {
if (!u.getId().equals(author.getId())) {
notificationService.createNotification(u, NotificationType.USER_ACTIVITY, post, comment, null);
notificationService.createNotification(u, NotificationType.USER_ACTIVITY, post, comment, null, null, null, null);
}
}
return comment;
@@ -70,21 +70,21 @@ public class CommentService {
comment.setContent(content);
comment = commentRepository.save(comment);
if (!author.getId().equals(parent.getAuthor().getId())) {
notificationService.createNotification(parent.getAuthor(), NotificationType.COMMENT_REPLY, parent.getPost(), comment, null);
notificationService.createNotification(parent.getAuthor(), NotificationType.COMMENT_REPLY, parent.getPost(), comment, null, null, null, null);
}
for (User u : subscriptionService.getCommentSubscribers(parentId)) {
if (!u.getId().equals(author.getId())) {
notificationService.createNotification(u, NotificationType.COMMENT_REPLY, parent.getPost(), comment, null);
notificationService.createNotification(u, NotificationType.COMMENT_REPLY, parent.getPost(), comment, null, null, null, null);
}
}
for (User u : subscriptionService.getPostSubscribers(parent.getPost().getId())) {
if (!u.getId().equals(author.getId())) {
notificationService.createNotification(u, NotificationType.POST_UPDATED, parent.getPost(), comment, null);
notificationService.createNotification(u, NotificationType.POST_UPDATED, parent.getPost(), comment, null, null, null, null);
}
}
for (User u : subscriptionService.getSubscribers(author.getUsername())) {
if (!u.getId().equals(author.getId())) {
notificationService.createNotification(u, NotificationType.USER_ACTIVITY, parent.getPost(), comment, null);
notificationService.createNotification(u, NotificationType.USER_ACTIVITY, parent.getPost(), comment, null, null, null, null);
}
}
return comment;

View File

@@ -23,7 +23,7 @@ public class GoogleAuthService {
@Value("${google.client-id:}")
private String clientId;
public Optional<User> authenticate(String idTokenString) {
public Optional<User> authenticate(String idTokenString, String reason, com.openisle.model.RegisterMode mode) {
GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(new NetHttpTransport(), new JacksonFactory())
.setAudience(Collections.singletonList(clientId))
.build();
@@ -35,13 +35,13 @@ public class GoogleAuthService {
GoogleIdToken.Payload payload = idToken.getPayload();
String email = payload.getEmail();
String name = (String) payload.get("name");
return Optional.of(processUser(email, name));
return Optional.of(processUser(email, name, reason, mode));
} catch (Exception e) {
return Optional.empty();
}
}
private User processUser(String email, String name) {
private User processUser(String email, String name, String reason, com.openisle.model.RegisterMode mode) {
Optional<User> existing = userRepository.findByEmail(email);
if (existing.isPresent()) {
User user = existing.get();
@@ -64,6 +64,8 @@ public class GoogleAuthService {
user.setPassword("");
user.setRole(Role.USER);
user.setVerified(true);
user.setRegisterReason(reason);
user.setApproved(mode == com.openisle.model.RegisterMode.DIRECT);
user.setAvatar("https://github.com/identicons/" + username + ".png");
return userRepository.save(user);
}

View File

@@ -16,11 +16,11 @@ public class NotificationService {
private final UserRepository userRepository;
public Notification createNotification(User user, NotificationType type, Post post, Comment comment, Boolean approved) {
return createNotification(user, type, post, comment, approved, null, null);
return createNotification(user, type, post, comment, approved, null, null, null);
}
public Notification createNotification(User user, NotificationType type, Post post, Comment comment, Boolean approved,
User fromUser, ReactionType reactionType) {
User fromUser, ReactionType reactionType, String content) {
Notification n = new Notification();
n.setUser(user);
n.setType(type);
@@ -29,6 +29,7 @@ public class NotificationService {
n.setApproved(approved);
n.setFromUser(fromUser);
n.setReactionType(reactionType);
n.setContent(content);
return notificationRepository.save(n);
}

View File

@@ -109,10 +109,10 @@ public class PostService {
java.util.List<User> admins = userRepository.findByRole(com.openisle.model.Role.ADMIN);
for (User admin : admins) {
notificationService.createNotification(admin,
NotificationType.POST_REVIEW_REQUEST, post, null, null, author, null);
NotificationType.POST_REVIEW_REQUEST, post, null, null, author, null, null);
}
notificationService.createNotification(author,
NotificationType.POST_REVIEW_REQUEST, post, null, null, null, null);
NotificationType.POST_REVIEW_REQUEST, post, null, null, null, null, null);
}
// notify followers of author
for (User u : subscriptionService.getSubscribers(author.getUsername())) {
@@ -124,6 +124,7 @@ public class PostService {
null,
null,
author,
null,
null);
}
}
@@ -151,9 +152,9 @@ public class PostService {
if (viewer != null && !viewer.equals(post.getAuthor().getUsername())) {
User viewerUser = userRepository.findByUsername(viewer).orElse(null);
if (viewerUser != null) {
notificationService.createNotification(post.getAuthor(), NotificationType.POST_VIEWED, post, null, null, viewerUser, null);
notificationService.createNotification(post.getAuthor(), NotificationType.POST_VIEWED, post, null, null, viewerUser, null, null);
} else {
notificationService.createNotification(post.getAuthor(), NotificationType.POST_VIEWED, post, null, null);
notificationService.createNotification(post.getAuthor(), NotificationType.POST_VIEWED, post, null, null, null, null, null);
}
}
return post;
@@ -321,7 +322,7 @@ public class PostService {
}
post.setStatus(PostStatus.PUBLISHED);
post = postRepository.save(post);
notificationService.createNotification(post.getAuthor(), NotificationType.POST_REVIEWED, post, null, true);
notificationService.createNotification(post.getAuthor(), NotificationType.POST_REVIEWED, post, null, true, null, null, null);
return post;
}
@@ -341,7 +342,7 @@ public class PostService {
}
post.setStatus(PostStatus.REJECTED);
post = postRepository.save(post);
notificationService.createNotification(post.getAuthor(), NotificationType.POST_REVIEWED, post, null, false);
notificationService.createNotification(post.getAuthor(), NotificationType.POST_REVIEWED, post, null, false, null, null, null);
return post;
}

View File

@@ -40,7 +40,7 @@ public class ReactionService {
reaction.setType(type);
reaction = reactionRepository.save(reaction);
if (!user.getId().equals(post.getAuthor().getId())) {
notificationService.createNotification(post.getAuthor(), NotificationType.REACTION, post, null, null, user, type);
notificationService.createNotification(post.getAuthor(), NotificationType.REACTION, post, null, null, user, type, null);
}
return reaction;
}
@@ -63,7 +63,7 @@ public class ReactionService {
reaction.setType(type);
reaction = reactionRepository.save(reaction);
if (!user.getId().equals(comment.getAuthor().getId())) {
notificationService.createNotification(comment.getAuthor(), NotificationType.REACTION, comment.getPost(), comment, null, user, type);
notificationService.createNotification(comment.getAuthor(), NotificationType.REACTION, comment.getPost(), comment, null, user, type, null);
}
return reaction;
}

View File

@@ -0,0 +1,25 @@
package com.openisle.service;
import com.openisle.model.RegisterMode;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
/**
* Holds current registration mode. Configurable at runtime.
*/
@Service
public class RegisterModeService {
private RegisterMode registerMode;
public RegisterModeService(@Value("${app.register.mode:WHITELIST}") RegisterMode registerMode) {
this.registerMode = registerMode;
}
public RegisterMode getRegisterMode() {
return registerMode;
}
public void setRegisterMode(RegisterMode mode) {
this.registerMode = mode;
}
}

View File

@@ -28,7 +28,7 @@ public class SubscriptionService {
ps.setPost(post);
if (!user.getId().equals(post.getAuthor().getId())) {
notificationService.createNotification(post.getAuthor(),
NotificationType.POST_SUBSCRIBED, post, null, null, user, null);
NotificationType.POST_SUBSCRIBED, post, null, null, user, null, null);
}
return postSubRepo.save(ps);
});
@@ -41,7 +41,7 @@ public class SubscriptionService {
postSubRepo.delete(ps);
if (!user.getId().equals(post.getAuthor().getId())) {
notificationService.createNotification(post.getAuthor(),
NotificationType.POST_UNSUBSCRIBED, post, null, null, user, null);
NotificationType.POST_UNSUBSCRIBED, post, null, null, user, null, null);
}
});
}
@@ -72,7 +72,7 @@ public class SubscriptionService {
us.setSubscriber(subscriber);
us.setTarget(target);
notificationService.createNotification(target,
NotificationType.USER_FOLLOWED, null, null, null, subscriber, null);
NotificationType.USER_FOLLOWED, null, null, null, subscriber, null, null);
return userSubRepo.save(us);
});
}
@@ -83,7 +83,7 @@ public class SubscriptionService {
userSubRepo.findBySubscriberAndTarget(subscriber, target).ifPresent(us -> {
userSubRepo.delete(us);
notificationService.createNotification(target,
NotificationType.USER_UNFOLLOWED, null, null, null, subscriber, null);
NotificationType.USER_UNFOLLOWED, null, null, null, subscriber, null, null);
});
}

View File

@@ -22,7 +22,7 @@ public class UserService {
private final UsernameValidator usernameValidator;
private final PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
public User register(String username, String email, String password) {
public User register(String username, String email, String password, String reason, com.openisle.model.RegisterMode mode) {
usernameValidator.validate(username);
passwordValidator.validate(password);
// ── 先按用户名查 ──────────────────────────────────────────
@@ -36,6 +36,8 @@ public class UserService {
u.setEmail(email); // 若不允许改邮箱可去掉
u.setPassword(passwordEncoder.encode(password));
u.setVerificationCode(genCode());
u.setRegisterReason(reason);
u.setApproved(mode == com.openisle.model.RegisterMode.DIRECT);
return userRepository.save(u);
}
@@ -50,6 +52,8 @@ public class UserService {
u.setUsername(username); // 若不允许改用户名可去掉
u.setPassword(passwordEncoder.encode(password));
u.setVerificationCode(genCode());
u.setRegisterReason(reason);
u.setApproved(mode == com.openisle.model.RegisterMode.DIRECT);
return userRepository.save(u);
}
@@ -62,6 +66,8 @@ public class UserService {
user.setVerified(false);
user.setVerificationCode(genCode());
user.setAvatar("https://github.com/identicons/" + username + ".png");
user.setRegisterReason(reason);
user.setApproved(mode == com.openisle.model.RegisterMode.DIRECT);
return userRepository.save(user);
}
@@ -84,6 +90,7 @@ public class UserService {
public Optional<User> authenticate(String username, String password) {
return userRepository.findByUsername(username)
.filter(User::isVerified)
.filter(User::isApproved)
.filter(user -> passwordEncoder.matches(password, user.getPassword()));
}