added basic group permission system

This commit is contained in:
vabene1111 2020-04-26 17:21:44 +02:00
parent c7046bc705
commit ad467fae28
11 changed files with 157 additions and 53 deletions

View File

@ -0,0 +1,53 @@
"""
Source: https://djangosnippets.org/snippets/1703/
"""
from django.contrib import messages
from django.contrib.auth.decorators import user_passes_test
from django.utils.translation import gettext as _
from django.http import HttpResponseRedirect
from django.urls import reverse_lazy
def get_allowed_groups(groups_required):
groups_allowed = tuple(groups_required)
if 'guest' in groups_required:
groups_allowed = groups_allowed + ('user', 'admin')
if 'user' in groups_required:
groups_allowed = groups_allowed + ('admin',)
return groups_allowed
def group_required(*groups_required):
"""Requires user membership in at least one of the groups passed in."""
def in_groups(u):
groups_allowed = get_allowed_groups(groups_required)
if u.is_authenticated:
if u.is_superuser | bool(u.groups.filter(name__in=groups_allowed)):
return True
return False
return user_passes_test(in_groups, login_url='index')
class GroupRequiredMixin(object):
"""
groups_required - list of strings, required param
"""
groups_required = None
def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated:
messages.add_message(request, messages.ERROR, _('You are not logged in and therefore cannot view this page!'))
return HttpResponseRedirect(reverse_lazy('login'))
else:
if not request.user.is_superuser:
group_allowed = get_allowed_groups(self.groups_required)
user_groups = []
for group in request.user.groups.values_list('name', flat=True):
user_groups.append(group)
if len(set(user_groups).intersection(group_allowed)) <= 0:
messages.add_message(request, messages.ERROR, _('You do not have the required permissions to view this page!'))
return HttpResponseRedirect(reverse_lazy('index'))
return super(GroupRequiredMixin, self).dispatch(request, *args, **kwargs)

View File

@ -0,0 +1,22 @@
# Generated by Django 3.0.5 on 2020-04-26 14:14
from django.db import migrations
def apply_migration(apps, schema_editor):
Group = apps.get_model('auth', 'Group')
Group.objects.bulk_create([
Group(name=u'guest'),
Group(name=u'user'),
Group(name=u'admin'),
])
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0033_userpreference_default_page'),
]
operations = [
migrations.RunPython(apply_migration)
]

View File

@ -1,5 +1,5 @@
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.test import TestCase, Client from django.test import TestCase, Client
@ -11,14 +11,17 @@ class TestBase(TestCase):
self.client = Client() self.client = Client()
self.client.force_login(User.objects.get_or_create(username='client')[0]) self.client.force_login(User.objects.get_or_create(username='client')[0])
user = auth.get_user(self.client) user = auth.get_user(self.client)
user.groups.add(Group.objects.get(name='admin'))
self.assertTrue(user.is_authenticated) self.assertTrue(user.is_authenticated)
self.another_client = Client() self.another_client = Client()
self.another_client.force_login(User.objects.get_or_create(username='another_client')[0]) self.another_client.force_login(User.objects.get_or_create(username='another_client')[0])
user = auth.get_user(self.another_client) user = auth.get_user(self.another_client)
user.groups.add(Group.objects.get(name='admin'))
self.assertTrue(user.is_authenticated) self.assertTrue(user.is_authenticated)
self.superuser_client = Client() self.superuser_client = Client()
self.superuser_client.force_login(User.objects.get_or_create(username='superuser_client', is_superuser=True)[0]) self.superuser_client.force_login(User.objects.get_or_create(username='superuser_client', is_superuser=True)[0])
user = auth.get_user(self.superuser_client) user = auth.get_user(self.superuser_client)
user.groups.add(Group.objects.get(name='admin'))
self.assertTrue(user.is_authenticated) self.assertTrue(user.is_authenticated)

View File

@ -5,6 +5,7 @@ from django.utils.translation import gettext as _
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect from django.shortcuts import redirect
from cookbook.helper.group_helper import group_required
from cookbook.models import Recipe, Sync, Storage from cookbook.models import Recipe, Sync, Storage
from cookbook.provider.dropbox import Dropbox from cookbook.provider.dropbox import Dropbox
from cookbook.provider.nextcloud import Nextcloud from cookbook.provider.nextcloud import Nextcloud
@ -26,7 +27,7 @@ def update_recipe_links(recipe):
recipe.save() recipe.save()
@login_required @group_required('user')
def get_external_file_link(request, recipe_id): def get_external_file_link(request, recipe_id):
recipe = Recipe.objects.get(id=recipe_id) recipe = Recipe.objects.get(id=recipe_id)
if not recipe.link: if not recipe.link:
@ -35,7 +36,7 @@ def get_external_file_link(request, recipe_id):
return HttpResponse(recipe.link) return HttpResponse(recipe.link)
@login_required @group_required('user')
def get_recipe_file(request, recipe_id): def get_recipe_file(request, recipe_id):
recipe = Recipe.objects.get(id=recipe_id) recipe = Recipe.objects.get(id=recipe_id)
if not recipe.cors_link: if not recipe.cors_link:
@ -44,7 +45,7 @@ def get_recipe_file(request, recipe_id):
return HttpResponse(get_recipe_provider(recipe).get_base64_file(recipe)) return HttpResponse(get_recipe_provider(recipe).get_base64_file(recipe))
@login_required @group_required('user')
def sync_all(request): def sync_all(request):
monitors = Sync.objects.filter(active=True) monitors = Sync.objects.filter(active=True)

View File

@ -7,11 +7,12 @@ from django.utils.translation import ngettext
from django_tables2 import RequestConfig from django_tables2 import RequestConfig
from cookbook.forms import SyncForm, BatchEditForm from cookbook.forms import SyncForm, BatchEditForm
from cookbook.helper.group_helper import group_required
from cookbook.models import * from cookbook.models import *
from cookbook.tables import SyncTable from cookbook.tables import SyncTable
@login_required @group_required('user')
def sync(request): def sync(request):
if request.method == "POST": if request.method == "POST":
form = SyncForm(request.POST) form = SyncForm(request.POST)
@ -31,12 +32,12 @@ def sync(request):
return render(request, 'batch/monitor.html', {'form': form, 'monitored_paths': monitored_paths}) return render(request, 'batch/monitor.html', {'form': form, 'monitored_paths': monitored_paths})
@login_required @group_required('user')
def sync_wait(request): def sync_wait(request):
return render(request, 'batch/waiting.html') return render(request, 'batch/waiting.html')
@login_required @group_required('user')
def batch_import(request): def batch_import(request):
imports = RecipeImport.objects.all() imports = RecipeImport.objects.all()
for new_recipe in imports: for new_recipe in imports:
@ -47,7 +48,7 @@ def batch_import(request):
return redirect('list_recipe_import') return redirect('list_recipe_import')
@login_required @group_required('user')
def batch_edit(request): def batch_edit(request):
if request.method == "POST": if request.method == "POST":
form = BatchEditForm(request.POST) form = BatchEditForm(request.POST)
@ -86,7 +87,7 @@ class Object(object):
pass pass
@login_required @group_required('user')
def statistics(request): def statistics(request):
counts = Object() counts = Object()
counts.recipes = Recipe.objects.count() counts.recipes = Recipe.objects.count()

View File

@ -5,13 +5,15 @@ from django.urls import reverse_lazy, reverse
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.views.generic import DeleteView from django.views.generic import DeleteView
from cookbook.helper.group_helper import GroupRequiredMixin
from cookbook.models import Recipe, Sync, Keyword, RecipeImport, Storage, Comment, RecipeBook, \ from cookbook.models import Recipe, Sync, Keyword, RecipeImport, Storage, Comment, RecipeBook, \
RecipeBookEntry, MealPlan, Ingredient RecipeBookEntry, MealPlan, Ingredient
from cookbook.provider.dropbox import Dropbox from cookbook.provider.dropbox import Dropbox
from cookbook.provider.nextcloud import Nextcloud from cookbook.provider.nextcloud import Nextcloud
class RecipeDelete(LoginRequiredMixin, DeleteView): class RecipeDelete(GroupRequiredMixin, DeleteView):
groups_required = ['user']
template_name = "generic/delete_template.html" template_name = "generic/delete_template.html"
model = Recipe model = Recipe
success_url = reverse_lazy('index') success_url = reverse_lazy('index')
@ -23,6 +25,7 @@ class RecipeDelete(LoginRequiredMixin, DeleteView):
def delete_recipe_source(request, pk): def delete_recipe_source(request, pk):
group_required = ['user']
recipe = get_object_or_404(Recipe, pk=pk) recipe = get_object_or_404(Recipe, pk=pk)
if recipe.storage.method == Storage.DROPBOX: if recipe.storage.method == Storage.DROPBOX:
@ -38,7 +41,8 @@ def delete_recipe_source(request, pk):
return HttpResponseRedirect(reverse('edit_recipe', args=[recipe.pk])) return HttpResponseRedirect(reverse('edit_recipe', args=[recipe.pk]))
class RecipeImportDelete(LoginRequiredMixin, DeleteView): class RecipeImportDelete(GroupRequiredMixin, DeleteView):
groups_required = ['user']
template_name = "generic/delete_template.html" template_name = "generic/delete_template.html"
model = RecipeImport model = RecipeImport
success_url = reverse_lazy('list_recipe_import') success_url = reverse_lazy('list_recipe_import')
@ -49,7 +53,8 @@ class RecipeImportDelete(LoginRequiredMixin, DeleteView):
return context return context
class SyncDelete(LoginRequiredMixin, DeleteView): class SyncDelete(GroupRequiredMixin, DeleteView):
groups_required = ['admin']
template_name = "generic/delete_template.html" template_name = "generic/delete_template.html"
model = Sync model = Sync
success_url = reverse_lazy('data_sync') success_url = reverse_lazy('data_sync')
@ -60,7 +65,8 @@ class SyncDelete(LoginRequiredMixin, DeleteView):
return context return context
class KeywordDelete(LoginRequiredMixin, DeleteView): class KeywordDelete(GroupRequiredMixin, DeleteView):
groups_required = ['user']
template_name = "generic/delete_template.html" template_name = "generic/delete_template.html"
model = Keyword model = Keyword
success_url = reverse_lazy('list_keyword') success_url = reverse_lazy('list_keyword')
@ -71,7 +77,8 @@ class KeywordDelete(LoginRequiredMixin, DeleteView):
return context return context
class IngredientDelete(LoginRequiredMixin, DeleteView): class IngredientDelete(GroupRequiredMixin, DeleteView):
groups_required = ['user']
template_name = "generic/delete_template.html" template_name = "generic/delete_template.html"
model = Ingredient model = Ingredient
success_url = reverse_lazy('list_ingredient') success_url = reverse_lazy('list_ingredient')
@ -82,7 +89,8 @@ class IngredientDelete(LoginRequiredMixin, DeleteView):
return context return context
class StorageDelete(LoginRequiredMixin, DeleteView): class StorageDelete(GroupRequiredMixin, DeleteView):
groups_required = ['admin']
template_name = "generic/delete_template.html" template_name = "generic/delete_template.html"
model = Storage model = Storage
success_url = reverse_lazy('list_storage') success_url = reverse_lazy('list_storage')
@ -104,7 +112,8 @@ class CommentDelete(LoginRequiredMixin, DeleteView):
return context return context
class RecipeBookDelete(LoginRequiredMixin, DeleteView): class RecipeBookDelete(GroupRequiredMixin, DeleteView):
groups_required = ['user']
template_name = "generic/delete_template.html" template_name = "generic/delete_template.html"
model = RecipeBook model = RecipeBook
success_url = reverse_lazy('view_books') success_url = reverse_lazy('view_books')
@ -115,7 +124,8 @@ class RecipeBookDelete(LoginRequiredMixin, DeleteView):
return context return context
class RecipeBookEntryDelete(LoginRequiredMixin, DeleteView): class RecipeBookEntryDelete(GroupRequiredMixin, DeleteView):
groups_required = ['user']
template_name = "generic/delete_template.html" template_name = "generic/delete_template.html"
model = RecipeBookEntry model = RecipeBookEntry
success_url = reverse_lazy('view_books') success_url = reverse_lazy('view_books')
@ -126,7 +136,8 @@ class RecipeBookEntryDelete(LoginRequiredMixin, DeleteView):
return context return context
class MealPlanDelete(LoginRequiredMixin, DeleteView): class MealPlanDelete(GroupRequiredMixin, DeleteView):
groups_required = ['user']
template_name = "generic/delete_template.html" template_name = "generic/delete_template.html"
model = MealPlan model = MealPlan
success_url = reverse_lazy('view_plan') success_url = reverse_lazy('view_plan')

View File

@ -5,7 +5,6 @@ import simplejson
import simplejson as json import simplejson as json
from PIL import Image from PIL import Image
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.files import File from django.core.files import File
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
@ -16,13 +15,14 @@ from django.views.generic import UpdateView
from cookbook.forms import ExternalRecipeForm, KeywordForm, StorageForm, SyncForm, InternalRecipeForm, CommentForm, \ from cookbook.forms import ExternalRecipeForm, KeywordForm, StorageForm, SyncForm, InternalRecipeForm, CommentForm, \
MealPlanForm, UnitMergeForm, IngredientMergeForm, IngredientForm MealPlanForm, UnitMergeForm, IngredientMergeForm, IngredientForm
from cookbook.helper.group_helper import group_required, GroupRequiredMixin
from cookbook.models import Recipe, Sync, Keyword, RecipeImport, Storage, Comment, RecipeIngredient, RecipeBook, \ from cookbook.models import Recipe, Sync, Keyword, RecipeImport, Storage, Comment, RecipeIngredient, RecipeBook, \
MealPlan, Unit, Ingredient MealPlan, Unit, Ingredient
from cookbook.provider.dropbox import Dropbox from cookbook.provider.dropbox import Dropbox
from cookbook.provider.nextcloud import Nextcloud from cookbook.provider.nextcloud import Nextcloud
@login_required @group_required('guest')
def switch_recipe(request, pk): def switch_recipe(request, pk):
recipe = get_object_or_404(Recipe, pk=pk) recipe = get_object_or_404(Recipe, pk=pk)
if recipe.internal: if recipe.internal:
@ -31,7 +31,7 @@ def switch_recipe(request, pk):
return HttpResponseRedirect(reverse('edit_external_recipe', args=[pk])) return HttpResponseRedirect(reverse('edit_external_recipe', args=[pk]))
@login_required @group_required('user')
def convert_recipe(request, pk): def convert_recipe(request, pk):
recipe = get_object_or_404(Recipe, pk=pk) recipe = get_object_or_404(Recipe, pk=pk)
if not recipe.internal: if not recipe.internal:
@ -41,7 +41,7 @@ def convert_recipe(request, pk):
return HttpResponseRedirect(reverse('edit_internal_recipe', args=[pk])) return HttpResponseRedirect(reverse('edit_internal_recipe', args=[pk]))
@login_required @group_required('user')
def internal_recipe_update(request, pk): def internal_recipe_update(request, pk):
recipe_instance = get_object_or_404(Recipe, pk=pk) recipe_instance = get_object_or_404(Recipe, pk=pk)
status = 200 status = 200
@ -131,7 +131,8 @@ def internal_recipe_update(request, pk):
'view_url': reverse('view_recipe', args=[pk])}, status=status) 'view_url': reverse('view_recipe', args=[pk])}, status=status)
class SyncUpdate(LoginRequiredMixin, UpdateView): class SyncUpdate(GroupRequiredMixin, UpdateView):
groups_required = ['admin']
template_name = "generic/edit_template.html" template_name = "generic/edit_template.html"
model = Sync model = Sync
form_class = SyncForm form_class = SyncForm
@ -147,7 +148,8 @@ class SyncUpdate(LoginRequiredMixin, UpdateView):
return context return context
class KeywordUpdate(LoginRequiredMixin, UpdateView): class KeywordUpdate(GroupRequiredMixin, UpdateView):
groups_required = ['user']
template_name = "generic/edit_template.html" template_name = "generic/edit_template.html"
model = Keyword model = Keyword
form_class = KeywordForm form_class = KeywordForm
@ -163,7 +165,8 @@ class KeywordUpdate(LoginRequiredMixin, UpdateView):
return context return context
class IngredientUpdate(LoginRequiredMixin, UpdateView): class IngredientUpdate(GroupRequiredMixin, UpdateView):
groups_required = ['user']
template_name = "generic/edit_template.html" template_name = "generic/edit_template.html"
model = Ingredient model = Ingredient
form_class = IngredientForm form_class = IngredientForm
@ -179,7 +182,7 @@ class IngredientUpdate(LoginRequiredMixin, UpdateView):
return context return context
@login_required @group_required('admin')
def edit_storage(request, pk): def edit_storage(request, pk):
instance = get_object_or_404(Storage, pk=pk) instance = get_object_or_404(Storage, pk=pk)
@ -239,7 +242,8 @@ class CommentUpdate(LoginRequiredMixin, UpdateView):
return context return context
class ImportUpdate(LoginRequiredMixin, UpdateView): class ImportUpdate(GroupRequiredMixin, UpdateView):
groups_required = ['user']
template_name = "generic/edit_template.html" template_name = "generic/edit_template.html"
model = RecipeImport model = RecipeImport
fields = ['name', 'path'] fields = ['name', 'path']
@ -255,7 +259,8 @@ class ImportUpdate(LoginRequiredMixin, UpdateView):
return context return context
class RecipeBookUpdate(LoginRequiredMixin, UpdateView): class RecipeBookUpdate(GroupRequiredMixin, UpdateView):
groups_required = ['user']
template_name = "generic/edit_template.html" template_name = "generic/edit_template.html"
model = RecipeBook model = RecipeBook
fields = ['name'] fields = ['name']
@ -271,7 +276,8 @@ class RecipeBookUpdate(LoginRequiredMixin, UpdateView):
return context return context
class MealPlanUpdate(LoginRequiredMixin, UpdateView): class MealPlanUpdate(GroupRequiredMixin, UpdateView):
groups_required = ['user']
template_name = "generic/edit_template.html" template_name = "generic/edit_template.html"
model = MealPlan model = MealPlan
form_class = MealPlanForm form_class = MealPlanForm
@ -287,7 +293,8 @@ class MealPlanUpdate(LoginRequiredMixin, UpdateView):
return context return context
class ExternalRecipeUpdate(LoginRequiredMixin, UpdateView): class ExternalRecipeUpdate(GroupRequiredMixin, UpdateView):
groups_required = ['user']
model = Recipe model = Recipe
form_class = ExternalRecipeForm form_class = ExternalRecipeForm
template_name = "generic/edit_template.html" template_name = "generic/edit_template.html"
@ -322,7 +329,7 @@ class ExternalRecipeUpdate(LoginRequiredMixin, UpdateView):
return context return context
@login_required @group_required('user')
def edit_ingredients(request): def edit_ingredients(request):
if request.method == "POST": if request.method == "POST":
success = False success = False

View File

@ -11,9 +11,11 @@ from django.urls import reverse_lazy
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from cookbook.forms import ExportForm, ImportForm from cookbook.forms import ExportForm, ImportForm
from cookbook.helper.group_helper import group_required
from cookbook.models import RecipeIngredient, Recipe, Unit, Ingredient, Keyword from cookbook.models import RecipeIngredient, Recipe, Unit, Ingredient, Keyword
@group_required('user')
def import_recipe(request): def import_recipe(request):
if request.method == "POST": if request.method == "POST":
form = ImportForm(request.POST) form = ImportForm(request.POST)
@ -62,6 +64,7 @@ def import_recipe(request):
return render(request, 'import.html', {'form': form}) return render(request, 'import.html', {'form': form})
@group_required('user')
def export_recipe(request): def export_recipe(request):
context = {} context = {}
if request.method == "POST": if request.method == "POST":

View File

@ -1,16 +1,16 @@
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.db.models.functions import Lower from django.db.models.functions import Lower
from django.shortcuts import render from django.shortcuts import render
from django.urls import reverse_lazy
from django_tables2 import RequestConfig
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django_tables2 import RequestConfig
from cookbook.filters import IngredientFilter from cookbook.filters import IngredientFilter
from cookbook.helper.group_helper import group_required
from cookbook.models import Keyword, SyncLog, RecipeImport, Storage, Ingredient from cookbook.models import Keyword, SyncLog, RecipeImport, Storage, Ingredient
from cookbook.tables import KeywordTable, ImportLogTable, RecipeImportTable, StorageTable, IngredientTable from cookbook.tables import KeywordTable, ImportLogTable, RecipeImportTable, StorageTable, IngredientTable
@login_required @group_required('user')
def keyword(request): def keyword(request):
table = KeywordTable(Keyword.objects.all()) table = KeywordTable(Keyword.objects.all())
RequestConfig(request, paginate={'per_page': 25}).configure(table) RequestConfig(request, paginate={'per_page': 25}).configure(table)
@ -18,7 +18,7 @@ def keyword(request):
return render(request, 'generic/list_template.html', {'title': _("Keyword"), 'table': table, 'create_url': 'new_keyword'}) return render(request, 'generic/list_template.html', {'title': _("Keyword"), 'table': table, 'create_url': 'new_keyword'})
@login_required @group_required('admin')
def sync_log(request): def sync_log(request):
table = ImportLogTable(SyncLog.objects.all().order_by(Lower('created_at').desc())) table = ImportLogTable(SyncLog.objects.all().order_by(Lower('created_at').desc()))
RequestConfig(request, paginate={'per_page': 25}).configure(table) RequestConfig(request, paginate={'per_page': 25}).configure(table)
@ -26,7 +26,7 @@ def sync_log(request):
return render(request, 'generic/list_template.html', {'title': _("Import Log"), 'table': table}) return render(request, 'generic/list_template.html', {'title': _("Import Log"), 'table': table})
@login_required @group_required('user')
def recipe_import(request): def recipe_import(request):
table = RecipeImportTable(RecipeImport.objects.all()) table = RecipeImportTable(RecipeImport.objects.all())
@ -35,7 +35,7 @@ def recipe_import(request):
return render(request, 'generic/list_template.html', {'title': _("Discovery"), 'table': table, 'import_btn': True}) return render(request, 'generic/list_template.html', {'title': _("Discovery"), 'table': table, 'import_btn': True})
@login_required @group_required('user')
def ingredient(request): def ingredient(request):
f = IngredientFilter(request.GET, queryset=Ingredient.objects.all().order_by('pk')) f = IngredientFilter(request.GET, queryset=Ingredient.objects.all().order_by('pk'))
@ -45,7 +45,7 @@ def ingredient(request):
return render(request, 'generic/list_template.html', {'title': _("Ingredients"), 'table': table, 'filter': f}) return render(request, 'generic/list_template.html', {'title': _("Ingredients"), 'table': table, 'filter': f})
@login_required @group_required('admin')
def storage(request): def storage(request):
table = StorageTable(Storage.objects.all()) table = StorageTable(Storage.objects.all())
RequestConfig(request, paginate={'per_page': 25}).configure(table) RequestConfig(request, paginate={'per_page': 25}).configure(table)

View File

@ -2,8 +2,6 @@ import re
from datetime import datetime from datetime import datetime
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.shortcuts import render, redirect from django.shortcuts import render, redirect
from django.urls import reverse_lazy, reverse from django.urls import reverse_lazy, reverse
@ -12,10 +10,12 @@ 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
from cookbook.helper.group_helper import GroupRequiredMixin, group_required
from cookbook.models import Keyword, Recipe, RecipeBook, MealPlan from cookbook.models import Keyword, Recipe, RecipeBook, MealPlan
class RecipeCreate(LoginRequiredMixin, CreateView): class RecipeCreate(GroupRequiredMixin, CreateView):
groups_required = ['user']
template_name = "generic/new_template.html" template_name = "generic/new_template.html"
model = Recipe model = Recipe
fields = ('name',) fields = ('name',)
@ -36,7 +36,8 @@ class RecipeCreate(LoginRequiredMixin, CreateView):
return context return context
class KeywordCreate(LoginRequiredMixin, CreateView): class KeywordCreate(GroupRequiredMixin, CreateView):
groups_required = ['user']
template_name = "generic/new_template.html" template_name = "generic/new_template.html"
model = Keyword model = Keyword
form_class = KeywordForm form_class = KeywordForm
@ -48,7 +49,8 @@ class KeywordCreate(LoginRequiredMixin, CreateView):
return context return context
class StorageCreate(LoginRequiredMixin, CreateView): class StorageCreate(GroupRequiredMixin, CreateView):
groups_required = ['admin']
template_name = "generic/new_template.html" template_name = "generic/new_template.html"
model = Storage model = Storage
form_class = StorageForm form_class = StorageForm
@ -66,7 +68,7 @@ class StorageCreate(LoginRequiredMixin, CreateView):
return context return context
@login_required @group_required('user')
def create_new_external_recipe(request, import_id): def create_new_external_recipe(request, import_id):
if request.method == "POST": if request.method == "POST":
form = ImportRecipeForm(request.POST) form = ImportRecipeForm(request.POST)
@ -97,7 +99,8 @@ def create_new_external_recipe(request, import_id):
return render(request, 'forms/edit_import_recipe.html', {'form': form}) return render(request, 'forms/edit_import_recipe.html', {'form': form})
class RecipeBookCreate(LoginRequiredMixin, CreateView): class RecipeBookCreate(GroupRequiredMixin, CreateView):
groups_required = ['user']
template_name = "generic/new_template.html" template_name = "generic/new_template.html"
model = RecipeBook model = RecipeBook
form_class = RecipeBookForm form_class = RecipeBookForm
@ -115,7 +118,8 @@ class RecipeBookCreate(LoginRequiredMixin, CreateView):
return context return context
class MealPlanCreate(LoginRequiredMixin, CreateView): class MealPlanCreate(GroupRequiredMixin, CreateView):
groups_required = ['user']
template_name = "generic/new_template.html" template_name = "generic/new_template.html"
model = MealPlan model = MealPlan
form_class = MealPlanForm form_class = MealPlanForm

View File

@ -1,10 +1,8 @@
import copy import copy
import re
from datetime import datetime, timedelta from datetime import datetime, timedelta
from django.contrib import messages from django.contrib import messages
from django.contrib.auth import update_session_auth_hash from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import PasswordChangeForm from django.contrib.auth.forms import PasswordChangeForm
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404
@ -14,6 +12,7 @@ from django.utils.translation import gettext as _
from cookbook.filters import RecipeFilter from cookbook.filters import RecipeFilter
from cookbook.forms import * from cookbook.forms import *
from cookbook.helper.group_helper import group_required
from cookbook.tables import RecipeTable from cookbook.tables import RecipeTable
@ -44,7 +43,7 @@ def search(request):
return render(request, 'index.html') return render(request, 'index.html')
@login_required @group_required('guest')
def recipe_view(request, pk): def recipe_view(request, pk):
recipe = get_object_or_404(Recipe, pk=pk) recipe = get_object_or_404(Recipe, pk=pk)
ingredients = RecipeIngredient.objects.filter(recipe=recipe) ingredients = RecipeIngredient.objects.filter(recipe=recipe)
@ -80,7 +79,7 @@ def recipe_view(request, pk):
'bookmark_form': bookmark_form}) 'bookmark_form': bookmark_form})
@login_required() @group_required('user')
def books(request): def books(request):
book_list = [] book_list = []
@ -106,7 +105,7 @@ def get_days_from_week(start, end):
return days return days
@login_required() @group_required('user')
def meal_plan(request): def meal_plan(request):
js_week = datetime.now().strftime("%Y-W%V") js_week = datetime.now().strftime("%Y-W%V")
if request.method == "POST": if request.method == "POST":
@ -134,7 +133,7 @@ def meal_plan(request):
return render(request, 'meal_plan.html', {'js_week': js_week, 'plan': plan, 'days': days, 'surrounding_weeks': surrounding_weeks}) return render(request, 'meal_plan.html', {'js_week': js_week, 'plan': plan, 'days': days, 'surrounding_weeks': surrounding_weeks})
@login_required @group_required('user')
def shopping_list(request): def shopping_list(request):
markdown_format = True markdown_format = True
@ -174,7 +173,7 @@ def shopping_list(request):
return render(request, 'shopping_list.html', {'ingredients': ingredients, 'recipes': recipes, 'form': form, 'markdown_format': markdown_format}) return render(request, 'shopping_list.html', {'ingredients': ingredients, 'recipes': recipes, 'form': form, 'markdown_format': markdown_format})
@login_required @group_required('guest')
def settings(request): def settings(request):
try: try:
up = request.user.userpreference up = request.user.userpreference