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.contrib.auth.models import Permission
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 (
OIDCAuthenticationBackend as BaseOIDCAuthenticationBackend,
)
@ -13,8 +16,12 @@ def get_permissions(claims):
if roles is None or settings.OIDC_RP_CLIENT_ID not in roles:
return Permission.objects.none()
return Permission.objects.filter(
codename__in=claims.get("resource_access")[settings.OIDC_RP_CLIENT_ID]["roles"]
return Permission.objects.annotate(
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 %}
<!DOCTYPE html>
<html lang="{{ LANGUAGE_CODE }}">
@ -11,6 +10,8 @@
</head>
<body>
{% block body %}
{% block content %}
{% endblock %}
{% endblock %}
</body>
</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.staticfiles",
"ljg.core.apps.CoreConfig",
"ljg.redirect.apps.RedirectConfig",
"mozilla_django_oidc",
]

View File

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