def _set_request_auth_type_guess_attribute(self, request):
        """
        Add custom attribute 'request_auth_type_guess' for the authentication type used.

        NOTE: This is a best guess at this point.  Possible values include:
            no-user
            unauthenticated
            jwt/bearer/other-token-type
            jwt-cookie
            session-or-other (catch all)

        """
        if not hasattr(request, 'user') or not request.user:
            auth_type = 'no-user'
        elif not request.user.is_authenticated:
            auth_type = 'unauthenticated'
        elif 'HTTP_AUTHORIZATION' in request.META and request.META[
                'HTTP_AUTHORIZATION']:
            token_parts = request.META['HTTP_AUTHORIZATION'].split()
            # Example: "JWT eyJhbGciO..."
            if len(token_parts) == 2:
                auth_type = token_parts[0].lower(
                )  # 'jwt' or 'bearer' (for example)
            else:
                auth_type = 'other-token-type'
        elif USE_JWT_COOKIE_HEADER in request.META and jwt_cookie_name(
        ) in request.COOKIES:
            auth_type = 'jwt-cookie'
        else:
            auth_type = 'session-or-other'
        monitoring.set_custom_attribute('request_auth_type_guess', auth_type)
Пример #2
0
 def test_success(self, mock_set_custom_metric):
     self.request.META[USE_JWT_COOKIE_HEADER] = 'true'
     self.request.COOKIES[jwt_cookie_header_payload_name()] = 'header.payload'
     self.request.COOKIES[jwt_cookie_signature_name()] = 'signature'
     self.middleware.process_request(self.request)
     self.assertEqual(self.request.COOKIES[jwt_cookie_name()], 'header.payload.signature')
     mock_set_custom_metric.assert_called_once_with('request_jwt_cookie', 'success')
def set_jwt_cookie(client, user, role_context_pairs=None):
    """
    Set jwt token in cookies
    """
    jwt_token = _jwt_token_from_role_context_pairs(user, role_context_pairs
                                                   or [])
    client.cookies[jwt_cookie_name()] = jwt_token
Пример #4
0
    def process_request(self, request):
        """
        Reconstitute the full JWT and add a new cookie on the request object.
        """
        use_jwt_cookie_requested = request.META.get(USE_JWT_COOKIE_HEADER)
        header_payload_cookie = request.COOKIES.get(jwt_cookie_header_payload_name())
        signature_cookie = request.COOKIES.get(jwt_cookie_signature_name())

        if not use_jwt_cookie_requested:
            metric_value = 'not-requested'
        elif header_payload_cookie and signature_cookie:
            # Reconstitute JWT auth cookie if split cookies are available and jwt cookie
            # authentication was requested by the client.
            request.COOKIES[jwt_cookie_name()] = '{}{}{}'.format(
                header_payload_cookie,
                JWT_DELIMITER,
                signature_cookie,
            )
            metric_value = 'success'
        elif header_payload_cookie or signature_cookie:
            # Log unexpected case of only finding one cookie.
            if not header_payload_cookie:
                log_message, metric_value = self._get_missing_cookie_message_and_metric(
                    jwt_cookie_header_payload_name()
                )
            if not signature_cookie:
                log_message, metric_value = self._get_missing_cookie_message_and_metric(
                    jwt_cookie_signature_name()
                )
            log.warning(log_message)
        else:
            metric_value = 'missing-both'

        monitoring.set_custom_metric('request_jwt_cookie', metric_value)
Пример #5
0
 def test_success(self, mock_set_custom_attribute):
     self.request.META[USE_JWT_COOKIE_HEADER] = 'true'
     self.request.COOKIES[jwt_cookie_header_payload_name()] = 'header.payload'
     self.request.COOKIES[jwt_cookie_signature_name()] = 'signature'
     self.middleware.process_view(self.request, None, None, None)
     self.assertEqual(self.request.COOKIES[jwt_cookie_name()], 'header.payload.signature')
     mock_set_custom_attribute.assert_called_once_with('request_jwt_cookie', 'success')
Пример #6
0
    def process_request(self, request):
        """
        Reconstitute the full JWT and add a new cookie on the request object.
        """
        use_jwt_cookie_requested = request.META.get(USE_JWT_COOKIE_HEADER)
        header_payload_cookie = request.COOKIES.get(jwt_cookie_header_payload_name())
        signature_cookie = request.COOKIES.get(jwt_cookie_signature_name())

        if not use_jwt_cookie_requested:
            metric_value = 'not-requested'
        elif header_payload_cookie and signature_cookie:
            # Reconstitute JWT auth cookie if split cookies are available and jwt cookie
            # authentication was requested by the client.
            request.COOKIES[jwt_cookie_name()] = '{}{}{}'.format(
                header_payload_cookie,
                JWT_DELIMITER,
                signature_cookie,
            )
            metric_value = 'success'
        elif header_payload_cookie or signature_cookie:
            # Log unexpected case of only finding one cookie.
            if not header_payload_cookie:
                log_message, metric_value = self._get_missing_cookie_message_and_metric(
                    jwt_cookie_header_payload_name()
                )
            if not signature_cookie:
                log_message, metric_value = self._get_missing_cookie_message_and_metric(
                    jwt_cookie_signature_name()
                )
            log.warning(log_message)
        else:
            metric_value = 'missing-both'

        monitoring.set_custom_metric('request_jwt_cookie', metric_value)
    def test_request_auth_type_guess_jwt_cookie_attribute(
            self, mock_set_custom_attribute):
        self.request.user = UserFactory()
        self.request.META[USE_JWT_COOKIE_HEADER] = True
        self.request.COOKIES[jwt_cookie_name()] = 'reconstituted-jwt-cookie'

        self.middleware.process_response(self.request, None)
        mock_set_custom_attribute.assert_any_call('request_auth_type_guess',
                                                  'jwt-cookie')
Пример #8
0
 def test_missing_cookies(self, set_cookie_name, missing_cookie_name,
                          mock_set_custom_metric, mock_log):
     self.request.META[USE_JWT_COOKIE_HEADER] = 'true'
     self.request.COOKIES[set_cookie_name] = 'test'
     self.middleware.process_request(self.request)
     self.assertIsNone(self.request.COOKIES.get(jwt_cookie_name()))
     mock_log.warning.assert_called_once_with(
         '%s cookie is missing. JWT auth cookies will not be reconstituted.'
         % missing_cookie_name)
     mock_set_custom_metric.assert_called_once_with(
         'request_jwt_cookie', 'missing-{}'.format(missing_cookie_name))
Пример #9
0
 def test_missing_cookies(
         self, set_cookie_name, missing_cookie_name, mock_set_custom_metric, mock_log
 ):
     self.request.META[USE_JWT_COOKIE_HEADER] = 'true'
     self.request.COOKIES[set_cookie_name] = 'test'
     self.middleware.process_request(self.request)
     self.assertIsNone(self.request.COOKIES.get(jwt_cookie_name()))
     mock_log.warning.assert_called_once_with(
         '%s cookie is missing. JWT auth cookies will not be reconstituted.' %
         missing_cookie_name
     )
     mock_set_custom_metric.assert_called_once_with('request_jwt_cookie', 'missing-{}'.format(missing_cookie_name))
Пример #10
0
    def authenticate(self, request):
        if request.COOKIES.get(jwt_cookie_name(), None) != 'header.payload.signature':
            return None

        # authenticate was failing on POST calls because it previously wasn't passing the
        # supported parsers into the new Request object. This retrieval of POST data
        # simulates the CSRF POST data checks in the non-test authenticate method. This
        # line lets us verify that the parsers are being correctly passed to the request
        request.POST.get('csrfmiddlewaretoken', '')

        user = UserFactory()
        return (user, None)
Пример #11
0
def get_decoded_jwt_from_request(request):
    """
    Grab jwt from request if possible.

    Returns a decoded jwt dict if it finds it.
    Returns a None if it does not.
    """
    jwt_cookie = request.COOKIES.get(jwt_cookie_name(), None) or getattr(
        request, 'auth', None)

    if not jwt_cookie:
        return None
    return jwt_decode_handler(jwt_cookie)
Пример #12
0
    def set_jwt_cookie(self, system_wide_role='admin', context='some_context'):
        """
        Set jwt token in cookies
        """
        role_data = '{system_wide_role}'.format(
            system_wide_role=system_wide_role)
        if context is not None:
            role_data += ':{context}'.format(context=context)

        payload = generate_unversioned_payload(self.user)
        payload.update({'roles': [role_data]})
        jwt_token = generate_jwt_token(payload)
        self.client.cookies[jwt_cookie_name()] = jwt_token
    def process_view(self, request, view_func, view_args, view_kwargs):  # pylint: disable=unused-argument
        """
        Reconstitute the full JWT and add a new cookie on the request object.
        """
        assert hasattr(
            request, 'session'
        ), "The Django authentication middleware requires session middleware to be installed. Edit your MIDDLEWARE setting to insert 'django.contrib.sessions.middleware.SessionMiddleware'."  # noqa E501 line too long

        use_jwt_cookie_requested = request.META.get(USE_JWT_COOKIE_HEADER)
        header_payload_cookie = request.COOKIES.get(
            jwt_cookie_header_payload_name())
        signature_cookie = request.COOKIES.get(jwt_cookie_signature_name())

        is_set_request_user_for_jwt_cookie_enabled = get_setting(
            ENABLE_SET_REQUEST_USER_FOR_JWT_COOKIE)
        if use_jwt_cookie_requested and is_set_request_user_for_jwt_cookie_enabled:
            # DRF does not set request.user until process_response. This makes it available in process_view.
            # For more info, see https://github.com/jpadilla/django-rest-framework-jwt/issues/45#issuecomment-74996698
            request.user = SimpleLazyObject(
                lambda: _get_user_from_jwt(request, view_func))

        if not use_jwt_cookie_requested:
            metric_value = 'not-requested'
        elif header_payload_cookie and signature_cookie:
            # Reconstitute JWT auth cookie if split cookies are available and jwt cookie
            # authentication was requested by the client.
            request.COOKIES[jwt_cookie_name()] = '{}{}{}'.format(
                header_payload_cookie,
                JWT_DELIMITER,
                signature_cookie,
            )
            metric_value = 'success'
        elif header_payload_cookie or signature_cookie:
            # Log unexpected case of only finding one cookie.
            if not header_payload_cookie:
                log_message, metric_value = self._get_missing_cookie_message_and_metric(
                    jwt_cookie_header_payload_name())
            if not signature_cookie:
                log_message, metric_value = self._get_missing_cookie_message_and_metric(
                    jwt_cookie_signature_name())
            log.warning(log_message)
        else:
            metric_value = 'missing-both'
            log.warning(
                'Both JWT auth cookies missing. JWT auth cookies will not be reconstituted.'
            )

        monitoring.set_custom_metric('request_jwt_cookie', metric_value)
Пример #14
0
    def get_request_with_jwt_cookie(self, system_wide_role=None, context=None):
        """
        Set jwt token in cookies.
        """
        payload = generate_unversioned_payload(self.user)
        if system_wide_role:
            payload.update({
                'roles': [
                    '{system_wide_role}:{context}'.format(system_wide_role=system_wide_role, context=context)
                ]
            })
        jwt_token = generate_jwt_token(payload)

        request = RequestFactory().get('/')
        request.COOKIES[jwt_cookie_name()] = jwt_token
        return request
Пример #15
0
    def test_get_decoded_jwt_from_request(self, mock_decoder):
        """
        A decoded jwt should be returned from request if it exists
        """
        payload = generate_unversioned_payload(self.request.user)
        payload.update({
          "roles": [
            "some_new_role_name:some_context"
          ]
        })
        jwt_token = generate_jwt_token(payload)

        self.request.COOKIES[jwt_cookie_name()] = jwt_token
        get_decoded_jwt_from_request(self.request)

        mock_decoder.assert_called_once()
Пример #16
0
    def test_jwt_authentication(self):
        """Test that requests made without a valid JWT fail."""
        # Remove jwt cookie
        self.client.cookies[jwt_cookie_name()] = {}

        # Verify that the basket creation endpoint requires JWT authentication
        response = self.create_basket(skus=[self.PAID_SKU], auth=False)
        self.assertEqual(response.status_code, 401)

        # Verify that the basket creation endpoint requires valid user data in the JWT payload
        token = self.generate_token({})
        response = self.create_basket(skus=[self.PAID_SKU], token=token)
        self.assertEqual(response.status_code, 401)

        # Verify that the basket creation endpoint requires user data to be signed with a valid secret;
        # guarantee an invalid secret by truncating the valid secret
        invalid_secret = self.JWT_SECRET_KEY[:-1]
        payload = {
            'username': self.user.username,
            'email': self.user.email,
        }
        token = self.generate_token(payload, secret=invalid_secret)
        response = self.create_basket(skus=[self.PAID_SKU], token=token)
        self.assertEqual(response.status_code, 401)
Пример #17
0
def _set_encoded_jwt_in_cookies(client, payload):
    """
    JWT-encodes the given payload and sets it in the client's cookies.
    """
    client.cookies[jwt_cookie_name()] = generate_jwt_token(payload)
Пример #18
0
 def test_do_not_use_jwt_cookies(self, mock_set_custom_attribute):
     self.middleware.process_view(self.request, None, None, None)
     self.assertIsNone(self.request.COOKIES.get(jwt_cookie_name()))
     mock_set_custom_attribute.assert_called_once_with('request_jwt_cookie', 'not-requested')
 def authenticate(self, request):
     if request.COOKIES.get(jwt_cookie_name(),
                            None) != 'header.payload.signature':
         return None
     user = UserFactory()
     return (user, None)
Пример #20
0
 def test_no_cookies(self, mock_set_custom_metric):
     self.request.META[USE_JWT_COOKIE_HEADER] = 'true'
     self.middleware.process_request(self.request)
     self.assertIsNone(self.request.COOKIES.get(jwt_cookie_name()))
     mock_set_custom_metric.assert_called_once_with('request_jwt_cookie', 'missing-both')
Пример #21
0
 def test_do_not_use_jwt_cookies(self, mock_set_custom_metric):
     self.middleware.process_request(self.request)
     self.assertIsNone(self.request.COOKIES.get(jwt_cookie_name()))
     mock_set_custom_metric.assert_called_once_with('request_jwt_cookie', 'not-requested')
Пример #22
0
 def test_no_cookies(self, mock_set_custom_metric):
     self.request.META[USE_JWT_COOKIE_HEADER] = 'true'
     self.middleware.process_request(self.request)
     self.assertIsNone(self.request.COOKIES.get(jwt_cookie_name()))
     mock_set_custom_metric.assert_called_once_with('request_jwt_cookie',
                                                    'missing-both')
Пример #23
0
 def test_do_not_use_jwt_cookies(self, mock_set_custom_metric):
     self.middleware.process_request(self.request)
     self.assertIsNone(self.request.COOKIES.get(jwt_cookie_name()))
     mock_set_custom_metric.assert_called_once_with('request_jwt_cookie',
                                                    'not-requested')