diff --git a/.circleci/config.yml b/.circleci/config.yml index efcf792..7032790 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -12,15 +12,28 @@ jobs: executor: docker/docker steps: - checkout - - run: pip install --user -r dev-requirements.txt - - run: pip install --user -r dj_rest_auth/tests/requirements.pip - - run: pip install -q --user coveralls djangorestframework==$DRF Django==$DJANGO_VERSION - run: - command: coverage run --source=dj_rest_auth setup.py test + command: pip install --user -r dev-requirements.txt + name: "Pip Install dev requirements" + - run: + command: pip install --user -r dj_rest_auth/tests/requirements.pip + name: "Pip Install test requirements" + - run: + command: | + mkdir -p test-results/ + coverage run --source=dj_rest_auth setup.py test + coverage report name: Test - run: command: COVERALLS_REPO_TOKEN=Q58WdUuZOi89XHyDeDsGE2lxUGQ2IfqP3 coveralls name: Coverage + - run: + command: python3 setup.py sdist + name: Build + - store_test_results: + path: test-results/ + - store_artifacts: + path: dist/ test-django-2: <<: *template environment: diff --git a/.gitignore b/.gitignore index 136132c..266f6ad 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,7 @@ coverage.xml *.cover .hypothesis/ .pytest_cache/ +test-results/ # Translations *.mo @@ -106,4 +107,7 @@ venv.bak/ # mypy .mypy_cache/ demo/react-spa/node_modules/ -demo/react-spa/yarn.lock \ No newline at end of file +demo/react-spa/yarn.lock + +# Visual Studio Code +.vscode/ diff --git a/demo/requirements.pip b/demo/requirements.pip index e9276aa..4a0061a 100644 --- a/demo/requirements.pip +++ b/demo/requirements.pip @@ -1,5 +1,5 @@ -django>=1.9.0 -git+https://github.com/jazzband/dj-rest-auth.git@master +django>=2.2 +dj-rest-auth @ git+https://github.com/jazzband/dj-rest-auth.git@master djangorestframework>=3.11.0 djangorestframework-simplejwt==4.4.0 django-allauth>=0.24.1 diff --git a/demo/templates/rest_framework/api.html b/demo/templates/rest_framework/api.html new file mode 100644 index 0000000..57f02c9 --- /dev/null +++ b/demo/templates/rest_framework/api.html @@ -0,0 +1,52 @@ +{% extends "rest_framework/base.html" %} + +{% block style %} + {{ block.super }} + +{% endblock %} + +{% block userlinks %} + {% if user.is_authenticated or response.data.access_token %} + + {% else %} + {% url 'rest_login' as login_url %} +
  • Login
  • + {% url 'rest_register' as register_url %} +
  • Register
  • + {% endif %} +{% endblock %} diff --git a/dev-requirements.txt b/dev-requirements.txt index cee8ea6..73b9db0 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,5 +1,5 @@ --editable . responses>=0.5.0 djangorestframework-simplejwt==4.4.0 -django-allauth +django-allauth>=0.25.0 coveralls>=1.11.1 \ No newline at end of file diff --git a/dj_rest_auth/tests/requirements.pip b/dj_rest_auth/tests/requirements.pip index 9f28d70..66af74f 100644 --- a/dj_rest_auth/tests/requirements.pip +++ b/dj_rest_auth/tests/requirements.pip @@ -1,4 +1,4 @@ django-allauth>=0.25.0 -responses>=0.3.0 +responses>=0.5.0 flake8==2.4.0 djangorestframework-simplejwt==4.4.0 diff --git a/dj_rest_auth/tests/settings.py b/dj_rest_auth/tests/settings.py index 5f57f91..56f0e94 100644 --- a/dj_rest_auth/tests/settings.py +++ b/dj_rest_auth/tests/settings.py @@ -72,6 +72,9 @@ REST_FRAMEWORK = { ) } +TEST_RUNNER = 'xmlrunner.extra.djangotestrunner.XMLTestRunner' +TEST_OUTPUT_DIR = 'test-results' + INSTALLED_APPS = [ 'django.contrib.messages', 'django.contrib.admin', diff --git a/dj_rest_auth/views.py b/dj_rest_auth/views.py index dc3dea8..21e064c 100644 --- a/dj_rest_auth/views.py +++ b/dj_rest_auth/views.py @@ -86,6 +86,9 @@ class LoginView(GenericAPIView): response = Response(serializer.data, status=status.HTTP_200_OK) if getattr(settings, 'REST_USE_JWT', False): cookie_name = getattr(settings, 'JWT_AUTH_COOKIE', None) + cookie_secure = getattr(settings, 'JWT_AUTH_SECURE', False) + cookie_httponly = getattr(settings, 'JWT_AUTH_HTTPONLY', True) + cookie_samesite = getattr(settings, 'JWT_AUTH_SAMESITE', 'Lax') from rest_framework_simplejwt.settings import api_settings as jwt_settings if cookie_name: from datetime import datetime @@ -94,7 +97,9 @@ class LoginView(GenericAPIView): cookie_name, self.access_token, expires=expiration, - httponly=True + secure=cookie_secure, + httponly=cookie_httponly, + samesite=cookie_samesite ) return response diff --git a/docs/configuration.rst b/docs/configuration.rst index aac74c2..f421d76 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -12,6 +12,8 @@ Configuration - JWT_SERIALIZER - (Using REST_USE_JWT=True) response for successful authentication in ``dj_rest_auth.views.LoginView``, default value ``dj_rest_auth.serializers.JWTSerializer`` + - JWT_TOKEN_CLAIMS_SERIALIZER - A custom JWT Claim serializer. Default is `rest_framework_simplejwt.serializers.TokenObtainPairSerializer` + - USER_DETAILS_SERIALIZER - serializer class in ``dj_rest_auth.views.UserDetailsView``, default value ``dj_rest_auth.serializers.UserDetailsSerializer`` - PASSWORD_RESET_SERIALIZER - serializer class in ``dj_rest_auth.views.PasswordResetView``, default value ``dj_rest_auth.serializers.PasswordResetSerializer`` @@ -48,6 +50,9 @@ Configuration - **REST_USE_JWT** - Enable JWT Authentication instead of Token/Session based. This is built on top of djangorestframework-simplejwt https://github.com/SimpleJWT/django-rest-framework-simplejwt, which must also be installed. (default: False) - **JWT_AUTH_COOKIE** - The cookie name/key. +- **JWT_AUTH_SECURE** - If you want the cookie to be only sent to the server when a request is made with the https scheme (default: False). +- **JWT_AUTH_HTTPONLY** - If you want to prevent client-side JavaScript from having access to the cookie (default: True). +- **JWT_AUTH_SAMESITE** - To tell the browser not to send this cookie when performing a cross-origin request (default: 'Lax'). SameSite isn’t supported by all browsers. - **OLD_PASSWORD_FIELD_ENABLED** - set it to True if you want to have old password verification on password change enpoint (default: False) - **LOGOUT_ON_PASSWORD_CHANGE** - set to False if you want to keep the current user logged in after a password change diff --git a/setup.py b/setup.py index fac004b..fc9811d 100644 --- a/setup.py +++ b/setup.py @@ -34,6 +34,7 @@ setup( 'with_social': ['django-allauth>=0.25.0'], }, tests_require=[ + 'unittest-xml-reporting>=3.0.2', 'responses>=0.5.0', 'django-allauth>=0.25.0', 'djangorestframework-simplejwt>=4.4.0 ',