Move endpoint to _synapse

This commit is contained in:
Andrew Morgan 2019-06-06 14:52:00 +01:00
parent 1a796cbd38
commit f7395bbd0a
5 changed files with 109 additions and 173 deletions

View file

@ -33,7 +33,6 @@ CONTENT_REPO_PREFIX = "/_matrix/content"
SERVER_KEY_V2_PREFIX = "/_matrix/key/v2"
MEDIA_PREFIX = "/_matrix/media/r0"
LEGACY_MEDIA_PREFIX = "/_matrix/media/v1"
IDENTITY_PREFIX = "/_matrix/identity/api/v1"
class ConsentURIBuilder(object):

View file

@ -40,7 +40,6 @@ from synapse import events
from synapse.api.urls import (
CONTENT_REPO_PREFIX,
FEDERATION_PREFIX,
IDENTITY_PREFIX,
LEGACY_MEDIA_PREFIX,
MEDIA_PREFIX,
SERVER_KEY_V2_PREFIX,
@ -64,7 +63,6 @@ from synapse.replication.http import REPLICATION_PREFIX, ReplicationRestResource
from synapse.replication.tcp.resource import ReplicationStreamProtocolFactory
from synapse.rest import ClientRestResource
from synapse.rest.admin import AdminRestResource
from synapse.rest.identity import IdentityRestResource
from synapse.rest.key.v2 import KeyApiV2Resource
from synapse.rest.media.v0.content_repository import ContentRepoResource
from synapse.rest.well_known import WellKnownResource
@ -190,10 +188,6 @@ class SynapseHomeServer(HomeServer):
from synapse.rest.saml2 import SAML2Resource
resources["/_matrix/saml2"] = SAML2Resource(self)
resources.update({
IDENTITY_PREFIX: IdentityRestResource(self),
})
if name == "consent":
from synapse.rest.consent.consent_resource import ConsentResource
consent_resource = ConsentResource(self)

View file

@ -15,17 +15,22 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
import re
from six.moves import http_client
import jinja2
from twisted.internet import defer
from synapse.api.constants import LoginType
from synapse.api.errors import Codes, SynapseError
from synapse.api.errors import Codes, SynapseError, ThreepidValidationError
from synapse.http.server import finish_request
from synapse.http.servlet import (
RestServlet,
assert_params_in_dict,
parse_json_object_from_request,
parse_string,
)
from synapse.util.msisdn import phone_number_to_msisdn
from synapse.util.stringutils import random_string
@ -221,6 +226,109 @@ class MsisdnPasswordRequestTokenRestServlet(RestServlet):
defer.returnValue((200, ret))
class ThreepidSubmitTokenServlet(RestServlet):
"""Handles 3PID validation token submission"""
PATTERNS = [
re.compile("/_synapse/password_reset/validate/(email|msisdn)/submitToken/*$"),
]
def __init__(self, hs):
"""
Args:
hs (synapse.server.HomeServer): server
"""
self.hs = hs
self.auth = hs.get_auth()
self.config = hs.config
self.clock = hs.get_clock()
self.datastore = hs.get_datastore()
@defer.inlineCallbacks
def on_GET(self, request):
sid = parse_string(request, "sid")
client_secret = parse_string(request, "client_secret")
token = parse_string(request, "token")
# Attempt to validate a 3PID sesssion
try:
# Mark the session as valid
next_link = yield self.datastore.validate_threepid_session(
sid,
client_secret,
token,
self.clock.time_msec(),
)
# Delete associated session tokens from the db as we have no
# further use for them
yield self.datastore.delete_threepid_tokens(sid)
# Perform a 302 redirect if next_link is set
if next_link:
if next_link.startswith("file:///"):
logger.warn(
"Not redirecting to next_link as it is a local file: address"
)
else:
request.setResponseCode(302)
request.setHeader("Location", next_link)
finish_request(request)
defer.returnValue(None)
# Otherwise show the success template
html = self.config.email_password_reset_success_html_content
request.setResponseCode(200)
except ThreepidValidationError as e:
# Show a failure page with a reason
html = self.load_jinja2_template(
self.config.email_template_dir,
self.config.email_password_reset_failure_template,
template_vars={
"failure_reason": e.msg,
}
)
request.setResponseCode(e.code)
request.write(html.encode('utf-8'))
finish_request(request)
defer.returnValue(None)
def load_jinja2_template(self, template_dir, template_filename, template_vars):
"""Loads a jinja2 template with variables to insert
Args:
template_dir (str): The directory where templates are stored
template_filename (str): The name of the template in the template_dir
template_vars (Dict): Dictionary of keys in the template
alongside their values to insert
Returns:
str containing the contents of the rendered template
"""
loader = jinja2.FileSystemLoader(template_dir)
env = jinja2.Environment(loader=loader)
template = env.get_template(template_filename)
return template.render(**template_vars)
@defer.inlineCallbacks
def on_POST(self, request):
body = parse_json_object_from_request(request)
assert_params_in_dict(body, [
'sid', 'client_secret', 'token',
])
valid, _ = yield self.datastore.validate_threepid_validation_token(
body['sid'],
body['client_secret'],
body['token'],
self.clock.time_msec(),
)
response_code = 200 if valid else 400
defer.returnValue((response_code, {"success": valid}))
class PasswordRestServlet(RestServlet):
PATTERNS = client_patterns("/account/password$")

View file

@ -1,28 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2019 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from synapse.http.server import JsonResource
from synapse.rest.identity.threepid_submit_token_servlet import (
ThreepidSubmitTokenServlet,
)
class IdentityRestResource(JsonResource):
"""The REST resource which gets mounted at /_matrix/identity/api/v1"""
def __init__(self, hs):
JsonResource.__init__(self, hs, canonical_json=False)
ThreepidSubmitTokenServlet(hs).register(self)

View file

@ -1,137 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2019 New Vector Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
import re
import jinja2
from twisted.internet import defer
from synapse.api.errors import ThreepidValidationError
from synapse.http.server import finish_request
from synapse.http.servlet import (
RestServlet,
assert_params_in_dict,
parse_json_object_from_request,
parse_string,
)
logger = logging.getLogger(__name__)
def make_identity_path_pattern(path_regex):
prefix = "/_matrix/identity/api/v1"
return [re.compile(prefix + path_regex)]
class ThreepidSubmitTokenServlet(RestServlet):
"""Servlet which will handle 3PID token validation"""
PATTERNS = make_identity_path_pattern("/validate/(email|msisdn)/submitToken/*$")
def __init__(self, hs):
"""
Args:
hs (synapse.server.HomeServer): server
"""
self.hs = hs
self.auth = hs.get_auth()
self.config = hs.config
self.clock = hs.get_clock()
self.datastore = hs.get_datastore()
@defer.inlineCallbacks
def on_GET(self, request):
sid = parse_string(request, "sid")
client_secret = parse_string(request, "client_secret")
token = parse_string(request, "token")
# Attempt to validate a 3PID sesssion
try:
# Mark the session as valid
next_link = yield self.datastore.validate_threepid_session(
sid,
client_secret,
token,
self.clock.time_msec(),
)
# Delete associated session tokens from the db as we have no
# further use for them
yield self.datastore.delete_threepid_tokens(sid)
# Perform a 302 redirect if next_link is set
if next_link:
if next_link.startswith("file:///"):
logger.warn(
"Not redirecting to next_link as it is a local file: address"
)
else:
request.setResponseCode(302)
request.setHeader("Location", next_link)
finish_request(request)
defer.returnValue(None)
# Otherwise show the success template
html = self.config.email_password_reset_success_html_content
request.setResponseCode(200)
except ThreepidValidationError as e:
# Show a failure page with a reason
html = self.load_jinja2_template(
self.config.email_template_dir,
self.config.email_password_reset_failure_template,
template_vars={
"failure_reason": e.msg,
}
)
request.setResponseCode(e.code)
request.write(html.encode('utf-8'))
finish_request(request)
defer.returnValue(None)
def load_jinja2_template(self, template_dir, template_filename, template_vars):
"""Loads a jinja2 template with variables to insert
Args:
template_dir (str): The directory where templates are stored
template_filename (str): The name of the template in the template_dir
template_vars (Dict): Dictionary of keys in the template
alongside their values to insert
Returns:
str containing the contents of the rendered template
"""
loader = jinja2.FileSystemLoader(template_dir)
env = jinja2.Environment(loader=loader)
template = env.get_template(template_filename)
return template.render(**template_vars)
@defer.inlineCallbacks
def on_POST(self, request):
body = parse_json_object_from_request(request)
assert_params_in_dict(body, [
'sid', 'client_secret', 'token',
])
valid, _ = yield self.datastore.validate_threepid_validation_token(
body['sid'],
body['client_secret'],
body['token'],
self.clock.time_msec(),
)
response_code = 200 if valid else 400
defer.returnValue((response_code, {"success": valid}))