From e13ac7af1a9f7479626bd50955b46e30b7b3f60b Mon Sep 17 00:00:00 2001 From: Josef Rousek Date: Mon, 23 Mar 2020 09:19:49 +0100 Subject: [PATCH 1/3] Introduce 3rd party cookie check Based on https://www.whatismybrowser.com/detect/are-third-party-cookies-enabled --- .../templates/shopify_auth/check_cookies.html | 131 ++++++++++++++++++ .../templates/shopify_auth/login.html | 56 ++++++-- shopify_auth/tests/test_views.py | 16 ++- shopify_auth/urls.py | 1 + shopify_auth/views.py | 27 +++- 5 files changed, 212 insertions(+), 19 deletions(-) create mode 100644 shopify_auth/templates/shopify_auth/check_cookies.html diff --git a/shopify_auth/templates/shopify_auth/check_cookies.html b/shopify_auth/templates/shopify_auth/check_cookies.html new file mode 100644 index 0000000..8523f10 --- /dev/null +++ b/shopify_auth/templates/shopify_auth/check_cookies.html @@ -0,0 +1,131 @@ + + +
+
+
+
+
+
+
+
+
+
+ +
+
+

+ Verifying your cookie configuration... +

+
+
+ + + + + +
+
+
+
+
+
+
+
+
+
+ +
+ {% csrf_token %} + +
+ + \ No newline at end of file diff --git a/shopify_auth/templates/shopify_auth/login.html b/shopify_auth/templates/shopify_auth/login.html index 55d9dec..62666c7 100644 --- a/shopify_auth/templates/shopify_auth/login.html +++ b/shopify_auth/templates/shopify_auth/login.html @@ -1,15 +1,45 @@ -

Log In

+ -
- {% csrf_token %} +
+
+
+
+
+

{{SHOPIFY_APP_NAME}}

+
+

+ Enter your shop domain to log in or install this app. +

+
+
+
+ + {% csrf_token %} +
+
+
+ +
+
+
+ +
+
+
+
+
+ +
+
-

- -

- -

- -

- - - \ No newline at end of file + +
+
+
+
+
\ No newline at end of file diff --git a/shopify_auth/tests/test_views.py b/shopify_auth/tests/test_views.py index f69a4d8..662622c 100644 --- a/shopify_auth/tests/test_views.py +++ b/shopify_auth/tests/test_views.py @@ -29,9 +29,6 @@ def test_authenticate_view(self): response = self.client.post('/authenticate/') self.assertEqual(response.status_code, 302) - response = self.client.get('/?shop=test.myshopify.com') - self.assertContains(response, 'window.top.location.href = "https://test.myshopify.com/admin/oauth/authorize') - # Dev mode so token does not need to be valid settings.SHOPIFY_APP_DEV_MODE = True response = self.client.get('/authenticate/?shop=test.myshopify.com') @@ -40,6 +37,15 @@ def test_authenticate_view(self): self.assertEqual(self.client.session['_auth_user_backend'], 'shopify_auth.backends.ShopUserBackend') self.assertIsNot(self.client.session['_auth_user_hash'], None) + def test_shows_cookie_check_for_embedded_app_with_shop_param(self): + response = self.client.get('/?shop=test.myshopify.com') + self.assertTemplateUsed(response, "shopify_auth/check_cookies.html") + + def test_authenticates_standalone_app_with_shop_param(self): + with self.settings(SHOPIFY_APP_IS_EMBEDDED=False): + response = self.client.get('/?shop=test.myshopify.com') + self.assertEqual(response.status_code, 302) + def test_redirect_to_view(self): """ Test that return_address is persisted through login flow. @@ -51,3 +57,7 @@ def test_redirect_to_view(self): response = self.client.get('/authenticate/?shop=test.myshopify.com') self.assertEqual(response.status_code, 302) self.assertEqual(response.url, 'other-view') + + def test_check_cookie(self): + response = self.client.get('/check-cookie') + self.assertContains(response, "window.detect.cookies_third_party.cookies_test_finished(false);") \ No newline at end of file diff --git a/shopify_auth/urls.py b/shopify_auth/urls.py index 4e648e4..886b1ca 100644 --- a/shopify_auth/urls.py +++ b/shopify_auth/urls.py @@ -6,4 +6,5 @@ url(r'^finalize/$', views.finalize), url(r'^authenticate/$', views.authenticate), url(r'^$', views.login), + url(r'^check-cookie$', views.check_cookie), ] diff --git a/shopify_auth/views.py b/shopify_auth/views.py index 273910a..e4b0903 100644 --- a/shopify_auth/views.py +++ b/shopify_auth/views.py @@ -3,7 +3,7 @@ from django import VERSION as DJANGO_VERSION from django.conf import settings from django.contrib import auth -from django.http.response import HttpResponseRedirect +from django.http.response import HttpResponseRedirect, HttpResponse from django.shortcuts import render, resolve_url from .decorators import anonymous_required @@ -14,6 +14,7 @@ from django.core.urlresolvers import reverse SESSION_REDIRECT_FIELD_NAME = 'shopify_auth_next' +THIRD_PARTY_COOKIE_NAME = 'a_third_party_cookie' def get_return_address(request): return request.session.get(SESSION_REDIRECT_FIELD_NAME) or request.GET.get(auth.REDIRECT_FIELD_NAME) or resolve_url(settings.LOGIN_REDIRECT_URL) @@ -25,15 +26,35 @@ def login(request, *args, **kwargs): # as a result of submitting the login form. shop = request.POST.get('shop', request.GET.get('shop')) - # If the shop parameter has already been provided, attempt to authenticate immediately. + # If the merchant is authenticating from Shopify Admin, make sure cookies work. if shop: + if settings.SHOPIFY_APP_IS_EMBEDDED: + response = render(request, "shopify_auth/check_cookies.html", { + 'SHOPIFY_APP_NAME': settings.SHOPIFY_APP_NAME, + 'shop': shop, + 'login_url': reverse(authenticate), + 'check_cookie_url': reverse(check_cookie), + }) + response.set_cookie(THIRD_PARTY_COOKIE_NAME, 'true', secure=True) + return response + + # If the shop parameter has already been provided, attempt to authenticate immediately. return authenticate(request, *args, **kwargs) return render(request, "shopify_auth/login.html", { - 'SHOPIFY_APP_NAME': settings.SHOPIFY_APP_NAME + 'SHOPIFY_APP_NAME': settings.SHOPIFY_APP_NAME, + 'shop': shop, }) +def check_cookie(request): + is_cookie_present = request.COOKIES.get(THIRD_PARTY_COOKIE_NAME, 'false') + return HttpResponse( + 'window.detect.cookies_third_party.cookies_test_finished({});'.format(is_cookie_present), + content_type='application/javascript; charset=UTF-8;' + ) + + @anonymous_required def authenticate(request, *args, **kwargs): shop = request.POST.get('shop', request.GET.get('shop')) From 155f0a8067cf6f228a9ff57e43d68c4b5d55aa6f Mon Sep 17 00:00:00 2001 From: Josef Rousek Date: Tue, 24 Mar 2020 10:51:43 +0100 Subject: [PATCH 2/3] Python 3.4 is EOL According to https://devguide.python.org/ --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4f234fb..8f309f2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,6 @@ sudo: false language: python python: - - "3.4" - "3.5" - "3.6" - "3.7" From 516e0a965ae59130d17dcf110cf424d86a28d6b6 Mon Sep 17 00:00:00 2001 From: Josef Rousek Date: Tue, 24 Mar 2020 11:11:40 +0100 Subject: [PATCH 3/3] Update changelog --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e171e96..9b62afc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ # Change Log All notable changes to this project will be documented in this file. +## Unreleased +### Added +- Detection if third party cookies are allowed + +### Removed +- Dropped support for Python 3.4 + ## 0.9.0 - 2019-12-22 ### Added - Support for Django 3 by removing Python 2 support