forked from MirrorHub/synapse
Add basic application_services SQL, and hook up parts of the appservice store to read from it.
This commit is contained in:
parent
b46fa8603e
commit
42876969b9
5 changed files with 117 additions and 16 deletions
|
@ -16,7 +16,7 @@
|
|||
from twisted.internet import defer
|
||||
|
||||
from ._base import BaseHandler
|
||||
from synapse.api.errors import StoreError, SynapseError
|
||||
from synapse.api.errors import Codes, StoreError, SynapseError
|
||||
|
||||
import logging
|
||||
|
||||
|
@ -36,11 +36,12 @@ class ApplicationServicesHandler(BaseHandler):
|
|||
try:
|
||||
stored_service = yield self.store.get_app_service(app_service.token)
|
||||
if not stored_service:
|
||||
raise StoreError(404, "Not found")
|
||||
raise StoreError(404, "Application Service Not found")
|
||||
except StoreError:
|
||||
raise SynapseError(
|
||||
403, "Unrecognised application services token. "
|
||||
"Consult the home server admin."
|
||||
"Consult the home server admin.",
|
||||
errcode=Codes.FORBIDDEN
|
||||
)
|
||||
# TODO store this AS
|
||||
|
||||
|
|
|
@ -64,9 +64,9 @@ class RegisterRestServlet(AppServiceRestServlet):
|
|||
yield self.handler.register(app_service)
|
||||
hs_token = "_not_implemented_yet" # TODO: Pull this from self.hs?
|
||||
|
||||
defer.returnValue({
|
||||
defer.returnValue((200, {
|
||||
"hs_token": hs_token
|
||||
})
|
||||
}))
|
||||
|
||||
def _parse_namespace(self, target_ns, origin_ns, ns):
|
||||
if ns not in target_ns or ns not in origin_ns:
|
||||
|
|
|
@ -62,6 +62,7 @@ SCHEMAS = [
|
|||
"event_edges",
|
||||
"event_signatures",
|
||||
"media_repository",
|
||||
"application_services"
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -12,12 +12,15 @@
|
|||
# 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.api.errors import StoreError
|
||||
import logging
|
||||
from twisted.internet import defer
|
||||
|
||||
from ._base import SQLBaseStore
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# XXX: This feels like it should belong in a "models" module, not storage.
|
||||
class ApplicationService(object):
|
||||
"""Defines an application service.
|
||||
|
@ -30,7 +33,22 @@ class ApplicationService(object):
|
|||
if url:
|
||||
self.url = url
|
||||
if namespaces:
|
||||
self.namespaces = namespaces
|
||||
self._set_namespaces(namespaces)
|
||||
|
||||
def _set_namespaces(self, namespaces):
|
||||
# Sanity check that it is of the form:
|
||||
# {
|
||||
# users: ["regex",...],
|
||||
# aliases: ["regex",...],
|
||||
# rooms: ["regex",...],
|
||||
# }
|
||||
for ns in ["users", "rooms", "aliases"]:
|
||||
if type(namespaces[ns]) != list:
|
||||
raise ValueError("Bad namespace value for '%s'", ns)
|
||||
for regex in namespaces[ns]:
|
||||
if not isinstance(regex, basestring):
|
||||
raise ValueError("Expected string regex for ns '%s'", ns)
|
||||
self.namespaces = namespaces
|
||||
|
||||
def is_interested(self, event):
|
||||
"""Check if this service is interested in this event.
|
||||
|
@ -133,15 +151,64 @@ class ApplicationServiceStore(SQLBaseStore):
|
|||
return service
|
||||
return None
|
||||
|
||||
# TODO: The from_cache=False impl
|
||||
# TODO: This should be JOINed with the application_services_regex table.
|
||||
row = self._simple_select_one(
|
||||
"application_services", {"token": token},
|
||||
["url", "token"]
|
||||
)
|
||||
if not row:
|
||||
raise StoreError(400, "Bad application services token supplied.")
|
||||
return row
|
||||
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def _populate_cache(self):
|
||||
"""Populates the ApplicationServiceCache from the database."""
|
||||
pass
|
||||
sql = ("SELECT * FROM application_services LEFT JOIN "
|
||||
"application_services_regex ON application_services.id = "
|
||||
"application_services_regex.as_id")
|
||||
|
||||
namespace_enum = [
|
||||
"users", # 0
|
||||
"aliases", # 1
|
||||
"rooms" # 2
|
||||
]
|
||||
# SQL results in the form:
|
||||
# [
|
||||
# {
|
||||
# 'regex': "something",
|
||||
# 'url': "something",
|
||||
# 'namespace': enum,
|
||||
# 'as_id': 0,
|
||||
# 'token': "something",
|
||||
# 'id': 0
|
||||
# }
|
||||
# ]
|
||||
services = {}
|
||||
results = yield self._execute_and_decode(sql)
|
||||
for res in results:
|
||||
as_token = res["token"]
|
||||
if as_token not in services:
|
||||
# add the service
|
||||
services[as_token] = {
|
||||
"url": res["url"],
|
||||
"token": as_token,
|
||||
"namespaces": {
|
||||
"users": [],
|
||||
"aliases": [],
|
||||
"rooms": []
|
||||
}
|
||||
}
|
||||
# add the namespace regex if one exists
|
||||
ns_int = res["namespace"]
|
||||
if ns_int is None:
|
||||
continue
|
||||
try:
|
||||
services[as_token]["namespaces"][namespace_enum[ns_int]].append(
|
||||
res["regex"]
|
||||
)
|
||||
except IndexError:
|
||||
logger.error("Bad namespace enum '%s'. %s", ns_int, res)
|
||||
|
||||
for service in services.values():
|
||||
logger.info("Found application service: %s", service)
|
||||
self.cache.services.append(ApplicationService(
|
||||
service["token"],
|
||||
service["url"],
|
||||
service["namespaces"]
|
||||
))
|
||||
|
||||
|
|
32
synapse/storage/schema/application_services.sql
Normal file
32
synapse/storage/schema/application_services.sql
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* Copyright 2015 OpenMarket 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.
|
||||
*/
|
||||
|
||||
CREATE TABLE IF NOT EXISTS application_services(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
url TEXT,
|
||||
token TEXT,
|
||||
UNIQUE(token) ON CONFLICT ROLLBACK
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS application_services_regex(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
as_id INTEGER NOT NULL,
|
||||
namespace INTEGER, /* enum[room_id|room_alias|user_id] */
|
||||
regex TEXT,
|
||||
FOREIGN KEY(as_id) REFERENCES application_services(id)
|
||||
);
|
||||
|
||||
|
||||
|
Loading…
Reference in a new issue