fixed permissions comments, books
This commit is contained in:
parent
ad467fae28
commit
1617fa7a3f
@ -80,7 +80,7 @@ class RecipeBookAdmin(admin.ModelAdmin):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def user_name(obj):
|
def user_name(obj):
|
||||||
return obj.user.get_user_name()
|
return obj.created_by.get_user_name()
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(RecipeBook, RecipeBookAdmin)
|
admin.site.register(RecipeBook, RecipeBookAdmin)
|
||||||
@ -98,7 +98,7 @@ class MealPlanAdmin(admin.ModelAdmin):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def user(obj):
|
def user(obj):
|
||||||
return obj.user.get_user_name()
|
return obj.created_by.get_user_name()
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(MealPlan, MealPlanAdmin)
|
admin.site.register(MealPlan, MealPlanAdmin)
|
||||||
|
@ -5,7 +5,7 @@ from django.contrib import messages
|
|||||||
from django.contrib.auth.decorators import user_passes_test
|
from django.contrib.auth.decorators import user_passes_test
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy, reverse
|
||||||
|
|
||||||
|
|
||||||
def get_allowed_groups(groups_required):
|
def get_allowed_groups(groups_required):
|
||||||
@ -51,3 +51,18 @@ class GroupRequiredMixin(object):
|
|||||||
messages.add_message(request, messages.ERROR, _('You do not have the required permissions to view this page!'))
|
messages.add_message(request, messages.ERROR, _('You do not have the required permissions to view this page!'))
|
||||||
return HttpResponseRedirect(reverse_lazy('index'))
|
return HttpResponseRedirect(reverse_lazy('index'))
|
||||||
return super(GroupRequiredMixin, self).dispatch(request, *args, **kwargs)
|
return super(GroupRequiredMixin, self).dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class OwnerRequiredMixin(object):
|
||||||
|
|
||||||
|
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:
|
||||||
|
obj = self.get_object()
|
||||||
|
if not (obj.created_by == request.user or request.user.is_superuser):
|
||||||
|
messages.add_message(request, messages.ERROR, _('You cannot interact with this object as its not owned by you!'))
|
||||||
|
return HttpResponseRedirect(reverse('index'))
|
||||||
|
|
||||||
|
return super(OwnerRequiredMixin, self).dispatch(request, *args, **kwargs)
|
28
cookbook/migrations/0035_auto_20200427_1637.py
Normal file
28
cookbook/migrations/0035_auto_20200427_1637.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# Generated by Django 3.0.5 on 2020-04-27 14:37
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('cookbook', '0034_auto_20200426_1614'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='mealplan',
|
||||||
|
old_name='user',
|
||||||
|
new_name='created_by',
|
||||||
|
),
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='recipebook',
|
||||||
|
old_name='user',
|
||||||
|
new_name='created_by',
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='userpreference',
|
||||||
|
name='default_page',
|
||||||
|
field=models.CharField(choices=[('SEARCH', 'Search'), ('PLAN', 'Meal-Plan'), ('BOOKS', 'Books')], default='SEARCH', max_length=64),
|
||||||
|
),
|
||||||
|
]
|
@ -188,7 +188,7 @@ class RecipeImport(models.Model):
|
|||||||
|
|
||||||
class RecipeBook(models.Model):
|
class RecipeBook(models.Model):
|
||||||
name = models.CharField(max_length=128)
|
name = models.CharField(max_length=128)
|
||||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
@ -209,7 +209,7 @@ class MealPlan(models.Model):
|
|||||||
OTHER = 'OTHER'
|
OTHER = 'OTHER'
|
||||||
MEAL_TYPES = ((BREAKFAST, _('Breakfast')), (LUNCH, _('Lunch')), (DINNER, _('Dinner')), (OTHER, _('Other')),)
|
MEAL_TYPES = ((BREAKFAST, _('Breakfast')), (LUNCH, _('Lunch')), (DINNER, _('Dinner')), (OTHER, _('Other')),)
|
||||||
|
|
||||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE)
|
recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE)
|
||||||
meal = models.CharField(choices=MEAL_TYPES, max_length=128, default=BREAKFAST)
|
meal = models.CharField(choices=MEAL_TYPES, max_length=128, default=BREAKFAST)
|
||||||
note = models.TextField(blank=True)
|
note = models.TextField(blank=True)
|
||||||
|
@ -5,7 +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.helper.permission_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
|
||||||
|
@ -7,7 +7,7 @@ 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.helper.permission_helper import group_required
|
||||||
from cookbook.models import *
|
from cookbook.models import *
|
||||||
from cookbook.tables import SyncTable
|
from cookbook.tables import SyncTable
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
from django.contrib import messages
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
@ -5,7 +6,7 @@ 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.helper.permission_helper import GroupRequiredMixin, OwnerRequiredMixin
|
||||||
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
|
||||||
@ -101,7 +102,7 @@ class StorageDelete(GroupRequiredMixin, DeleteView):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class CommentDelete(LoginRequiredMixin, DeleteView):
|
class CommentDelete(OwnerRequiredMixin, DeleteView):
|
||||||
template_name = "generic/delete_template.html"
|
template_name = "generic/delete_template.html"
|
||||||
model = Comment
|
model = Comment
|
||||||
success_url = reverse_lazy('index')
|
success_url = reverse_lazy('index')
|
||||||
@ -112,8 +113,7 @@ class CommentDelete(LoginRequiredMixin, DeleteView):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class RecipeBookDelete(GroupRequiredMixin, DeleteView):
|
class RecipeBookDelete(OwnerRequiredMixin, 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')
|
||||||
@ -130,14 +130,20 @@ class RecipeBookEntryDelete(GroupRequiredMixin, DeleteView):
|
|||||||
model = RecipeBookEntry
|
model = RecipeBookEntry
|
||||||
success_url = reverse_lazy('view_books')
|
success_url = reverse_lazy('view_books')
|
||||||
|
|
||||||
|
def dispatch(self, request, *args, **kwargs):
|
||||||
|
obj = self.get_object()
|
||||||
|
if not (obj.book.created_by == request.user or request.user.is_superuser):
|
||||||
|
messages.add_message(request, messages.ERROR, _('You cannot interact with this object as its not owned by you!'))
|
||||||
|
return HttpResponseRedirect(reverse('index'))
|
||||||
|
return super(RecipeBookEntryDelete, self).dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(RecipeBookEntryDelete, self).get_context_data(**kwargs)
|
context = super(RecipeBookEntryDelete, self).get_context_data(**kwargs)
|
||||||
context['title'] = _("Bookmarks")
|
context['title'] = _("Bookmarks")
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class MealPlanDelete(GroupRequiredMixin, DeleteView):
|
class MealPlanDelete(OwnerRequiredMixin, 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')
|
||||||
|
@ -15,7 +15,9 @@ 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.helper.permission_helper import group_required, GroupRequiredMixin
|
||||||
|
|
||||||
|
from cookbook.helper.permission_helper import OwnerRequiredMixin
|
||||||
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
|
||||||
@ -218,20 +220,11 @@ def edit_storage(request, pk):
|
|||||||
return render(request, 'generic/edit_template.html', {'form': form})
|
return render(request, 'generic/edit_template.html', {'form': form})
|
||||||
|
|
||||||
|
|
||||||
class CommentUpdate(LoginRequiredMixin, UpdateView):
|
class CommentUpdate(OwnerRequiredMixin, UpdateView):
|
||||||
template_name = "generic/edit_template.html"
|
template_name = "generic/edit_template.html"
|
||||||
model = Comment
|
model = Comment
|
||||||
form_class = CommentForm
|
form_class = CommentForm
|
||||||
|
|
||||||
# TODO add msg box
|
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
|
||||||
obj = self.get_object()
|
|
||||||
if not (obj.created_by == request.user or request.user.is_superuser):
|
|
||||||
messages.add_message(request, messages.ERROR, _('You cannot edit this comment!'))
|
|
||||||
return HttpResponseRedirect(reverse('view_recipe', args=[obj.recipe.pk]))
|
|
||||||
return super(CommentUpdate, self).dispatch(request, *args, **kwargs)
|
|
||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
return reverse('edit_comment', kwargs={'pk': self.object.pk})
|
return reverse('edit_comment', kwargs={'pk': self.object.pk})
|
||||||
|
|
||||||
@ -259,14 +252,11 @@ class ImportUpdate(GroupRequiredMixin, UpdateView):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class RecipeBookUpdate(GroupRequiredMixin, UpdateView):
|
class RecipeBookUpdate(OwnerRequiredMixin, UpdateView):
|
||||||
groups_required = ['user']
|
|
||||||
template_name = "generic/edit_template.html"
|
template_name = "generic/edit_template.html"
|
||||||
model = RecipeBook
|
model = RecipeBook
|
||||||
fields = ['name']
|
fields = ['name']
|
||||||
|
|
||||||
# TODO add msg box
|
|
||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
return reverse('view_books')
|
return reverse('view_books')
|
||||||
|
|
||||||
@ -276,14 +266,11 @@ class RecipeBookUpdate(GroupRequiredMixin, UpdateView):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class MealPlanUpdate(GroupRequiredMixin, UpdateView):
|
class MealPlanUpdate(OwnerRequiredMixin, 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
|
||||||
|
|
||||||
# TODO add msg box
|
|
||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
return reverse('view_plan')
|
return reverse('view_plan')
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ 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.helper.permission_helper import group_required
|
||||||
from cookbook.models import RecipeIngredient, Recipe, Unit, Ingredient, Keyword
|
from cookbook.models import RecipeIngredient, Recipe, Unit, Ingredient, Keyword
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ from django.utils.translation import gettext as _
|
|||||||
from django_tables2 import RequestConfig
|
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.helper.permission_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
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ 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.helper.permission_helper import GroupRequiredMixin, group_required
|
||||||
from cookbook.models import Keyword, Recipe, RecipeBook, MealPlan
|
from cookbook.models import Keyword, Recipe, RecipeBook, MealPlan
|
||||||
|
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ class RecipeBookCreate(GroupRequiredMixin, CreateView):
|
|||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
obj = form.save(commit=False)
|
obj = form.save(commit=False)
|
||||||
obj.user = self.request.user
|
obj.created_by = self.request.user
|
||||||
obj.save()
|
obj.save()
|
||||||
return HttpResponseRedirect(reverse('view_books'))
|
return HttpResponseRedirect(reverse('view_books'))
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ class MealPlanCreate(GroupRequiredMixin, CreateView):
|
|||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
obj = form.save(commit=False)
|
obj = form.save(commit=False)
|
||||||
obj.user = self.request.user
|
obj.created_by = self.request.user
|
||||||
obj.save()
|
obj.save()
|
||||||
return HttpResponseRedirect(reverse('view_plan'))
|
return HttpResponseRedirect(reverse('view_plan'))
|
||||||
|
|
||||||
|
@ -12,7 +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.helper.permission_helper import group_required
|
||||||
from cookbook.tables import RecipeTable
|
from cookbook.tables import RecipeTable
|
||||||
|
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ def recipe_view(request, pk):
|
|||||||
def books(request):
|
def books(request):
|
||||||
book_list = []
|
book_list = []
|
||||||
|
|
||||||
books = RecipeBook.objects.filter(user=request.user).all()
|
books = RecipeBook.objects.filter(created_by=request.user).all()
|
||||||
|
|
||||||
for b in books:
|
for b in books:
|
||||||
book_list.append({'book': b, 'recipes': RecipeBookEntry.objects.filter(book=b).all()})
|
book_list.append({'book': b, 'recipes': RecipeBookEntry.objects.filter(book=b).all()})
|
||||||
|
Loading…
Reference in New Issue
Block a user