feat: Add trust bridge and user activation
This commit is contained in:
parent
74afc805dc
commit
0f1cd98a80
8 changed files with 78 additions and 52 deletions
|
@ -43,12 +43,14 @@ export class User {
|
|||
email: string | undefined;
|
||||
password: string | undefined;
|
||||
username: string | null = null;
|
||||
confidantEmail: string | null = null;
|
||||
isAuthenticated = false;
|
||||
isTrusted = false;
|
||||
private token = "";
|
||||
|
||||
static async confirm(uid: string, token: string): Promise<void> {
|
||||
await api_request("POST", "users/activation", 204, { uid, token });
|
||||
async activate(): Promise<void> {
|
||||
await api_request("POST", "users/activate", 204, {
|
||||
password: this.password,
|
||||
});
|
||||
}
|
||||
|
||||
async login(): Promise<void> {
|
||||
|
@ -84,7 +86,6 @@ export class User {
|
|||
200,
|
||||
{
|
||||
username: this.username,
|
||||
confidant_email: this.confidantEmail,
|
||||
},
|
||||
this.token
|
||||
);
|
||||
|
|
|
@ -1,20 +1,8 @@
|
|||
<template>
|
||||
<div>
|
||||
<b-notification
|
||||
v-if="!user.username"
|
||||
type="is-warning"
|
||||
aria-close-label="Close notification"
|
||||
>
|
||||
Um dein Konto zu aktivieren, musst du einen
|
||||
<strong>Benutzernamen</strong> festlegen.
|
||||
</b-notification>
|
||||
<b-notification
|
||||
v-if="!user.confidant_email"
|
||||
type="is-warning"
|
||||
aria-close-label="Close notification"
|
||||
>
|
||||
Um dein Konto zu aktivieren, musst du eine
|
||||
<strong>Vertrauensperson</strong> angeben.
|
||||
<b-notification type="is-info" aria-close-label="Close notification">
|
||||
Dein Konto ist noch nicht aktiv.
|
||||
<a @click="activate()">Jetzt aktivieren</a>
|
||||
</b-notification>
|
||||
<table class="table is-fullwidth">
|
||||
<tbody>
|
||||
|
@ -34,10 +22,6 @@
|
|||
<inline-editor v-model="user.confidantEmail" @input="user.save()" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>E-Mail-Adresse</td>
|
||||
<td>{{ user.email }} (bestätigt)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
@ -53,5 +37,9 @@ import InlineEditor from "@/components/InlineEditor.vue";
|
|||
})
|
||||
export default class UserTable extends Vue {
|
||||
@Prop() private user!: User;
|
||||
|
||||
async activate(): Promise<void> {
|
||||
await this.user.activate();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from django.contrib import admin
|
||||
|
||||
from userausfall.models import User
|
||||
from userausfall.models import User, TrustBridge
|
||||
|
||||
admin.site.register(TrustBridge)
|
||||
admin.site.register(User)
|
||||
|
|
29
userausfall/migrations/0010_auto_20210802_1131.py
Normal file
29
userausfall/migrations/0010_auto_20210802_1131.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
# Generated by Django 2.2.20 on 2021-08-02 11:31
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('userausfall', '0009_auto_20210802_0745'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='user',
|
||||
name='confidant',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='user',
|
||||
name='confidant_unconfirmed',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='user',
|
||||
name='email',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='user',
|
||||
name='email_unconfirmed',
|
||||
),
|
||||
]
|
23
userausfall/migrations/0011_trustbridge.py
Normal file
23
userausfall/migrations/0011_trustbridge.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Generated by Django 2.2.20 on 2021-08-02 11:41
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('userausfall', '0010_auto_20210802_1131'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='TrustBridge',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('is_trusted', models.BooleanField(default=False)),
|
||||
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='trust_bridge', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
]
|
|
@ -66,28 +66,16 @@ class User(AbstractBaseUser, PermissionsMixin):
|
|||
unique=True,
|
||||
blank=True,
|
||||
)
|
||||
email = models.EmailField(_("email address"), blank=True)
|
||||
email_unconfirmed = models.EmailField(_("email address"), blank=True)
|
||||
is_staff = models.BooleanField(
|
||||
_("staff status"),
|
||||
default=False,
|
||||
help_text=_("Designates whether the user can log into this admin site."),
|
||||
)
|
||||
date_joined = models.DateTimeField(_("date joined"), default=timezone.now)
|
||||
confidant = models.ForeignKey(
|
||||
"User", on_delete=models.SET_NULL, null=True, blank=True, related_name="confidants"
|
||||
)
|
||||
confidant_unconfirmed = models.ForeignKey(
|
||||
"User",
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name="unconfirmed_confidants",
|
||||
)
|
||||
|
||||
objects = UserManager()
|
||||
|
||||
EMAIL_FIELD = "email"
|
||||
# EMAIL_FIELD = "email"
|
||||
USERNAME_FIELD = "username"
|
||||
REQUIRED_FIELDS = []
|
||||
|
||||
|
@ -95,13 +83,6 @@ class User(AbstractBaseUser, PermissionsMixin):
|
|||
verbose_name = _("user")
|
||||
verbose_name_plural = _("users")
|
||||
|
||||
@property
|
||||
def confidant_email(self):
|
||||
if self.confidant is not None:
|
||||
return self.confidant.email
|
||||
else:
|
||||
return None
|
||||
|
||||
def clean(self):
|
||||
super().clean()
|
||||
self.email = self.__class__.objects.normalize_email(self.email)
|
||||
|
@ -114,10 +95,13 @@ class User(AbstractBaseUser, PermissionsMixin):
|
|||
"""Create the LDAP account which corresponds to this user."""
|
||||
if not self.username:
|
||||
raise MissingUserAttribute("User is missing a username.")
|
||||
if not self.confidant:
|
||||
raise MissingUserAttribute("User is missing a confirmed confidant.")
|
||||
if not self.check_password(raw_password):
|
||||
raise PasswordMismatch(
|
||||
"The given password does not match the user's password."
|
||||
)
|
||||
return ldap.create_account(self.username, raw_password)
|
||||
|
||||
|
||||
class TrustBridge(models.Model):
|
||||
user = models.OneToOneField("User", on_delete=models.CASCADE, related_name="trust_bridge")
|
||||
is_trusted = models.BooleanField(default=False)
|
||||
|
|
|
@ -14,13 +14,13 @@ class ConfidantConfirmationView(ConfirmationView):
|
|||
|
||||
|
||||
class UserViewSet(viewsets.ModelViewSet):
|
||||
permission_classes = [UserPermission]
|
||||
# permission_classes = [UserPermission]
|
||||
queryset = User.objects.all()
|
||||
|
||||
@action(detail=True, methods=["post"])
|
||||
@action(detail=False, methods=["post"])
|
||||
def activate(self, request, pk=None):
|
||||
"""Create the corresponding LDAP account."""
|
||||
user: User = self.get_object()
|
||||
user: User = request.user # self.get_object()
|
||||
serializer = UserActivationSerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
try:
|
||||
|
|
|
@ -2,10 +2,10 @@ from django.db.models.signals import post_save
|
|||
from django.dispatch import receiver
|
||||
|
||||
from userausfall.models import User
|
||||
from userausfall.confirmations import ConfidantConfirmation
|
||||
|
||||
|
||||
@receiver(post_save, sender=User)
|
||||
def user_saved(sender, instance: User, **kwargs):
|
||||
if instance.confidant_unconfirmed is not None:
|
||||
ConfidantConfirmation(instance.confidant_unconfirmed, instance).send_request()
|
||||
# if instance.confidant_unconfirmed is not None:
|
||||
# ConfidantConfirmation(instance.confidant_unconfirmed, instance).send_request()
|
||||
pass
|
||||
|
|
Reference in a new issue