Skip to content

Commit

Permalink
feat(invite): add an invite app, that provides invite tokens
Browse files Browse the repository at this point in the history
The `invite` app provides the logic to create tokens for user signup. A
token can be created in the Django Admin interface and the used in the
`/invite/<token>` route to create a user account. Once used, the token
is deleted.

Closes: #1293
  • Loading branch information
b1rger committed Nov 27, 2024
1 parent 7b89774 commit 568c091
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 0 deletions.
5 changes: 5 additions & 0 deletions apis_core/invite/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.contrib import admin

from .models import InviteToken

admin.site.register(InviteToken)
27 changes: 27 additions & 0 deletions apis_core/invite/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Generated by Django 5.1.2 on 2024-11-27 12:21

import uuid
from django.db import migrations, models


class Migration(migrations.Migration):
initial = True

dependencies = []

operations = [
migrations.CreateModel(
name="InviteToken",
fields=[
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
),
),
],
),
]
Empty file.
10 changes: 10 additions & 0 deletions apis_core/invite/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import uuid

from django.db import models


class InviteToken(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

def __str__(self):
return str(self.id)
15 changes: 15 additions & 0 deletions apis_core/invite/templates/invite.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{% extends basetemplate|default:"base.html" %}
{% load crispy_forms_tags %}

{% block content %}
<div class="container">
<div class="mt-4">
<form method="post">
{% csrf_token %}
{{ form|crispy }}
<input type="submit" value="login">
<input type="hidden" name="next" value="{{ next }}">
</form>
</div>
</div>
{% endblock content %}
7 changes: 7 additions & 0 deletions apis_core/invite/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from django.urls import path

from apis_core.invite.views import Invite

urlpatterns = [
path("invite/<uuid:invite>", Invite.as_view()),
]
25 changes: 25 additions & 0 deletions apis_core/invite/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from django.contrib import messages
from django.contrib.auth.forms import UserCreationForm
from django.shortcuts import get_object_or_404
from django.urls import reverse
from django.views.generic.edit import CreateView

from apis_core.invite.models import InviteToken


class Invite(CreateView):
form_class = UserCreationForm
template_name = "invite.html"

def setup(self, *args, **kwargs):
super().setup(*args, **kwargs)
self.invite = get_object_or_404(InviteToken, id=kwargs.get("invite"))

def form_valid(self, form):
ret = super().form_valid(form)
self.invite.delete()
messages.success(self.request, f"Created user {self.object}")
return ret

def get_success_url(self):
return reverse("apis_core:login")
4 changes: 4 additions & 0 deletions apis_core/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@
urlpatterns.append(path("", include("apis_core.documentation.urls")))


if "apis_core.invite" in settings.INSTALLED_APPS:
urlpatterns.append(path("", include("apis_core.invite.urls")))


urlpatterns.append(path("api/", include(router.urls)))
urlpatterns.append(path("api-auth/", include("rest_framework.urls")))

Expand Down

0 comments on commit 568c091

Please sign in to comment.