all: invites -> invitations

This commit is contained in:
Jens Langhammer 2018-12-10 14:21:42 +01:00
parent 89c2b8d49c
commit 545795ebc6
14 changed files with 61 additions and 58 deletions

View file

@ -20,8 +20,8 @@
<li class="{% is_active 'passbook_admin:rules' 'passbook_admin:rule-create' 'passbook_admin:rule-update' 'passbook_admin:rule-delete' 'passbook_admin:rule-test' %}">
<a href="{% url 'passbook_admin:rules' %}">{% trans 'Rules' %}</a>
</li>
<li class="{% is_active 'passbook_admin:invites' 'passbook_admin:invite-create' 'passbook_admin:invite-update' 'passbook_admin:invite-delete' 'passbook_admin:invite-test' %}">
<a href="{% url 'passbook_admin:invites' %}">{% trans 'Invites' %}</a>
<li class="{% is_active 'passbook_admin:invitations' 'passbook_admin:invitation-create' 'passbook_admin:invitation-update' 'passbook_admin:invitation-delete' 'passbook_admin:invitation-test' %}">
<a href="{% url 'passbook_admin:invitations' %}">{% trans 'Invitations' %}</a>
</li>
<li>
<a href="#">{% trans 'Users' %}</a>

View file

@ -9,8 +9,8 @@
{% block content %}
<div class="container">
<h1>{% trans "Invites" %}</h1>
<a href="{% url 'passbook_admin:invite-create' %}" class="btn btn-primary">
<h1>{% trans "Invitations" %}</h1>
<a href="{% url 'passbook_admin:invitation-create' %}" class="btn btn-primary">
{% trans 'Create...' %}
</a>
<hr>
@ -23,13 +23,13 @@
</tr>
</thead>
<tbody>
{% for invite in object_list %}
{% for invitation in object_list %}
<tr>
<td>{{ invite.name }}</td>
<td>{{ invite.provider }}</td>
<td>{{ invitation.name }}</td>
<td>{{ invitation.provider }}</td>
<td>
<a class="btn btn-default btn-sm" href="{% url 'passbook_admin:invite-update' pk=invite.uuid %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a>
<a class="btn btn-default btn-sm" href="{% url 'passbook_admin:invite-delete' pk=invite.uuid %}?back={{ request.get_full_path }}">{% trans 'Delete' %}</a>
<a class="btn btn-default btn-sm" href="{% url 'passbook_admin:invitation-update' pk=invitation.uuid %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a>
<a class="btn btn-default btn-sm" href="{% url 'passbook_admin:invitation-delete' pk=invitation.uuid %}?back={{ request.get_full_path }}">{% trans 'Delete' %}</a>
</td>
</tr>
{% endfor %}

View file

@ -1,8 +1,8 @@
"""passbook URL Configuration"""
from django.urls import path
from passbook.admin.views import (applications, invites, overview, providers,
rules, sources)
from passbook.admin.views import (applications, invitations, overview,
providers, rules, sources)
urlpatterns = [
path('', overview.AdministrationOverviewView.as_view(), name='overview'),
@ -34,10 +34,12 @@ urlpatterns = [
providers.ProviderUpdateView.as_view(), name='provider-update'),
path('providers/<int:pk>/delete/',
providers.ProviderDeleteView.as_view(), name='provider-delete'),
# Invites
path('invites/', invites.InviteListView.as_view(), name='invites'),
path('invites/create/', invites.InviteCreateView.as_view(), name='invite-create'),
path('invites/<uuid:pk>/update/', invites.InviteUpdateView.as_view(), name='invite-update'),
path('invites/<uuid:pk>/delete/', invites.InviteDeleteView.as_view(), name='invite-delete'),
# Invitations
path('invitations/', invitations.InviteListView.as_view(), name='invitations'),
path('invitations/create/', invitations.InviteCreateView.as_view(), name='invitation-create'),
path('invitations/<uuid:pk>/update/',
invitations.InviteUpdateView.as_view(), name='invitation-update'),
path('invitations/<uuid:pk>/delete/',
invitations.InviteDeleteView.as_view(), name='invitation-delete'),
# path('api/v1/', include('passbook.admin.api.v1.urls'))
]

View file

@ -5,39 +5,39 @@ from django.utils.translation import ugettext as _
from django.views.generic import CreateView, DeleteView, ListView, UpdateView
from passbook.admin.mixins import AdminRequiredMixin
from passbook.core.forms.invites import InviteForm
from passbook.core.forms.invitations import InviteForm
from passbook.core.models import Invite
class InviteListView(AdminRequiredMixin, ListView):
"""Show list of all invites"""
"""Show list of all invitations"""
model = Invite
template_name = 'administration/invite/list.html'
template_name = 'administration/invitation/list.html'
class InviteCreateView(SuccessMessageMixin, AdminRequiredMixin, CreateView):
"""Create new Invite"""
template_name = 'generic/create.html'
success_url = reverse_lazy('passbook_admin:invites')
success_url = reverse_lazy('passbook_admin:invitations')
success_message = _('Successfully created Invite')
form_class = InviteForm
class InviteUpdateView(SuccessMessageMixin, AdminRequiredMixin, UpdateView):
"""Update invite"""
"""Update invitation"""
model = Invite
template_name = 'generic/update.html'
success_url = reverse_lazy('passbook_admin:invites')
success_url = reverse_lazy('passbook_admin:invitations')
success_message = _('Successfully updated Invite')
form_class = InviteForm
class InviteDeleteView(SuccessMessageMixin, AdminRequiredMixin, DeleteView):
"""Delete invite"""
"""Delete invitation"""
model = Invite
template_name = 'generic/delete.html'
success_url = reverse_lazy('passbook_admin:invites')
success_url = reverse_lazy('passbook_admin:invitations')
success_message = _('Successfully updated Invite')

View file

@ -22,6 +22,6 @@ class Migration(migrations.Migration):
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'), ('invite_used', 'invite_used')]),
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_used', 'invitation_used')]),
),
]

View file

@ -24,8 +24,8 @@ class AuditEntry(UUIDModel):
ACTION_SUSPICIOUS_REQUEST = 'suspicious_request'
ACTION_SIGN_UP = 'sign_up'
ACTION_PASSWORD_RESET = 'password_reset'
ACTION_INVITE_CREATED = 'invite_created'
ACTION_INVITE_USED = 'invite_used'
ACTION_INVITE_CREATED = 'invitation_created'
ACTION_INVITE_USED = 'invitation_used'
ACTIONS = (
(ACTION_LOGIN, ACTION_LOGIN),
(ACTION_LOGIN_FAILED, ACTION_LOGIN_FAILED),

View file

@ -4,7 +4,8 @@ from django.contrib.auth.signals import (user_logged_in, user_logged_out,
from django.dispatch import receiver
from passbook.audit.models import AuditEntry
from passbook.core.signals import invite_created, invite_used, user_signed_up
from passbook.core.signals import (invitation_created, invitation_used,
user_signed_up)
@receiver(user_logged_in)
@ -22,15 +23,15 @@ def on_user_signed_up(sender, request, user, **kwargs):
"""Log successfully signed up"""
AuditEntry.create(AuditEntry.ACTION_SIGN_UP, request)
@receiver(invite_created)
def on_invite_created(sender, request, invite, **kwargs):
@receiver(invitation_created)
def on_invitation_created(sender, request, invitation, **kwargs):
"""Log Invite creation"""
AuditEntry.create(AuditEntry.ACTION_INVITE_CREATED, request, invite_uuid=invite.uuid)
AuditEntry.create(AuditEntry.ACTION_INVITE_CREATED, request, invitation_uuid=invitation.uuid)
@receiver(invite_used)
def on_invite_used(sender, request, invite, **kwargs):
@receiver(invitation_used)
def on_invitation_used(sender, request, invitation, **kwargs):
"""Log Invite usage"""
AuditEntry.create(AuditEntry.ACTION_INVITE_USED, request, invite_uuid=invite.uuid)
AuditEntry.create(AuditEntry.ACTION_INVITE_USED, request, invitation_uuid=invitation.uuid)
@receiver(user_login_failed)
def on_user_login_failed(sender, request, user, **kwargs):

View file

@ -1,4 +1,4 @@
"""passbook core invite form"""
"""passbook core invitation form"""
from django import forms

View file

@ -25,7 +25,7 @@ class Migration(migrations.Migration):
],
options={
'verbose_name': 'Invite',
'verbose_name_plural': 'Invites',
'verbose_name_plural': 'Invitations',
},
),
]

View file

@ -251,7 +251,7 @@ class DebugRule(Rule):
verbose_name_plural = _('Debug Rules')
class Invite(UUIDModel):
"""Single-use invite link"""
"""Single-use invitation link"""
created_by = models.ForeignKey('User', on_delete=models.CASCADE)
expires = models.DateTimeField(default=None, blank=True, null=True)
@ -264,4 +264,4 @@ class Invite(UUIDModel):
class Meta:
verbose_name = _('Invite')
verbose_name_plural = _('Invites')
verbose_name_plural = _('Invitations')

View file

@ -8,5 +8,5 @@ from django.core.signals import Signal
user_signed_up = Signal(providing_args=['request', 'user'])
# TODO: Send this signal in admin interface
invite_created = Signal(providing_args=['request', 'invite'])
invite_used = Signal(providing_args=['request', 'invite', 'user'])
invitation_created = Signal(providing_args=['request', 'invitation'])
invitation_used = Signal(providing_args=['request', 'invitation', 'user'])

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 6.3 MiB

View file

@ -13,7 +13,7 @@ from django.views.generic import FormView
from passbook.core.forms.authentication import LoginForm, SignUpForm
from passbook.core.models import Invite, User
from passbook.core.signals import invite_used, user_signed_up
from passbook.core.signals import invitation_used, user_signed_up
from passbook.lib.config import CONFIG
LOGGER = getLogger(__name__)
@ -113,13 +113,13 @@ class LogoutView(LoginRequiredMixin, View):
class SignUpView(UserPassesTestMixin, FormView):
"""Sign up new user, optionally consume one-use invite link."""
"""Sign up new user, optionally consume one-use invitation link."""
template_name = 'login/form.html'
form_class = SignUpForm
success_url = '.'
# Invite insatnce, if invite link was used
_invite = None
# Invite insatnce, if invitation link was used
_invitation = None
# Instance of newly created user
_user = None
@ -131,13 +131,13 @@ class SignUpView(UserPassesTestMixin, FormView):
return redirect(reverse('passbook_core:overview'))
def dispatch(self, request, *args, **kwargs):
"""Check if sign-up is enabled or invite link given"""
"""Check if sign-up is enabled or invitation link given"""
allowed = False
if 'invite' in request.GET:
invites = Invite.objects.filter(uuid=request.GET.get('invite'))
allowed = invites.exists()
if 'invitation' in request.GET:
invitations = Invite.objects.filter(uuid=request.GET.get('invitation'))
allowed = invitations.exists()
if allowed:
self._invite = invites.first()
self._invitation = invitations.first()
if CONFIG.y('passbook.sign_up.enabled'):
allowed = True
if not allowed:
@ -155,21 +155,21 @@ class SignUpView(UserPassesTestMixin, FormView):
def form_valid(self, form: SignUpForm) -> HttpResponse:
"""Create user"""
self._user = SignUpView.create_user(form.cleaned_data, self.request)
self.consume_invite()
self.consume_invitation()
messages.success(self.request, _("Successfully signed up!"))
LOGGER.debug("Successfully signed up %s",
form.cleaned_data.get('email'))
return redirect(reverse('passbook_core:auth-login'))
def consume_invite(self):
"""Consume invite if an invite was used"""
if self._invite:
invite_used.send(
def consume_invitation(self):
"""Consume invitation if an invitation was used"""
if self._invitation:
invitation_used.send(
sender=self,
request=self.request,
invite=self._invite,
invitation=self._invitation,
user=self._user)
self._invite.delete()
self._invitation.delete()
@staticmethod
def create_user(data: Dict, request: HttpRequest = None) -> User:

View file

@ -90,8 +90,8 @@ def login_process(request):
# # Only check if there is a connection from OAuth2 Application to product
# product = remote.productextensionsaml2_set.first().product_set.first()
# relationship = UserAcquirableRelationship.objects.filter(user=request.user, model=product)
# # Product is invite_only = True and no relation with user exists
# if product.invite_only and not relationship.exists():
# # Product is invitation_only = True and no relation with user exists
# if product.invitation_only and not relationship.exists():
# access = False
# Check if we should just autosubmit
if remote.skip_authorization and access: