package kickr.security.service; import java.time.Duration; import java.time.Instant; import java.util.Date; import kickr.db.dao.AccessTokenDAO; import kickr.db.dao.UserDAO; import kickr.db.entity.user.AccessToken; import kickr.db.entity.user.User; import support.security.AuthenticationException; /** * * @author nikku */ public class AuthenticationService { private static final Duration SESSION_DURATION = Duration.ofMinutes(60); private final AccessTokenDAO accessTokenDao; private final CredentialsService credentialsService; private final UserDAO userDao; public AuthenticationService(CredentialsService credentialsService, UserDAO userDao, AccessTokenDAO accessTokenDao) { this.credentialsService = credentialsService; this.userDao = userDao; this.accessTokenDao = accessTokenDao; } public User authenticate(String token) { AccessToken accessToken = accessTokenDao.get(token); if (accessToken != null) { Date validUntil = accessToken.getValidUntil(); // update valid access token, otherwise delete invalid if (validUntil == null || validUntil.after(new Date())) { if (validUntil != null) { limitValidity(accessToken); } return accessToken.getUser(); } else { accessTokenDao.remove(accessToken); } } throw authenticationFailed(); } public AccessToken authenticate(String name, String password, boolean limited) { User user = userDao.getByName(name); if (user != null) { if (credentialsService.matches(password, user.getPassword())) { return createAccessToken(user, limited); } } throw authenticationFailed(); } protected AccessToken createAccessToken(User user, boolean limited) { String sessionToken = credentialsService.createSessionToken(user); AccessToken accessToken = new AccessToken(sessionToken, user); if (limited) { limitValidity(accessToken); } accessTokenDao.create(accessToken); return accessToken; } private AuthenticationException authenticationFailed() { return new AuthenticationException("Failed to authenticate"); } public void unauthenticate(User user, String token) { if (token == null) { accessTokenDao.removeByUser(user); } else { accessTokenDao.removeByToken(user, token); } } private void limitValidity(AccessToken accessToken) { accessToken.setValidUntil(Date.from(Instant.now().plus(SESSION_DURATION))); } }