Implement CachingAuthenticationService (2.1.1.2)

This commit is contained in:
Tobias Eidelpes 2021-04-28 15:50:50 +02:00
parent 05d4c2ded6
commit 516092c3f4

View File

@ -0,0 +1,108 @@
package dst.ass2.service.auth.impl;
import dst.ass1.jpa.dao.impl.DAOFactory;
import dst.ass1.jpa.model.IRider;
import dst.ass2.service.api.auth.AuthenticationException;
import dst.ass2.service.api.auth.NoSuchUserException;
import dst.ass2.service.auth.ICachingAuthenticationService;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import static java.lang.String.format;
@Named("ICachingAuthenticationService")
@Singleton
public class CachingAuthenticationService implements ICachingAuthenticationService {
@PersistenceContext
private EntityManager entityManager;
@Resource
private DAOFactory daoFactory;
private final ConcurrentHashMap<String, byte[]> userCache = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, String> tokenCache = new ConcurrentHashMap<>();
@Transactional
@Override
public void changePassword(String email, String newPassword) throws NoSuchUserException {
IRider rider = daoFactory.createRiderDAO().findByEmail(email);
if (rider == null)
throw new NoSuchUserException("Could not find user with email " + email);
byte[] hashedPw = generateSHA1(newPassword);
rider.setPassword(hashedPw);
entityManager.merge(rider);
userCache.replace(email, hashedPw);
}
@Override
public String getUser(String token) {
return tokenCache.get(token);
}
@Override
public boolean isValid(String token) {
return tokenCache.containsKey(token);
}
@Override
public boolean invalidate(String token) {
return tokenCache.remove(token) != null;
}
@Transactional
@Override
public String authenticate(String email, String password) throws NoSuchUserException, AuthenticationException {
// Check if user in cache
if (!userCache.containsKey(email)) {
IRider rider = daoFactory.createRiderDAO().findByEmail(email);
if (rider == null)
throw new NoSuchUserException("Could not find user with email " + email);
userCache.put(email, rider.getPassword());
}
byte[] currentPassword = userCache.get(email);
byte[] newPassword = generateSHA1(password);
if (!Arrays.equals(currentPassword, newPassword)) {
throw new AuthenticationException("Failed to authenticate: Passwords do not match");
}
String token = UUID.randomUUID().toString();
tokenCache.put(token, email);
return token;
}
@PostConstruct
@Override
public void loadData() {
for (IRider rider : daoFactory.createRiderDAO().findAll()) {
userCache.putIfAbsent(rider.getEmail(), rider.getPassword());
}
}
@Override
public void clearCache() {
userCache.clear();
}
private byte[] generateSHA1(String string) {
MessageDigest digest;
try {
digest = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
digest.update(string.getBytes());
return digest.digest();
}
}