Implement redirects
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Luca 2023-10-16 21:42:51 +02:00
parent 989453f5e4
commit d17646e79c
15 changed files with 171 additions and 3 deletions

View File

@ -1,6 +1,9 @@
from django.conf import settings from django.conf import settings
from django.contrib.auth.models import Permission from django.contrib.auth.models import Permission
from django.db import transaction from django.db import transaction
from django.db.models import CharField
from django.db.models import Value as V
from django.db.models.functions import Concat
from mozilla_django_oidc.auth import ( from mozilla_django_oidc.auth import (
OIDCAuthenticationBackend as BaseOIDCAuthenticationBackend, OIDCAuthenticationBackend as BaseOIDCAuthenticationBackend,
) )
@ -13,8 +16,12 @@ def get_permissions(claims):
if roles is None or settings.OIDC_RP_CLIENT_ID not in roles: if roles is None or settings.OIDC_RP_CLIENT_ID not in roles:
return Permission.objects.none() return Permission.objects.none()
return Permission.objects.filter( return Permission.objects.annotate(
codename__in=claims.get("resource_access")[settings.OIDC_RP_CLIENT_ID]["roles"] fullname=Concat(
"content_type__app_label", V("."), "codename", output_field=CharField()
)
).filter(
fullname__in=claims.get("resource_access")[settings.OIDC_RP_CLIENT_ID]["roles"]
) )

View File

@ -1,4 +1,3 @@
{% load i18n %}
{% load static %} {% load static %}
<!DOCTYPE html> <!DOCTYPE html>
<html lang="{{ LANGUAGE_CODE }}"> <html lang="{{ LANGUAGE_CODE }}">
@ -11,6 +10,8 @@
</head> </head>
<body> <body>
{% block body %} {% block body %}
{% block content %}
{% endblock %}
{% endblock %} {% endblock %}
</body> </body>
</html> </html>

0
ljg/redirect/__init__.py Normal file
View File

3
ljg/redirect/admin.py Normal file
View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

6
ljg/redirect/apps.py Normal file
View File

@ -0,0 +1,6 @@
from django.apps import AppConfig
class RedirectConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "ljg.redirect"

9
ljg/redirect/forms.py Normal file
View File

@ -0,0 +1,9 @@
from django import forms
from .models import Redirect
class RedirectForm(forms.ModelForm):
class Meta:
model = Redirect
fields = ("target",)

View File

@ -0,0 +1,31 @@
# Generated by Django 4.2.4 on 2023-10-16 18:14
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name="Redirect",
fields=[
("name", models.SlugField(primary_key=True, serialize=False)),
("target", models.URLField()),
(
"owner",
models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to=settings.AUTH_USER_MODEL,
),
),
],
),
]

View File

11
ljg/redirect/models.py Normal file
View File

@ -0,0 +1,11 @@
from django.contrib.auth.models import User
from django.db import models
class Redirect(models.Model):
name = models.SlugField(primary_key=True)
target = models.URLField()
owner = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
def get_absolute_url(self):
return self.target

View File

@ -0,0 +1,13 @@
{% extends "base.html" %}
{% load i18n %}
{% block title %}{{ name }} &ndash; {{ APP_TITLE }}{% endblock %}
{% block content %}
<form method="post">
{% csrf_token %}
{{ form }}
<button type="submit">{% if new %}{% translate "Create redirect" %}{% else %}{% translate "Save redirect" %}{% endif %}</button>
</form>
{% endblock %}

3
ljg/redirect/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

16
ljg/redirect/urls.py Normal file
View File

@ -0,0 +1,16 @@
from django.urls import include, path
from . import views
app_name = "redirect"
urlpatterns = [
path(
"<slug:name>/",
include(
[
path("", views.go, name="go"),
path("manage", views.manage, name="manage"),
]
),
),
]

66
ljg/redirect/views.py Normal file
View File

@ -0,0 +1,66 @@
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.http import Http404
from django.shortcuts import redirect, render
from django.utils.translation import gettext as _
from .forms import RedirectForm
from .models import Redirect
def go(request, name):
try:
obj = Redirect.objects.get(name=name)
except Redirect.DoesNotExist:
if request.user.has_perm("redirect.add_redirect"):
return redirect("redirect:manage", name=name)
raise Http404()
return redirect(obj)
@login_required
def manage(request, name):
try:
obj = Redirect.objects.get(name=name)
except Redirect.DoesNotExist:
obj = None
form = RedirectForm(instance=obj)
if request.method == "POST":
form = RedirectForm(request.POST, instance=obj)
if form.is_valid():
action = "add" if obj is None else "change"
if request.user.has_perm(f"redirect.{action}_redirect"):
obj = form.save(commit=False)
if action == "add":
obj.name = name
obj.owner = request.user
obj.save()
messages.success(
request,
_(
"Successfully %s redirect"
% ("added" if action == "add" else "changed")
),
)
else:
messages.error(
request, _(f"You do not have permission to {action} this redirect.")
)
return redirect("redirect:manage", name=name)
else:
return redirect("redirect:manage", name=name)
return render(
request,
"redirect/manage.html",
{"form": form, "name": name, "new": obj is None},
)

View File

@ -44,6 +44,7 @@ INSTALLED_APPS = [
"django.contrib.messages", "django.contrib.messages",
"django.contrib.staticfiles", "django.contrib.staticfiles",
"ljg.core.apps.CoreConfig", "ljg.core.apps.CoreConfig",
"ljg.redirect.apps.RedirectConfig",
"mozilla_django_oidc", "mozilla_django_oidc",
] ]

View File

@ -18,6 +18,7 @@ from django.contrib import admin
from django.urls import include, path from django.urls import include, path
urlpatterns = [ urlpatterns = [
path("", include("ljg.redirect.urls")),
path("admin/", admin.site.urls), path("admin/", admin.site.urls),
path("oidc/", include("mozilla_django_oidc.urls")), path("oidc/", include("mozilla_django_oidc.urls")),
] ]