basics of invite link creation
This commit is contained in:
parent
2a0a85018a
commit
392ee73719
@ -271,6 +271,15 @@ class MealPlanForm(forms.ModelForm):
|
|||||||
widgets = {'recipe': SelectWidget, 'date': DateWidget, 'shared': MultiSelectWidget}
|
widgets = {'recipe': SelectWidget, 'date': DateWidget, 'shared': MultiSelectWidget}
|
||||||
|
|
||||||
|
|
||||||
|
class InviteLinkForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = InviteLink
|
||||||
|
fields = ('username', 'group', 'valid_until')
|
||||||
|
help_texts = {
|
||||||
|
'username': _('A username is not required, if left blank the new user can choose one.')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class SuperUserForm(forms.Form):
|
class SuperUserForm(forms.Form):
|
||||||
name = forms.CharField()
|
name = forms.CharField()
|
||||||
password = forms.CharField(widget=forms.TextInput(attrs={'autocomplete': 'new-password', 'type': 'password'}))
|
password = forms.CharField(widget=forms.TextInput(attrs={'autocomplete': 'new-password', 'type': 'password'}))
|
||||||
|
29
cookbook/migrations/0077_invitelink.py
Normal file
29
cookbook/migrations/0077_invitelink.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Generated by Django 3.0.7 on 2020-09-01 11:31
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('cookbook', '0076_shoppinglist_entries'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='InviteLink',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('uuid', models.UUIDField(default=uuid.uuid4)),
|
||||||
|
('username', models.CharField(blank=True, max_length=64)),
|
||||||
|
('valid_until', models.DateField(default=datetime.date(2020, 9, 15))),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
21
cookbook/migrations/0078_invitelink_used_by.py
Normal file
21
cookbook/migrations/0078_invitelink_used_by.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Generated by Django 3.0.7 on 2020-09-01 11:39
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('cookbook', '0077_invitelink'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='invitelink',
|
||||||
|
name='used_by',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='used_by', to=settings.AUTH_USER_MODEL),
|
||||||
|
),
|
||||||
|
]
|
21
cookbook/migrations/0079_invitelink_group.py
Normal file
21
cookbook/migrations/0079_invitelink_group.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Generated by Django 3.0.7 on 2020-09-01 12:54
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('auth', '0011_update_proxy_permissions'),
|
||||||
|
('cookbook', '0078_invitelink_used_by'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='invitelink',
|
||||||
|
name='group',
|
||||||
|
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='auth.Group'),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
]
|
@ -1,8 +1,10 @@
|
|||||||
import re
|
import re
|
||||||
import uuid
|
import uuid
|
||||||
|
from datetime import date, timedelta
|
||||||
|
|
||||||
from annoying.fields import AutoOneToOneField
|
from annoying.fields import AutoOneToOneField
|
||||||
from django.contrib import auth
|
from django.contrib import auth
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User, Group
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
@ -296,6 +298,16 @@ class ShareLink(models.Model):
|
|||||||
created_at = models.DateTimeField(auto_now_add=True)
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
|
|
||||||
|
class InviteLink(models.Model):
|
||||||
|
uuid = models.UUIDField(default=uuid.uuid4)
|
||||||
|
username = models.CharField(blank=True, max_length=64)
|
||||||
|
group = models.ForeignKey(Group, on_delete=models.CASCADE)
|
||||||
|
valid_until = models.DateField(default=date.today()+timedelta(days=14))
|
||||||
|
used_by = models.ForeignKey(User, null=True, on_delete=models.CASCADE, related_name='used_by')
|
||||||
|
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
|
|
||||||
class CookLog(models.Model):
|
class CookLog(models.Model):
|
||||||
recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE)
|
recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE)
|
||||||
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
|
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
|
@ -117,6 +117,13 @@ class ShoppingListTable(tables.Table):
|
|||||||
fields = ('id', 'created_by', 'created_at')
|
fields = ('id', 'created_by', 'created_at')
|
||||||
|
|
||||||
|
|
||||||
|
class InviteLinkTable(tables.Table):
|
||||||
|
class Meta:
|
||||||
|
model = InviteLink
|
||||||
|
template_name = 'generic/table_template.html'
|
||||||
|
fields = ('id', 'username', 'group', 'valid_until', 'created_by', 'created_at', 'used_by')
|
||||||
|
|
||||||
|
|
||||||
class ViewLogTable(tables.Table):
|
class ViewLogTable(tables.Table):
|
||||||
recipe = tables.LinkColumn('view_recipe', args=[A('recipe_id')])
|
recipe = tables.LinkColumn('view_recipe', args=[A('recipe_id')])
|
||||||
|
|
||||||
|
@ -16,8 +16,18 @@
|
|||||||
<br/>
|
<br/>
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
<h3>{% trans 'Backup & Restore' %}</h3>
|
<div class="row">
|
||||||
<a href="{% url 'api_backup' %}" class="btn btn-success">{% trans 'Download Backup' %}</a>
|
<div class="col-md-6">
|
||||||
|
<h3>{% trans 'Invite Links' %}</h3>
|
||||||
|
<a href="{% url 'list_invite_link' %}" class="btn btn-success">{% trans 'Show Links' %}</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<h3>{% trans 'Backup & Restore' %}</h3>
|
||||||
|
<a href="{% url 'api_backup' %}" class="btn btn-success">{% trans 'Download Backup' %}</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
<br/>
|
<br/>
|
||||||
@ -59,7 +69,8 @@
|
|||||||
{% trans 'Warning' %}{% else %}{% trans 'Ok' %}{% endif %}</span></h4>
|
{% trans 'Warning' %}{% else %}{% trans 'Ok' %}{% endif %}</span></h4>
|
||||||
{% if secret_key %}
|
{% if secret_key %}
|
||||||
{% blocktrans %}
|
{% blocktrans %}
|
||||||
You do not have a <code>SECRET_KEY</code> configured in your <code>.env</code> file. Django defaulted to the standard key
|
You do not have a <code>SECRET_KEY</code> configured in your <code>.env</code> file. Django defaulted to the
|
||||||
|
standard key
|
||||||
provided with the installation which is publicly know and insecure! Please set
|
provided with the installation which is publicly know and insecure! Please set
|
||||||
<code>SECRET_KEY</code> int the <code>.env</code> configuration file.
|
<code>SECRET_KEY</code> int the <code>.env</code> configuration file.
|
||||||
{% endblocktrans %}
|
{% endblocktrans %}
|
||||||
|
@ -91,7 +91,7 @@ urlpatterns = [
|
|||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
generic_models = (Recipe, RecipeImport, Storage, RecipeBook, MealPlan, SyncLog, Sync, Comment, RecipeBookEntry, Keyword, Food, ShoppingList)
|
generic_models = (Recipe, RecipeImport, Storage, RecipeBook, MealPlan, SyncLog, Sync, Comment, RecipeBookEntry, Keyword, Food, ShoppingList, InviteLink)
|
||||||
|
|
||||||
for m in generic_models:
|
for m in generic_models:
|
||||||
py_name = get_model_name(m)
|
py_name = get_model_name(m)
|
||||||
|
@ -6,8 +6,8 @@ from django_tables2 import RequestConfig
|
|||||||
|
|
||||||
from cookbook.filters import IngredientFilter
|
from cookbook.filters import IngredientFilter
|
||||||
from cookbook.helper.permission_helper import group_required
|
from cookbook.helper.permission_helper import group_required
|
||||||
from cookbook.models import Keyword, SyncLog, RecipeImport, Storage, Food, ShoppingList
|
from cookbook.models import Keyword, SyncLog, RecipeImport, Storage, Food, ShoppingList, InviteLink
|
||||||
from cookbook.tables import KeywordTable, ImportLogTable, RecipeImportTable, StorageTable, IngredientTable, ShoppingListTable
|
from cookbook.tables import KeywordTable, ImportLogTable, RecipeImportTable, StorageTable, IngredientTable, ShoppingListTable, InviteLinkTable
|
||||||
|
|
||||||
|
|
||||||
@group_required('user')
|
@group_required('user')
|
||||||
@ -59,3 +59,11 @@ def storage(request):
|
|||||||
RequestConfig(request, paginate={'per_page': 25}).configure(table)
|
RequestConfig(request, paginate={'per_page': 25}).configure(table)
|
||||||
|
|
||||||
return render(request, 'generic/list_template.html', {'title': _("Storage Backend"), 'table': table, 'create_url': 'new_storage'})
|
return render(request, 'generic/list_template.html', {'title': _("Storage Backend"), 'table': table, 'create_url': 'new_storage'})
|
||||||
|
|
||||||
|
|
||||||
|
@group_required('admin')
|
||||||
|
def invite_link(request):
|
||||||
|
table = InviteLinkTable(InviteLink.objects.all())
|
||||||
|
RequestConfig(request, paginate={'per_page': 25}).configure(table)
|
||||||
|
|
||||||
|
return render(request, 'generic/list_template.html', {'title': _("Invite Links"), 'table': table, 'create_url': 'new_invite_link'})
|
||||||
|
@ -9,9 +9,9 @@ from django.utils.translation import gettext as _
|
|||||||
from django.views.generic import CreateView
|
from django.views.generic import CreateView
|
||||||
|
|
||||||
from cookbook.forms import ImportRecipeForm, RecipeImport, KeywordForm, Storage, StorageForm, InternalRecipeForm, \
|
from cookbook.forms import ImportRecipeForm, RecipeImport, KeywordForm, Storage, StorageForm, InternalRecipeForm, \
|
||||||
RecipeBookForm, MealPlanForm
|
RecipeBookForm, MealPlanForm, InviteLinkForm
|
||||||
from cookbook.helper.permission_helper import GroupRequiredMixin, group_required
|
from cookbook.helper.permission_helper import GroupRequiredMixin, group_required
|
||||||
from cookbook.models import Keyword, Recipe, RecipeBook, MealPlan, ShareLink, MealType, Step
|
from cookbook.models import Keyword, Recipe, RecipeBook, MealPlan, ShareLink, MealType, Step, InviteLink
|
||||||
|
|
||||||
|
|
||||||
class RecipeCreate(GroupRequiredMixin, CreateView):
|
class RecipeCreate(GroupRequiredMixin, CreateView):
|
||||||
@ -162,3 +162,21 @@ class MealPlanCreate(GroupRequiredMixin, CreateView):
|
|||||||
context['default_recipe'] = Recipe.objects.get(pk=int(recipe))
|
context['default_recipe'] = Recipe.objects.get(pk=int(recipe))
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
class InviteLinkCreate(GroupRequiredMixin, CreateView):
|
||||||
|
groups_required = ['admin']
|
||||||
|
template_name = "generic/new_template.html"
|
||||||
|
model = InviteLink
|
||||||
|
form_class = InviteLinkForm
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
obj = form.save(commit=False)
|
||||||
|
obj.created_by = self.request.user
|
||||||
|
obj.save()
|
||||||
|
return HttpResponseRedirect(reverse('list_invite_link'))
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super(InviteLinkCreate, self).get_context_data(**kwargs)
|
||||||
|
context['title'] = _("Invite Link")
|
||||||
|
return context
|
||||||
|
Loading…
Reference in New Issue
Block a user