all: fully switch to Invitation
This commit is contained in:
parent
57f285ae54
commit
d0099edac4
|
@ -35,9 +35,10 @@ urlpatterns = [
|
|||
path('providers/<int:pk>/delete/',
|
||||
providers.ProviderDeleteView.as_view(), name='provider-delete'),
|
||||
# Invitations
|
||||
path('invitations/', invitations.InviteListView.as_view(), name='invitations'),
|
||||
path('invitations/create/', invitations.InviteCreateView.as_view(), name='invitation-create'),
|
||||
path('invitations/', invitations.InvitationListView.as_view(), name='invitations'),
|
||||
path('invitations/create/',
|
||||
invitations.InvitationCreateView.as_view(), name='invitation-create'),
|
||||
path('invitations/<uuid:pk>/delete/',
|
||||
invitations.InviteDeleteView.as_view(), name='invitation-delete'),
|
||||
invitations.InvitationDeleteView.as_view(), name='invitation-delete'),
|
||||
# path('api/v1/', include('passbook.admin.api.v1.urls'))
|
||||
]
|
||||
|
|
|
@ -1,38 +1,40 @@
|
|||
"""passbook Invite administration"""
|
||||
"""passbook Invitation administration"""
|
||||
from django.contrib.messages.views import SuccessMessageMixin
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.views.generic import CreateView, DeleteView, ListView, UpdateView
|
||||
from django.views.generic import CreateView, DeleteView, ListView
|
||||
|
||||
from passbook.admin.mixins import AdminRequiredMixin
|
||||
from passbook.core.forms.invitations import InviteForm
|
||||
from passbook.core.models import Invite
|
||||
from passbook.core.forms.invitations import InvitationForm
|
||||
from passbook.core.models import Invitation
|
||||
|
||||
|
||||
class InviteListView(AdminRequiredMixin, ListView):
|
||||
class InvitationListView(AdminRequiredMixin, ListView):
|
||||
"""Show list of all invitations"""
|
||||
|
||||
model = Invite
|
||||
model = Invitation
|
||||
template_name = 'administration/invitation/list.html'
|
||||
|
||||
|
||||
class InviteCreateView(SuccessMessageMixin, AdminRequiredMixin, CreateView):
|
||||
"""Create new Invite"""
|
||||
class InvitationCreateView(SuccessMessageMixin, AdminRequiredMixin, CreateView):
|
||||
"""Create new Invitation"""
|
||||
|
||||
template_name = 'generic/create.html'
|
||||
success_url = reverse_lazy('passbook_admin:invitations')
|
||||
success_message = _('Successfully created Invite')
|
||||
form_class = InviteForm
|
||||
success_message = _('Successfully created Invitation')
|
||||
form_class = InvitationForm
|
||||
|
||||
def get_initial(self):
|
||||
return {
|
||||
'created_by': self.request.user
|
||||
}
|
||||
def form_valid(self, form):
|
||||
obj = form.save(commit=False)
|
||||
obj.created_by = self.request.user
|
||||
obj.save()
|
||||
return HttpResponseRedirect(self.success_url)
|
||||
|
||||
class InviteDeleteView(SuccessMessageMixin, AdminRequiredMixin, DeleteView):
|
||||
class InvitationDeleteView(SuccessMessageMixin, AdminRequiredMixin, DeleteView):
|
||||
"""Delete invitation"""
|
||||
|
||||
model = Invite
|
||||
model = Invitation
|
||||
template_name = 'generic/delete.html'
|
||||
success_url = reverse_lazy('passbook_admin:invitations')
|
||||
success_message = _('Successfully updated Invite')
|
||||
success_message = _('Successfully updated Invitation')
|
||||
|
|
18
passbook/audit/migrations/0004_auto_20181210_1348.py
Normal file
18
passbook/audit/migrations/0004_auto_20181210_1348.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 2.1.4 on 2018-12-10 13:48
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('passbook_audit', '0003_auto_20181210_1213'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='auditentry',
|
||||
name='action',
|
||||
field=models.TextField(choices=[('login', 'login'), ('login_failed', 'login_failed'), ('logout', 'logout'), ('authorize_application', 'authorize_application'), ('suspicious_request', 'suspicious_request'), ('sign_up', 'sign_up'), ('password_reset', 'password_reset'), ('invitation_created', 'invitation_created'), ('invitation_used', 'invitation_used')]),
|
||||
),
|
||||
]
|
|
@ -25,12 +25,12 @@ def on_user_signed_up(sender, request, user, **kwargs):
|
|||
|
||||
@receiver(invitation_created)
|
||||
def on_invitation_created(sender, request, invitation, **kwargs):
|
||||
"""Log Invite creation"""
|
||||
"""Log Invitation creation"""
|
||||
AuditEntry.create(AuditEntry.ACTION_INVITE_CREATED, request, invitation_uuid=invitation.uuid)
|
||||
|
||||
@receiver(invitation_used)
|
||||
def on_invitation_used(sender, request, invitation, **kwargs):
|
||||
"""Log Invite usage"""
|
||||
"""Log Invitation usage"""
|
||||
AuditEntry.create(AuditEntry.ACTION_INVITE_USED, request, invitation_uuid=invitation.uuid)
|
||||
|
||||
@receiver(user_login_failed)
|
||||
|
|
|
@ -2,22 +2,21 @@
|
|||
|
||||
from django import forms
|
||||
|
||||
from passbook.core.models import Invite
|
||||
from passbook.core.models import Invitation
|
||||
|
||||
|
||||
class InviteForm(forms.ModelForm):
|
||||
"""InviteForm"""
|
||||
class InvitationForm(forms.ModelForm):
|
||||
"""InvitationForm"""
|
||||
|
||||
class Meta:
|
||||
|
||||
model = Invite
|
||||
fields = ['created_by', 'expires', 'fixed_username', 'fixed_email']
|
||||
model = Invitation
|
||||
fields = ['expires', 'fixed_username', 'fixed_email']
|
||||
labels = {
|
||||
'fixed_username': "Force user's username (optional)",
|
||||
'fixed_email': "Force user's email (optional)",
|
||||
}
|
||||
widgets = {
|
||||
'created_by': forms.Select(attrs={'disabled': 'disabled'}),
|
||||
'fixed_username': forms.TextInput(),
|
||||
'fixed_email': forms.TextInput(),
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ class Migration(migrations.Migration):
|
|||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Invite',
|
||||
name='Invitation',
|
||||
fields=[
|
||||
('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('expires', models.DateTimeField(blank=True, default=None, null=True)),
|
||||
|
@ -24,7 +24,7 @@ class Migration(migrations.Migration):
|
|||
('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Invite',
|
||||
'verbose_name': 'Invitation',
|
||||
'verbose_name_plural': 'Invitations',
|
||||
},
|
||||
),
|
||||
|
|
|
@ -8,6 +8,7 @@ from uuid import uuid4
|
|||
import reversion
|
||||
from django.contrib.auth.models import AbstractUser
|
||||
from django.db import models
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.translation import gettext as _
|
||||
from model_utils.managers import InheritanceManager
|
||||
|
||||
|
@ -250,7 +251,7 @@ class DebugRule(Rule):
|
|||
verbose_name = _('Debug Rule')
|
||||
verbose_name_plural = _('Debug Rules')
|
||||
|
||||
class Invite(UUIDModel):
|
||||
class Invitation(UUIDModel):
|
||||
"""Single-use invitation link"""
|
||||
|
||||
created_by = models.ForeignKey('User', on_delete=models.CASCADE)
|
||||
|
@ -258,10 +259,15 @@ class Invite(UUIDModel):
|
|||
fixed_username = models.TextField(blank=True, default=None)
|
||||
fixed_email = models.TextField(blank=True, default=None)
|
||||
|
||||
@property
|
||||
def link(self):
|
||||
"""Get link to use invitation"""
|
||||
return reverse_lazy('passbook_core:auth-sign-up') + '?invitation=%s' % self.uuid
|
||||
|
||||
def __str__(self):
|
||||
return "Invite %s created by %s" % (self.uuid, self.created_by)
|
||||
return "Invitation %s created by %s" % (self.uuid, self.created_by)
|
||||
|
||||
class Meta:
|
||||
|
||||
verbose_name = _('Invite')
|
||||
verbose_name = _('Invitation')
|
||||
verbose_name_plural = _('Invitations')
|
||||
|
|
|
@ -4,7 +4,7 @@ from django.core.signals import Signal
|
|||
|
||||
# from django.db.models.signals import post_save, pre_delete
|
||||
# from django.dispatch import receiver
|
||||
# from passbook.core.models import Invite, User
|
||||
# from passbook.core.models import Invitation, User
|
||||
|
||||
user_signed_up = Signal(providing_args=['request', 'user'])
|
||||
# TODO: Send this signal in admin interface
|
||||
|
|
|
@ -12,7 +12,7 @@ from django.views import View
|
|||
from django.views.generic import FormView
|
||||
|
||||
from passbook.core.forms.authentication import LoginForm, SignUpForm
|
||||
from passbook.core.models import Invite, User
|
||||
from passbook.core.models import Invitation, User
|
||||
from passbook.core.signals import invitation_used, user_signed_up
|
||||
from passbook.lib.config import CONFIG
|
||||
|
||||
|
@ -118,7 +118,7 @@ class SignUpView(UserPassesTestMixin, FormView):
|
|||
template_name = 'login/form.html'
|
||||
form_class = SignUpForm
|
||||
success_url = '.'
|
||||
# Invite insatnce, if invitation link was used
|
||||
# Invitation insatnce, if invitation link was used
|
||||
_invitation = None
|
||||
# Instance of newly created user
|
||||
_user = None
|
||||
|
@ -134,7 +134,7 @@ class SignUpView(UserPassesTestMixin, FormView):
|
|||
"""Check if sign-up is enabled or invitation link given"""
|
||||
allowed = False
|
||||
if 'invitation' in request.GET:
|
||||
invitations = Invite.objects.filter(uuid=request.GET.get('invitation'))
|
||||
invitations = Invitation.objects.filter(uuid=request.GET.get('invitation'))
|
||||
allowed = invitations.exists()
|
||||
if allowed:
|
||||
self._invitation = invitations.first()
|
||||
|
@ -145,6 +145,16 @@ class SignUpView(UserPassesTestMixin, FormView):
|
|||
return redirect(reverse('passbook_core:auth-login'))
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get_initial(self):
|
||||
if self._invitation:
|
||||
initial = {}
|
||||
if self._invitation.fixed_username:
|
||||
initial['username'] = self._invitation.fixed_username
|
||||
if self._invitation.fixed_email:
|
||||
initial['e-mail'] = self._invitation.fixed_email
|
||||
return initial
|
||||
return super().get_initial()
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
kwargs['config'] = CONFIG.get('passbook')
|
||||
kwargs['is_login'] = True
|
||||
|
|
Reference in a new issue