Skip to content
Snippets Groups Projects
Commit 6713e54d authored by yvesn's avatar yvesn
Browse files

SSDM-5398: password reset - storing tokens in file; added timestamp to make...

SSDM-5398: password reset - storing tokens in file; added timestamp to make sure the token in not older then 2 days

SVN: 38598
parent 3a1df3d4
No related branches found
No related tags found
No related merge requests found
package ch.ethz.sis; package ch.ethz.sis;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable; import java.io.Serializable;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import ch.systemsx.cisd.openbis.dss.generic.server.DataStoreServer;
public class PersistentKeyValueStore { public class PersistentKeyValueStore {
private static final String KEY_STORE_FILE;
private static ConcurrentMap<String, Serializable> keyStore = new ConcurrentHashMap<>(); private static ConcurrentMap<String, Serializable> keyStore = new ConcurrentHashMap<>();
public static void put(String key, Serializable value) { static {
Properties properties = DataStoreServer.getConfigParameters().getProperties();
String storerootDir = properties.getProperty("storeroot-dir");
KEY_STORE_FILE = storerootDir + "/" + "PersistentKeyValueStore.bin";
load();
}
//
// Public API
//
public synchronized static void put(String key, Serializable value) {
keyStore.put(key, value); keyStore.put(key, value);
save();
print();
} }
public static Serializable get(String key) { public synchronized static Serializable get(String key) {
print();
return keyStore.get(key); return keyStore.get(key);
} }
public static void remove(String key) { public synchronized static void remove(String key) {
keyStore.remove(key); keyStore.remove(key);
save();
} }
public static boolean containsKey(String key) { public synchronized static boolean containsKey(String key) {
print();
return keyStore.containsKey(key); return keyStore.containsKey(key);
} }
private synchronized static void print() {
for (String key : keyStore.keySet()) {
System.out.println(key + " - " + keyStore.get(key));
}
}
//
// save / load
//
private static void save() {
try (FileOutputStream fos = new FileOutputStream(KEY_STORE_FILE))
{
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(keyStore);
oos.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
@SuppressWarnings("unchecked")
private static void load() {
try (FileInputStream fis = new FileInputStream(KEY_STORE_FILE)) {
if (new File(KEY_STORE_FILE).exists()) {
ObjectInputStream ois = new ObjectInputStream(fis);
keyStore = (ConcurrentMap<String, Serializable>) ois.readObject();
ois.close();
}
} catch (IOException | ClassNotFoundException e)
{
e.printStackTrace();
}
}
} }
...@@ -54,7 +54,7 @@ def sendResetPasswordEmail(tr, userId, baseUrl): ...@@ -54,7 +54,7 @@ def sendResetPasswordEmail(tr, userId, baseUrl):
sendResetPasswordEmailInternal(tr, emailAddress, userId, token, baseUrl) sendResetPasswordEmailInternal(tr, emailAddress, userId, token, baseUrl)
def resetPassword(tr, userId, token): def resetPassword(tr, userId, token):
if tokenIsValid(userId, token): if tokenIsValid(tr, userId, token):
email = getUserEmail(tr, userId) email = getUserEmail(tr, userId)
resetPasswordInternal(tr, email, userId) resetPasswordInternal(tr, email, userId)
PersistentKeyValueStore.remove(userId + RESET_TOKEN_KEY_POSTFIX) PersistentKeyValueStore.remove(userId + RESET_TOKEN_KEY_POSTFIX)
...@@ -78,8 +78,17 @@ def getJsonForData(data): ...@@ -78,8 +78,17 @@ def getJsonForData(data):
jsonValue = objectMapper.writeValueAsString(data); jsonValue = objectMapper.writeValueAsString(data);
return jsonValue; return jsonValue;
def tokenIsValid(userId, token): def tokenIsValid(tr, userId, token):
return PersistentKeyValueStore.get(userId + RESET_TOKEN_KEY_POSTFIX) == token tokenAndTimestamp = PersistentKeyValueStore.get(userId + RESET_TOKEN_KEY_POSTFIX)
if (tokenAndTimestamp != None and tokenAndTimestamp["token"] == token):
timestampNow = time.time()
deltaInSeconds = timestampNow - float(tokenAndTimestamp["timestamp"])
maxDelayInMinutes = float(getProperty(tr, "max-delay-in-minutes"))
if deltaInSeconds < maxDelayInMinutes * 60:
return True
else:
PersistentKeyValueStore.remove(userId + RESET_TOKEN_KEY_POSTFIX)
return False
def sendResetPasswordEmailInternal(tr, email, userId, token, baseUrl): def sendResetPasswordEmailInternal(tr, email, userId, token, baseUrl):
passwordResetLink = getPasswordResetLink(email, userId, token, baseUrl) passwordResetLink = getPasswordResetLink(email, userId, token, baseUrl)
......
label = Password Reset API label = Password Reset API
class = ch.systemsx.cisd.openbis.dss.generic.server.plugins.jython.JythonIngestionService class = ch.systemsx.cisd.openbis.dss.generic.server.plugins.jython.JythonIngestionService
script-path = password-reset-api.py script-path = password-reset-api.py
max-delay-in-minutes = 2880
password-reset-request-subject = ELN-LIMS password reset for %s password-reset-request-subject = ELN-LIMS password reset for %s
password-reset-request-body = Hi,\n\nA request has been made to reset the password of user %s.\n\nClick on this link in order to get a new password:\n%s\n\nSincere regards,\nYour ELN-LIMS Team password-reset-request-body = Hi,\n\nA request has been made to reset the password of user %s.\n\nClick on this link in order to get a new password:\n%s\n\nSincere regards,\nYour ELN-LIMS Team
new-password-subject = ELN-LIMS new password for %s new-password-subject = ELN-LIMS new password for %s
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment