-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added a verification email on registration #27
Changes from all commits
1e1cdf9
e6bf9a9
077ae38
fa7113c
388c3d4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package pl.simpleascoding.tutoringplatform.domain.token; | ||
|
||
import lombok.Data; | ||
import lombok.NoArgsConstructor; | ||
import pl.simpleascoding.tutoringplatform.domain.user.User; | ||
|
||
import javax.persistence.*; | ||
import java.time.LocalDateTime; | ||
import java.util.UUID; | ||
|
||
@Data | ||
@Entity | ||
@Table(name = "token") | ||
@NoArgsConstructor | ||
public class Token { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
|
||
private TokenType type; | ||
|
||
private String value = UUID.randomUUID().toString(); | ||
|
||
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) | ||
private User user; | ||
|
||
private LocalDateTime createdAt = LocalDateTime.now(); | ||
private LocalDateTime expiresAt = createdAt.plusMinutes(15); | ||
private LocalDateTime confirmedAt; | ||
|
||
public Token(TokenType type) { | ||
this.type = type; | ||
} | ||
|
||
public void confirm() { | ||
this.confirmedAt = LocalDateTime.now(); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package pl.simpleascoding.tutoringplatform.domain.token; | ||
|
||
public enum TokenType { | ||
REGISTER, PASSWORD, EMAIL | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package pl.simpleascoding.tutoringplatform.exception; | ||
|
||
public class EmailTakenException extends RuntimeException { | ||
public EmailTakenException(String email) { | ||
super("Email \"" + email + "\" is already in use"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tutaj jest konkatencja 3ch obiektów klasy String. Więc wychodzi, że JVM wykonuje takie operacje aby utworzyć wynikowy obiekt:
JVM też musi wykonać dodatkową robotę aby obiekty String stworzyć - właściwie na darmo, bo za chwile nie są one już potrzebne. Więc może zamiast tak łączyć i rzeźbić warto użyć klasy StringBuffer bądź StringBuilder. Zależnie od wymaganego bezpieczeństwa wielowątkowości przy tej operacji. p.s. W tym miejscu będzie też w przyszłości użyta metoda do pobrania odpowiedniej wersji językowej komunikatu. Ale przeróbka będzie banalnie prosta w pszyszłości.
A w przyszłości całość będzie taka: |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package pl.simpleascoding.tutoringplatform.exception; | ||
|
||
public class TokenAlreadyConfirmedException extends RuntimeException { | ||
public TokenAlreadyConfirmedException() { | ||
super("Token already confirmed"); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package pl.simpleascoding.tutoringplatform.exception; | ||
|
||
public class TokenNotFoundException extends RuntimeException { | ||
public TokenNotFoundException() { | ||
super("Token not found"); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package pl.simpleascoding.tutoringplatform.exception; | ||
|
||
public class UserAlreadyEnabledException extends RuntimeException { | ||
public UserAlreadyEnabledException(String username) { | ||
super("User \"" + username + "\" is already enabled"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Taka sama uwaga jak przy klasie: |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package pl.simpleascoding.tutoringplatform.repository; | ||
|
||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import pl.simpleascoding.tutoringplatform.domain.token.Token; | ||
|
||
import java.time.LocalDateTime; | ||
import java.util.List; | ||
import java.util.Optional; | ||
|
||
public interface TokenRepository extends JpaRepository<Token, Long> { | ||
Optional<Token> findTokenByValue(String value); | ||
|
||
List<Token> findTokensByExpiresAtBefore(LocalDateTime localDateTime); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package pl.simpleascoding.tutoringplatform.service.token; | ||
|
||
public interface ExpiredTokensCleanerService { | ||
void cleanExpiredTokens(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package pl.simpleascoding.tutoringplatform.service.token; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.scheduling.annotation.Scheduled; | ||
import org.springframework.stereotype.Service; | ||
import pl.simpleascoding.tutoringplatform.domain.token.Token; | ||
import pl.simpleascoding.tutoringplatform.domain.token.TokenType; | ||
import pl.simpleascoding.tutoringplatform.domain.user.User; | ||
import pl.simpleascoding.tutoringplatform.repository.TokenRepository; | ||
import pl.simpleascoding.tutoringplatform.repository.UserRepository; | ||
|
||
import java.time.LocalDateTime; | ||
import java.util.List; | ||
import java.util.Optional; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
@Slf4j | ||
public class ExpiredTokensCleanerServiceImpl implements ExpiredTokensCleanerService { | ||
|
||
private final TokenRepository tokenRepository; | ||
private final UserRepository userRepository; | ||
|
||
@Override | ||
@Scheduled(cron = "0 0 * ? * *") | ||
public void cleanExpiredTokens() { | ||
List<Token> expiredTokens = tokenRepository.findTokensByExpiresAtBefore(LocalDateTime.now()); | ||
List<User> inactiveUsers = expiredTokens | ||
.stream() | ||
.filter(token -> TokenType.REGISTER.equals(token.getType()) && Optional.ofNullable(token.getConfirmedAt()).isEmpty()) | ||
.map(Token::getUser) | ||
.toList(); | ||
|
||
tokenRepository.deleteAll(expiredTokens); | ||
log.info("Deleted expired tokens from the database."); | ||
userRepository.deleteAll(inactiveUsers); | ||
inactiveUsers.forEach(user -> log.info("Deleted user \"" + user.getUsername() + "\". Reason: Account has not been been activated.")); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Proponowana nazwa klasy: