added basic group permission system
This commit is contained in:
parent
c7046bc705
commit
ad467fae28
53
cookbook/helper/group_helper.py
Normal file
53
cookbook/helper/group_helper.py
Normal 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)
|
22
cookbook/migrations/0034_auto_20200426_1614.py
Normal file
22
cookbook/migrations/0034_auto_20200426_1614.py
Normal 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)
|
||||
]
|
@ -1,5 +1,5 @@
|
||||
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
|
||||
|
||||
|
||||
@ -11,14 +11,17 @@ class TestBase(TestCase):
|
||||
self.client = Client()
|
||||
self.client.force_login(User.objects.get_or_create(username='client')[0])
|
||||
user = auth.get_user(self.client)
|
||||
user.groups.add(Group.objects.get(name='admin'))
|
||||
self.assertTrue(user.is_authenticated)
|
||||
|
||||
self.another_client = Client()
|
||||
self.another_client.force_login(User.objects.get_or_create(username='another_client')[0])
|
||||
user = auth.get_user(self.another_client)
|
||||
user.groups.add(Group.objects.get(name='admin'))
|
||||
self.assertTrue(user.is_authenticated)
|
||||
|
||||
self.superuser_client = Client()
|
||||
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.groups.add(Group.objects.get(name='admin'))
|
||||
self.assertTrue(user.is_authenticated)
|
||||
|
@ -5,6 +5,7 @@ from django.utils.translation import gettext as _
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.shortcuts import redirect
|
||||
|
||||
from cookbook.helper.group_helper import group_required
|
||||
from cookbook.models import Recipe, Sync, Storage
|
||||
from cookbook.provider.dropbox import Dropbox
|
||||
from cookbook.provider.nextcloud import Nextcloud
|
||||
@ -26,7 +27,7 @@ def update_recipe_links(recipe):
|
||||
recipe.save()
|
||||
|
||||
|
||||
@login_required
|
||||
@group_required('user')
|
||||
def get_external_file_link(request, recipe_id):
|
||||
recipe = Recipe.objects.get(id=recipe_id)
|
||||
if not recipe.link:
|
||||
@ -35,7 +36,7 @@ def get_external_file_link(request, recipe_id):
|
||||
return HttpResponse(recipe.link)
|
||||
|
||||
|
||||
@login_required
|
||||
@group_required('user')
|
||||
def get_recipe_file(request, recipe_id):
|
||||
recipe = Recipe.objects.get(id=recipe_id)
|
||||
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))
|
||||
|
||||
|
||||
@login_required
|
||||
@group_required('user')
|
||||
def sync_all(request):
|
||||
monitors = Sync.objects.filter(active=True)
|
||||
|
||||
|
@ -7,11 +7,12 @@ from django.utils.translation import ngettext
|
||||
from django_tables2 import RequestConfig
|
||||
|
||||
from cookbook.forms import SyncForm, BatchEditForm
|
||||
from cookbook.helper.group_helper import group_required
|
||||
from cookbook.models import *
|
||||
from cookbook.tables import SyncTable
|
||||
|
||||
|
||||
@login_required
|
||||
@group_required('user')
|
||||
def sync(request):
|
||||
if request.method == "POST":
|
||||
form = SyncForm(request.POST)
|
||||
@ -31,12 +32,12 @@ def sync(request):
|
||||
return render(request, 'batch/monitor.html', {'form': form, 'monitored_paths': monitored_paths})
|
||||
|
||||
|
||||
@login_required
|
||||
@group_required('user')
|
||||
def sync_wait(request):
|
||||
return render(request, 'batch/waiting.html')
|
||||
|
||||
|
||||
@login_required
|
||||
@group_required('user')
|
||||
def batch_import(request):
|
||||
imports = RecipeImport.objects.all()
|
||||
for new_recipe in imports:
|
||||
@ -47,7 +48,7 @@ def batch_import(request):
|
||||
return redirect('list_recipe_import')
|
||||
|
||||
|
||||
@login_required
|
||||
@group_required('user')
|
||||
def batch_edit(request):
|
||||
if request.method == "POST":
|
||||
form = BatchEditForm(request.POST)
|
||||
@ -86,7 +87,7 @@ class Object(object):
|
||||
pass
|
||||
|
||||
|
||||
@login_required
|
||||
@group_required('user')
|
||||
def statistics(request):
|
||||
counts = Object()
|
||||
counts.recipes = Recipe.objects.count()
|
||||
|
@ -5,13 +5,15 @@ from django.urls import reverse_lazy, reverse
|
||||
from django.utils.translation import gettext as _
|
||||
from django.views.generic import DeleteView
|
||||
|
||||
from cookbook.helper.group_helper import GroupRequiredMixin
|
||||
from cookbook.models import Recipe, Sync, Keyword, RecipeImport, Storage, Comment, RecipeBook, \
|
||||
RecipeBookEntry, MealPlan, Ingredient
|
||||
from cookbook.provider.dropbox import Dropbox
|
||||
from cookbook.provider.nextcloud import Nextcloud
|
||||
|
||||
|
||||
class RecipeDelete(LoginRequiredMixin, DeleteView):
|
||||
class RecipeDelete(GroupRequiredMixin, DeleteView):
|
||||
groups_required = ['user']
|
||||
template_name = "generic/delete_template.html"
|
||||
model = Recipe
|
||||
success_url = reverse_lazy('index')
|
||||
@ -23,6 +25,7 @@ class RecipeDelete(LoginRequiredMixin, DeleteView):
|
||||
|
||||
|
||||
def delete_recipe_source(request, pk):
|
||||
group_required = ['user']
|
||||
recipe = get_object_or_404(Recipe, pk=pk)
|
||||
|
||||
if recipe.storage.method == Storage.DROPBOX:
|
||||
@ -38,7 +41,8 @@ def delete_recipe_source(request, 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"
|
||||
model = RecipeImport
|
||||
success_url = reverse_lazy('list_recipe_import')
|
||||
@ -49,7 +53,8 @@ class RecipeImportDelete(LoginRequiredMixin, DeleteView):
|
||||
return context
|
||||
|
||||
|
||||
class SyncDelete(LoginRequiredMixin, DeleteView):
|
||||
class SyncDelete(GroupRequiredMixin, DeleteView):
|
||||
groups_required = ['admin']
|
||||
template_name = "generic/delete_template.html"
|
||||
model = Sync
|
||||
success_url = reverse_lazy('data_sync')
|
||||
@ -60,7 +65,8 @@ class SyncDelete(LoginRequiredMixin, DeleteView):
|
||||
return context
|
||||
|
||||
|
||||
class KeywordDelete(LoginRequiredMixin, DeleteView):
|
||||
class KeywordDelete(GroupRequiredMixin, DeleteView):
|
||||
groups_required = ['user']
|
||||
template_name = "generic/delete_template.html"
|
||||
model = Keyword
|
||||
success_url = reverse_lazy('list_keyword')
|
||||
@ -71,7 +77,8 @@ class KeywordDelete(LoginRequiredMixin, DeleteView):
|
||||
return context
|
||||
|
||||
|
||||
class IngredientDelete(LoginRequiredMixin, DeleteView):
|
||||
class IngredientDelete(GroupRequiredMixin, DeleteView):
|
||||
groups_required = ['user']
|
||||
template_name = "generic/delete_template.html"
|
||||
model = Ingredient
|
||||
success_url = reverse_lazy('list_ingredient')
|
||||
@ -82,7 +89,8 @@ class IngredientDelete(LoginRequiredMixin, DeleteView):
|
||||
return context
|
||||
|
||||
|
||||
class StorageDelete(LoginRequiredMixin, DeleteView):
|
||||
class StorageDelete(GroupRequiredMixin, DeleteView):
|
||||
groups_required = ['admin']
|
||||
template_name = "generic/delete_template.html"
|
||||
model = Storage
|
||||
success_url = reverse_lazy('list_storage')
|
||||
@ -104,7 +112,8 @@ class CommentDelete(LoginRequiredMixin, DeleteView):
|
||||
return context
|
||||
|
||||
|
||||
class RecipeBookDelete(LoginRequiredMixin, DeleteView):
|
||||
class RecipeBookDelete(GroupRequiredMixin, DeleteView):
|
||||
groups_required = ['user']
|
||||
template_name = "generic/delete_template.html"
|
||||
model = RecipeBook
|
||||
success_url = reverse_lazy('view_books')
|
||||
@ -115,7 +124,8 @@ class RecipeBookDelete(LoginRequiredMixin, DeleteView):
|
||||
return context
|
||||
|
||||
|
||||
class RecipeBookEntryDelete(LoginRequiredMixin, DeleteView):
|
||||
class RecipeBookEntryDelete(GroupRequiredMixin, DeleteView):
|
||||
groups_required = ['user']
|
||||
template_name = "generic/delete_template.html"
|
||||
model = RecipeBookEntry
|
||||
success_url = reverse_lazy('view_books')
|
||||
@ -126,7 +136,8 @@ class RecipeBookEntryDelete(LoginRequiredMixin, DeleteView):
|
||||
return context
|
||||
|
||||
|
||||
class MealPlanDelete(LoginRequiredMixin, DeleteView):
|
||||
class MealPlanDelete(GroupRequiredMixin, DeleteView):
|
||||
groups_required = ['user']
|
||||
template_name = "generic/delete_template.html"
|
||||
model = MealPlan
|
||||
success_url = reverse_lazy('view_plan')
|
||||
|
@ -5,7 +5,6 @@ import simplejson
|
||||
import simplejson as json
|
||||
from PIL import Image
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.core.files import File
|
||||
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, \
|
||||
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, \
|
||||
MealPlan, Unit, Ingredient
|
||||
from cookbook.provider.dropbox import Dropbox
|
||||
from cookbook.provider.nextcloud import Nextcloud
|
||||
|
||||
|
||||
@login_required
|
||||
@group_required('guest')
|
||||
def switch_recipe(request, pk):
|
||||
recipe = get_object_or_404(Recipe, pk=pk)
|
||||
if recipe.internal:
|
||||
@ -31,7 +31,7 @@ def switch_recipe(request, pk):
|
||||
return HttpResponseRedirect(reverse('edit_external_recipe', args=[pk]))
|
||||
|
||||
|
||||
@login_required
|
||||
@group_required('user')
|
||||
def convert_recipe(request, pk):
|
||||
recipe = get_object_or_404(Recipe, pk=pk)
|
||||
if not recipe.internal:
|
||||
@ -41,7 +41,7 @@ def convert_recipe(request, pk):
|
||||
return HttpResponseRedirect(reverse('edit_internal_recipe', args=[pk]))
|
||||
|
||||
|
||||
@login_required
|
||||
@group_required('user')
|
||||
def internal_recipe_update(request, pk):
|
||||
recipe_instance = get_object_or_404(Recipe, pk=pk)
|
||||
status = 200
|
||||
@ -131,7 +131,8 @@ def internal_recipe_update(request, pk):
|
||||
'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"
|
||||
model = Sync
|
||||
form_class = SyncForm
|
||||
@ -147,7 +148,8 @@ class SyncUpdate(LoginRequiredMixin, UpdateView):
|
||||
return context
|
||||
|
||||
|
||||
class KeywordUpdate(LoginRequiredMixin, UpdateView):
|
||||
class KeywordUpdate(GroupRequiredMixin, UpdateView):
|
||||
groups_required = ['user']
|
||||
template_name = "generic/edit_template.html"
|
||||
model = Keyword
|
||||
form_class = KeywordForm
|
||||
@ -163,7 +165,8 @@ class KeywordUpdate(LoginRequiredMixin, UpdateView):
|
||||
return context
|
||||
|
||||
|
||||
class IngredientUpdate(LoginRequiredMixin, UpdateView):
|
||||
class IngredientUpdate(GroupRequiredMixin, UpdateView):
|
||||
groups_required = ['user']
|
||||
template_name = "generic/edit_template.html"
|
||||
model = Ingredient
|
||||
form_class = IngredientForm
|
||||
@ -179,7 +182,7 @@ class IngredientUpdate(LoginRequiredMixin, UpdateView):
|
||||
return context
|
||||
|
||||
|
||||
@login_required
|
||||
@group_required('admin')
|
||||
def edit_storage(request, pk):
|
||||
instance = get_object_or_404(Storage, pk=pk)
|
||||
|
||||
@ -239,7 +242,8 @@ class CommentUpdate(LoginRequiredMixin, UpdateView):
|
||||
return context
|
||||
|
||||
|
||||
class ImportUpdate(LoginRequiredMixin, UpdateView):
|
||||
class ImportUpdate(GroupRequiredMixin, UpdateView):
|
||||
groups_required = ['user']
|
||||
template_name = "generic/edit_template.html"
|
||||
model = RecipeImport
|
||||
fields = ['name', 'path']
|
||||
@ -255,7 +259,8 @@ class ImportUpdate(LoginRequiredMixin, UpdateView):
|
||||
return context
|
||||
|
||||
|
||||
class RecipeBookUpdate(LoginRequiredMixin, UpdateView):
|
||||
class RecipeBookUpdate(GroupRequiredMixin, UpdateView):
|
||||
groups_required = ['user']
|
||||
template_name = "generic/edit_template.html"
|
||||
model = RecipeBook
|
||||
fields = ['name']
|
||||
@ -271,7 +276,8 @@ class RecipeBookUpdate(LoginRequiredMixin, UpdateView):
|
||||
return context
|
||||
|
||||
|
||||
class MealPlanUpdate(LoginRequiredMixin, UpdateView):
|
||||
class MealPlanUpdate(GroupRequiredMixin, UpdateView):
|
||||
groups_required = ['user']
|
||||
template_name = "generic/edit_template.html"
|
||||
model = MealPlan
|
||||
form_class = MealPlanForm
|
||||
@ -287,7 +293,8 @@ class MealPlanUpdate(LoginRequiredMixin, UpdateView):
|
||||
return context
|
||||
|
||||
|
||||
class ExternalRecipeUpdate(LoginRequiredMixin, UpdateView):
|
||||
class ExternalRecipeUpdate(GroupRequiredMixin, UpdateView):
|
||||
groups_required = ['user']
|
||||
model = Recipe
|
||||
form_class = ExternalRecipeForm
|
||||
template_name = "generic/edit_template.html"
|
||||
@ -322,7 +329,7 @@ class ExternalRecipeUpdate(LoginRequiredMixin, UpdateView):
|
||||
return context
|
||||
|
||||
|
||||
@login_required
|
||||
@group_required('user')
|
||||
def edit_ingredients(request):
|
||||
if request.method == "POST":
|
||||
success = False
|
||||
|
@ -11,9 +11,11 @@ from django.urls import reverse_lazy
|
||||
|
||||
from django.utils.translation import gettext as _
|
||||
from cookbook.forms import ExportForm, ImportForm
|
||||
from cookbook.helper.group_helper import group_required
|
||||
from cookbook.models import RecipeIngredient, Recipe, Unit, Ingredient, Keyword
|
||||
|
||||
|
||||
@group_required('user')
|
||||
def import_recipe(request):
|
||||
if request.method == "POST":
|
||||
form = ImportForm(request.POST)
|
||||
@ -62,6 +64,7 @@ def import_recipe(request):
|
||||
return render(request, 'import.html', {'form': form})
|
||||
|
||||
|
||||
@group_required('user')
|
||||
def export_recipe(request):
|
||||
context = {}
|
||||
if request.method == "POST":
|
||||
|
@ -1,16 +1,16 @@
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.db.models.functions import Lower
|
||||
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_tables2 import RequestConfig
|
||||
|
||||
from cookbook.filters import IngredientFilter
|
||||
from cookbook.helper.group_helper import group_required
|
||||
from cookbook.models import Keyword, SyncLog, RecipeImport, Storage, Ingredient
|
||||
from cookbook.tables import KeywordTable, ImportLogTable, RecipeImportTable, StorageTable, IngredientTable
|
||||
|
||||
|
||||
@login_required
|
||||
@group_required('user')
|
||||
def keyword(request):
|
||||
table = KeywordTable(Keyword.objects.all())
|
||||
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'})
|
||||
|
||||
|
||||
@login_required
|
||||
@group_required('admin')
|
||||
def sync_log(request):
|
||||
table = ImportLogTable(SyncLog.objects.all().order_by(Lower('created_at').desc()))
|
||||
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})
|
||||
|
||||
|
||||
@login_required
|
||||
@group_required('user')
|
||||
def recipe_import(request):
|
||||
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})
|
||||
|
||||
|
||||
@login_required
|
||||
@group_required('user')
|
||||
def ingredient(request):
|
||||
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})
|
||||
|
||||
|
||||
@login_required
|
||||
@group_required('admin')
|
||||
def storage(request):
|
||||
table = StorageTable(Storage.objects.all())
|
||||
RequestConfig(request, paginate={'per_page': 25}).configure(table)
|
||||
|
@ -2,8 +2,6 @@ import re
|
||||
from datetime import datetime
|
||||
|
||||
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.shortcuts import render, redirect
|
||||
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, \
|
||||
RecipeBookForm, MealPlanForm
|
||||
from cookbook.helper.group_helper import GroupRequiredMixin, group_required
|
||||
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"
|
||||
model = Recipe
|
||||
fields = ('name',)
|
||||
@ -36,7 +36,8 @@ class RecipeCreate(LoginRequiredMixin, CreateView):
|
||||
return context
|
||||
|
||||
|
||||
class KeywordCreate(LoginRequiredMixin, CreateView):
|
||||
class KeywordCreate(GroupRequiredMixin, CreateView):
|
||||
groups_required = ['user']
|
||||
template_name = "generic/new_template.html"
|
||||
model = Keyword
|
||||
form_class = KeywordForm
|
||||
@ -48,7 +49,8 @@ class KeywordCreate(LoginRequiredMixin, CreateView):
|
||||
return context
|
||||
|
||||
|
||||
class StorageCreate(LoginRequiredMixin, CreateView):
|
||||
class StorageCreate(GroupRequiredMixin, CreateView):
|
||||
groups_required = ['admin']
|
||||
template_name = "generic/new_template.html"
|
||||
model = Storage
|
||||
form_class = StorageForm
|
||||
@ -66,7 +68,7 @@ class StorageCreate(LoginRequiredMixin, CreateView):
|
||||
return context
|
||||
|
||||
|
||||
@login_required
|
||||
@group_required('user')
|
||||
def create_new_external_recipe(request, import_id):
|
||||
if request.method == "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})
|
||||
|
||||
|
||||
class RecipeBookCreate(LoginRequiredMixin, CreateView):
|
||||
class RecipeBookCreate(GroupRequiredMixin, CreateView):
|
||||
groups_required = ['user']
|
||||
template_name = "generic/new_template.html"
|
||||
model = RecipeBook
|
||||
form_class = RecipeBookForm
|
||||
@ -115,7 +118,8 @@ class RecipeBookCreate(LoginRequiredMixin, CreateView):
|
||||
return context
|
||||
|
||||
|
||||
class MealPlanCreate(LoginRequiredMixin, CreateView):
|
||||
class MealPlanCreate(GroupRequiredMixin, CreateView):
|
||||
groups_required = ['user']
|
||||
template_name = "generic/new_template.html"
|
||||
model = MealPlan
|
||||
form_class = MealPlanForm
|
||||
|
@ -1,10 +1,8 @@
|
||||
import copy
|
||||
import re
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from django.contrib import messages
|
||||
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.http import HttpResponseRedirect
|
||||
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.forms import *
|
||||
from cookbook.helper.group_helper import group_required
|
||||
from cookbook.tables import RecipeTable
|
||||
|
||||
|
||||
@ -44,7 +43,7 @@ def search(request):
|
||||
return render(request, 'index.html')
|
||||
|
||||
|
||||
@login_required
|
||||
@group_required('guest')
|
||||
def recipe_view(request, pk):
|
||||
recipe = get_object_or_404(Recipe, pk=pk)
|
||||
ingredients = RecipeIngredient.objects.filter(recipe=recipe)
|
||||
@ -80,7 +79,7 @@ def recipe_view(request, pk):
|
||||
'bookmark_form': bookmark_form})
|
||||
|
||||
|
||||
@login_required()
|
||||
@group_required('user')
|
||||
def books(request):
|
||||
book_list = []
|
||||
|
||||
@ -106,7 +105,7 @@ def get_days_from_week(start, end):
|
||||
return days
|
||||
|
||||
|
||||
@login_required()
|
||||
@group_required('user')
|
||||
def meal_plan(request):
|
||||
js_week = datetime.now().strftime("%Y-W%V")
|
||||
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})
|
||||
|
||||
|
||||
@login_required
|
||||
@group_required('user')
|
||||
def shopping_list(request):
|
||||
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})
|
||||
|
||||
|
||||
@login_required
|
||||
@group_required('guest')
|
||||
def settings(request):
|
||||
try:
|
||||
up = request.user.userpreference
|
||||
|
Loading…
Reference in New Issue
Block a user