Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@


There are two primary ways to help:

- Using the issue tracker, and
- Changing the code-base.


## Using the issue tracker

Use the issue tracker to suggest feature requests, report bugs, and ask questions.
Expand Down
12 changes: 12 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,18 @@ Shared pages will also have a new dropdown menu option that links to this sharin
:alt: Dropdown with sharing link
:width: 640px

To use tokens in place of the page path on the sharing site, add the following setting:

.. code-block:: python

WAGTAILSHARING_TOKENIZE_URL = True

In some environments such as Heroku, SERVER_PORT set at release time and the real port is fowarded, so the following is needed in settings:

.. code-block:: python

USE_X_FORWARDED_PORT = True

Hooks
-----

Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ authors = [
]
dependencies = [
"wagtail>=5.1",
"pyjwt>=2.0,<3.0"
]
classifiers = [
"Framework :: Django",
Expand Down
14 changes: 14 additions & 0 deletions wagtailsharing/helpers.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
from django.conf import settings

from wagtail.models import Site

import jwt

from wagtailsharing.models import SharingSite


def get_tokenized_sharing_url(sharing_site, page_path):
share_path = getattr(settings, "WAGTAILSHARING_TOKEN_SHARE_PATH", "share")
payload = {"path": page_path}
hash = jwt.encode(payload, settings.SECRET_KEY, algorithm="HS256")
return "/".join([sharing_site.root_url, share_path, hash])


def get_sharing_url(page):
"""Get a sharing URL for a page, if available."""

Expand All @@ -27,4 +38,7 @@ def get_sharing_url(page):
# Site is not shared.
return None

if getattr(settings, "WAGTAILSHARING_TOKENIZE_URL", False):
return get_tokenized_sharing_url(sharing_site, page_path)

return sharing_site.root_url + page_path
20 changes: 19 additions & 1 deletion wagtailsharing/urls.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from django.conf import settings
from django.urls import re_path

from wagtail.urls import serve_pattern
from wagtail.urls import urlpatterns as wagtailcore_urlpatterns

from wagtailsharing.views import ServeView
from wagtailsharing.views import ServeView, TokenServeView


urlpatterns = [
Expand All @@ -12,3 +13,20 @@
else urlpattern
for urlpattern in wagtailcore_urlpatterns
]

if getattr(settings, "WAGTAILSHARING_TOKENIZE_URL", False):
share_path = getattr(settings, "WAGTAILSHARING_TOKEN_SHARE_PATH", "share")
urlpatterns = wagtailcore_urlpatterns + [
re_path(
rf"^{share_path}/([\w\.\-\_]+)/$",
TokenServeView.as_view(),
name="wagtail_serve",
)
]
else:
urlpatterns = [
re_path(serve_pattern, ServeView.as_view(), name="wagtail_serve")
if urlpattern.name == "wagtail_serve"
else urlpattern
for urlpattern in wagtailcore_urlpatterns
]
44 changes: 40 additions & 4 deletions wagtailsharing/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import inspect
import logging

from django.conf import settings
from django.http import Http404, HttpResponse
from django.views.generic import View

Expand All @@ -9,19 +11,26 @@
from wagtail.url_routing import RouteResult
from wagtail.views import serve as wagtail_serve

import jwt

from wagtailsharing.models import SharingSite


class ServeView(View):
def dispatch(self, request, path):
if request.method.upper() != "GET":
return wagtail_serve(request, path)

def get_sharing_site(self, request, path):
try:
sharing_site = SharingSite.find_for_request(request)
except SharingSite.DoesNotExist:
sharing_site = None

return sharing_site

def dispatch(self, request, path):
if request.method.upper() != "GET":
return wagtail_serve(request, path)

sharing_site = self.get_sharing_site(request, path)

if not sharing_site:
return wagtail_serve(request, path)

Expand Down Expand Up @@ -109,3 +118,30 @@ def serve(page, request, args, kwargs):
return result

return response


class TokenServeView(ServeView):
def dispatch(self, request, path):
if request.method.upper() != "GET":
return wagtail_serve(request, path)

sharing_site = self.get_sharing_site(request, path)

if not sharing_site:
return wagtail_serve(request, path)

try:
# Get the wagtail path from the JWT token
data = jwt.decode(path, settings.SECRET_KEY, algorithms=["HS256"])
decoded_path = data["path"]
except Exception as e:
logging.warn(
f"Could not decode Wagtail path from sharing link: {e}"
)
return wagtail_serve(request, path)

page, args, kwargs = self.route(
sharing_site.site, request, decoded_path
)

return self.serve(page, request, args, kwargs)