105 lines
3.9 KiB
Python
105 lines
3.9 KiB
Python
# combo - content management system
|
|
# Copyright (C) 2015-2018 Entr'ouvert
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify it
|
|
# under the terms of the GNU Affero General Public License as published
|
|
# by the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU Affero General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
import base64
|
|
import json
|
|
|
|
from django.conf import settings
|
|
|
|
from django.http import HttpResponse, HttpResponseForbidden, Http404, JsonResponse
|
|
from django.template.loader import get_template, TemplateDoesNotExist
|
|
from django.utils.encoding import force_text, force_bytes
|
|
from django.views.decorators.csrf import csrf_exempt
|
|
from django.views.generic import TemplateView
|
|
|
|
from cryptography.hazmat.primitives import serialization
|
|
from py_vapid import Vapid
|
|
|
|
from .models import PushSubscription, PwaSettings
|
|
from combo import VERSION
|
|
|
|
|
|
def manifest_json(request, *args, **kwargs):
|
|
try:
|
|
template = get_template('combo/manifest.json')
|
|
except TemplateDoesNotExist:
|
|
raise Http404()
|
|
context = {
|
|
'site_base': request.build_absolute_uri('/')[:-1],
|
|
}
|
|
return HttpResponse(template.render(context, request), content_type='application/json')
|
|
|
|
|
|
def js_response(request, template_name, **kwargs):
|
|
template = get_template(template_name)
|
|
pwa_vapid_public_key = None
|
|
pwa_settings = PwaSettings.singleton()
|
|
if pwa_settings.push_notifications:
|
|
if settings.PWA_VAPID_PUBLIK_KEY: # legacy
|
|
pwa_vapid_public_key = settings.PWA_VAPID_PUBLIK_KEY
|
|
elif hasattr(serialization.Encoding, 'X962'):
|
|
pwa_vapid_public_key = force_text(
|
|
base64.urlsafe_b64encode(
|
|
Vapid.from_pem(pwa_settings.push_notifications_infos['private_key'].encode('ascii')
|
|
).private_key.public_key().public_bytes(
|
|
encoding=serialization.Encoding.X962,
|
|
format=serialization.PublicFormat.UncompressedPoint)).strip(b'='))
|
|
context = {
|
|
'pwa_vapid_public_key': pwa_vapid_public_key,
|
|
'pwa_notification_badge_url': settings.PWA_NOTIFICATION_BADGE_URL,
|
|
'pwa_notification_icon_url': settings.PWA_NOTIFICATION_ICON_URL,
|
|
}
|
|
context.update(kwargs)
|
|
return HttpResponse(template.render(context, request),
|
|
content_type='application/javascript; charset=utf-8')
|
|
|
|
|
|
def service_worker_js(request, *args, **kwargs):
|
|
pwa_settings = PwaSettings.singleton()
|
|
if pwa_settings.id:
|
|
version = '%s-%s' % (VERSION, pwa_settings.last_update_timestamp)
|
|
else:
|
|
version = VERSION
|
|
return js_response(request, 'combo/service-worker.js',
|
|
version=version)
|
|
|
|
|
|
def service_worker_registration_js(request, *args, **kwargs):
|
|
return js_response(request, 'combo/service-worker-registration.js')
|
|
|
|
|
|
@csrf_exempt
|
|
def subscribe_push(request, *args, **kwargs):
|
|
if not (request.user and request.user.is_authenticated):
|
|
return HttpResponseForbidden()
|
|
if request.method != 'POST':
|
|
return HttpResponseForbidden()
|
|
subscription_data = json.loads(force_text(request.body))
|
|
if subscription_data is None:
|
|
PushSubscription.objects.filter(user=request.user).delete()
|
|
else:
|
|
subscription, created = PushSubscription.objects.get_or_create(
|
|
user=request.user,
|
|
subscription_info=subscription_data)
|
|
subscription.save()
|
|
return JsonResponse({'err': 0})
|
|
|
|
|
|
class OfflinePage(TemplateView):
|
|
template_name = 'combo/pwa/offline.html'
|
|
|
|
offline_page = OfflinePage.as_view()
|