package com.mattrixwv.raidbuilder.service; import java.time.Duration; import java.time.ZonedDateTime; import java.util.List; import java.util.UUID; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.mattrixwv.raidbuilder.entity.Account; import com.mattrixwv.raidbuilder.entity.AccountPermission; import com.mattrixwv.raidbuilder.entity.AccountTutorialStatus; import com.mattrixwv.raidbuilder.repository.account.AccountRepository; import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.AccountPermissionType; import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.AccountStatus; import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.TutorialStatus; import com.mattrixwv.raidbuilder.util.UserPrincipal; import lombok.RequiredArgsConstructor; @Service @Transactional(rollbackFor = Exception.class) @RequiredArgsConstructor public class AccountService implements UserDetailsService{ private final PasswordEncoder passwordEncoder; private final AccountRepository accountRepository; private final AccountTutorialStatusService accountTutorialStatusService; //Related services private final AccountPermissionService accountPermissionService; //Fields @Value("${jwt.refreshTokenDuration}") private Duration refreshTokenDuration; //Write public Account createAccount(Account account){ //Set default values account.setAccountStatus(AccountStatus.UNCONFIRMED); account.setPassword(passwordEncoder.encode(account.getPassword())); account.setRefreshToken(UUID.randomUUID()); account.setRefreshTokenExpiration(ZonedDateTime.now().plus(refreshTokenDuration)); //Save account account = accountRepository.save(account); //Return the new account return account; } public Account confirmAccount(Account account){ //Setup the confirmed values account.setRefreshToken(null); account.setRefreshTokenExpiration(null); account.setAccountStatus(AccountStatus.ACTIVE); //Save the account account = accountRepository.save(account); //Give account default permissions AccountPermission accountPermission = new AccountPermission(); accountPermission.setAccountId(account.getAccountId()); accountPermission.setAccountPermissionType(AccountPermissionType.USER); accountPermission = accountPermissionService.createAccountPermission(accountPermission); //Give account default tutorial actions AccountTutorialStatus accountTutorialStatus = new AccountTutorialStatus(); accountTutorialStatus.setAccountId(account.getAccountId()); accountTutorialStatus.setGamesTutorialStatus(TutorialStatus.NOT_COMPLETED); accountTutorialStatus.setGameTutorialStatus(TutorialStatus.NOT_COMPLETED); accountTutorialStatus.setRaidGroupsTutorialStatus(TutorialStatus.NOT_COMPLETED); accountTutorialStatus.setRaidGroupTutorialStatus(TutorialStatus.NOT_COMPLETED); accountTutorialStatus.setInstanceTutorialStatus(TutorialStatus.NOT_COMPLETED); accountTutorialStatus = accountTutorialStatusService.createAccountTutorialStatus(accountTutorialStatus); //Return the account return account; } public Account updateAccount(Account account){ return accountRepository.save(account); } public Account updatePassword(UUID accountId, String password){ Account account = accountRepository.findById(accountId).orElse(null); if(account != null){ account.setPassword(passwordEncoder.encode(password)); account = accountRepository.save(account); } return account; } //Read public Account getByAccountId(UUID accountId){ return accountRepository.findById(accountId).orElse(null); } public Account getByUsername(String username){ return accountRepository.findByUsername(username); } public Account getByEmail(String email){ return accountRepository.findByEmail(email); } public Account getByRefreshToken(UUID refreshToken){ return accountRepository.findByRefreshToken(refreshToken); } //! UserDetailsService @Override public UserDetails loadUserByUsername(String username){ Account account = accountRepository.findByUsername(username); //If no account with that username exists, throw an exception if(account == null){ throw new UsernameNotFoundException(username); } //Update the login timestamp and refresh token account.setLoginDate(ZonedDateTime.now()); account.setRefreshToken(UUID.randomUUID()); account.setRefreshTokenExpiration(ZonedDateTime.now().plus(refreshTokenDuration)); account = accountRepository.save(account); //Get the account permissions List accountPermissions = accountPermissionService.getByAccountId(account.getAccountId()); return new UserPrincipal(account, accountPermissions); } }