Merge pull request #35221 from open-craft/kshitij/fox/token-login-grants

feat: Allow trusted apps to perform cookie login.
This commit is contained in:
Feanil Patel
2024-11-14 11:02:40 -05:00
committed by GitHub
2 changed files with 21 additions and 7 deletions

View File

@@ -168,11 +168,15 @@ class TestLoginWithAccessTokenView(TestCase):
if expected_cookie_name:
assert expected_cookie_name in response.cookies
def _create_dot_access_token(self, grant_type='Client credentials'):
def _create_dot_access_token(self, grant_type='Client credentials', skip_authorization=False):
"""
Create dot based access token
"""
dot_application = dot_factories.ApplicationFactory(user=self.user, authorization_grant_type=grant_type)
dot_application = dot_factories.ApplicationFactory(
user=self.user,
authorization_grant_type=grant_type,
skip_authorization=skip_authorization,
)
return dot_factories.AccessTokenFactory(user=self.user, application=dot_application)
def test_failure_with_invalid_token(self):
@@ -189,6 +193,10 @@ class TestLoginWithAccessTokenView(TestCase):
access_token = self._create_dot_access_token()
self._verify_response(access_token, expected_status_code=401)
def test_dot_client_credentials_supported_if_authorization_skipped(self):
access_token = self._create_dot_access_token(skip_authorization=True)
self._verify_response(access_token, expected_status_code=204, expected_cookie_name='sessionid')
def _create_jwt_token(self, grant_type='password', scope='email profile', use_asymmetric_key=True):
"""
Create jwt token

View File

@@ -132,9 +132,10 @@ class LoginWithAccessTokenView(APIView):
return backend_path
@staticmethod
def _ensure_access_token_has_password_grant(request):
def _ensure_access_token_has_password_grant_or_privileged_application(request):
"""
Ensures the access token provided has password type grant.
Ensures the access token provided has password type grant, or if 'skip_authorization'
has been enabled, implying this is a trusted application.
"""
if is_jwt_authenticated(request):
jwt_payload = get_decoded_jwt_from_auth(request)
@@ -143,12 +144,17 @@ class LoginWithAccessTokenView(APIView):
else:
token_query = dot_models.AccessToken.objects.select_related('user')
dot_token = token_query.filter(token=request.auth).first()
if dot_token and dot_token.application.authorization_grant_type == dot_models.Application.GRANT_PASSWORD:
if dot_token and (
dot_token.application.authorization_grant_type == dot_models.Application.GRANT_PASSWORD
or dot_token.application.skip_authorization
):
return
raise AuthenticationFailed({
'error_code': 'non_supported_token',
'developer_message': 'Only access tokens with grant type password are supported.'
'developer_message': 'Only Django Oauth Toolkit access tokens for applications which '
'are trusted (with "skip_authentication" set to True, or with grant type '
'password) are supported.'
})
@staticmethod
@@ -194,7 +200,7 @@ class LoginWithAccessTokenView(APIView):
request.user.backend = self._get_path_of_arbitrary_backend_for_user(request.user)
self._ensure_user_is_not_disabled(request)
self._ensure_access_token_has_password_grant(request)
self._ensure_access_token_has_password_grant_or_privileged_application(request)
self._ensure_jwt_is_asymmetric(request)
login(request, request.user) # login generates and stores the user's cookies in the session