2020#
2121import logging
2222from dataclasses import dataclass
23- from typing import TYPE_CHECKING , Any , Callable , Dict , List , Optional
23+ from typing import TYPE_CHECKING , Any , Callable , Dict , List , Optional , Set
2424from urllib .parse import urlencode
2525
2626from authlib .oauth2 import ClientAuth
3434 AuthError ,
3535 HttpResponseException ,
3636 InvalidClientTokenError ,
37- OAuthInsufficientScopeError ,
3837 SynapseError ,
3938 UnrecognizedRequestError ,
4039)
6362
6463# Scope as defined by MSC2967
6564# https://github.com/matrix-org/matrix-spec-proposals/pull/2967
66- SCOPE_MATRIX_API = "urn:matrix:org.matrix.msc2967.client:api:*"
67- SCOPE_MATRIX_GUEST = "urn:matrix:org.matrix.msc2967.client:api:guest"
68- SCOPE_MATRIX_DEVICE_PREFIX = "urn:matrix:org.matrix.msc2967.client:device:"
65+ UNSTABLE_SCOPE_MATRIX_API = "urn:matrix:org.matrix.msc2967.client:api:*"
66+ UNSTABLE_SCOPE_MATRIX_DEVICE_PREFIX = "urn:matrix:org.matrix.msc2967.client:device:"
67+ STABLE_SCOPE_MATRIX_API = "urn:matrix:client:api:*"
68+ STABLE_SCOPE_MATRIX_DEVICE_PREFIX = "urn:matrix:client:device:"
6969
7070# Scope which allows access to the Synapse admin API
7171SCOPE_SYNAPSE_ADMIN = "urn:synapse:admin:*"
@@ -444,9 +444,6 @@ async def _wrapped_get_user_by_req(
444444 if not self ._is_access_token_the_admin_token (access_token ):
445445 await self ._record_request (request , requester )
446446
447- if not allow_guest and requester .is_guest :
448- raise OAuthInsufficientScopeError ([SCOPE_MATRIX_API ])
449-
450447 request .requester = requester
451448
452449 return requester
@@ -528,10 +525,11 @@ async def get_user_by_access_token(
528525 scope : List [str ] = introspection_result .get_scope_list ()
529526
530527 # Determine type of user based on presence of particular scopes
531- has_user_scope = SCOPE_MATRIX_API in scope
532- has_guest_scope = SCOPE_MATRIX_GUEST in scope
528+ has_user_scope = (
529+ UNSTABLE_SCOPE_MATRIX_API in scope or STABLE_SCOPE_MATRIX_API in scope
530+ )
533531
534- if not has_user_scope and not has_guest_scope :
532+ if not has_user_scope :
535533 raise InvalidClientTokenError ("No scope in token granting user rights" )
536534
537535 # Match via the sub claim
@@ -579,19 +577,20 @@ async def get_user_by_access_token(
579577 # We only allow a single device_id in the scope, so we find them all in the
580578 # scope list, and raise if there are more than one. The OIDC server should be
581579 # the one enforcing valid scopes, so we raise a 500 if we find an invalid scope.
582- device_ids = [
583- tok [len (SCOPE_MATRIX_DEVICE_PREFIX ) :]
584- for tok in scope
585- if tok .startswith (SCOPE_MATRIX_DEVICE_PREFIX )
586- ]
580+ device_ids : Set [str ] = set ()
581+ for tok in scope :
582+ if tok .startswith (UNSTABLE_SCOPE_MATRIX_DEVICE_PREFIX ):
583+ device_ids .add (tok [len (UNSTABLE_SCOPE_MATRIX_DEVICE_PREFIX ) :])
584+ elif tok .startswith (STABLE_SCOPE_MATRIX_DEVICE_PREFIX ):
585+ device_ids .add (tok [len (STABLE_SCOPE_MATRIX_DEVICE_PREFIX ) :])
587586
588587 if len (device_ids ) > 1 :
589588 raise AuthError (
590589 500 ,
591590 "Multiple device IDs in scope" ,
592591 )
593592
594- device_id = device_ids [ 0 ] if device_ids else None
593+ device_id = next ( iter ( device_ids ), None )
595594
596595 if device_id is not None :
597596 # Sanity check the device_id
@@ -617,5 +616,4 @@ async def get_user_by_access_token(
617616 user_id = user_id ,
618617 device_id = device_id ,
619618 scope = scope ,
620- is_guest = (has_guest_scope and not has_user_scope ),
621619 )
0 commit comments