Added LoginType constants. Created general structure for processing registrations.

This commit is contained in:
Kegan Dougal 2014-09-15 10:23:20 +01:00
parent bf6fa6dd3d
commit 34878bc26a
2 changed files with 83 additions and 19 deletions

View File

@ -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"

View File

@ -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):
register_json = _parse_json(request)
session = (register_json["session"] if "session" in register_json
else None)
try:
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:
raise SynapseError(400, "Bad login type.")
desired_user_id = None
password = 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."))
except KeyError:
pass # user_id is optional
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)