Implement CachingAuthenticationService (2.1.1.2)
This commit is contained in:
parent
05d4c2ded6
commit
516092c3f4
@ -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();
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user