diff --git a/backend/src/main/kotlin/com/github/sor2171/backend/service/impl/AccountServiceImpl.kt b/backend/src/main/kotlin/com/github/sor2171/backend/service/impl/AccountServiceImpl.kt index 2dbf893..129147a 100644 --- a/backend/src/main/kotlin/com/github/sor2171/backend/service/impl/AccountServiceImpl.kt +++ b/backend/src/main/kotlin/com/github/sor2171/backend/service/impl/AccountServiceImpl.kt @@ -10,104 +10,136 @@ import org.springframework.security.core.userdetails.UserDetails import org.springframework.security.core.userdetails.UsernameNotFoundException import org.springframework.stereotype.Service import reactor.core.publisher.Mono +import reactor.core.scheduler.Schedulers +import javax.security.auth.login.AccountNotFoundException @Service class AccountServiceImpl : ServiceImpl(), AccountService { - val logger = LoggerFactory.getLogger(this::class.java)!! + private val logger = LoggerFactory.getLogger(this::class.java) + + override fun findByUsername( + username: String + ): Mono { - override fun findByUsername(username: String): Mono { return findAccountByName(username) - .switchIfEmpty(Mono.error(UsernameNotFoundException("Account with name $username not found"))) - .map { account -> - User.withUsername(username) - .password(account.password) - .roles(account.role) + .map { + User.withUsername(it.username) + .password(it.password) + .roles(it.role) .build() } + .onErrorMap( + AccountNotFoundException::class.java + ) { + UsernameNotFoundException( + "User not found" + ) + } } override fun findAccountByName(username: String): Mono = - findAccount("name", username) { + findAccount("username") { ktQuery() .eq(Account::username, username) .one() } override fun findAccountByEmail(email: String): Mono = - findAccount("email", email) { + findAccount("email") { ktQuery() .eq(Account::email, email) .one() } + private fun blockingCall( + block: () -> T? + ): Mono = + Mono.fromCallable(block) + .subscribeOn(Schedulers.boundedElastic()) + .flatMap { + Mono.just(it) + } + private fun findAccount( fieldName: String, - value: String, query: () -> Account? - ): Mono = - Mono.fromCallable { - logger.info("Find account with {} {}", fieldName, value) + ): Mono { + return blockingCall { + logger.info( + "Searching account by {}", + fieldName + ) query() }.switchIfEmpty( Mono.error( - UsernameNotFoundException("Account with $fieldName $value not found") + AccountNotFoundException() ) ) + } - override fun findAccountByNameOrEmail(text: String): Mono = - findAccountByEmail(text).onErrorResume( - UsernameNotFoundException::class.java - ) { - findAccountByName(text) - } + override fun findAccountByNameOrEmail( + text: String + ): Mono { + return blockingCall { + logger.info( + "Searching account by identifier" + ) + ktQuery() + .and { + it.eq(Account::email, text) + .or() + .eq(Account::username, text) + } + .one() + }.switchIfEmpty( + Mono.error(AccountNotFoundException()) + ) + } - override fun existAccountByName(username: String): Mono = - Mono.fromCallable { - logger.info("Determine if name {} exists", username) + override fun existAccountByName( + username: String + ): Mono { + return blockingCall { ktQuery() .eq(Account::username, username) .exists() - } - override fun existAccountByEmail(email: String): Mono = - Mono.fromCallable { - logger.info("Determine if email {} exists", email) + } + } + + override fun existAccountByEmail( + email: String + ): Mono { + return blockingCall { ktQuery() .eq(Account::email, email) .exists() + } + } override fun resetPasswordByEmail( email: String, encodedPassword: String - ): Mono = - existAccountByEmail(email) - .flatMap { exists -> - if (!exists) { - return@flatMap Mono.error( - UsernameNotFoundException( - "Account with email $email not found" - ) - ) - } - - Mono.fromCallable { - ktUpdate() - .eq(Account::email, email) - .set(Account::password, encodedPassword) - .update() - } - } - .flatMap { success -> - if (success) { + ): Mono { + return blockingCall { + ktUpdate() + .eq(Account::email, email) + .set( + Account::password, + encodedPassword + ) + .update() + } + .flatMap { updated -> + if (updated) { Mono.empty() } else { Mono.error( - IllegalStateException( - "Failed to reset password" - ) + AccountNotFoundException() ) } } + } } \ No newline at end of file