forked from DGNum/gestiojeux
feat: switch to authens
Be careful there is no User migration
This commit is contained in:
parent
253acde240
commit
fee31ab07b
23 changed files with 105 additions and 259 deletions
|
@ -1,38 +0,0 @@
|
||||||
from django.contrib import admin
|
|
||||||
from django.contrib.auth.admin import UserAdmin as DjangoUserAdmin
|
|
||||||
from django.utils.translation import gettext_lazy as _
|
|
||||||
from .models import User
|
|
||||||
|
|
||||||
|
|
||||||
class UserAdmin(DjangoUserAdmin):
|
|
||||||
fieldsets = (
|
|
||||||
(None, {"fields": ("email", "password")}),
|
|
||||||
(_("Personal info"), {"fields": ("public_name",)}),
|
|
||||||
(
|
|
||||||
_("Permissions"),
|
|
||||||
{
|
|
||||||
"fields": (
|
|
||||||
"is_active",
|
|
||||||
"is_staff",
|
|
||||||
"is_superuser",
|
|
||||||
"groups",
|
|
||||||
"user_permissions",
|
|
||||||
),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
add_fieldsets = (
|
|
||||||
(
|
|
||||||
None,
|
|
||||||
{
|
|
||||||
"classes": ("wide",),
|
|
||||||
"fields": ("email", "public_name", "password1", "password2"),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
list_display = ("public_name", "email", "is_staff")
|
|
||||||
search_fields = ("public_name", "email")
|
|
||||||
ordering = ("email",)
|
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(User, UserAdmin)
|
|
|
@ -1,7 +0,0 @@
|
||||||
from django_cas_ng.backends import CASBackend as DjangoCasNgBackend
|
|
||||||
|
|
||||||
|
|
||||||
class CasBackend(DjangoCasNgBackend):
|
|
||||||
def clean_username(self, username):
|
|
||||||
# We need to build an email out of the CAS username
|
|
||||||
return username.lower() + "@clipper.ens.fr"
|
|
|
@ -1,5 +1,5 @@
|
||||||
from django.forms import ModelForm, ValidationError
|
from django.forms import ModelForm, ValidationError
|
||||||
from .models import User
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
|
||||||
class AccountSettingsForm(ModelForm):
|
class AccountSettingsForm(ModelForm):
|
||||||
|
@ -7,13 +7,13 @@ class AccountSettingsForm(ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = User
|
model = User
|
||||||
fields = ["public_name"]
|
fields = ["username"]
|
||||||
|
|
||||||
def clean_public_name(self):
|
def clean_public_name(self):
|
||||||
public_name = self.cleaned_data["public_name"]
|
public_name = self.cleaned_data["username"]
|
||||||
public_name = public_name.strip()
|
public_name = public_name.strip()
|
||||||
if (
|
if (
|
||||||
User.objects.filter(public_name=public_name)
|
User.objects.filter(username=public_name)
|
||||||
.exclude(pk=self.instance.pk)
|
.exclude(pk=self.instance.pk)
|
||||||
.exists()
|
.exists()
|
||||||
):
|
):
|
||||||
|
|
16
accounts/migrations/0002_delete_user.py
Normal file
16
accounts/migrations/0002_delete_user.py
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# Generated by Django 4.2.11 on 2024-07-02 20:26
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('accounts', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.DeleteModel(
|
||||||
|
name='User',
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,76 +0,0 @@
|
||||||
from django.db import models
|
|
||||||
from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
|
|
||||||
from django.contrib.auth.models import PermissionsMixin
|
|
||||||
from django.core.mail import send_mail
|
|
||||||
|
|
||||||
|
|
||||||
class User(AbstractBaseUser, PermissionsMixin):
|
|
||||||
USERNAME_FIELD = "email"
|
|
||||||
EMAIL_FIELD = "email"
|
|
||||||
REQUIRED_FIELDS = ["public_name"]
|
|
||||||
MAX_NAME_LENGTH = 150
|
|
||||||
|
|
||||||
email = models.EmailField(verbose_name="adresse email", unique=True)
|
|
||||||
public_name = models.CharField(
|
|
||||||
verbose_name="nom ou pseudo",
|
|
||||||
max_length=MAX_NAME_LENGTH,
|
|
||||||
unique=True,
|
|
||||||
help_text="Ce nom est utilisé pour toutes les interactions publiques sur GestioJeux. Il doit être unique.",
|
|
||||||
)
|
|
||||||
is_staff = models.BooleanField(
|
|
||||||
"statut équipe",
|
|
||||||
default=False,
|
|
||||||
help_text="Précise si l’utilisateur peut se connecter à ce site d'administration.",
|
|
||||||
)
|
|
||||||
is_active = models.BooleanField(
|
|
||||||
"actif",
|
|
||||||
default=True,
|
|
||||||
help_text="Précise si l’utilisateur doit être considéré comme actif. Décochez ceci plutôt que de supprimer le compte.",
|
|
||||||
)
|
|
||||||
|
|
||||||
objects = BaseUserManager()
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = "utilisateur·ice"
|
|
||||||
verbose_name_plural = "utilisateur·ice·s"
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def generate_unique_public_name(cls, base_name):
|
|
||||||
index = 0
|
|
||||||
public_name = base_name
|
|
||||||
while cls.objects.filter(public_name=public_name).exists():
|
|
||||||
index += 1
|
|
||||||
|
|
||||||
# ensure the resulting string is not too long
|
|
||||||
tail_length = len(str(index))
|
|
||||||
combined_length = len(base_name) + tail_length
|
|
||||||
if cls.MAX_NAME_LENGTH < combined_length:
|
|
||||||
base_name = base_name[: cls.MAX_NAME_LENGTH - tail_length]
|
|
||||||
|
|
||||||
public_name = base_name + str(index)
|
|
||||||
|
|
||||||
return public_name
|
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
|
||||||
if not self.public_name:
|
|
||||||
# Fill the public name with a generated one from email address
|
|
||||||
base_name = self.email.split("@")[0]
|
|
||||||
self.public_name = User.generate_unique_public_name(base_name)
|
|
||||||
super().save(*args, **kwargs)
|
|
||||||
|
|
||||||
def get_full_name(self):
|
|
||||||
return self.public_name
|
|
||||||
|
|
||||||
def get_short_name(self):
|
|
||||||
return self.public_name
|
|
||||||
|
|
||||||
def email_user(self, subject, message, from_email=None, **kwargs):
|
|
||||||
"""Send an email to this user."""
|
|
||||||
send_mail(subject, message, from_email, [self.email], **kwargs)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def normalize_username(cls, username):
|
|
||||||
return super().normalize_username(username.lower())
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.public_name
|
|
|
@ -3,7 +3,7 @@
|
||||||
{% block "content" %}
|
{% block "content" %}
|
||||||
<h1>Paramètres du compte</h1>
|
<h1>Paramètres du compte</h1>
|
||||||
|
|
||||||
<p>Vous êtes connecté en tant que <tt>{{ request.user.email }}</tt></p>
|
<p>Vous êtes connecté en tant que <tt>{{ request.user }}</tt></p>
|
||||||
|
|
||||||
<form method="post">
|
<form method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
{% extends "small_page.html" %}
|
|
||||||
|
|
||||||
{% block "content" %}
|
|
||||||
<h1>Changement de mot de passe</h1>
|
|
||||||
|
|
||||||
<form method="post">
|
|
||||||
{% csrf_token %}
|
|
||||||
{{ form.as_p }}
|
|
||||||
<button type="submit">Changer de mot de passe</button>
|
|
||||||
</form>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
{% extends "small_page.html" %}
|
|
||||||
|
|
||||||
{% block "content" %}
|
|
||||||
<h1>Connexion par mot de passe</h1>
|
|
||||||
|
|
||||||
<form method="post">
|
|
||||||
{% csrf_token %}
|
|
||||||
{{ form.as_p }}
|
|
||||||
<button type="submit">Connexion</button>
|
|
||||||
<input type="hidden" name="next" value="{{ next }}" />
|
|
||||||
</form>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
{% extends "small_page.html" %}
|
|
||||||
|
|
||||||
{% block "content" %}
|
|
||||||
<h1>Mode de connexion</h1>
|
|
||||||
|
|
||||||
<a class="button" href="{{ cas_url }}">
|
|
||||||
Compte clipper
|
|
||||||
</a>
|
|
||||||
<a class="button" href="{{ pass_url }}">
|
|
||||||
Mot de passe
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<p>Si vous êtes exté·e et que vous n'avez pas encore de compte, demandez en un.</p>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
|
@ -1,25 +1,9 @@
|
||||||
from django.urls import include, path
|
from django.urls import include, path
|
||||||
import django.contrib.auth.views as dj_auth_views
|
from .views import PasswordChangeView, AccountSettingsView
|
||||||
from .views import LoginView, LogoutView, PasswordChangeView, AccountSettingsView
|
|
||||||
import django_cas_ng.views
|
|
||||||
|
|
||||||
app_name = "accounts"
|
app_name = "accounts"
|
||||||
|
|
||||||
cas_patterns = [
|
|
||||||
path("login/", django_cas_ng.views.LoginView.as_view(), name="cas_ng_login"),
|
|
||||||
path("logout/", django_cas_ng.views.LogoutView.as_view(), name="cas_ng_logout"),
|
|
||||||
path(
|
|
||||||
"callback/",
|
|
||||||
django_cas_ng.views.CallbackView.as_view(),
|
|
||||||
name="cas_ng_proxy_callback",
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
||||||
accounts_patterns = [
|
accounts_patterns = [
|
||||||
path("cas/", include(cas_patterns)),
|
|
||||||
path("login/", LoginView.as_view(), name="login"),
|
|
||||||
path("logout/", LogoutView.as_view(), name="logout"),
|
|
||||||
path("password_login/", dj_auth_views.LoginView.as_view(), name="password_login"),
|
|
||||||
path("change_password/", PasswordChangeView.as_view(), name="change_password"),
|
path("change_password/", PasswordChangeView.as_view(), name="change_password"),
|
||||||
path("settings/", AccountSettingsView.as_view(), name="account_settings"),
|
path("settings/", AccountSettingsView.as_view(), name="account_settings"),
|
||||||
]
|
]
|
||||||
|
|
|
@ -14,59 +14,6 @@ from urllib.parse import quote as urlquote
|
||||||
from .forms import AccountSettingsForm
|
from .forms import AccountSettingsForm
|
||||||
|
|
||||||
|
|
||||||
class LoginView(TemplateView):
|
|
||||||
template_name = "registration/login_switch.html"
|
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
|
||||||
if request.user.is_authenticated:
|
|
||||||
return redirect(self.get_next_url() or "/")
|
|
||||||
|
|
||||||
return super().dispatch(request, *args, **kwargs)
|
|
||||||
|
|
||||||
def get_next_url(self):
|
|
||||||
if self.request.method == "GET":
|
|
||||||
req_dict = self.request.GET
|
|
||||||
elif self.request.method == "POST":
|
|
||||||
req_dict = self.request.POST
|
|
||||||
return req_dict.get("next")
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
context = super().get_context_data(**kwargs)
|
|
||||||
|
|
||||||
next_url = self.get_next_url()
|
|
||||||
if next_url:
|
|
||||||
context["pass_url"] = "{}?next={}".format(
|
|
||||||
reverse("accounts:password_login"), urlquote(next_url, safe="")
|
|
||||||
)
|
|
||||||
context["cas_url"] = "{}?next={}".format(
|
|
||||||
reverse("accounts:cas_ng_login"), urlquote(next_url, safe="")
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
context["pass_url"] = reverse("accounts:password_login")
|
|
||||||
context["cas_url"] = reverse("accounts:cas_ng_login")
|
|
||||||
|
|
||||||
return context
|
|
||||||
|
|
||||||
|
|
||||||
class LogoutView(RedirectView):
|
|
||||||
permanent = False
|
|
||||||
|
|
||||||
def get_redirect_url(self, *args, **kwargs):
|
|
||||||
CAS_BACKEND_NAME = "accounts.backends.CasBackend"
|
|
||||||
if self.request.session["_auth_user_backend"] != CAS_BACKEND_NAME:
|
|
||||||
auth_logout(self.request)
|
|
||||||
if "next" in self.request.GET:
|
|
||||||
return self.request.GET["next"]
|
|
||||||
return reverse("website:home")
|
|
||||||
|
|
||||||
if "next" in self.request.GET:
|
|
||||||
return "{}?next={}".format(
|
|
||||||
reverse("accounts:cas_ng_logout"),
|
|
||||||
urlquote(self.request.GET["next"], safe=""),
|
|
||||||
)
|
|
||||||
return reverse("accounts:cas_ng_logout")
|
|
||||||
|
|
||||||
|
|
||||||
@receiver(user_logged_in)
|
@receiver(user_logged_in)
|
||||||
def on_login(request, user, **kwargs):
|
def on_login(request, user, **kwargs):
|
||||||
messages.success(request, "Connexion réussie. Bienvenue, {}.".format(user))
|
messages.success(request, "Connexion réussie. Bienvenue, {}.".format(user))
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
from django.contrib.auth.models import User
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from accounts.models import User
|
|
||||||
|
|
||||||
|
|
||||||
class AbstractComment(models.Model):
|
class AbstractComment(models.Model):
|
||||||
|
|
|
@ -34,6 +34,6 @@
|
||||||
<button type="submit"><i class="fa fa-paper-plane" aria-hidden="true"></i> Envoyer le commentaire</button>
|
<button type="submit"><i class="fa fa-paper-plane" aria-hidden="true"></i> Envoyer le commentaire</button>
|
||||||
</form>
|
</form>
|
||||||
{% else %}
|
{% else %}
|
||||||
<p><a href="{% url "accounts:login" %}?next={{ request.get_full_path }}">Connectez-vous</a> pour ajouter un commentaire.</p>
|
<p><a href="{% url "authens:login" %}?next={{ request.get_full_path }}">Connectez-vous</a> pour ajouter un commentaire.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -7,13 +7,14 @@ let
|
||||||
nix-pkgs = import sources.nix-pkgs { inherit pkgs; };
|
nix-pkgs = import sources.nix-pkgs { inherit pkgs; };
|
||||||
|
|
||||||
python3 = pkgs.python3.override {
|
python3 = pkgs.python3.override {
|
||||||
packageOverrides = _: _: {
|
packageOverrides = final: _: {
|
||||||
inherit (nix-pkgs)
|
inherit (nix-pkgs)
|
||||||
django-autoslug
|
django-autoslug
|
||||||
django-cas-ng
|
|
||||||
loadcredential
|
loadcredential
|
||||||
markdown-icons
|
markdown-icons
|
||||||
|
python-cas
|
||||||
;
|
;
|
||||||
|
authens = final.callPackage ./nix/authens {};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
|
@ -25,9 +26,9 @@ in
|
||||||
packages = [
|
packages = [
|
||||||
(python3.withPackages (ps: [
|
(python3.withPackages (ps: [
|
||||||
ps.django
|
ps.django
|
||||||
|
ps.django-types
|
||||||
ps.django-autoslug
|
ps.django-autoslug
|
||||||
ps.loadcredential
|
ps.loadcredential
|
||||||
ps.django-cas-ng
|
|
||||||
ps.django-cleanup
|
ps.django-cleanup
|
||||||
ps.django-haystack
|
ps.django-haystack
|
||||||
ps.django-markdownx
|
ps.django-markdownx
|
||||||
|
@ -35,6 +36,7 @@ in
|
||||||
ps.pillow
|
ps.pillow
|
||||||
ps.whoosh
|
ps.whoosh
|
||||||
ps.markdown-icons
|
ps.markdown-icons
|
||||||
|
ps.authens
|
||||||
|
|
||||||
# Django haystack is drunk
|
# Django haystack is drunk
|
||||||
ps.setuptools
|
ps.setuptools
|
||||||
|
|
|
@ -12,6 +12,7 @@ https://docs.djangoproject.com/en/3.0/ref/settings/
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
from django.urls import reverse_lazy
|
||||||
from loadcredential import Credentials
|
from loadcredential import Credentials
|
||||||
|
|
||||||
# Secrets
|
# Secrets
|
||||||
|
@ -80,7 +81,6 @@ INSTALLED_APPS = [
|
||||||
"django.contrib.sessions",
|
"django.contrib.sessions",
|
||||||
"django.contrib.messages",
|
"django.contrib.messages",
|
||||||
"django.contrib.staticfiles",
|
"django.contrib.staticfiles",
|
||||||
"django_cas_ng",
|
|
||||||
"django_tables2",
|
"django_tables2",
|
||||||
"markdownx",
|
"markdownx",
|
||||||
"haystack",
|
"haystack",
|
||||||
|
@ -91,6 +91,7 @@ INSTALLED_APPS = [
|
||||||
"suggestions",
|
"suggestions",
|
||||||
"loans",
|
"loans",
|
||||||
"django_cleanup", # Keep last
|
"django_cleanup", # Keep last
|
||||||
|
"authens",
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
|
@ -101,7 +102,6 @@ MIDDLEWARE = [
|
||||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||||
"django.contrib.messages.middleware.MessageMiddleware",
|
"django.contrib.messages.middleware.MessageMiddleware",
|
||||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||||
"django_cas_ng.middleware.CASMiddleware",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
ROOT_URLCONF = "gestiojeux.urls"
|
ROOT_URLCONF = "gestiojeux.urls"
|
||||||
|
@ -124,11 +124,12 @@ TEMPLATES = [
|
||||||
|
|
||||||
WSGI_APPLICATION = "gestiojeux.wsgi.application"
|
WSGI_APPLICATION = "gestiojeux.wsgi.application"
|
||||||
|
|
||||||
AUTH_USER_MODEL = "accounts.User"
|
# Authentication backends
|
||||||
|
|
||||||
AUTHENTICATION_BACKENDS = (
|
AUTHENTICATION_BACKENDS = (
|
||||||
"django.contrib.auth.backends.ModelBackend",
|
"django.contrib.auth.backends.ModelBackend",
|
||||||
"accounts.backends.CasBackend",
|
"authens.backends.ENSCASBackend",
|
||||||
|
"authens.backends.OldCASBackend",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Password validation
|
# Password validation
|
||||||
|
@ -143,7 +144,11 @@ AUTH_PASSWORD_VALIDATORS = [
|
||||||
{"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"},
|
{"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"},
|
||||||
]
|
]
|
||||||
|
|
||||||
LOGIN_URL = "accounts:login"
|
LOGIN_URL = reverse_lazy("authens:login")
|
||||||
|
|
||||||
|
LOGIN_REDIRECT_URL = reverse_lazy("website:home")
|
||||||
|
|
||||||
|
LOGOUT_REDIRECT_URL = reverse_lazy("website:home")
|
||||||
|
|
||||||
# Use markdown extensions
|
# Use markdown extensions
|
||||||
MARKDOWNX_MARKDOWN_EXTENSIONS = [
|
MARKDOWNX_MARKDOWN_EXTENSIONS = [
|
||||||
|
@ -185,12 +190,4 @@ MEDIA_URL = "/media/"
|
||||||
STATIC_ROOT = os.path.join(PUBLIC_DIR, "static")
|
STATIC_ROOT = os.path.join(PUBLIC_DIR, "static")
|
||||||
MEDIA_ROOT = os.path.join(PUBLIC_DIR, "media")
|
MEDIA_ROOT = os.path.join(PUBLIC_DIR, "media")
|
||||||
|
|
||||||
# CAS settings
|
|
||||||
|
|
||||||
CAS_SERVER_URL = "https://cas.eleves.ens.fr/"
|
|
||||||
CAS_VERIFY_URL = "https://cas.eleves.ens.fr/"
|
|
||||||
CAS_VERSION = "CAS_2_SAML_1_0"
|
|
||||||
CAS_IGNORE_REFERER = True
|
|
||||||
CAS_LOGIN_MSG = None
|
|
||||||
CAS_LOGIN_URL_NAME = "accounts:cas_ng_login"
|
|
||||||
CAS_LOGOUT_URL_NAME = "accounts:cas_ng_logout"
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ urlpatterns = [
|
||||||
path("inventory/", include("inventory.urls")),
|
path("inventory/", include("inventory.urls")),
|
||||||
path("suggestions/", include("suggestions.urls")),
|
path("suggestions/", include("suggestions.urls")),
|
||||||
path("account/", include("accounts.urls")),
|
path("account/", include("accounts.urls")),
|
||||||
|
path("authens/", include("authens.urls")),
|
||||||
path("", include("website.urls")),
|
path("", include("website.urls")),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
15
nix/authens/01-get-success_url.patch
Normal file
15
nix/authens/01-get-success_url.patch
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
diff --git a/authens/views.py b/authens/views.py
|
||||||
|
index 0478861..b1c93e9 100644
|
||||||
|
--- a/authens/views.py
|
||||||
|
+++ b/authens/views.py
|
||||||
|
@@ -138,8 +138,8 @@ class LogoutView(auth_views.LogoutView):
|
||||||
|
else:
|
||||||
|
self.cas_connected = False
|
||||||
|
|
||||||
|
- def get_next_page(self):
|
||||||
|
- next_page = super().get_next_page()
|
||||||
|
+ def get_success_url(self):
|
||||||
|
+ next_page = super().get_success_url()
|
||||||
|
if self.cas_connected:
|
||||||
|
cas_client = get_cas_client(self.request)
|
||||||
|
|
22
nix/authens/default.nix
Normal file
22
nix/authens/default.nix
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
python-cas,
|
||||||
|
django,
|
||||||
|
ldap,
|
||||||
|
buildPythonPackage,
|
||||||
|
}:
|
||||||
|
buildPythonPackage rec {
|
||||||
|
pname = "authens";
|
||||||
|
version = "v0.1b5";
|
||||||
|
doCheck = false;
|
||||||
|
patches = [ ./01-get-success_url.patch ];
|
||||||
|
src = builtins.fetchGit {
|
||||||
|
url = "https://git.eleves.ens.fr/klub-dev-ens/authens.git";
|
||||||
|
#rev = "master";
|
||||||
|
#sha256 = "sha256-R0Nw212/BOPHfpspT5wzxtji1vxZ/JOuwr00naklWE8=";
|
||||||
|
};
|
||||||
|
propagatedBuildInputs = [
|
||||||
|
django
|
||||||
|
ldap
|
||||||
|
python-cas
|
||||||
|
];
|
||||||
|
}
|
23
nix/python-cas/default.nix
Normal file
23
nix/python-cas/default.nix
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
requests,
|
||||||
|
lxml,
|
||||||
|
six,
|
||||||
|
buildPythonPackage,
|
||||||
|
fetchFromGitHub,
|
||||||
|
}:
|
||||||
|
buildPythonPackage rec {
|
||||||
|
pname = "python-cas";
|
||||||
|
version = "1.6.0";
|
||||||
|
doCheck = false;
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "python-cas";
|
||||||
|
repo = "python-cas";
|
||||||
|
rev = "v1.6.0";
|
||||||
|
sha512 = "sha512-qnYzgwELUij2EdqA6H17q8vnNUsfI7DkbZSI8CCIGfXOM+cZ7vsWe7CJxzsDUw73sBPB4+zzpLxvb7tpm/IDeg==";
|
||||||
|
};
|
||||||
|
propagatedBuildInputs = [
|
||||||
|
requests
|
||||||
|
lxml
|
||||||
|
six
|
||||||
|
];
|
||||||
|
}
|
|
@ -4,7 +4,7 @@ from django.core.validators import MinValueValidator
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from autoslug import AutoSlugField
|
from autoslug import AutoSlugField
|
||||||
from website.validators import MaxFileSizeValidator
|
from website.validators import MaxFileSizeValidator
|
||||||
from accounts.models import User
|
from django.contrib.auth.models import User
|
||||||
from inventory.models import Category, Tag
|
from inventory.models import Category, Tag
|
||||||
from comments.models import AbstractComment
|
from comments.models import AbstractComment
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
<a class="button" href="{% url "suggestions:upvote_suggestion" suggestion.slug %}"><i class="fa fa-thumbs-up" aria-hidden="true"></i> Voter pour acheter ce jeu</a>
|
<a class="button" href="{% url "suggestions:upvote_suggestion" suggestion.slug %}"><i class="fa fa-thumbs-up" aria-hidden="true"></i> Voter pour acheter ce jeu</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<p><a href="{% url "accounts:login" %}?next={{ request.get_full_path }}">Connectez-vous</a> pour voter pour une suggestion.</p>
|
<p><a href="{% url "authens:login" %}?next={{ request.get_full_path }}">Connectez-vous</a> pour voter pour une suggestion.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if suggestion.description %}
|
{% if suggestion.description %}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<p>Vous n'avez pas la permission pour consulter cette page.</p>
|
<p>Vous n'avez pas la permission pour consulter cette page.</p>
|
||||||
{% if not user.is_authenticated %}
|
{% if not user.is_authenticated %}
|
||||||
<p>Cet accès vous est probablement refusé car vous n'êtes actuellement pas connecté·e.
|
<p>Cet accès vous est probablement refusé car vous n'êtes actuellement pas connecté·e.
|
||||||
Vous pouvez vous rendre à la page de <a href="{% url "accounts:login" %}?next={{ request.get_full_path }}">connexion</a>.</p>
|
Vous pouvez vous rendre à la page de <a href="{% url "authens:login" %}?next={{ request.get_full_path }}">connexion</a>.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<p>Vous pouvez retourner sur la <a href="{% url "website:home" %}">page d'accueil</a>.</p>
|
<p>Vous pouvez retourner sur la <a href="{% url "website:home" %}">page d'accueil</a>.</p>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -21,9 +21,9 @@
|
||||||
<div id="account">
|
<div id="account">
|
||||||
{% if request.user.is_authenticated %}
|
{% if request.user.is_authenticated %}
|
||||||
<a class="username" href="{% url "accounts:account_settings" %}">{{ request.user }}</a>
|
<a class="username" href="{% url "accounts:account_settings" %}">{{ request.user }}</a>
|
||||||
<a class="logout" href="{% url "accounts:logout" %}?next={{ request.get_full_path }}"><i class="fa fa-sign-out" aria-hidden="true"></i></a>
|
<a class="logout" href="{% url "authens:logout" %}?next={{ request.get_full_path }}"><i class="fa fa-sign-out" aria-hidden="true"></i></a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a class="login{% if url_name == "login" %} current{% endif %}" href="{% url "accounts:login" %}?next={{ request.get_full_path }}">Connexion</a>
|
<a class="login{% if url_name == "login" %} current{% endif %}" href="{% url "authens:login" %}?next={{ request.get_full_path }}">Connexion</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
|
|
Loading…
Add table
Reference in a new issue