storage/appservice: make appservice methods only relying on the cache synchronous

This commit is contained in:
Patrik Oldsberg 2016-10-06 10:43:32 +02:00
parent 503c0ab78b
commit 9bfc617791
10 changed files with 31 additions and 41 deletions

View File

@ -653,7 +653,7 @@ class Auth(object):
@defer.inlineCallbacks @defer.inlineCallbacks
def _get_appservice_user_id(self, request): def _get_appservice_user_id(self, request):
app_service = yield self.store.get_app_service_by_token( app_service = self.store.get_app_service_by_token(
get_access_token_from_request( get_access_token_from_request(
request, self.TOKEN_NOT_FOUND_HTTP_STATUS request, self.TOKEN_NOT_FOUND_HTTP_STATUS
) )
@ -855,13 +855,12 @@ class Auth(object):
} }
defer.returnValue(user_info) defer.returnValue(user_info)
@defer.inlineCallbacks
def get_appservice_by_req(self, request): def get_appservice_by_req(self, request):
try: try:
token = get_access_token_from_request( token = get_access_token_from_request(
request, self.TOKEN_NOT_FOUND_HTTP_STATUS request, self.TOKEN_NOT_FOUND_HTTP_STATUS
) )
service = yield self.store.get_app_service_by_token(token) service = self.store.get_app_service_by_token(token)
if not service: if not service:
logger.warn("Unrecognised appservice access token: %s" % (token,)) logger.warn("Unrecognised appservice access token: %s" % (token,))
raise AuthError( raise AuthError(
@ -870,7 +869,7 @@ class Auth(object):
errcode=Codes.UNKNOWN_TOKEN errcode=Codes.UNKNOWN_TOKEN
) )
request.authenticated_entity = service.sender request.authenticated_entity = service.sender
defer.returnValue(service) return defer.succeed(service)
except KeyError: except KeyError:
raise AuthError( raise AuthError(
self.TOKEN_NOT_FOUND_HTTP_STATUS, "Missing access token." self.TOKEN_NOT_FOUND_HTTP_STATUS, "Missing access token."

View File

@ -59,7 +59,7 @@ class ApplicationServicesHandler(object):
Args: Args:
current_id(int): The current maximum ID. current_id(int): The current maximum ID.
""" """
services = yield self.store.get_app_services() services = self.store.get_app_services()
if not services or not self.notify_appservices: if not services or not self.notify_appservices:
return return
@ -142,7 +142,7 @@ class ApplicationServicesHandler(object):
association can be found. association can be found.
""" """
room_alias_str = room_alias.to_string() room_alias_str = room_alias.to_string()
services = yield self.store.get_app_services() services = self.store.get_app_services()
alias_query_services = [ alias_query_services = [
s for s in services if ( s for s in services if (
s.is_interested_in_alias(room_alias_str) s.is_interested_in_alias(room_alias_str)
@ -177,7 +177,7 @@ class ApplicationServicesHandler(object):
@defer.inlineCallbacks @defer.inlineCallbacks
def get_3pe_protocols(self, only_protocol=None): def get_3pe_protocols(self, only_protocol=None):
services = yield self.store.get_app_services() services = self.store.get_app_services()
protocols = {} protocols = {}
# Collect up all the individual protocol responses out of the ASes # Collect up all the individual protocol responses out of the ASes
@ -224,7 +224,7 @@ class ApplicationServicesHandler(object):
list<ApplicationService>: A list of services interested in this list<ApplicationService>: A list of services interested in this
event based on the service regex. event based on the service regex.
""" """
services = yield self.store.get_app_services() services = self.store.get_app_services()
interested_list = [ interested_list = [
s for s in services if ( s for s in services if (
yield s.is_interested(event, self.store) yield s.is_interested(event, self.store)
@ -232,23 +232,21 @@ class ApplicationServicesHandler(object):
] ]
defer.returnValue(interested_list) defer.returnValue(interested_list)
@defer.inlineCallbacks
def _get_services_for_user(self, user_id): def _get_services_for_user(self, user_id):
services = yield self.store.get_app_services() services = self.store.get_app_services()
interested_list = [ interested_list = [
s for s in services if ( s for s in services if (
s.is_interested_in_user(user_id) s.is_interested_in_user(user_id)
) )
] ]
defer.returnValue(interested_list) return defer.succeed(interested_list)
@defer.inlineCallbacks
def _get_services_for_3pn(self, protocol): def _get_services_for_3pn(self, protocol):
services = yield self.store.get_app_services() services = self.store.get_app_services()
interested_list = [ interested_list = [
s for s in services if s.is_interested_in_protocol(protocol) s for s in services if s.is_interested_in_protocol(protocol)
] ]
defer.returnValue(interested_list) return defer.succeed(interested_list)
@defer.inlineCallbacks @defer.inlineCallbacks
def _is_unknown_user(self, user_id): def _is_unknown_user(self, user_id):
@ -264,7 +262,7 @@ class ApplicationServicesHandler(object):
return return
# user not found; could be the AS though, so check. # user not found; could be the AS though, so check.
services = yield self.store.get_app_services() services = self.store.get_app_services()
service_list = [s for s in services if s.sender == user_id] service_list = [s for s in services if s.sender == user_id]
defer.returnValue(len(service_list) == 0) defer.returnValue(len(service_list) == 0)

View File

@ -288,13 +288,12 @@ class DirectoryHandler(BaseHandler):
result = yield as_handler.query_room_alias_exists(room_alias) result = yield as_handler.query_room_alias_exists(room_alias)
defer.returnValue(result) defer.returnValue(result)
@defer.inlineCallbacks
def can_modify_alias(self, alias, user_id=None): def can_modify_alias(self, alias, user_id=None):
# Any application service "interested" in an alias they are regexing on # Any application service "interested" in an alias they are regexing on
# can modify the alias. # can modify the alias.
# Users can only modify the alias if ALL the interested services have # Users can only modify the alias if ALL the interested services have
# non-exclusive locks on the alias (or there are no interested services) # non-exclusive locks on the alias (or there are no interested services)
services = yield self.store.get_app_services() services = self.store.get_app_services()
interested_services = [ interested_services = [
s for s in services if s.is_interested_in_alias(alias.to_string()) s for s in services if s.is_interested_in_alias(alias.to_string())
] ]
@ -302,14 +301,12 @@ class DirectoryHandler(BaseHandler):
for service in interested_services: for service in interested_services:
if user_id == service.sender: if user_id == service.sender:
# this user IS the app service so they can do whatever they like # this user IS the app service so they can do whatever they like
defer.returnValue(True) return defer.succeed(True)
return
elif service.is_exclusive_alias(alias.to_string()): elif service.is_exclusive_alias(alias.to_string()):
# another service has an exclusive lock on this alias. # another service has an exclusive lock on this alias.
defer.returnValue(False) return defer.succeed(False)
return
# either no interested services, or no service with an exclusive lock # either no interested services, or no service with an exclusive lock
defer.returnValue(True) return defer.succeed(True)
@defer.inlineCallbacks @defer.inlineCallbacks
def _user_can_delete_alias(self, alias, user_id): def _user_can_delete_alias(self, alias, user_id):

View File

@ -194,7 +194,7 @@ class RegistrationHandler(BaseHandler):
def appservice_register(self, user_localpart, as_token): def appservice_register(self, user_localpart, as_token):
user = UserID(user_localpart, self.hs.hostname) user = UserID(user_localpart, self.hs.hostname)
user_id = user.to_string() user_id = user.to_string()
service = yield self.store.get_app_service_by_token(as_token) service = self.store.get_app_service_by_token(as_token)
if not service: if not service:
raise AuthError(403, "Invalid application service token.") raise AuthError(403, "Invalid application service token.")
if not service.is_interested_in_user(user_id): if not service.is_interested_in_user(user_id):
@ -305,11 +305,10 @@ class RegistrationHandler(BaseHandler):
# XXX: This should be a deferred list, shouldn't it? # XXX: This should be a deferred list, shouldn't it?
yield identity_handler.bind_threepid(c, user_id) yield identity_handler.bind_threepid(c, user_id)
@defer.inlineCallbacks
def check_user_id_not_appservice_exclusive(self, user_id, allowed_appservice=None): def check_user_id_not_appservice_exclusive(self, user_id, allowed_appservice=None):
# valid user IDs must not clash with any user ID namespaces claimed by # valid user IDs must not clash with any user ID namespaces claimed by
# application services. # application services.
services = yield self.store.get_app_services() services = self.store.get_app_services()
interested_services = [ interested_services = [
s for s in services s for s in services
if s.is_interested_in_user(user_id) if s.is_interested_in_user(user_id)

View File

@ -437,7 +437,7 @@ class RoomEventSource(object):
logger.warn("Stream has topological part!!!! %r", from_key) logger.warn("Stream has topological part!!!! %r", from_key)
from_key = "s%s" % (from_token.stream,) from_key = "s%s" % (from_token.stream,)
app_service = yield self.store.get_app_service_by_user_id( app_service = self.store.get_app_service_by_user_id(
user.to_string() user.to_string()
) )
if app_service: if app_service:

View File

@ -788,7 +788,7 @@ class SyncHandler(object):
assert since_token assert since_token
app_service = yield self.store.get_app_service_by_user_id(user_id) app_service = self.store.get_app_service_by_user_id(user_id)
if app_service: if app_service:
rooms = yield self.store.get_app_service_rooms(app_service) rooms = yield self.store.get_app_service_rooms(app_service)
joined_room_ids = set(r.room_id for r in rooms) joined_room_ids = set(r.room_id for r in rooms)

View File

@ -391,7 +391,7 @@ class CreateUserRestServlet(ClientV1RestServlet):
user_json = parse_json_object_from_request(request) user_json = parse_json_object_from_request(request)
access_token = get_access_token_from_request(request) access_token = get_access_token_from_request(request)
app_service = yield self.store.get_app_service_by_token( app_service = self.store.get_app_service_by_token(
access_token access_token
) )
if not app_service: if not app_service:

View File

@ -37,7 +37,7 @@ class ApplicationServiceStore(SQLBaseStore):
) )
def get_app_services(self): def get_app_services(self):
return defer.succeed(self.services_cache) return self.services_cache
def get_app_service_by_user_id(self, user_id): def get_app_service_by_user_id(self, user_id):
"""Retrieve an application service from their user ID. """Retrieve an application service from their user ID.
@ -54,8 +54,8 @@ class ApplicationServiceStore(SQLBaseStore):
""" """
for service in self.services_cache: for service in self.services_cache:
if service.sender == user_id: if service.sender == user_id:
return defer.succeed(service) return service
return defer.succeed(None) return None
def get_app_service_by_token(self, token): def get_app_service_by_token(self, token):
"""Get the application service with the given appservice token. """Get the application service with the given appservice token.
@ -67,8 +67,8 @@ class ApplicationServiceStore(SQLBaseStore):
""" """
for service in self.services_cache: for service in self.services_cache:
if service.token == token: if service.token == token:
return defer.succeed(service) return service
return defer.succeed(None) return None
def get_app_service_rooms(self, service): def get_app_service_rooms(self, service):
"""Get a list of RoomsForUser for this application service. """Get a list of RoomsForUser for this application service.
@ -163,7 +163,7 @@ class ApplicationServiceTransactionStore(SQLBaseStore):
["as_id"] ["as_id"]
) )
# NB: This assumes this class is linked with ApplicationServiceStore # NB: This assumes this class is linked with ApplicationServiceStore
as_list = yield self.get_app_services() as_list = self.get_app_services()
services = [] services = []
for res in results: for res in results:

View File

@ -19,7 +19,7 @@ class RegisterRestServletTestCase(unittest.TestCase):
self.appservice = None self.appservice = None
self.auth = Mock(get_appservice_by_req=Mock( self.auth = Mock(get_appservice_by_req=Mock(
side_effect=lambda x: defer.succeed(self.appservice)) side_effect=lambda x: self.appservice)
) )
self.auth_result = (False, None, None, None) self.auth_result = (False, None, None, None)

View File

@ -71,14 +71,12 @@ class ApplicationServiceStoreTestCase(unittest.TestCase):
outfile.write(yaml.dump(as_yaml)) outfile.write(yaml.dump(as_yaml))
self.as_yaml_files.append(as_token) self.as_yaml_files.append(as_token)
@defer.inlineCallbacks
def test_retrieve_unknown_service_token(self): def test_retrieve_unknown_service_token(self):
service = yield self.store.get_app_service_by_token("invalid_token") service = self.store.get_app_service_by_token("invalid_token")
self.assertEquals(service, None) self.assertEquals(service, None)
@defer.inlineCallbacks
def test_retrieval_of_service(self): def test_retrieval_of_service(self):
stored_service = yield self.store.get_app_service_by_token( stored_service = self.store.get_app_service_by_token(
self.as_token self.as_token
) )
self.assertEquals(stored_service.token, self.as_token) self.assertEquals(stored_service.token, self.as_token)
@ -97,9 +95,8 @@ class ApplicationServiceStoreTestCase(unittest.TestCase):
[] []
) )
@defer.inlineCallbacks
def test_retrieval_of_all_services(self): def test_retrieval_of_all_services(self):
services = yield self.store.get_app_services() services = self.store.get_app_services()
self.assertEquals(len(services), 3) self.assertEquals(len(services), 3)