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)
|