summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--README.rst20
-rw-r--r--scripts/gen_password1
-rwxr-xr-xscripts/hash_password39
3 files changed, 59 insertions, 1 deletions
diff --git a/README.rst b/README.rst
index 8a745259bf..a48a0802b2 100644
--- a/README.rst
+++ b/README.rst
@@ -525,6 +525,26 @@ Logging In To An Existing Account
 Just enter the ``@localpart:my.domain.here`` Matrix user ID and password into
 the form and click the Login button.
 
+Password reset
+==============
+
+Synapse does not yet support a password-reset function (see
+https://matrix.org/jira/browse/SYN-11). In the meantime, it is possible to
+manually reset a user's password via direct database access.
+
+First calculate the hash of the new password:
+
+    $ source ~/.synapse/bin/activate
+    $ ./scripts/hash_password
+    Password: 
+    Confirm password: 
+    $2a$12$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+
+Then update the `users` table in the database:
+
+    UPDATE users SET password_hash='$2a$12$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
+        WHERE name='@test:test.com';
+
 
 Identity Servers
 ================
diff --git a/scripts/gen_password b/scripts/gen_password
deleted file mode 100644
index 7afd3a5dfd..0000000000
--- a/scripts/gen_password
+++ /dev/null
@@ -1 +0,0 @@
-perl -MCrypt::Random -MCrypt::Eksblowfish::Bcrypt -e 'print Crypt::Eksblowfish::Bcrypt::bcrypt("secret", "\$2\$12\$" . Crypt::Eksblowfish::Bcrypt::en_base64(Crypt::Random::makerandom_octet(Length=>16)))."\n"'
diff --git a/scripts/hash_password b/scripts/hash_password
new file mode 100755
index 0000000000..e784600989
--- /dev/null
+++ b/scripts/hash_password
@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+
+import argparse
+import bcrypt
+import getpass
+
+bcrypt_rounds=12
+
+def prompt_for_pass():
+    password = getpass.getpass("Password: ")
+
+    if not password:
+        raise Exception("Password cannot be blank.")
+
+    confirm_password = getpass.getpass("Confirm password: ")
+
+    if password != confirm_password:
+        raise Exception("Passwords do not match.")
+
+    return password
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser(
+        description="Calculate the hash of a new password, so that passwords"
+                    " can be reset")
+    parser.add_argument(
+        "-p", "--password",
+        default=None,
+        help="New password for user. Will prompt if omitted.",
+    )
+
+    args = parser.parse_args()
+    password = args.password
+
+    if not password:
+        password = prompt_for_pass()
+
+    print bcrypt.hashpw(password, bcrypt.gensalt(bcrypt_rounds))
+