summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--synapse/api/constants.py9
-rw-r--r--synapse/rest/register.py95
2 files changed, 84 insertions, 20 deletions
diff --git a/synapse/api/constants.py b/synapse/api/constants.py
index fcef062fc9..618d3d7577 100644
--- a/synapse/api/constants.py
+++ b/synapse/api/constants.py
@@ -50,3 +50,12 @@ class JoinRules(object):
     KNOCK = u"knock"
     INVITE = u"invite"
     PRIVATE = u"private"
+
+
+class LoginType(object):
+    PASSWORD = u"m.login.password"
+    OAUTH = u"m.login.oauth2"
+    EMAIL_CODE = u"m.login.email.code"
+    EMAIL_URL = u"m.login.email.url"
+    EMAIL_IDENTITY = u"m.login.email.identity"
+    RECAPTCHA = u"m.login.recaptcha"
\ No newline at end of file
diff --git a/synapse/rest/register.py b/synapse/rest/register.py
index 48d3c6eca0..8faa26572a 100644
--- a/synapse/rest/register.py
+++ b/synapse/rest/register.py
@@ -17,6 +17,7 @@
 from twisted.internet import defer
 
 from synapse.api.errors import SynapseError, Codes
+from synapse.api.constants import LoginType
 from base import RestServlet, client_path_pattern
 
 import json
@@ -26,31 +27,64 @@ import urllib
 class RegisterRestServlet(RestServlet):
     PATTERN = client_path_pattern("/register$")
 
+    def on_GET(self, request):
+        return (200, {
+            "flows": [
+                {
+                    "type": LoginType.RECAPTCHA,
+                    "stages": ([LoginType.RECAPTCHA, LoginType.EMAIL_IDENTITY,
+                        LoginType.PASSWORD])
+                },
+                {
+                    "type": LoginType.RECAPTCHA,
+                    "stages": [LoginType.RECAPTCHA, LoginType.PASSWORD]
+                },
+            ]
+        })
+
     @defer.inlineCallbacks
     def on_POST(self, request):
-        desired_user_id = None
-        password = None
+        register_json = _parse_json(request)
+
+        session = (register_json["session"] if "session" in register_json
+                  else None)
         try:
-            register_json = json.loads(request.content.read())
-            if "password" in register_json:
-                password = register_json["password"].encode("utf-8")
-
-            if type(register_json["user_id"]) == unicode:
-                desired_user_id = register_json["user_id"].encode("utf-8")
-                if urllib.quote(desired_user_id) != desired_user_id:
-                    raise SynapseError(
-                        400,
-                        "User ID must only contain characters which do not " +
-                        "require URL encoding.")
-        except ValueError:
-            defer.returnValue((400, "No JSON object."))
+            login_type = register_json["type"]
+            stages = {
+                LoginType.RECAPTCHA: self._do_recaptcha,
+                LoginType.PASSWORD: self._do_password,
+                LoginType.EMAIL_IDENTITY: self._do_email_identity
+            }
+
+            session_info = None
+            if session:
+                session_info = self._get_session_info(session)
+
+            response = yield stages[login_type](register_json, session_info)
+            defer.returnValue((200, response))
         except KeyError:
-            pass  # user_id is optional
+            raise SynapseError(400, "Bad login type.")
+
+
+        desired_user_id = None
+        password = None
+
+        if "password" in register_json:
+            password = register_json["password"].encode("utf-8")
+
+        if ("user_id" in register_json and
+                type(register_json["user_id"]) == unicode):
+            desired_user_id = register_json["user_id"].encode("utf-8")
+            if urllib.quote(desired_user_id) != desired_user_id:
+                raise SynapseError(
+                    400,
+                    "User ID must only contain characters which do not " +
+                    "require URL encoding.")
 
         threepidCreds = None
         if 'threepidCreds' in register_json:
             threepidCreds = register_json['threepidCreds']
-            
+
         captcha = {}
         if self.hs.config.enable_registration_captcha:
             challenge = None
@@ -65,7 +99,7 @@ class RegisterRestServlet(RestServlet):
             except KeyError:
                 raise SynapseError(400, "Captcha response is required",
                                    errcode=Codes.CAPTCHA_NEEDED)
-            
+
             # TODO determine the source IP : May be an X-Forwarding-For header depending on config
             ip_addr = request.getClientIP()
             if self.hs.config.captcha_ip_origin_is_x_forwarded:
@@ -73,14 +107,14 @@ class RegisterRestServlet(RestServlet):
                 if request.requestHeaders.hasHeader("X-Forwarded-For"):
                     ip_addr = request.requestHeaders.getRawHeaders(
                         "X-Forwarded-For")[0]
-            
+
             captcha = {
                 "ip": ip_addr,
                 "private_key": self.hs.config.recaptcha_private_key,
                 "challenge": challenge,
                 "response": user_response
             }
-            
+
 
         handler = self.handlers.registration_handler
         (user_id, token) = yield handler.register(
@@ -101,6 +135,27 @@ class RegisterRestServlet(RestServlet):
     def on_OPTIONS(self, request):
         return (200, {})
 
+    def _get_session_info(self, session_id):
+        pass
+
+    def _do_recaptcha(self, register_json, session):
+        pass
+
+    def _do_email_identity(self, register_json, session):
+        pass
+
+    def _do_password(self, register_json, session):
+        pass
+
+
+def _parse_json(request):
+    try:
+        content = json.loads(request.content.read())
+        if type(content) != dict:
+            raise SynapseError(400, "Content must be a JSON object.")
+        return content
+    except ValueError:
+        raise SynapseError(400, "Content not JSON.")
 
 def register_servlets(hs, http_server):
     RegisterRestServlet(hs).register(http_server)