diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/password-reset-api/lib/persistentkeyvaluestore-source/PersistentKeyValueStore.java b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/password-reset-api/lib/persistentkeyvaluestore-source/PersistentKeyValueStore.java index c1aec05d6bbd423904e249ee5c068aa4ce0371ba..cbbd3a4b2f7af536cd202d4f099ab8a967cc84e7 100644 --- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/password-reset-api/lib/persistentkeyvaluestore-source/PersistentKeyValueStore.java +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/password-reset-api/lib/persistentkeyvaluestore-source/PersistentKeyValueStore.java @@ -1,27 +1,88 @@ 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.util.Properties; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import ch.systemsx.cisd.openbis.dss.generic.server.DataStoreServer; public class PersistentKeyValueStore { + + private static final String KEY_STORE_FILE; 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); + save(); + print(); } - - public static Serializable get(String key) { + + public synchronized static Serializable get(String key) { + print(); return keyStore.get(key); } - - public static void remove(String key) { + + public synchronized static void remove(String key) { keyStore.remove(key); + save(); } - - public static boolean containsKey(String key) { + + public synchronized static boolean containsKey(String key) { + print(); 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(); + } + } + } diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/password-reset-api/lib/persistentkeyvaluestore.jar b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/password-reset-api/lib/persistentkeyvaluestore.jar index d3f77f6a23766b0947ddd07d80311cdfe1069101..1f2a896f4205e7371109844e1328390ff6557c8f 100644 Binary files a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/password-reset-api/lib/persistentkeyvaluestore.jar and b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/password-reset-api/lib/persistentkeyvaluestore.jar differ diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/password-reset-api/password-reset-api.py b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/password-reset-api/password-reset-api.py index 486988df762a7fdf8297c09894d403c9566a9651..25067b6783602f4849a6576293c651b2514f247c 100644 --- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/password-reset-api/password-reset-api.py +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/password-reset-api/password-reset-api.py @@ -54,7 +54,7 @@ def sendResetPasswordEmail(tr, userId, baseUrl): sendResetPasswordEmailInternal(tr, emailAddress, userId, token, baseUrl) def resetPassword(tr, userId, token): - if tokenIsValid(userId, token): + if tokenIsValid(tr, userId, token): email = getUserEmail(tr, userId) resetPasswordInternal(tr, email, userId) PersistentKeyValueStore.remove(userId + RESET_TOKEN_KEY_POSTFIX) @@ -78,8 +78,17 @@ def getJsonForData(data): jsonValue = objectMapper.writeValueAsString(data); return jsonValue; -def tokenIsValid(userId, token): - return PersistentKeyValueStore.get(userId + RESET_TOKEN_KEY_POSTFIX) == token +def tokenIsValid(tr, userId, 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): passwordResetLink = getPasswordResetLink(email, userId, token, baseUrl) diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/password-reset-api/plugin.properties b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/password-reset-api/plugin.properties index 18c916fc9a59e026ae19951400e3bf2897d5a9ec..e8a94ee542c2d7e3b9267c614246847b828e0b10 100644 --- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/password-reset-api/plugin.properties +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/password-reset-api/plugin.properties @@ -1,6 +1,7 @@ label = Password Reset API class = ch.systemsx.cisd.openbis.dss.generic.server.plugins.jython.JythonIngestionService script-path = password-reset-api.py +max-delay-in-minutes = 2880 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 new-password-subject = ELN-LIMS new password for %s