mirror of
https://github.com/jazzband/django-authority.git
synced 2026-03-16 22:20:28 +00:00
Merge pull request #46 from safwanrahman/master
Update and add migration for django 1.8
This commit is contained in:
commit
c713eb5419
19 changed files with 180 additions and 90 deletions
12
.travis.yml
12
.travis.yml
|
|
@ -2,16 +2,8 @@ language: python
|
|||
python:
|
||||
- "2.7"
|
||||
env:
|
||||
- TOX_ENV=py26-django14
|
||||
- TOX_ENV=py26-django15
|
||||
- TOX_ENV=py26-django16
|
||||
- TOX_ENV=py27-django14
|
||||
- TOX_ENV=py27-django15
|
||||
- TOX_ENV=py27-django16
|
||||
- TOX_ENV=py27-django17
|
||||
- TOX_ENV=py33-django15
|
||||
- TOX_ENV=py33-django16
|
||||
- TOX_ENV=py33-django17
|
||||
- TOX_ENV=py27-django18
|
||||
- TOX_ENV=py33-django18
|
||||
install:
|
||||
- pip install tox
|
||||
notifications:
|
||||
|
|
|
|||
|
|
@ -56,6 +56,15 @@ html version using the setup.py::
|
|||
Changelog:
|
||||
==========
|
||||
|
||||
0.11 (2016-03-29):
|
||||
-----------------
|
||||
|
||||
* Added Migration in order to support Django 1.8
|
||||
|
||||
* Dropped Support for Django 1.7 and lower
|
||||
|
||||
* Fix linter issues
|
||||
|
||||
0.10 (2015-12-14):
|
||||
------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
import sys
|
||||
from authority.sites import site, get_check, get_choices_for, register, unregister
|
||||
|
||||
from authority.sites import site, get_check, get_choices_for, register, unregister # noqa
|
||||
|
||||
|
||||
LOADING = False
|
||||
|
||||
|
||||
def autodiscover():
|
||||
"""
|
||||
Goes and imports the permissions submodule of every app in INSTALLED_APPS
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import django
|
||||
from django import forms, template
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.utils.translation import ugettext, ungettext, ugettext_lazy as _
|
||||
|
|
@ -21,15 +20,11 @@ try:
|
|||
except ImportError:
|
||||
actions = False
|
||||
|
||||
# From 1.7 forward, Django consistenly uses the name "utils",
|
||||
# not "util". We alias for backwards compatibility.
|
||||
if django.VERSION[:2] < (1, 7):
|
||||
forms.utils = forms.util
|
||||
|
||||
from authority.models import Permission
|
||||
from authority.widgets import GenericForeignKeyRawIdWidget
|
||||
from authority import get_choices_for
|
||||
|
||||
|
||||
class PermissionInline(generic.GenericTabularInline):
|
||||
model = Permission
|
||||
raw_id_fields = ('user', 'group', 'creator')
|
||||
|
|
@ -42,10 +37,12 @@ class PermissionInline(generic.GenericTabularInline):
|
|||
kwargs['widget'] = forms.Select(choices=perm_choices)
|
||||
return super(PermissionInline, self).formfield_for_dbfield(db_field, **kwargs)
|
||||
|
||||
|
||||
class ActionPermissionInline(PermissionInline):
|
||||
raw_id_fields = ()
|
||||
template = 'admin/edit_inline/action_tabular.html'
|
||||
|
||||
|
||||
class ActionErrorList(forms.utils.ErrorList):
|
||||
def __init__(self, inline_formsets):
|
||||
for inline_formset in inline_formsets:
|
||||
|
|
@ -53,6 +50,7 @@ class ActionErrorList(forms.utils.ErrorList):
|
|||
for errors_in_inline_form in inline_formset.errors:
|
||||
self.extend(errors_in_inline_form.values())
|
||||
|
||||
|
||||
def edit_permissions(modeladmin, request, queryset):
|
||||
opts = modeladmin.model._meta
|
||||
app_label = opts.app_label
|
||||
|
|
@ -128,6 +126,7 @@ def edit_permissions(modeladmin, request, queryset):
|
|||
context_instance=template.RequestContext(request))
|
||||
edit_permissions.short_description = _("Edit permissions for selected %(verbose_name_plural)s")
|
||||
|
||||
|
||||
class PermissionAdmin(admin.ModelAdmin):
|
||||
list_display = ('codename', 'content_type', 'user', 'group', 'approved')
|
||||
list_filter = ('approved', 'content_type')
|
||||
|
|
@ -143,7 +142,10 @@ class PermissionAdmin(admin.ModelAdmin):
|
|||
|
||||
def formfield_for_dbfield(self, db_field, **kwargs):
|
||||
# For generic foreign keys marked as generic_fields we use a special widget
|
||||
if db_field.name in [f.fk_field for f in self.model._meta.virtual_fields if f.name in self.generic_fields]:
|
||||
names = [f.fk_field
|
||||
for f in self.model._meta.virtual_fields
|
||||
if f.name in self.generic_fields]
|
||||
if db_field.name in names:
|
||||
for gfk in self.model._meta.virtual_fields:
|
||||
if gfk.fk_field == db_field.name:
|
||||
kwargs['widget'] = GenericForeignKeyRawIdWidget(
|
||||
|
|
@ -161,7 +163,8 @@ class PermissionAdmin(admin.ModelAdmin):
|
|||
def approve_permissions(self, request, queryset):
|
||||
for permission in queryset:
|
||||
permission.approve(request.user)
|
||||
message = ungettext("%(count)d permission successfully approved.",
|
||||
message = ungettext(
|
||||
"%(count)d permission successfully approved.",
|
||||
"%(count)d permissions successfully approved.", len(queryset))
|
||||
self.message_user(request, message % {'count': len(queryset)})
|
||||
approve_permissions.short_description = _("Approve selected permissions")
|
||||
|
|
|
|||
|
|
@ -11,4 +11,6 @@ try:
|
|||
from django.contrib.auth import get_user_model
|
||||
except ImportError:
|
||||
from django.contrib.auth.models import User
|
||||
get_user_model = lambda: User
|
||||
|
||||
def get_user_model():
|
||||
return User
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ from django.contrib.auth import REDIRECT_FIELD_NAME
|
|||
from authority import get_check
|
||||
from authority.views import permission_denied
|
||||
|
||||
|
||||
def permission_required(perm, *lookup_variables, **kwargs):
|
||||
"""
|
||||
Decorator for views that checks whether a user has a particular permission
|
||||
|
|
@ -18,6 +19,7 @@ def permission_required(perm, *lookup_variables, **kwargs):
|
|||
login_url = kwargs.pop('login_url', settings.LOGIN_URL)
|
||||
redirect_field_name = kwargs.pop('redirect_field_name', REDIRECT_FIELD_NAME)
|
||||
redirect_to_login = kwargs.pop('redirect_to_login', True)
|
||||
|
||||
def decorate(view_func):
|
||||
def decorated(request, *args, **kwargs):
|
||||
if request.user.is_authenticated():
|
||||
|
|
@ -60,6 +62,7 @@ def permission_required(perm, *lookup_variables, **kwargs):
|
|||
return wraps(view_func)(decorated)
|
||||
return decorate
|
||||
|
||||
|
||||
def permission_required_or_403(perm, *args, **kwargs):
|
||||
"""
|
||||
Decorator that wraps the permission_required decorator and returns a
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
class AuthorityException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class NotAModel(AuthorityException):
|
||||
def __init__(self, object):
|
||||
super(NotAModel, self).__init__(
|
||||
"Not a model class or instance")
|
||||
|
||||
|
||||
class UnsavedModelInstance(AuthorityException):
|
||||
def __init__(self, object):
|
||||
super(UnsavedModelInstance, self).__init__(
|
||||
|
|
|
|||
|
|
@ -95,7 +95,8 @@ class GroupPermissionForm(BasePermissionForm):
|
|||
check = permissions.BasePermission(group=group)
|
||||
if check.has_perm(self.perm, self.obj):
|
||||
raise forms.ValidationError(mark_safe(
|
||||
_("This group already has the permission '%(perm)s' for %(object_name)s '%(obj)s'") % {
|
||||
_("This group already has the permission '%(perm)s' "
|
||||
"for %(object_name)s '%(obj)s'") % {
|
||||
'perm': self.perm,
|
||||
'object_name': self.obj._meta.object_name.lower(),
|
||||
'obj': self.obj,
|
||||
|
|
|
|||
43
authority/migrations/0001_initial.py
Normal file
43
authority/migrations/0001_initial.py
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
import datetime
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('auth', '0001_initial'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('contenttypes', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Permission',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('codename', models.CharField(max_length=100, verbose_name='codename')),
|
||||
('object_id', models.PositiveIntegerField()),
|
||||
('approved', models.BooleanField(default=False, help_text='Designates whether the permission has been approved and treated as active. Unselect this instead of deleting permissions.', verbose_name='approved')),
|
||||
('date_requested', models.DateTimeField(default=datetime.datetime.now, verbose_name='date requested')),
|
||||
('date_approved', models.DateTimeField(null=True, verbose_name='date approved', blank=True)),
|
||||
('content_type', models.ForeignKey(related_name='row_permissions', to='contenttypes.ContentType')),
|
||||
('creator', models.ForeignKey(related_name='created_permissions', blank=True, to=settings.AUTH_USER_MODEL, null=True)),
|
||||
('group', models.ForeignKey(blank=True, to='auth.Group', null=True)),
|
||||
('user', models.ForeignKey(related_name='granted_permissions', blank=True, to=settings.AUTH_USER_MODEL, null=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'permission',
|
||||
'verbose_name_plural': 'permissions',
|
||||
'permissions': (('change_foreign_permissions', 'Can change foreign permissions'), ('delete_foreign_permissions', 'Can delete foreign permissions'), ('approve_permission_requests', 'Can approve permission requests')),
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='permission',
|
||||
unique_together=set([('codename', 'object_id', 'content_type', 'user', 'group')]),
|
||||
),
|
||||
]
|
||||
0
authority/migrations/__init__.py
Normal file
0
authority/migrations/__init__.py
Normal file
|
|
@ -20,11 +20,17 @@ class Permission(models.Model):
|
|||
object_id = models.PositiveIntegerField()
|
||||
content_object = generic.GenericForeignKey('content_type', 'object_id')
|
||||
|
||||
user = models.ForeignKey(user_model_label, null=True, blank=True, related_name='granted_permissions')
|
||||
user = models.ForeignKey(
|
||||
user_model_label, null=True, blank=True, related_name='granted_permissions')
|
||||
group = models.ForeignKey(Group, null=True, blank=True)
|
||||
creator = models.ForeignKey(user_model_label, null=True, blank=True, related_name='created_permissions')
|
||||
creator = models.ForeignKey(
|
||||
user_model_label, null=True, blank=True, related_name='created_permissions')
|
||||
|
||||
approved = models.BooleanField(_('approved'), default=False, help_text=_("Designates whether the permission has been approved and treated as active. Unselect this instead of deleting permissions."))
|
||||
approved = models.BooleanField(
|
||||
_('approved'),
|
||||
default=False,
|
||||
help_text=_("Designates whether the permission has been approved and treated as active. "
|
||||
"Unselect this instead of deleting permissions."))
|
||||
|
||||
date_requested = models.DateTimeField(_('date requested'), default=datetime.now)
|
||||
date_approved = models.DateTimeField(_('date approved'), blank=True, null=True)
|
||||
|
|
|
|||
|
|
@ -6,12 +6,15 @@ from django.core.exceptions import ImproperlyConfigured
|
|||
|
||||
from authority.permissions import BasePermission
|
||||
|
||||
|
||||
class AlreadyRegistered(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class NotRegistered(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class PermissionSite(object):
|
||||
"""
|
||||
A dictionary that contains permission instances and their labels.
|
||||
|
|
@ -64,8 +67,8 @@ class PermissionSite(object):
|
|||
|
||||
if permission_class.label in self.get_labels():
|
||||
raise ImproperlyConfigured(
|
||||
"The name of %s conflicts with %s" % (permission_class,
|
||||
self.get_permission_by_label(permission_class.label)))
|
||||
"The name of %s conflicts with %s" % (
|
||||
permission_class, self.get_permission_by_label(permission_class.label)))
|
||||
|
||||
for model in model_or_iterable:
|
||||
if model in self._registry:
|
||||
|
|
@ -73,8 +76,8 @@ class PermissionSite(object):
|
|||
'The model %s is already registered' % model.__name__)
|
||||
if options:
|
||||
options['__module__'] = __name__
|
||||
permission_class = type("%sPermission" % model.__name__,
|
||||
(permission_class,), options)
|
||||
permission_class = type(
|
||||
"%sPermission" % model.__name__, (permission_class,), options)
|
||||
|
||||
permission_class.model = model
|
||||
self.setup(model, permission_class)
|
||||
|
|
@ -94,7 +97,9 @@ class PermissionSite(object):
|
|||
if check_func is not None:
|
||||
func = self.create_check(check_name, check_func)
|
||||
func.__name__ = check_name
|
||||
func.short_description = getattr(check_func, 'short_description',
|
||||
func.short_description = getattr(
|
||||
check_func,
|
||||
'short_description',
|
||||
_("%(object_name)s permission '%(check)s'") % {
|
||||
'object_name': model._meta.object_name,
|
||||
'check': check_name})
|
||||
|
|
@ -122,6 +127,7 @@ class PermissionSite(object):
|
|||
return granted
|
||||
return check
|
||||
|
||||
|
||||
class PermissionDescriptor(object):
|
||||
def get_content_type(self, obj=None):
|
||||
ContentType = models.get_model("contenttypes", "contenttype")
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
{% block breadcrumbs %}{% if not is_popup %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="../../">{% trans "Home" %}</a> ›
|
||||
<a href="../">{{ app_label|capfirst|escape }}</a> ›
|
||||
<a href="../">{{ app_label|capfirst|escape }}</a> ›
|
||||
<a href="./">{{ opts.verbose_name_plural|capfirst }}</a> ›
|
||||
{% trans "Permissions" %}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -145,7 +145,6 @@ class PermissionFormNode(ResolverNode):
|
|||
@classmethod
|
||||
def handle_token(cls, parser, token, approved):
|
||||
bits = token.contents.split()
|
||||
tag_name = bits[0]
|
||||
kwargs = {
|
||||
'obj': cls.next_bit_for(bits, 'for'),
|
||||
'perm': cls.next_bit_for(bits, 'using', None),
|
||||
|
|
@ -164,7 +163,7 @@ class PermissionFormNode(ResolverNode):
|
|||
obj = self.resolve(self.obj, context)
|
||||
perm = self.resolve(self.perm, context)
|
||||
if self.template_name:
|
||||
template_name = [self.resolve(obj, context) for obj in self.template_name.split(',')]
|
||||
template_name = [self.resolve(o, context) for o in self.template_name.split(',')]
|
||||
else:
|
||||
template_name = 'authority/permission_form.html'
|
||||
request = context['request']
|
||||
|
|
@ -185,12 +184,15 @@ class PermissionFormNode(ResolverNode):
|
|||
'form_url': url_for_obj('authority-add-permission-request', obj),
|
||||
'next': request.build_absolute_uri(),
|
||||
'approved': self.approved,
|
||||
'form': UserPermissionForm(perm, obj,
|
||||
approved=self.approved, initial=dict(
|
||||
codename=perm, user=request.user.username)),
|
||||
'form': UserPermissionForm(
|
||||
perm,
|
||||
obj,
|
||||
approved=self.approved,
|
||||
initial=dict(codename=perm, user=request.user.username)),
|
||||
}
|
||||
return template.loader.render_to_string(template_name, extra_context,
|
||||
context_instance=template.RequestContext(request))
|
||||
return template.loader.render_to_string(
|
||||
template_name, extra_context, context_instance=template.RequestContext(request))
|
||||
|
||||
|
||||
@register.tag
|
||||
def permission_form(parser, token):
|
||||
|
|
@ -206,6 +208,7 @@ def permission_form(parser, token):
|
|||
"""
|
||||
return PermissionFormNode.handle_token(parser, token, approved=True)
|
||||
|
||||
|
||||
@register.tag
|
||||
def permission_request_form(parser, token):
|
||||
"""
|
||||
|
|
@ -215,7 +218,8 @@ def permission_request_form(parser, token):
|
|||
Syntax::
|
||||
|
||||
{% permission_request_form for OBJ and PERMISSION_LABEL.CHECK_NAME [with TEMPLATE] %}
|
||||
{% permission_request_form for lesson using "lesson_permission.add_lesson" with "authority/permission_request_form.html" %}
|
||||
{% permission_request_form for lesson using "lesson_permission.add_lesson"
|
||||
with "authority/permission_request_form.html" %}
|
||||
|
||||
"""
|
||||
return PermissionFormNode.handle_token(parser, token, approved=False)
|
||||
|
|
@ -254,6 +258,7 @@ class PermissionsForObjectNode(ResolverNode):
|
|||
context[var_name] = perms
|
||||
return ''
|
||||
|
||||
|
||||
@register.tag
|
||||
def get_permissions(parser, token):
|
||||
"""
|
||||
|
|
@ -274,6 +279,7 @@ def get_permissions(parser, token):
|
|||
return PermissionsForObjectNode.handle_token(parser, token, approved=True,
|
||||
name='"permissions"')
|
||||
|
||||
|
||||
@register.tag
|
||||
def get_permission_requests(parser, token):
|
||||
"""
|
||||
|
|
@ -295,6 +301,7 @@ def get_permission_requests(parser, token):
|
|||
approved=False,
|
||||
name='"permission_requests"')
|
||||
|
||||
|
||||
class PermissionForObjectNode(ResolverNode):
|
||||
|
||||
@classmethod
|
||||
|
|
@ -337,6 +344,7 @@ class PermissionForObjectNode(ResolverNode):
|
|||
context[var_name] = granted
|
||||
return ''
|
||||
|
||||
|
||||
@register.tag
|
||||
def get_permission(parser, token):
|
||||
"""
|
||||
|
|
@ -347,8 +355,10 @@ def get_permission(parser, token):
|
|||
|
||||
{% get_permission PERMISSION_LABEL.CHECK_NAME for USER and *OBJS [as VARNAME] %}
|
||||
|
||||
{% get_permission "poll_permission.change_poll" for request.user and poll as "is_allowed" %}
|
||||
{% get_permission "poll_permission.change_poll" for request.user and poll,second_poll as "is_allowed" %}
|
||||
{% get_permission "poll_permission.change_poll"
|
||||
for request.user and poll as "is_allowed" %}
|
||||
{% get_permission "poll_permission.change_poll"
|
||||
for request.user and poll,second_poll as "is_allowed" %}
|
||||
|
||||
{% if is_allowed %}
|
||||
I've got ze power to change ze pollllllzzz. Muahahaa.
|
||||
|
|
@ -361,6 +371,7 @@ def get_permission(parser, token):
|
|||
approved=True,
|
||||
name='"permission"')
|
||||
|
||||
|
||||
@register.tag
|
||||
def get_permission_request(parser, token):
|
||||
"""
|
||||
|
|
@ -371,8 +382,10 @@ def get_permission_request(parser, token):
|
|||
|
||||
{% get_permission_request PERMISSION_LABEL.CHECK_NAME for USER and *OBJS [as VARNAME] %}
|
||||
|
||||
{% get_permission_request "poll_permission.change_poll" for request.user and poll as "asked_for_permissio" %}
|
||||
{% get_permission_request "poll_permission.change_poll" for request.user and poll,second_poll as "asked_for_permissio" %}
|
||||
{% get_permission_request "poll_permission.change_poll"
|
||||
for request.user and poll as "asked_for_permissio" %}
|
||||
{% get_permission_request "poll_permission.change_poll"
|
||||
for request.user and poll,second_poll as "asked_for_permissio" %}
|
||||
|
||||
{% if asked_for_permissio %}
|
||||
Dude, you already asked for permission!
|
||||
|
|
@ -381,16 +394,17 @@ def get_permission_request(parser, token):
|
|||
{% endif %}
|
||||
|
||||
"""
|
||||
return PermissionForObjectNode.handle_token(parser, token,
|
||||
approved=False,
|
||||
name='"permission_request"')
|
||||
return PermissionForObjectNode.handle_token(
|
||||
parser, token, approved=False, name='"permission_request"')
|
||||
|
||||
|
||||
def base_link(context, perm, view_name):
|
||||
return {
|
||||
'next': context['request'].build_absolute_uri(),
|
||||
'url': reverse(view_name, kwargs={'permission_pk': perm.pk,}),
|
||||
'url': reverse(view_name, kwargs={'permission_pk': perm.pk}),
|
||||
}
|
||||
|
||||
|
||||
@register.inclusion_tag('authority/permission_delete_link.html', takes_context=True)
|
||||
def permission_delete_link(context, perm):
|
||||
"""
|
||||
|
|
@ -400,11 +414,12 @@ def permission_delete_link(context, perm):
|
|||
"""
|
||||
user = context['request'].user
|
||||
if user.is_authenticated():
|
||||
if user.has_perm('authority.delete_foreign_permissions') \
|
||||
or user.pk == perm.creator.pk:
|
||||
if (user.has_perm('authority.delete_foreign_permissions') or
|
||||
user.pk == perm.creator.pk):
|
||||
return base_link(context, perm, 'authority-delete-permission')
|
||||
return {'url': None}
|
||||
|
||||
|
||||
@register.inclusion_tag('authority/permission_request_delete_link.html', takes_context=True)
|
||||
def permission_request_delete_link(context, perm):
|
||||
"""
|
||||
|
|
@ -424,6 +439,7 @@ def permission_request_delete_link(context, perm):
|
|||
return link_kwargs
|
||||
return {'url': None}
|
||||
|
||||
|
||||
@register.inclusion_tag('authority/permission_request_approve_link.html', takes_context=True)
|
||||
def permission_request_approve_link(context, perm):
|
||||
"""
|
||||
|
|
@ -434,6 +450,5 @@ def permission_request_approve_link(context, perm):
|
|||
user = context['request'].user
|
||||
if user.is_authenticated():
|
||||
if user.has_perm('authority.approve_permission_requests'):
|
||||
return base_link(context, perm,
|
||||
'authority-approve-permission-request')
|
||||
return base_link(context, perm, 'authority-approve-permission-request')
|
||||
return {'url': None}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
from django import VERSION
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import Permission as DjangoPermission
|
||||
from django.contrib.auth.models import Group
|
||||
from django.db.models import Q
|
||||
from django.test import TestCase
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.db.models import Q
|
||||
|
||||
import authority
|
||||
from authority import permissions
|
||||
|
|
@ -17,13 +16,8 @@ from authority.forms import UserPermissionForm # noqa
|
|||
|
||||
|
||||
User = get_user_model()
|
||||
if VERSION >= (1, 5):
|
||||
FIXTURES = ['tests_custom.json']
|
||||
QUERY = Q(email="jezdez@github.com")
|
||||
else:
|
||||
FIXTURES = ['tests.json']
|
||||
QUERY = Q(username="jezdez")
|
||||
|
||||
FIXTURES = ['tests_custom.json']
|
||||
QUERY = Q(email="jezdez@github.com")
|
||||
|
||||
class UserPermission(permissions.BasePermission):
|
||||
checks = ('browse',)
|
||||
|
|
|
|||
|
|
@ -1,31 +1,24 @@
|
|||
try:
|
||||
from django.conf.urls import *
|
||||
except ImportError: # django < 1.4
|
||||
from django.conf.urls.defaults import *
|
||||
from django.conf.urls import patterns, url
|
||||
|
||||
urlpatterns = patterns('authority.views',
|
||||
urlpatterns = patterns(
|
||||
'authority.views',
|
||||
url(r'^permission/add/(?P<app_label>[\w\-]+)/(?P<module_name>[\w\-]+)/(?P<pk>\d+)/$',
|
||||
view='add_permission',
|
||||
name="authority-add-permission",
|
||||
kwargs={'approved': True}
|
||||
),
|
||||
kwargs={'approved': True}),
|
||||
url(r'^permission/delete/(?P<permission_pk>\d+)/$',
|
||||
view='delete_permission',
|
||||
name="authority-delete-permission",
|
||||
kwargs={'approved': True}
|
||||
),
|
||||
kwargs={'approved': True}),
|
||||
url(r'^request/add/(?P<app_label>[\w\-]+)/(?P<module_name>[\w\-]+)/(?P<pk>\d+)/$',
|
||||
view='add_permission',
|
||||
name="authority-add-permission-request",
|
||||
kwargs={'approved': False}
|
||||
),
|
||||
kwargs={'approved': False}),
|
||||
url(r'^request/approve/(?P<permission_pk>\d+)/$',
|
||||
view='approve_permission_request',
|
||||
name="authority-approve-permission-request"
|
||||
),
|
||||
name="authority-approve-permission-request"),
|
||||
url(r'^request/delete/(?P<permission_pk>\d+)/$',
|
||||
view='delete_permission',
|
||||
name="authority-delete-permission-request",
|
||||
kwargs={'approved': False}
|
||||
),
|
||||
kwargs={'approved': False}),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
from datetime import datetime
|
||||
from django.shortcuts import render_to_response, get_object_or_404
|
||||
from django.views.decorators.http import require_POST
|
||||
from django.http import HttpResponseRedirect, HttpResponseForbidden
|
||||
from django.db.models.loading import get_model
|
||||
from django.utils.translation import ugettext as _
|
||||
|
|
@ -12,6 +10,7 @@ from authority.models import Permission
|
|||
from authority.forms import UserPermissionForm
|
||||
from authority.templatetags.permissions import url_for_obj
|
||||
|
||||
|
||||
def get_next(request, obj=None):
|
||||
next = request.REQUEST.get('next')
|
||||
if not next:
|
||||
|
|
@ -21,9 +20,10 @@ def get_next(request, obj=None):
|
|||
next = '/'
|
||||
return next
|
||||
|
||||
|
||||
@login_required
|
||||
def add_permission(request, app_label, module_name, pk, approved=False,
|
||||
template_name = 'authority/permission_form.html',
|
||||
template_name='authority/permission_form.html',
|
||||
extra_context=None, form_class=UserPermissionForm):
|
||||
codename = request.POST.get('codename', None)
|
||||
model = get_model(app_label, module_name)
|
||||
|
|
@ -47,7 +47,7 @@ def add_permission(request, app_label, module_name, pk, approved=False,
|
|||
# Limit permission request to current user
|
||||
form.data['user'] = request.user
|
||||
if form.is_valid():
|
||||
permission = form.save(request)
|
||||
form.save(request)
|
||||
request.user.message_set.create(
|
||||
message=_('You added a permission request.'))
|
||||
return HttpResponseRedirect(next)
|
||||
|
|
@ -66,6 +66,7 @@ def add_permission(request, app_label, module_name, pk, approved=False,
|
|||
return render_to_response(template_name, context,
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
@login_required
|
||||
def approve_permission_request(request, permission_pk):
|
||||
requested_permission = get_object_or_404(Permission, pk=permission_pk)
|
||||
|
|
@ -76,12 +77,13 @@ def approve_permission_request(request, permission_pk):
|
|||
next = get_next(request, requested_permission)
|
||||
return HttpResponseRedirect(next)
|
||||
|
||||
|
||||
@login_required
|
||||
def delete_permission(request, permission_pk, approved):
|
||||
permission = get_object_or_404(Permission, pk=permission_pk,
|
||||
approved=approved)
|
||||
if (request.user.has_perm('authority.delete_foreign_permissions')
|
||||
or request.user == permission.creator):
|
||||
if (request.user.has_perm('authority.delete_foreign_permissions') or
|
||||
request.user == permission.creator):
|
||||
permission.delete()
|
||||
if approved:
|
||||
msg = _('You removed the permission.')
|
||||
|
|
@ -91,6 +93,7 @@ def delete_permission(request, permission_pk, approved):
|
|||
next = get_next(request)
|
||||
return HttpResponseRedirect(next)
|
||||
|
||||
|
||||
def permission_denied(request, template_name=None, extra_context=None):
|
||||
"""
|
||||
Default 403 handler.
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ from django.utils.safestring import mark_safe
|
|||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.contrib.admin.widgets import ForeignKeyRawIdWidget
|
||||
|
||||
|
||||
generic_script = """
|
||||
<script type="text/javascript">
|
||||
function showGenericRelatedObjectLookupPopup(ct_select, triggering_link, url_base) {
|
||||
|
|
@ -17,6 +18,7 @@ function showGenericRelatedObjectLookupPopup(ct_select, triggering_link, url_bas
|
|||
</script>
|
||||
"""
|
||||
|
||||
|
||||
class GenericForeignKeyRawIdWidget(ForeignKeyRawIdWidget):
|
||||
def __init__(self, ct_field, cts=[], attrs=None):
|
||||
self.ct_field = ct_field
|
||||
|
|
@ -35,10 +37,23 @@ class GenericForeignKeyRawIdWidget(ForeignKeyRawIdWidget):
|
|||
if 'class' not in attrs:
|
||||
attrs['class'] = 'vForeignKeyRawIdAdminField'
|
||||
output = [forms.TextInput.render(self, name, value, attrs)]
|
||||
output.append("""%(generic_script)s
|
||||
<a href="%(related)s%(url)s" class="related-lookup" id="lookup_id_%(name)s" onclick="return showGenericRelatedObjectLookupPopup(document.getElementById('id_%(ct_field)s'), this, '%(related)s%(url)s');"> """
|
||||
% {'generic_script': generic_script, 'related': related_url, 'url': url, 'name': name, 'ct_field': self.ct_field})
|
||||
output.append('<img src="%s/admin/img/selector-search.gif" width="16" height="16" alt="%s" /></a>' % (settings.STATIC_URL, _('Lookup')))
|
||||
output.append(
|
||||
"""%(generic_script)s
|
||||
<a href="%(related)s%(url)s"
|
||||
class="related-lookup"
|
||||
id="lookup_id_%(name)s"
|
||||
onclick="return showGenericRelatedObjectLookupPopup(
|
||||
document.getElementById('id_%(ct_field)s'), this, '%(related)s%(url)s');">
|
||||
""" % {
|
||||
'generic_script': generic_script,
|
||||
'related': related_url,
|
||||
'url': url,
|
||||
'name': name,
|
||||
'ct_field': self.ct_field
|
||||
})
|
||||
output.append(
|
||||
'<img src="%s/admin/img/selector-search.gif" width="16" height="16" alt="%s" /></a>'
|
||||
% (settings.STATIC_URL, _('Lookup')))
|
||||
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
content_types = """
|
||||
|
|
@ -46,7 +61,12 @@ class GenericForeignKeyRawIdWidget(ForeignKeyRawIdWidget):
|
|||
var content_types = new Array();
|
||||
%s
|
||||
</script>
|
||||
""" % ('\n'.join(["content_types[%s] = '%s/%s/';" % (ContentType.objects.get_for_model(ct).id, ct._meta.app_label, ct._meta.object_name.lower()) for ct in self.cts]))
|
||||
""" % ('\n'.join([
|
||||
"content_types[%s] = '%s/%s/';" % (
|
||||
ContentType.objects.get_for_model(ct).id,
|
||||
ct._meta.app_label,
|
||||
ct._meta.object_name.lower()
|
||||
) for ct in self.cts]))
|
||||
return mark_safe(u''.join(output) + content_types)
|
||||
|
||||
def url_parameters(self):
|
||||
|
|
|
|||
5
tox.ini
5
tox.ini
|
|
@ -1,14 +1,9 @@
|
|||
[tox]
|
||||
envlist =
|
||||
py26-django{14,15,16},
|
||||
py27-django{14,15,16,17,18},
|
||||
py33-django{15,16,17,18}
|
||||
|
||||
[testenv]
|
||||
commands = python example/manage.py test authority
|
||||
deps =
|
||||
django14: Django>=1.4, <1.5
|
||||
django15: Django>=1.5, <1.6
|
||||
django16: Django>=1.6, <1.7
|
||||
django17: Django>=1.7, <1.8
|
||||
django18: Django>=1.8, <1.9
|
||||
|
|
|
|||
Loading…
Reference in a new issue