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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user