Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/du584 replace perms codenames resolver #587

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions akvo/api/resources/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
# Akvo RSR is covered by the GNU Affero General Public License.
# See more details in the license.txt file located at the root folder of the Akvo RSR module.
# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >.


from decimal import Decimal

from django.contrib.auth import get_permission_codename
from django.core.exceptions import ObjectDoesNotExist

from django.forms.models import ModelForm

from tastypie import fields
Expand All @@ -26,7 +28,7 @@
from akvo.rsr.models import (
Project, Benchmarkname, Category, Goal, Partnership, BudgetItem, ProjectLocation, Benchmark
)
from akvo.utils import get_rsr_limited_change_permission
from akvo.utils import RSR_LIMITED_CHANGE

from .resources import ConditionalFullResource, get_extra_thumbnails
from .partnership import FIELD_NAME, FIELD_LONG_NAME
Expand Down Expand Up @@ -286,9 +288,9 @@ def get_object_list(self, request):
object_list = super(ProjectResource, self).get_object_list(request)
if self._meta.authentication.is_authenticated(request):
opts = Project._meta
if request.user.has_perm(opts.app_label + '.' + opts.get_change_permission()):
if request.user.has_perm(opts.app_label + '.' + get_permission_codename('change', opts)):
return object_list
elif request.user.has_perm(opts.app_label + '.' + get_rsr_limited_change_permission(opts)):
elif request.user.has_perm(opts.app_label + '.' + get_permission_codename(RSR_LIMITED_CHANGE, opts)):
object_list = object_list.published() | object_list.of_partner(
request.user.userprofile.organisation
)
Expand Down
72 changes: 32 additions & 40 deletions akvo/rsr/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from django.contrib import admin
from django.contrib.admin import helpers, widgets
from django.contrib.admin.util import flatten_fieldsets
from django.contrib.auth import get_permission_codename
from django.contrib.auth.admin import GroupAdmin
from django.contrib.auth.models import Group
from django.core.exceptions import PermissionDenied
Expand All @@ -22,7 +23,7 @@

from akvo.rsr.forms import PartnerSiteAdminForm
from akvo.rsr.mixins import TimestampsAdminDisplayMixin
from akvo.utils import get_rsr_limited_change_permission, permissions, custom_get_or_create_country
from akvo.utils import permissions, custom_get_or_create_country, RSR_LIMITED_CHANGE

NON_FIELD_ERRORS = '__all__'
csrf_protect_m = method_decorator(csrf_protect)
Expand Down Expand Up @@ -53,7 +54,7 @@ def get_actions(self, request):
""" Remove delete admin action for "non certified" users"""
actions = super(CountryAdmin, self).get_actions(request)
opts = self.opts
if not request.user.has_perm(opts.app_label + '.' + opts.get_delete_permission()):
if not request.user.has_perm(opts.app_label + '.' + get_permission_codename('delete', opts)):
del actions['delete_selected']
return actions

Expand Down Expand Up @@ -130,7 +131,7 @@ def get_actions(self, request):
""" Remove delete admin action for "non certified" users"""
actions = super(OrganisationAdmin, self).get_actions(request)
opts = self.opts
if not request.user.has_perm(opts.app_label + '.' + opts.get_delete_permission()):
if not request.user.has_perm(opts.app_label + '.' + get_permission_codename('delete', opts)):
del actions['delete_selected']
return actions

Expand All @@ -148,13 +149,13 @@ def allowed_partner_types(self, obj):

def get_list_display(self, request):
# see the notes fields in the change list if you have the right permissions
if request.user.has_perm(self.opts.app_label + '.' + self.opts.get_change_permission()):
if request.user.has_perm(self.opts.app_label + '.' + get_permission_codename('change', self.opts)):
return list(self.list_display) + ['allowed_partner_types']
return super(OrganisationAdmin, self).get_list_display(request)

def get_readonly_fields(self, request, obj=None):
# parter_types is read only unless you have change permission for organisations
if not request.user.has_perm(self.opts.app_label + '.' + self.opts.get_change_permission()):
if not request.user.has_perm(self.opts.app_label + '.' + get_permission_codename('change', self.opts)):
self.readonly_fields = ('partner_types', 'created_at', 'last_modified_at',)
else:
self.readonly_fields = ('created_at', 'last_modified_at',)
Expand All @@ -163,9 +164,9 @@ def get_readonly_fields(self, request, obj=None):
def queryset(self, request):
qs = super(OrganisationAdmin, self).queryset(request)
opts = self.opts
if request.user.has_perm(opts.app_label + '.' + opts.get_change_permission()):
if request.user.has_perm(opts.app_label + '.' + get_permission_codename('change', opts)):
return qs
elif request.user.has_perm(opts.app_label + '.' + get_rsr_limited_change_permission(opts)):
elif request.user.has_perm(opts.app_label + '.' + get_permission_codename(RSR_LIMITED_CHANGE, opts)):
organisation = request.user.userprofile.organisation
return qs.filter(pk=organisation.id)
else:
Expand All @@ -178,14 +179,12 @@ def has_change_permission(self, request, obj=None):

If `obj` is None, this should return True if the given request has
permission to change *any* object of the given type.

get_rsr_limited_change_permission is used for partner orgs to limit their listing and editing to
"own" projects, organisation and user profiles
"""
opts = self.opts
if request.user.has_perm(opts.app_label + '.' + opts.get_change_permission()):
if request.user.has_perm(opts.app_label + '.' + get_permission_codename('change', opts)):
return True
if request.user.has_perm(opts.app_label + '.' + get_rsr_limited_change_permission(opts)):
# RSR Partner admins/editors: limit their listing and editing to "own" projects, organisation and user profiles
if request.user.has_perm(opts.app_label + '.' + get_permission_codename(RSR_LIMITED_CHANGE, opts)):
if obj:
return obj == request.user.userprofile.organisation
else:
Expand Down Expand Up @@ -499,7 +498,7 @@ def get_actions(self, request):
""" Remove delete admin action for "non certified" users"""
actions = super(ProjectAdmin, self).get_actions(request)
opts = self.opts
if not request.user.has_perm(opts.app_label + '.' + opts.get_delete_permission()):
if not request.user.has_perm(opts.app_label + '.' + get_permission_codename('delete', opts)):
del actions['delete_selected']
return actions

Expand All @@ -518,10 +517,10 @@ def queryset(self, request):
"""
qs = super(ProjectAdmin, self).queryset(request)
opts = self.opts
user_profile = request.user.userprofile
if request.user.has_perm(opts.app_label + '.' + opts.get_change_permission()):
if request.user.has_perm(opts.app_label + '.' + get_permission_codename('change', opts)):
return qs
elif request.user.has_perm(opts.app_label + '.' + get_rsr_limited_change_permission(opts)):
elif request.user.has_perm(opts.app_label + '.' + get_permission_codename(RSR_LIMITED_CHANGE, opts)):
user_profile = request.user.userprofile
projects = user_profile.organisation.all_projects()
# Access to Partner users may be limited by Support partner "ownership"
allowed_projects = [project.pk for project in projects if user_profile.allow_edit(project)]
Expand All @@ -536,20 +535,17 @@ def has_change_permission(self, request, obj=None):

If `obj` is None, this should return True if the given request has
permission to change *any* object of the given type.

get_rsr_limited_change_permission is used for partner orgs to limit their listing and editing to
"own" projects, organisation and user profiles
"""
opts = self.opts
user = request.user
user_profile = user.userprofile

# RSR editors/managers
if user.has_perm(opts.app_label + '.' + opts.get_change_permission()):
if user.has_perm(opts.app_label + '.' + get_permission_codename('change', opts)):
return True

# RSR Partner admins/editors
if user.has_perm(opts.app_label + '.' + get_rsr_limited_change_permission(opts)):
# RSR Partner admins/editors: limit their listing and editing to "own" projects, organisation and user profiles
if user.has_perm(opts.app_label + '.' + get_permission_codename(RSR_LIMITED_CHANGE, opts)):
# On the Project form
if obj:
return user_profile.allow_edit(obj)
Expand Down Expand Up @@ -694,7 +690,7 @@ def get_actions(self, request):
""" Remove delete admin action for "non certified" users"""
actions = super(UserProfileAdmin, self).get_actions(request)
opts = self.opts
if not request.user.has_perm(opts.app_label + '.' + opts.get_delete_permission()):
if not request.user.has_perm(opts.app_label + '.' + get_permission_codename('delete', opts)):
del actions['delete_selected']
return actions

Expand All @@ -712,9 +708,9 @@ def queryset(self, request):
"""
qs = super(UserProfileAdmin, self).queryset(request)
opts = self.opts
if request.user.has_perm(opts.app_label + '.' + opts.get_change_permission()):
if request.user.has_perm(opts.app_label + '.' + get_permission_codename('change', opts)):
return qs
elif request.user.has_perm(opts.app_label + '.' + get_rsr_limited_change_permission(opts)):
elif request.user.has_perm(opts.app_label + '.' + get_permission_codename(RSR_LIMITED_CHANGE, opts)):
organisation = request.user.userprofile.organisation
return qs.filter(organisation=organisation)
else:
Expand All @@ -727,14 +723,12 @@ def has_change_permission(self, request, obj=None):

If `obj` is None, this should return True if the given request has
permission to change *any* object of the given type.

get_rsr_limited_change_permission is used for partner orgs to limit their listing and editing to
"own" projects, organisation and user profiles
"""
opts = self.opts
if request.user.has_perm(opts.app_label + '.' + opts.get_change_permission()):
if request.user.has_perm(opts.app_label + '.' + get_permission_codename('change', opts)):
return True
if request.user.has_perm(opts.app_label + '.' + get_rsr_limited_change_permission(opts)):
# RSR Partner admins/editors: limit their listing and editing to "own" projects, organisation and user profiles
if request.user.has_perm(opts.app_label + '.' + get_permission_codename(RSR_LIMITED_CHANGE, opts)):
my_org = request.user.userprofile.organisation
if obj:
return obj.organisation == my_org
Expand Down Expand Up @@ -876,7 +870,7 @@ def get_fieldsets(self, request, obj=None):
# don't show the notes field unless you have "add" permission on the PartnerSite model
# (currently means an Akvo staff user (or superuser))
# note that this is somewhat fragile as it relies on adding/removing from the _first_ fieldset
if request.user.has_perm(self.opts.app_label + '.' + self.opts.get_add_permission()):
if request.user.has_perm(self.opts.app_label + '.' + get_permission_codename('add', self.opts)):
self.fieldsets[0][1]['fields'] = ('organisation', 'enabled', 'notes',)
else:
self.fieldsets[0][1]['fields'] = ('organisation', 'enabled',)
Expand All @@ -891,24 +885,24 @@ def get_form(self, request, obj=None, **kwargs):

def get_list_display(self, request):
# see the notes fields in the change list if you have the right permissions
if request.user.has_perm(self.opts.app_label + '.' + self.opts.get_add_permission()):
if request.user.has_perm(self.opts.app_label + '.' + get_permission_codename('add', self.opts)):
return list(self.list_display) + ['notes']
return super(PartnerSiteAdmin, self).get_list_display(request)

def get_actions(self, request):
""" Remove delete admin action for "non certified" users"""
actions = super(PartnerSiteAdmin, self).get_actions(request)
opts = self.opts
if not request.user.has_perm(opts.app_label + '.' + opts.get_delete_permission()):
if not request.user.has_perm(opts.app_label + '.' + get_permission_codename('delete', opts)):
del actions['delete_selected']
return actions

def queryset(self, request):
qs = super(PartnerSiteAdmin, self).queryset(request)
opts = self.opts
if request.user.has_perm(opts.app_label + '.' + opts.get_change_permission()):
if request.user.has_perm(opts.app_label + '.' + get_permission_codename('change', opts)):
return qs
elif request.user.has_perm(opts.app_label + '.' + get_rsr_limited_change_permission(opts)):
elif request.user.has_perm(opts.app_label + '.' + get_permission_codename(RSR_LIMITED_CHANGE, opts)):
organisation = request.user.userprofile.organisation
return qs.filter(organisation=organisation)
else:
Expand All @@ -921,14 +915,12 @@ def has_change_permission(self, request, obj=None):

If `obj` is None, this should return True if the given request has
permission to change *any* object of the given type.

get_rsr_limited_change_permission is used for partner orgs to limit their listing and editing to
"own" projects, organisation, patner_site and user profiles
"""
opts = self.opts
if request.user.has_perm(opts.app_label + '.' + opts.get_change_permission()):
if request.user.has_perm(opts.app_label + '.' + get_permission_codename('change', opts)):
return True
if request.user.has_perm(opts.app_label + '.' + get_rsr_limited_change_permission(opts)):
# RSR Partner admins/editors: limit their listing and editing to "own" projects, organisation and user profiles
if request.user.has_perm(opts.app_label + '.' + get_permission_codename(RSR_LIMITED_CHANGE, opts)):
if obj:
return obj.organisation == request.user.userprofile.organisation
else:
Expand Down
12 changes: 0 additions & 12 deletions akvo/rsr/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@
from akvo.rsr.decorators import fetch_project, project_viewing_permissions
from akvo.rsr.iso3166 import COUNTRY_CONTINENTS

from akvo.utils import (wordpress_get_lastest_posts, get_rsr_limited_change_permission,
get_random_from_qs, state_equals, right_now_in_akvo)

from django import forms
from django import http
from django.conf import settings
Expand Down Expand Up @@ -828,18 +825,9 @@ def projectmain(request, project, draft=False, can_add_update=False):
if project.benchmarks.filter(category=category).aggregate(Sum('value'))['value__sum']
])

# a little model meta data magic
opts = project._meta
if request.user.has_perm(opts.app_label + '.' + get_rsr_limited_change_permission(opts)):
admin_change_url = reverse('admin:rsr_project_change', args=(project.id,)),
admin_change_url = admin_change_url[0] # don't friggin ask why!!!
else:
admin_change_url = None

can_add_update = project.connected_to_user(request.user)

return {
'admin_change_url': admin_change_url,
'benchmarks': benchmarks,
'can_add_update': can_add_update,
'draft': draft,
Expand Down
5 changes: 0 additions & 5 deletions akvo/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,6 @@ def groups_from_user(user):
return [group.name for group in user.groups.all()]


#Modeled on Options method get_change_permission in django/db/models/options.py
def get_rsr_limited_change_permission(obj):
return '%s_%s' % (RSR_LIMITED_CHANGE, obj.object_name.lower())


def rsr_image_path(instance, file_name, path_template='db/project/%s/%s'):
"""
Use to set ImageField upload_to attribute.
Expand Down