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..1adc3eebbb 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_msec()
+ expiry = now + (60 * 60 * 1000)
+ macaroon.add_first_party_caveat("time < %d" % (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 01fc4ea1e5..a87fdeb2a0 100644
--- a/synapse/python_dependencies.py
+++ b/synapse/python_dependencies.py
@@ -33,6 +33,7 @@ REQUIREMENTS = {
"ujson": ["ujson"],
"blist": ["blist"],
"pysaml2": ["saml2"],
+ "pymacaroons-pynacl": ["pymacaroons"],
}
CONDITIONAL_REQUIREMENTS = {
"web_client": {
|