mirror of
https://git.anonymousland.org/anonymousland/synapse.git
synced 2024-09-07 04:21:54 +00:00
1) Pushers are now associated with an access token
2) Change places where we mean unauthenticated to 401, not 403, in C/S v2: hack so it stays as 403 in v1 because web client relies on it.
This commit is contained in:
parent
d19e79ecc9
commit
c7023f2155
@ -40,6 +40,7 @@ class Auth(object):
|
|||||||
self.hs = hs
|
self.hs = hs
|
||||||
self.store = hs.get_datastore()
|
self.store = hs.get_datastore()
|
||||||
self.state = hs.get_state_handler()
|
self.state = hs.get_state_handler()
|
||||||
|
self.TOKEN_NOT_FOUND_HTTP_STATUS = 401
|
||||||
|
|
||||||
def check(self, event, auth_events):
|
def check(self, event, auth_events):
|
||||||
""" Checks if this event is correctly authed.
|
""" Checks if this event is correctly authed.
|
||||||
@ -373,7 +374,9 @@ class Auth(object):
|
|||||||
|
|
||||||
defer.returnValue((user, ClientInfo(device_id, token_id)))
|
defer.returnValue((user, ClientInfo(device_id, token_id)))
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise AuthError(403, "Missing access token.")
|
raise AuthError(
|
||||||
|
self.TOKEN_NOT_FOUND_HTTP_STATUS, "Missing access token."
|
||||||
|
)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def get_user_by_token(self, token):
|
def get_user_by_token(self, token):
|
||||||
@ -387,21 +390,20 @@ class Auth(object):
|
|||||||
Raises:
|
Raises:
|
||||||
AuthError if no user by that token exists or the token is invalid.
|
AuthError if no user by that token exists or the token is invalid.
|
||||||
"""
|
"""
|
||||||
try:
|
ret = yield self.store.get_user_by_token(token)
|
||||||
ret = yield self.store.get_user_by_token(token)
|
if not ret:
|
||||||
if not ret:
|
raise AuthError(
|
||||||
raise StoreError(400, "Unknown token")
|
self.TOKEN_NOT_FOUND_HTTP_STATUS, "Unrecognised access token.",
|
||||||
user_info = {
|
errcode=Codes.UNKNOWN_TOKEN
|
||||||
"admin": bool(ret.get("admin", False)),
|
)
|
||||||
"device_id": ret.get("device_id"),
|
user_info = {
|
||||||
"user": UserID.from_string(ret.get("name")),
|
"admin": bool(ret.get("admin", False)),
|
||||||
"token_id": ret.get("token_id", None),
|
"device_id": ret.get("device_id"),
|
||||||
}
|
"user": UserID.from_string(ret.get("name")),
|
||||||
|
"token_id": ret.get("token_id", None),
|
||||||
|
}
|
||||||
|
|
||||||
defer.returnValue(user_info)
|
defer.returnValue(user_info)
|
||||||
except StoreError:
|
|
||||||
raise AuthError(403, "Unrecognised access token.",
|
|
||||||
errcode=Codes.UNKNOWN_TOKEN)
|
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def get_appservice_by_req(self, request):
|
def get_appservice_by_req(self, request):
|
||||||
@ -409,11 +411,16 @@ class Auth(object):
|
|||||||
token = request.args["access_token"][0]
|
token = request.args["access_token"][0]
|
||||||
service = yield self.store.get_app_service_by_token(token)
|
service = yield self.store.get_app_service_by_token(token)
|
||||||
if not service:
|
if not service:
|
||||||
raise AuthError(403, "Unrecognised access token.",
|
raise AuthError(
|
||||||
errcode=Codes.UNKNOWN_TOKEN)
|
self.TOKEN_NOT_FOUND_HTTP_STATUS,
|
||||||
|
"Unrecognised access token.",
|
||||||
|
errcode=Codes.UNKNOWN_TOKEN
|
||||||
|
)
|
||||||
defer.returnValue(service)
|
defer.returnValue(service)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise AuthError(403, "Missing access token.")
|
raise AuthError(
|
||||||
|
self.TOKEN_NOT_FOUND_HTTP_STATUS, "Missing access token."
|
||||||
|
)
|
||||||
|
|
||||||
def is_server_admin(self, user):
|
def is_server_admin(self, user):
|
||||||
return self.store.is_server_admin(user)
|
return self.store.is_server_admin(user)
|
||||||
|
@ -57,7 +57,7 @@ class PusherPool:
|
|||||||
self._start_pushers(pushers)
|
self._start_pushers(pushers)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def add_pusher(self, user_name, profile_tag, kind, app_id,
|
def add_pusher(self, user_name, access_token, profile_tag, kind, app_id,
|
||||||
app_display_name, device_display_name, pushkey, lang, data):
|
app_display_name, device_display_name, pushkey, lang, data):
|
||||||
# we try to create the pusher just to validate the config: it
|
# we try to create the pusher just to validate the config: it
|
||||||
# will then get pulled out of the database,
|
# will then get pulled out of the database,
|
||||||
@ -79,17 +79,18 @@ class PusherPool:
|
|||||||
"failing_since": None
|
"failing_since": None
|
||||||
})
|
})
|
||||||
yield self._add_pusher_to_store(
|
yield self._add_pusher_to_store(
|
||||||
user_name, profile_tag, kind, app_id,
|
user_name, access_token, profile_tag, kind, app_id,
|
||||||
app_display_name, device_display_name,
|
app_display_name, device_display_name,
|
||||||
pushkey, lang, data
|
pushkey, lang, data
|
||||||
)
|
)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def _add_pusher_to_store(self, user_name, profile_tag, kind, app_id,
|
def _add_pusher_to_store(self, user_name, access_token, profile_tag, kind,
|
||||||
app_display_name, device_display_name,
|
app_id, app_display_name, device_display_name,
|
||||||
pushkey, lang, data):
|
pushkey, lang, data):
|
||||||
yield self.store.add_pusher(
|
yield self.store.add_pusher(
|
||||||
user_name=user_name,
|
user_name=user_name,
|
||||||
|
access_token=access_token,
|
||||||
profile_tag=profile_tag,
|
profile_tag=profile_tag,
|
||||||
kind=kind,
|
kind=kind,
|
||||||
app_id=app_id,
|
app_id=app_id,
|
||||||
|
@ -48,5 +48,5 @@ class ClientV1RestServlet(RestServlet):
|
|||||||
self.hs = hs
|
self.hs = hs
|
||||||
self.handlers = hs.get_handlers()
|
self.handlers = hs.get_handlers()
|
||||||
self.builder_factory = hs.get_event_builder_factory()
|
self.builder_factory = hs.get_event_builder_factory()
|
||||||
self.auth = hs.get_auth()
|
self.auth = hs.get_v1auth()
|
||||||
self.txns = HttpTransactionStore()
|
self.txns = HttpTransactionStore()
|
||||||
|
@ -27,7 +27,7 @@ class PusherRestServlet(ClientV1RestServlet):
|
|||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def on_POST(self, request):
|
def on_POST(self, request):
|
||||||
user, _ = yield self.auth.get_user_by_req(request)
|
user, client = yield self.auth.get_user_by_req(request)
|
||||||
|
|
||||||
content = _parse_json(request)
|
content = _parse_json(request)
|
||||||
|
|
||||||
@ -54,6 +54,7 @@ class PusherRestServlet(ClientV1RestServlet):
|
|||||||
try:
|
try:
|
||||||
yield pusher_pool.add_pusher(
|
yield pusher_pool.add_pusher(
|
||||||
user_name=user.to_string(),
|
user_name=user.to_string(),
|
||||||
|
access_token=client.token_id,
|
||||||
profile_tag=content['profile_tag'],
|
profile_tag=content['profile_tag'],
|
||||||
kind=content['kind'],
|
kind=content['kind'],
|
||||||
app_id=content['app_id'],
|
app_id=content['app_id'],
|
||||||
|
@ -65,6 +65,7 @@ class BaseHomeServer(object):
|
|||||||
'replication_layer',
|
'replication_layer',
|
||||||
'datastore',
|
'datastore',
|
||||||
'handlers',
|
'handlers',
|
||||||
|
'v1auth',
|
||||||
'auth',
|
'auth',
|
||||||
'rest_servlet_factory',
|
'rest_servlet_factory',
|
||||||
'state_handler',
|
'state_handler',
|
||||||
@ -182,6 +183,15 @@ class HomeServer(BaseHomeServer):
|
|||||||
def build_auth(self):
|
def build_auth(self):
|
||||||
return Auth(self)
|
return Auth(self)
|
||||||
|
|
||||||
|
def build_v1auth(self):
|
||||||
|
orf = Auth(self)
|
||||||
|
# Matrix spec makes no reference to what HTTP status code is returned,
|
||||||
|
# but the V1 API uses 403 where it means 401, and the webclient
|
||||||
|
# relies on this behaviour, so V1 gets its own copy of the auth
|
||||||
|
# with backwards compat behaviour.
|
||||||
|
orf.TOKEN_NOT_FOUND_HTTP_STATUS = 403
|
||||||
|
return orf
|
||||||
|
|
||||||
def build_state_handler(self):
|
def build_state_handler(self):
|
||||||
return StateHandler(self)
|
return StateHandler(self)
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ class PusherStore(SQLBaseStore):
|
|||||||
defer.returnValue(ret)
|
defer.returnValue(ret)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def add_pusher(self, user_name, profile_tag, kind, app_id,
|
def add_pusher(self, user_name, access_token, profile_tag, kind, app_id,
|
||||||
app_display_name, device_display_name,
|
app_display_name, device_display_name,
|
||||||
pushkey, pushkey_ts, lang, data):
|
pushkey, pushkey_ts, lang, data):
|
||||||
try:
|
try:
|
||||||
@ -107,6 +107,7 @@ class PusherStore(SQLBaseStore):
|
|||||||
),
|
),
|
||||||
dict(
|
dict(
|
||||||
user_name=user_name,
|
user_name=user_name,
|
||||||
|
access_token=access_token,
|
||||||
kind=kind,
|
kind=kind,
|
||||||
profile_tag=profile_tag,
|
profile_tag=profile_tag,
|
||||||
app_display_name=app_display_name,
|
app_display_name=app_display_name,
|
||||||
|
@ -174,4 +174,4 @@ class RegistrationStore(SQLBaseStore):
|
|||||||
if rows:
|
if rows:
|
||||||
return rows[0]
|
return rows[0]
|
||||||
|
|
||||||
raise StoreError(404, "Token not found.")
|
return None
|
||||||
|
2
synapse/storage/schema/delta/15/v15.sql
Normal file
2
synapse/storage/schema/delta/15/v15.sql
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE pushers ADD COLUMN access_token INTEGER DEFAULT NULL;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user