feat(models): Add a Profile model

This simplifies the management of the views data
This commit is contained in:
Tom Hubrecht 2024-09-13 16:55:44 +02:00
parent 8599992dd7
commit 7581bf59df
Signed by: thubrecht
SSH key fingerprint: SHA256:r+nK/SIcWlJ0zFZJGHtlAoRwq1Rm+WcKAm5ADYMoQPc
4 changed files with 82 additions and 32 deletions

View file

@ -0,0 +1,37 @@
# Generated by Django 4.2.12 on 2024-09-13 14:30
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="Profile",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"user",
models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL,
),
),
],
),
]

View file

@ -1 +1,31 @@
# Create your models here. # Create your models here.
from dataclasses import dataclass
from functools import cached_property
from typing import Optional
from asgiref.sync import async_to_sync
from django.contrib.auth.models import User
from django.db import models
from kanidm.models.person import Person
from shared.kanidm import client
@dataclass
class KanidmProfile:
person: Person
secret: Optional[str]
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
@cached_property
def kanidm_profile(self):
person = async_to_sync(client.person_account_get)(self.user.username)
data = async_to_sync(client.get_radius_token)(self.user.username).data
secret = data.get("secret") if data is not None else None
return KanidmProfile(person, secret)

View file

@ -1,35 +1,18 @@
# Create your views here.
import json
from typing import Optional
from asgiref.sync import async_to_sync
from django.contrib.auth import get_user_model
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.db.models import QuerySet from django.contrib.auth.models import User
from django.views.generic import DetailView from django.views.generic import TemplateView
from shared.kanidm import client
User = get_user_model()
class ProfileView(LoginRequiredMixin, DetailView): class ProfileView(LoginRequiredMixin, TemplateView):
model = User model = User
template_name = "account/profile.html" template_name = "account/profile.html"
def get_object(self, queryset: Optional[QuerySet] = None): def get_context_data(self, **kwargs):
assert isinstance(self.request.user, User) assert isinstance(self.request.user, User)
return self.request.user return super().get_context_data(
# Pyright throws a fit as it doesn't detect the reverse relation
def get_context_data(self, **kwargs): # giving a user its profile
ctx = super().get_context_data(**kwargs) profile=self.request.user.profile.kanidm_profile, # pyright: ignore
**kwargs
username = self.request.user.get_username() )
ctx["person"] = async_to_sync(client.person_account_get)(username)
content: str = async_to_sync(client.get_radius_token)(username).content
ctx["radius_secret"] = json.loads(content).get("secret")
return ctx

View file

@ -2,24 +2,24 @@
{% block content %} {% block content %}
<h2 class="subtitle"> <h2 class="subtitle">
<span>Profil de {{ person.displayname }}</span> <span>Profil de {{ profile.person.displayname }}</span>
<span class="tag is-primary is-medium is-pulled-right">{{ person.name }}</span> <span class="tag is-primary is-medium is-pulled-right">{{ profile.person.name }}</span>
</h2> </h2>
<hr> <hr>
<h3 class="has-text-weight-bold mb-3">Identifiant unique :</h3> <h3 class="has-text-weight-bold mb-3">Identifiant unique :</h3>
<span class="button is-fullwidth">{{ person.uuid }}</span> <span class="button is-fullwidth">{{ profile.person.uuid }}</span>
<br> <br>
<h3 class="has-text-weight-bold mb-3">Token RADIUS :</h3> <h3 class="has-text-weight-bold mb-3">Token RADIUS :</h3>
<span class="button is-fullwidth">{{ radius_secret }}</span> <span class="button is-fullwidth">{{ profile.secret }}</span>
<br> <br>
<h3 class="has-text-weight-bold mb-3">Membre des groupes suivants :</h3> <h3 class="has-text-weight-bold mb-3">Membre des groupes suivants :</h3>
{% for group in person.memberof %} {% for group in profile.person.memberof %}
<span class="button is-fullwidth">{{ group }}</span><br> <span class="button is-fullwidth">{{ group }}</span><br>
{% endfor %} {% endfor %}
{% endblock content %} {% endblock content %}