summary refs log tree commit diff
path: root/synapse
diff options
context:
space:
mode:
Diffstat (limited to 'synapse')
-rw-r--r--synapse/auth/macaroons.py0
-rw-r--r--synapse/config/registration.py4
-rw-r--r--synapse/handlers/register.py19
-rw-r--r--synapse/python_dependencies.py1
4 files changed, 18 insertions, 6 deletions
diff --git a/synapse/auth/macaroons.py b/synapse/auth/macaroons.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/synapse/auth/macaroons.py
diff --git a/synapse/config/registration.py b/synapse/config/registration.py
index 67e780864e..62de4b399f 100644
--- a/synapse/config/registration.py
+++ b/synapse/config/registration.py
@@ -32,9 +32,11 @@ class RegistrationConfig(Config):
             )
 
         self.registration_shared_secret = config.get("registration_shared_secret")
+        self.macaroon_secret_key = config.get("macaroon_secret_key")
 
     def default_config(self, config_dir, server_name):
         registration_shared_secret = random_string_with_symbols(50)
+        macaroon_secret_key = random_string_with_symbols(50)
         return """\
         ## Registration ##
 
@@ -44,6 +46,8 @@ class RegistrationConfig(Config):
         # If set, allows registration by anyone who also has the shared
         # secret, even if registration is otherwise disabled.
         registration_shared_secret: "%(registration_shared_secret)s"
+
+        macaroon_secret_key: "%(macaroon_secret_key)s"
         """ % locals()
 
     def add_arguments(self, parser):
diff --git a/synapse/handlers/register.py b/synapse/handlers/register.py
index 39392d9fdd..86bacdda1d 100644
--- a/synapse/handlers/register.py
+++ b/synapse/handlers/register.py
@@ -25,9 +25,9 @@ import synapse.util.stringutils as stringutils
 from synapse.util.async import run_on_reactor
 from synapse.http.client import CaptchaServerHttpClient
 
-import base64
 import bcrypt
 import logging
+import pymacaroons
 import urllib
 
 logger = logging.getLogger(__name__)
@@ -274,11 +274,18 @@ class RegistrationHandler(BaseHandler):
                 )
 
     def generate_token(self, user_id):
-        # urlsafe variant uses _ and - so use . as the separator and replace
-        # all =s with .s so http clients don't quote =s when it is used as
-        # query params.
-        return (base64.urlsafe_b64encode(user_id).replace('=', '.') + '.' +
-                stringutils.random_string(18))
+        macaroon = pymacaroons.Macaroon(
+            location = self.hs.config.server_name,
+            identifier = "key",
+            key = self.hs.config.macaroon_secret_key)
+        macaroon.add_first_party_caveat("gen = 1")
+        macaroon.add_first_party_caveat("user_id = %s" % user_id)
+        macaroon.add_first_party_caveat("type = access")
+        now = self.hs.get_clock().time()
+        expiry = now + 60 * 60
+        macaroon.add_first_party_caveat("time < %s" % expiry)
+
+        return macaroon.serialize()
 
     def _generate_user_id(self):
         return "-" + stringutils.random_string(18)
diff --git a/synapse/python_dependencies.py b/synapse/python_dependencies.py
index 115bee8c41..b6e00c27b5 100644
--- a/synapse/python_dependencies.py
+++ b/synapse/python_dependencies.py
@@ -33,6 +33,7 @@ REQUIREMENTS = {
     "ujson": ["ujson"],
     "blist": ["blist"],
     "pysaml2": ["saml2"],
+    "pymacaroons": ["pymacaroons"],
 }
 CONDITIONAL_REQUIREMENTS = {
     "web_client": {