fixed recipe api permissions when using shared recipes
This commit is contained in:
@ -9,6 +9,7 @@ from django.utils.translation import gettext as _
|
|||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.urls import reverse_lazy, reverse
|
from django.urls import reverse_lazy, reverse
|
||||||
from rest_framework import permissions
|
from rest_framework import permissions
|
||||||
|
from rest_framework.permissions import SAFE_METHODS
|
||||||
|
|
||||||
from cookbook.models import ShareLink
|
from cookbook.models import ShareLink
|
||||||
|
|
||||||
@ -154,6 +155,9 @@ class CustomIsGuest(permissions.BasePermission):
|
|||||||
def has_permission(self, request, view):
|
def has_permission(self, request, view):
|
||||||
return has_group_permission(request.user, ['guest'])
|
return has_group_permission(request.user, ['guest'])
|
||||||
|
|
||||||
|
def has_object_permission(self, request, view, obj):
|
||||||
|
return has_group_permission(request.user, ['guest'])
|
||||||
|
|
||||||
|
|
||||||
class CustomIsUser(permissions.BasePermission):
|
class CustomIsUser(permissions.BasePermission):
|
||||||
"""
|
"""
|
||||||
@ -175,3 +179,20 @@ class CustomIsAdmin(permissions.BasePermission):
|
|||||||
|
|
||||||
def has_permission(self, request, view):
|
def has_permission(self, request, view):
|
||||||
return has_group_permission(request.user, ['admin'])
|
return has_group_permission(request.user, ['admin'])
|
||||||
|
|
||||||
|
|
||||||
|
class CustomIsShare(permissions.BasePermission):
|
||||||
|
"""
|
||||||
|
Custom permission class for django rest framework views
|
||||||
|
verifies the requesting user provided a valid share link
|
||||||
|
"""
|
||||||
|
message = _('You do not have the required permissions to view this page!')
|
||||||
|
|
||||||
|
def has_permission(self, request, view):
|
||||||
|
return request.method in SAFE_METHODS and 'pk' in view.kwargs
|
||||||
|
|
||||||
|
def has_object_permission(self, request, view, obj):
|
||||||
|
share = request.query_params.get('share', None)
|
||||||
|
if share:
|
||||||
|
return share_link_valid(obj, share)
|
||||||
|
return False
|
||||||
|
@ -105,6 +105,8 @@
|
|||||||
<br/>
|
<br/>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="row" v-if="recipe && has_ingredients">
|
<div class="row" v-if="recipe && has_ingredients">
|
||||||
<div class="col-md-6 order-md-1 col-sm-12 order-sm-2 col-12 order-2">
|
<div class="col-md-6 order-md-1 col-sm-12 order-sm-2 col-12 order-2">
|
||||||
<div class="card border-primary">
|
<div class="card border-primary">
|
||||||
@ -482,7 +484,8 @@
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
loadRecipe: function () {
|
loadRecipe: function () {
|
||||||
this.$http.get("{% url 'api:recipe-detail' recipe.pk %}").then((response) => {
|
this.$http.get("{% url 'api:recipe-detail' recipe.pk %}" {% if share %}
|
||||||
|
+ "?share={{ share }}"{% endif %}).then((response) => {
|
||||||
this.recipe = response.data;
|
this.recipe = response.data;
|
||||||
this.loading = false
|
this.loading = false
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ from rest_framework.parsers import JSONParser, FileUploadParser, MultiPartParser
|
|||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.viewsets import ViewSetMixin
|
from rest_framework.viewsets import ViewSetMixin
|
||||||
|
|
||||||
from cookbook.helper.permission_helper import group_required, CustomIsOwner, CustomIsAdmin, CustomIsUser, CustomIsGuest
|
from cookbook.helper.permission_helper import group_required, CustomIsOwner, CustomIsAdmin, CustomIsUser, CustomIsGuest, CustomIsShare
|
||||||
from cookbook.helper.recipe_url_import import get_from_html
|
from cookbook.helper.recipe_url_import import get_from_html
|
||||||
from cookbook.models import Recipe, Sync, Storage, CookLog, MealPlan, MealType, ViewLog, UserPreference, RecipeBook, Ingredient, Food, Step, Keyword, Unit, SyncLog
|
from cookbook.models import Recipe, Sync, Storage, CookLog, MealPlan, MealType, ViewLog, UserPreference, RecipeBook, Ingredient, Food, Step, Keyword, Unit, SyncLog
|
||||||
from cookbook.provider.dropbox import Dropbox
|
from cookbook.provider.dropbox import Dropbox
|
||||||
@ -198,7 +198,7 @@ class RecipeViewSet(viewsets.ModelViewSet, StandardFilterMixin):
|
|||||||
"""
|
"""
|
||||||
queryset = Recipe.objects.all()
|
queryset = Recipe.objects.all()
|
||||||
serializer_class = RecipeSerializer
|
serializer_class = RecipeSerializer
|
||||||
permission_classes = [permissions.IsAuthenticated] # TODO split read and write permission for meal plan guest
|
permission_classes = [CustomIsShare | CustomIsGuest] # TODO split read and write permission for meal plan guest
|
||||||
|
|
||||||
@decorators.action(
|
@decorators.action(
|
||||||
detail=True,
|
detail=True,
|
||||||
|
@ -116,7 +116,7 @@ def recipe_view(request, pk, share=None):
|
|||||||
|
|
||||||
return render(request, 'recipe_view.html',
|
return render(request, 'recipe_view.html',
|
||||||
{'recipe': recipe, 'comments': comments, 'comment_form': comment_form,
|
{'recipe': recipe, 'comments': comments, 'comment_form': comment_form,
|
||||||
'bookmark_form': bookmark_form})
|
'bookmark_form': bookmark_form, 'share': share})
|
||||||
|
|
||||||
|
|
||||||
@group_required('user')
|
@group_required('user')
|
||||||
|
Reference in New Issue
Block a user