Commit e876b068 authored by Arkadiusz Hiler's avatar Arkadiusz Hiler Committed by Arkadiusz Hiler

permissions: Introduce central point for defining permissions

They were spread all over the place and somewhat duplicated.

This introduces clear notation and a single place to define all the
complicated logic for checking whether someone has permission to do
something.
Signed-off-by: Arkadiusz Hiler's avatarArkadiusz Hiler <arkadiusz.hiler@intel.com>
parent c53d12b3
......@@ -95,11 +95,6 @@ class Project(models.Model):
subject_prefix_tags = models.CharField(max_length=255, blank=True,
help_text='Comma separated list of tags')
def is_editable(self, user):
if not user.is_authenticated():
return False
return self in user.profile.maintainer_projects.all()
@cached_property
def tags(self):
if not self.use_tags:
......@@ -374,15 +369,6 @@ class Patch(models.Model):
super(Patch, self).save()
def is_editable(self, user):
if not user.is_authenticated():
return False
if self.submitter.user == user or self.delegate == user:
return True
return self.project.is_editable(user)
def filename(self):
return filename(self.name, '.patch')
......
# Patchwork - automated patch tracking system
# Copyright (C) 2018 Intel Corporation
#
# This file is part of the Patchwork package.
#
# Patchwork is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Patchwork is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Patchwork; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
from patchwork.models import Project, Patch
class Can:
def __init__(self, user):
self.user = user
def edit(self, obj):
can = self
if isinstance(obj, Project):
project = obj
return (self.user.is_authenticated and
project in self.user.profile.maintainer_projects.all())
if isinstance(obj, Patch):
patch = obj
return (self.user.is_authenticated and
(patch.submitter.user == self.user or
can.edit(patch.project)))
return False
......@@ -33,6 +33,7 @@ from patchwork.paginator import Paginator
from patchwork.forms import MultiplePatchForm
from patchwork.models import Comment, Patch
from patchwork.filters import Filters
from patchwork.permissions import Can
def generic_list(request, project, view,
......@@ -157,7 +158,7 @@ def process_multiplepatch_form(form, user, action, patches, context):
changed_patches = 0
for patch in patches:
if not patch.is_editable(user):
if not Can(user).edit(patch):
errors.append("You don't have permissions to edit patch '%s'"
% patch.name)
continue
......
......@@ -40,6 +40,7 @@ from patchwork.serializers import (ProjectSerializer, SeriesSerializer,
EventLogSerializer, TestResultSerializer)
from patchwork.views import patch_to_mbox
from patchwork.views.patch import mbox as patch_mbox
from patchwork.permissions import Can
import django_filters
......@@ -82,11 +83,7 @@ class MaintainerPermission(permissions.BasePermission):
if request.method in permissions.SAFE_METHODS:
return True
# editable for maintainers
user = request.user
if not user.is_authenticated():
return False
return obj.project.is_editable(user)
return Can(request.user).edit(obj.project)
class RequestDjangoFilterBackend(filters.DjangoFilterBackend):
......
......@@ -26,11 +26,12 @@ from django.utils import six
from patchwork.forms import PatchForm, CreateBundleForm
from patchwork.models import Patch, Project, Bundle, TestResult
from patchwork.views import generic_list, patch_to_mbox
from patchwork.permissions import Can
def patch(request, patch_id):
patch = get_object_or_404(Patch, id=patch_id)
editable = patch.is_editable(request.user)
editable = Can(request.user).edit(patch)
messages = []
form = None
......
......@@ -21,16 +21,17 @@ from django.conf import settings
from django.shortcuts import render, get_object_or_404, get_list_or_404
from django.views.generic import View
from patchwork.models import Project, Series, SeriesRevision, TestResult
from patchwork.permissions import Can
class SeriesListView(View):
def get(self, request, *args, **kwargs):
project = get_object_or_404(Project, linkname=kwargs['project'])
is_editable = project.is_editable(request.user)
return render(request, 'patchwork/series-list.html', {
'project': project,
'is_editable': is_editable,
'is_editable': Can(request.user).edit(project),
'default_patches_per_page': settings.DEFAULT_PATCHES_PER_PAGE,
})
......@@ -48,12 +49,10 @@ class SeriesView(View):
.filter(revision=revision, patch=None) \
.order_by('test__name').select_related('test')
is_editable = project.is_editable(request.user)
return render(request, 'patchwork/series.html', {
'series': series,
'project': project,
'is_editable': is_editable,
'is_editable': Can(request.user).edit(project),
'cover_letter': revision.cover_letter,
'revisions': revisions,
})
......@@ -42,6 +42,7 @@ from django.utils.six.moves.xmlrpc_server import SimpleXMLRPCDispatcher
from patchwork.models import Patch, Project, Person, State
from patchwork.threadlocalrequest import ThreadLocalRequestMiddleware
from patchwork.views import patch_to_mbox
from patchwork.permissions import Can
class PatchworkXMLRPCDispatcher(SimpleXMLRPCDispatcher,
......@@ -737,7 +738,7 @@ def patch_set(user, patch_id, params):
patch = Patch.objects.get(id=patch_id)
if not patch.is_editable(user):
if not Can(user).edit(patch):
raise Exception('No permissions to edit this patch')
for (k, v) in params.items():
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment