mirror of
https://github.com/element-hq/synapse.git
synced 2024-12-19 17:56:19 +03:00
Move endpoint to _synapse
This commit is contained in:
parent
1a796cbd38
commit
f7395bbd0a
5 changed files with 109 additions and 173 deletions
|
@ -33,7 +33,6 @@ CONTENT_REPO_PREFIX = "/_matrix/content"
|
||||||
SERVER_KEY_V2_PREFIX = "/_matrix/key/v2"
|
SERVER_KEY_V2_PREFIX = "/_matrix/key/v2"
|
||||||
MEDIA_PREFIX = "/_matrix/media/r0"
|
MEDIA_PREFIX = "/_matrix/media/r0"
|
||||||
LEGACY_MEDIA_PREFIX = "/_matrix/media/v1"
|
LEGACY_MEDIA_PREFIX = "/_matrix/media/v1"
|
||||||
IDENTITY_PREFIX = "/_matrix/identity/api/v1"
|
|
||||||
|
|
||||||
|
|
||||||
class ConsentURIBuilder(object):
|
class ConsentURIBuilder(object):
|
||||||
|
|
|
@ -40,7 +40,6 @@ from synapse import events
|
||||||
from synapse.api.urls import (
|
from synapse.api.urls import (
|
||||||
CONTENT_REPO_PREFIX,
|
CONTENT_REPO_PREFIX,
|
||||||
FEDERATION_PREFIX,
|
FEDERATION_PREFIX,
|
||||||
IDENTITY_PREFIX,
|
|
||||||
LEGACY_MEDIA_PREFIX,
|
LEGACY_MEDIA_PREFIX,
|
||||||
MEDIA_PREFIX,
|
MEDIA_PREFIX,
|
||||||
SERVER_KEY_V2_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.replication.tcp.resource import ReplicationStreamProtocolFactory
|
||||||
from synapse.rest import ClientRestResource
|
from synapse.rest import ClientRestResource
|
||||||
from synapse.rest.admin import AdminRestResource
|
from synapse.rest.admin import AdminRestResource
|
||||||
from synapse.rest.identity import IdentityRestResource
|
|
||||||
from synapse.rest.key.v2 import KeyApiV2Resource
|
from synapse.rest.key.v2 import KeyApiV2Resource
|
||||||
from synapse.rest.media.v0.content_repository import ContentRepoResource
|
from synapse.rest.media.v0.content_repository import ContentRepoResource
|
||||||
from synapse.rest.well_known import WellKnownResource
|
from synapse.rest.well_known import WellKnownResource
|
||||||
|
@ -190,10 +188,6 @@ class SynapseHomeServer(HomeServer):
|
||||||
from synapse.rest.saml2 import SAML2Resource
|
from synapse.rest.saml2 import SAML2Resource
|
||||||
resources["/_matrix/saml2"] = SAML2Resource(self)
|
resources["/_matrix/saml2"] = SAML2Resource(self)
|
||||||
|
|
||||||
resources.update({
|
|
||||||
IDENTITY_PREFIX: IdentityRestResource(self),
|
|
||||||
})
|
|
||||||
|
|
||||||
if name == "consent":
|
if name == "consent":
|
||||||
from synapse.rest.consent.consent_resource import ConsentResource
|
from synapse.rest.consent.consent_resource import ConsentResource
|
||||||
consent_resource = ConsentResource(self)
|
consent_resource = ConsentResource(self)
|
||||||
|
|
|
@ -15,17 +15,22 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
import logging
|
import logging
|
||||||
|
import re
|
||||||
|
|
||||||
from six.moves import http_client
|
from six.moves import http_client
|
||||||
|
|
||||||
|
import jinja2
|
||||||
|
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
|
||||||
from synapse.api.constants import LoginType
|
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 (
|
from synapse.http.servlet import (
|
||||||
RestServlet,
|
RestServlet,
|
||||||
assert_params_in_dict,
|
assert_params_in_dict,
|
||||||
parse_json_object_from_request,
|
parse_json_object_from_request,
|
||||||
|
parse_string,
|
||||||
)
|
)
|
||||||
from synapse.util.msisdn import phone_number_to_msisdn
|
from synapse.util.msisdn import phone_number_to_msisdn
|
||||||
from synapse.util.stringutils import random_string
|
from synapse.util.stringutils import random_string
|
||||||
|
@ -221,6 +226,109 @@ class MsisdnPasswordRequestTokenRestServlet(RestServlet):
|
||||||
defer.returnValue((200, ret))
|
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):
|
class PasswordRestServlet(RestServlet):
|
||||||
PATTERNS = client_patterns("/account/password$")
|
PATTERNS = client_patterns("/account/password$")
|
||||||
|
|
||||||
|
|
|
@ -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)
|
|
|
@ -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}))
|
|
Loading…
Reference in a new issue