diff --git a/synapse/api/auth.py b/synapse/api/auth.py
index b86c6c8399..b5536e8565 100644
--- a/synapse/api/auth.py
+++ b/synapse/api/auth.py
@@ -22,7 +22,7 @@ from twisted.internet import defer
from synapse.api.constants import EventTypes, Membership, JoinRules
from synapse.api.errors import AuthError, Codes, SynapseError, EventSizeError
-from synapse.types import RoomID, UserID, EventID
+from synapse.types import Requester, RoomID, UserID, EventID
from synapse.util.logutils import log_function
from unpaddedbase64 import decode_base64
@@ -510,35 +510,14 @@ class Auth(object):
"""
# Can optionally look elsewhere in the request (e.g. headers)
try:
- access_token = request.args["access_token"][0]
-
- # Check for application service tokens with a user_id override
- try:
- app_service = yield self.store.get_app_service_by_token(
- access_token
- )
- if not app_service:
- raise KeyError
-
- user_id = app_service.sender
- if "user_id" in request.args:
- user_id = request.args["user_id"][0]
- if not app_service.is_interested_in_user(user_id):
- raise AuthError(
- 403,
- "Application service cannot masquerade as this user."
- )
-
- if not user_id:
- raise KeyError
-
+ user_id = yield self._get_appservice_user_id(request.args)
+ if user_id:
request.authenticated_entity = user_id
+ defer.returnValue(
+ Requester(UserID.from_string(user_id), "", False)
+ )
- defer.returnValue((UserID.from_string(user_id), "", False))
- return
- except KeyError:
- pass # normal users won't have the user_id query parameter set.
-
+ access_token = request.args["access_token"][0]
user_info = yield self._get_user_by_access_token(access_token)
user = user_info["user"]
token_id = user_info["token_id"]
@@ -564,7 +543,7 @@ class Auth(object):
request.authenticated_entity = user.to_string()
- defer.returnValue((user, token_id, is_guest,))
+ defer.returnValue(Requester(user, token_id, is_guest))
except KeyError:
raise AuthError(
self.TOKEN_NOT_FOUND_HTTP_STATUS, "Missing access token.",
@@ -572,6 +551,33 @@ class Auth(object):
)
@defer.inlineCallbacks
+ def _get_appservice_user_id(self, request_args):
+ app_service = yield self.store.get_app_service_by_token(
+ request_args["access_token"][0]
+ )
+ if app_service is None:
+ defer.returnValue(None)
+
+ if "user_id" not in request_args:
+ defer.returnValue(app_service.sender)
+
+ user_id = request_args["user_id"][0]
+ if app_service.sender == user_id:
+ defer.returnValue(app_service.sender)
+
+ if not app_service.is_interested_in_user(user_id):
+ raise AuthError(
+ 403,
+ "Application service cannot masquerade as this user."
+ )
+ if not (yield self.store.get_user_by_id(user_id)):
+ raise AuthError(
+ 403,
+ "Application service has not registered this user"
+ )
+ defer.returnValue(user_id)
+
+ @defer.inlineCallbacks
def _get_user_by_access_token(self, token):
""" Get a registered user's ID.
|