Final changes to support permissions and roles

This commit is contained in:
Roberto Rosario
2011-02-13 04:33:40 -04:00
parent a47ff7c4b4
commit 344a613514
24 changed files with 455 additions and 71 deletions

View File

@@ -20,6 +20,7 @@ Features
* Previews for a great deal of image formats, including PDF
* Document OCR and searching
* Group documents by metadata automatically
* Permissions and roles support
Requirements
---

View File

@@ -2,9 +2,6 @@ import copy
from django.db.utils import DatabaseError
from permissions.utils import has_permission
from permissions.models import Permission
object_navigation = {}
menu_links = []
@@ -44,25 +41,3 @@ def register_model_list_columns(model, columns):
model_list_columns[model].extend(columns)
else:
model_list_columns[model] = copy.copy(columns)
def register_permissions(app, permissions):
if permissions:
for permission in permissions:
full_permission_name = "%s_%s" % (app, permission['name'])
try:
#if not Permission.objects.filter(codename=full_permission_name):
# Permission(name=unicode(permission['label']), codename=full_permission_name).save()
permission_obj, created = Permission.objects.get_or_create(codename=full_permission_name)
permission_obj.name=unicode(permission['label'])
permission_obj.save()
except DatabaseError:
#Special case for ./manage.py syncdb
pass
def check_permissions(object, user, permission_list):
temp_role = []
for permission in permission_list:
if has_permission(object, user, permission):
return True

View File

@@ -1,7 +1,17 @@
{% load i18n %}
{% load permission_tags %}
{% for link in object_navigation_links %}
{% if link.permissions %}
{% check_permissions request.user link.permissions.namespace link.permissions.permissions %}
{% if permission %}
{% if as_li %}<li>{% endif %}
<a class="{{ link.class }}" href="{{ link.url }}">{% if link.famfam %}<span class="famfam active famfam-{{ link.famfam|default:'link' }}"></span>{% endif %}{{ link.text|capfirst }}{% if link.error %} - {{ link.error }}{% endif %}{% if link.active %}<span class="famfam active famfam-resultset_previous"></span>{% endif %}</a>{% if horizontal %}{% if not forloop.last %} | {% endif %}{% endif %}
{% if as_li %}</li>{% endif %}
{% endif %}
{% else %}
{% if as_li %}<li>{% endif %}
<a class="{{ link.class }}" href="{{ link.url }}">{% if link.famfam %}<span class="famfam active famfam-{{ link.famfam|default:'link' }}"></span>{% endif %}{{ link.text|capfirst }}{% if link.error %} - {{ link.error }}{% endif %}{% if link.active %}<span class="famfam active famfam-resultset_previous"></span>{% endif %}</a>{% if horizontal %}{% if not forloop.last %} | {% endif %}{% endif %}
{% if as_li %}</li>{% endif %}
{% endif %}
{% endfor %}

View File

@@ -4,25 +4,42 @@ from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse
from common.api import register_links, register_menu, \
register_model_list_columns, register_permissions
register_model_list_columns
from common.utils import pretty_size
from permissions.api import register_permissions
from models import Document
from staging import StagingFile
from documents.conf import settings as documents_settings
PERMISSION_DOCUMENT_CREATE = 'document_create'
PERMISSION_DOCUMENT_PROPERTIES_EDIT = 'document_properties_edit'
PERMISSION_DOCUMENT_METADATA_EDIT = 'document_metadata_edit'
PERMISSION_DOCUMENT_VIEW = 'document_view'
PERMISSION_DOCUMENT_DELETE = 'document_delete'
PERMISSION_DOCUMENT_DOWNLOAD = 'document_download'
document_list = {'text':_(u'documents list'), 'view':'document_list', 'famfam':'page'}
document_create = {'text':_('upload a document'), 'view':'document_create', 'famfam':'page_add'}
document_create_multiple = {'text':_('upload multiple documents'), 'view':'document_create_multiple', 'famfam':'page_add'}
document_create_sibling = {'text':_('upload using same metadata'), 'view':'document_create_sibling', 'args':'object.id', 'famfam':'page_copy'}
document_view = {'text':_('details'), 'view':'document_view', 'args':'object.id', 'famfam':'page'}
document_delete = {'text':_('delete'), 'view':'document_delete', 'args':'object.id', 'famfam':'page_delete'}
document_edit = {'text':_('edit'), 'view':'document_edit', 'args':'object.id', 'famfam':'page_edit'}
document_edit_metadata = {'text':_('edit metadata'), 'view':'document_edit_metadata', 'args':'object.id', 'famfam':'page_edit'}
document_preview = {'text':_('preview'), 'class':'fancybox', 'view':'document_preview', 'args':'object.id', 'famfam':'magnifier'}
document_download = {'text':_('download'), 'view':'document_download', 'args':'object.id', 'famfam':'page_save'}
register_permissions('documents', [
{'name':PERMISSION_DOCUMENT_CREATE, 'label':_(u'Create document')},
{'name':PERMISSION_DOCUMENT_PROPERTIES_EDIT, 'label':_(u'Edit document properties')},
{'name':PERMISSION_DOCUMENT_METADATA_EDIT, 'label':_(u'Edit document metadata')},
{'name':PERMISSION_DOCUMENT_VIEW, 'label':_(u'View document')},
{'name':PERMISSION_DOCUMENT_DELETE, 'label':_(u'Delete document')},
{'name':PERMISSION_DOCUMENT_DOWNLOAD, 'label':_(u'Download document')},
])
document_list = {'text':_(u'documents list'), 'view':'document_list', 'famfam':'page', 'permissions':{'namespace':'documents', 'permissions':[PERMISSION_DOCUMENT_VIEW]}}
document_create = {'text':_('upload a document'), 'view':'document_create', 'famfam':'page_add', 'permissions':{'namespace':'documents', 'permissions':[PERMISSION_DOCUMENT_CREATE]}}
document_create_multiple = {'text':_('upload multiple documents'), 'view':'document_create_multiple', 'famfam':'page_add', 'permissions':{'namespace':'documents', 'permissions':[PERMISSION_DOCUMENT_CREATE]}}
document_create_sibling = {'text':_('upload using same metadata'), 'view':'document_create_sibling', 'args':'object.id', 'famfam':'page_copy', 'permissions':{'namespace':'documents', 'permissions':[PERMISSION_DOCUMENT_CREATE]}}
document_view = {'text':_('details'), 'view':'document_view', 'args':'object.id', 'famfam':'page', 'permissions':{'namespace':'documents', 'permissions':[PERMISSION_DOCUMENT_VIEW]}}
document_delete = {'text':_('delete'), 'view':'document_delete', 'args':'object.id', 'famfam':'page_delete', 'permissions':{'namespace':'documents', 'permissions':[PERMISSION_DOCUMENT_DELETE]}}
document_edit = {'text':_('edit'), 'view':'document_edit', 'args':'object.id', 'famfam':'page_edit', 'permissions':{'namespace':'documents', 'permissions':[PERMISSION_DOCUMENT_PROPERTIES_EDIT]}}
document_edit_metadata = {'text':_('edit metadata'), 'view':'document_edit_metadata', 'args':'object.id', 'famfam':'page_edit', 'permissions':{'namespace':'documents', 'permissions':[PERMISSION_DOCUMENT_METADATA_EDIT]}}
document_preview = {'text':_('preview'), 'class':'fancybox', 'view':'document_preview', 'args':'object.id', 'famfam':'magnifier', 'permissions':{'namespace':'documents', 'permissions':[PERMISSION_DOCUMENT_VIEW]}}
document_download = {'text':_('download'), 'view':'document_download', 'args':'object.id', 'famfam':'page_save', 'permissions':{'namespace':'documents', 'permissions':[PERMISSION_DOCUMENT_DOWNLOAD]}}
staging_file_preview = {'text':_('preview'), 'class':'fancybox', 'view':'staging_file_preview', 'args':'object.id', 'famfam':'drive_magnify'}
staging_file_delete = {'text':_('delete'), 'view':'staging_file_delete', 'args':'object.id', 'famfam':'drive_delete'}
@@ -50,21 +67,3 @@ register_menu([
],'famfam':'page','position':4}])
TEMPORARY_DIRECTORY = documents_settings.TEMPORARY_DIRECTORY if documents_settings.TEMPORARY_DIRECTORY else tempfile.mkdtemp()
PERMISSION_DOCUMENT_CREATE = 'document_create'
PERMISSION_DOCUMENT_PROPERTIES_EDIT = 'document_properties_edit'
PERMISSION_DOCUMENT_METADATA_EDIT = 'document_metadata_edit'
PERMISSION_DOCUMENT_VIEW = 'document_view'
PERMISSION_DOCUMENT_DELETE = 'document_delete'
PERMISSION_DOCUMENT_OCR = 'document_ocr'
PERMISSION_DOCUMENT_DOWNLOAD = 'document_download'
register_permissions('documents', [
{'name':PERMISSION_DOCUMENT_CREATE, 'label':_(u'Create document')},
{'name':PERMISSION_DOCUMENT_PROPERTIES_EDIT, 'label':_(u'Edit document properties')},
{'name':PERMISSION_DOCUMENT_METADATA_EDIT, 'label':_(u'Edit document metadata')},
{'name':PERMISSION_DOCUMENT_VIEW, 'label':_(u'View document')},
{'name':PERMISSION_DOCUMENT_DELETE, 'label':_(u'Delete document')},
{'name':PERMISSION_DOCUMENT_OCR, 'label':_(u'Submit document for OCR')},
{'name':PERMISSION_DOCUMENT_DOWNLOAD, 'label':_(u'Download document')},
])

View File

@@ -11,7 +11,7 @@ from django.conf import settings
from django.utils.http import urlencode
from django.template.defaultfilters import slugify
from permissions.api import check_permissions, Unauthorized
from filetransfers.api import serve_file
from converter.api import convert, in_image_cache, QUALITY_DEFAULT
from common.utils import pretty_size
@@ -38,13 +38,17 @@ from documents.conf.settings import GROUP_SHOW_EMPTY
from documents import PERMISSION_DOCUMENT_CREATE, \
PERMISSION_DOCUMENT_CREATE, PERMISSION_DOCUMENT_PROPERTIES_EDIT, \
PERMISSION_DOCUMENT_METADATA_EDIT, PERMISSION_DOCUMENT_VIEW, \
PERMISSION_DOCUMENT_DELETE, PERMISSION_DOCUMENT_OCR, \
PERMISSION_DOCUMENT_DOWNLOAD
PERMISSION_DOCUMENT_DELETE, PERMISSION_DOCUMENT_DOWNLOAD
from utils import save_metadata, save_metadata_list, decode_metadata_from_url
def document_list(request):
permissions = [PERMISSION_DOCUMENT_VIEW]
try:
check_permissions(request.user, 'documents', permissions)
except Unauthorized, e:
raise Http404(e)
return object_list(
request,
queryset=Document.objects.all(),
@@ -56,8 +60,10 @@ def document_list(request):
def document_create(request, multiple=True):
permissions = [PERMISSION_DOCUMENT_CREATE]
if not check_permissions(main_object, request.user, permissions):
raise Http404
try:
check_permissions(request.user, 'documents', permissions)
except Unauthorized, e:
raise Http404(e)
if DocumentType.objects.all().count() == 1:
wizard = DocumentCreateWizard(
@@ -72,6 +78,12 @@ def document_create(request, multiple=True):
return wizard(request)
def document_create_sibling(request, document_id, multiple=True):
permissions = [PERMISSION_DOCUMENT_CREATE]
try:
check_permissions(request.user, 'documents', permissions)
except Unauthorized, e:
raise Http404(e)
document = get_object_or_404(Document, pk=document_id)
urldata = []
for id, metadata in enumerate(document.documentmetadata_set.all()):
@@ -89,6 +101,12 @@ def document_create_sibling(request, document_id, multiple=True):
def upload_document_with_type(request, document_type_id, multiple=True):
permissions = [PERMISSION_DOCUMENT_CREATE]
try:
check_permissions(request.user, 'documents', permissions)
except Unauthorized, e:
raise Http404(e)
document_type = get_object_or_404(DocumentType, pk=document_type_id)
local_form = DocumentForm(prefix='local', initial={'document_type':document_type})
if USE_STAGING_DIRECTORY:
@@ -206,6 +224,12 @@ def upload_document_with_type(request, document_type_id, multiple=True):
context_instance=RequestContext(request))
def document_view(request, document_id):
permissions = [PERMISSION_DOCUMENT_VIEW]
try:
check_permissions(request.user, 'documents', permissions)
except Unauthorized, e:
raise Http404(e)
document = get_object_or_404(Document, pk=document_id)
form = DocumentForm_view(instance=document, extra_fields=[
{'label':_(u'Filename'), 'field':'file_filename'},
@@ -285,6 +309,12 @@ def document_view(request, document_id):
def document_delete(request, document_id):
permissions = [PERMISSION_DOCUMENT_DELETE]
try:
check_permissions(request.user, 'documents', permissions)
except Unauthorized, e:
raise Http404(e)
document = get_object_or_404(Document, pk=document_id)
return delete_object(request, model=Document, object_id=document_id,
@@ -298,6 +328,12 @@ def document_delete(request, document_id):
def document_edit(request, document_id):
permissions = [PERMISSION_DOCUMENT_PROPERTIES_EDIT]
try:
check_permissions(request.user, 'documents', permissions)
except Unauthorized, e:
raise Http404(e)
document = get_object_or_404(Document, pk=document_id)
if request.method == 'POST':
form = DocumentForm_edit(request.POST, initial={'document_type':document.document_type})
@@ -338,6 +374,12 @@ def document_edit(request, document_id):
def document_edit_metadata(request, document_id):
permissions = [PERMISSION_DOCUMENT_METADATA_EDIT]
try:
check_permissions(request.user, 'documents', permissions)
except Unauthorized, e:
raise Http404(e)
document = get_object_or_404(Document, pk=document_id)
initial=[]
@@ -386,6 +428,12 @@ def document_edit_metadata(request, document_id):
def get_document_image(request, document_id, size=PREVIEW_SIZE, quality=QUALITY_DEFAULT):
permissions = [PERMISSION_DOCUMENT_VIEW]
try:
check_permissions(request.user, 'documents', permissions)
except Unauthorized, e:
raise Http404(e)
document = get_object_or_404(Document, pk=document_id)
try:
@@ -407,6 +455,12 @@ def get_document_image(request, document_id, size=PREVIEW_SIZE, quality=QUALITY_
def document_download(request, document_id):
permissions = [PERMISSION_DOCUMENT_DOWNLOAD]
try:
check_permissions(request.user, 'documents', permissions)
except Unauthorized, e:
raise Http404(e)
document = get_object_or_404(Document, pk=document_id)
try:
#Test permissions and trigger exception
@@ -417,6 +471,7 @@ def document_download(request, document_id):
return HttpResponseRedirect(request.META['HTTP_REFERER'])
#TODO: Need permission
def staging_file_preview(request, staging_file_id):
try:
filepath = StagingFile.get(staging_file_id).filepath
@@ -426,6 +481,7 @@ def staging_file_preview(request, staging_file_id):
return serve_file(request, File(file=open('%simages/1297211435_error.png' % settings.MEDIA_ROOT, 'r')))
#TODO: Need permission
def staging_file_delete(request, staging_file_id):
staging_file = StagingFile.get(staging_file_id)
next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', None)))

View File

@@ -1,11 +1,17 @@
from django.utils.translation import ugettext_lazy as _
from common.api import register_links, register_menu
from permissions.api import register_permissions
from documents.models import Document
OCR_DOCUMENT_OCR = 'document_ocr'
submit_document = {'text':_('submit to OCR queue'), 'view':'submit_document', 'args':'object.id', 'famfam':'page_lightning'}
register_permissions('ocr', [
{'name':OCR_DOCUMENT_OCR, 'label':_(u'Submit document for OCR')},
])
submit_document = {'text':_('submit to OCR queue'), 'view':'submit_document', 'args':'object.id', 'famfam':'page_lightning', 'permissions':{'namespace':'ocr', 'permissions':[OCR_DOCUMENT_OCR]}}
register_links(Document, [submit_document], menu_name='sidebar')

View File

@@ -1,4 +1,4 @@
from django.http import HttpResponse, HttpResponseRedirect
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.shortcuts import render_to_response, get_object_or_404, redirect
from django.template import RequestContext
from django.contrib import messages
@@ -8,13 +8,19 @@ from django.core.urlresolvers import reverse
from django.conf import settings
from django.utils.translation import ugettext as _
from permissions.api import check_permissions, Unauthorized
from documents.models import Document
from ocr import OCR_DOCUMENT_OCR
from api import ocr_document
def submit_document(request, document_id):
permissions = [OCR_DOCUMENT_OCR]
try:
check_permissions(request.user, 'ocr', permissions)
except Unauthorized, e:
raise Http404(e)
document = get_object_or_404(Document, pk=document_id)
try:

View File

@@ -0,0 +1,21 @@
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.core.exceptions import ObjectDoesNotExist
from permissions.conf.settings import DEFAULT_ROLES
from models import Role
def user_post_save(sender, instance, **kwargs):
for default_role in DEFAULT_ROLES:
if isinstance(default_role, Role):
default_role.add_member(instance)
else:
try:
role = Role.objects.get(name=default_role)
role.add_member(instance)
except ObjectDoesNotExist:
pass
post_save.connect(user_post_save, sender=User)

33
apps/permissions/admin.py Normal file
View File

@@ -0,0 +1,33 @@
from django.contrib import admin
from models import Permission, PermissionHolder, Role, RoleMember
from django.contrib.contenttypes import generic
class PermissionHolderInline(admin.StackedInline):
model = PermissionHolder
extra = 1
classes = ('collapse-open',)
allow_add = True
class PermissionAdmin(admin.ModelAdmin):
inlines = [PermissionHolderInline]
list_display = ('namespace', 'name', 'label')
list_display_links = list_display
class RoleMemberInline(admin.StackedInline):
model = RoleMember
extra = 1
classes = ('collapse-open',)
allow_add = True
class RoleAdmin(admin.ModelAdmin):
inlines = [RoleMemberInline]
admin.site.register(Permission, PermissionAdmin)
admin.site.register(Role, RoleAdmin)

70
apps/permissions/api.py Normal file
View File

@@ -0,0 +1,70 @@
from django.http import Http404
from django.contrib.auth.models import User
from django.contrib.auth.models import Group
from django.db.utils import DatabaseError
from django.shortcuts import get_object_or_404
from django.contrib.contenttypes.models import ContentType
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext
from models import Permission, Role
class Unauthorized(Exception):
pass
def register_permissions(namespace, permissions):
if permissions:
for permission in permissions:
try:
permission_obj, created = Permission.objects.get_or_create(
namespace=namespace, name=permission['name'])
permission_obj.label=unicode(permission['label'])
permission_obj.save()
except DatabaseError:
#Special case for ./manage.py syncdb
pass
#TODO: Handle anonymous users
def check_permissions(requester, namespace, permission_list):
if isinstance(requester, User):
if requester.is_superuser:
return True
for permission_item in permission_list:
permission = get_object_or_404(Permission,
namespace=namespace, name=permission_item)
if check_permission(requester, permission):
return True
raise Unauthorized(ugettext(u'Insufficient permissions.'))
def check_permission(requester, permission):
for permission_holder in permission.permissionholder_set.all():
if check_requester(requester, permission_holder):
return True
def check_requester(requester, permission_holder):
ct = ContentType.objects.get_for_model(requester)
if permission_holder.holder_type == ct and permission_holder.holder_id == requester.id:
return True
if isinstance(permission_holder.holder_object, Role):
requester_list = [role_member.member_object for role_member in permission_holder.holder_object.rolemember_set.all()]
if check_elements(requester, requester_list):
return True
#Untested
if isinstance(permission_holder.holder_object, Group):
if check_elements(requester, permission_holder.holder_object.user_set.all()):
return True
#TODO: a role may contain groups, make recursive
def check_elements(requester, requester_list):
ct = ContentType.objects.get_for_model(requester)
for requester_object in requester_list:
if requester == requester_object:
return True

View File

View File

@@ -0,0 +1,3 @@
from django.conf import settings
DEFAULT_ROLES = getattr(settings, 'ROLES_DEFAULT_ROLES', [])

View File

@@ -0,0 +1,67 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-02-13 04:12-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: api.py:40
msgid "Insufficient permissions."
msgstr ""
#: models.py:8
msgid "namespace"
msgstr ""
#: models.py:9
msgid "name"
msgstr ""
#: models.py:10 models.py:40
msgid "label"
msgstr ""
#: models.py:14 models.py:23
msgid "permission"
msgstr ""
#: models.py:15
msgid "permissions"
msgstr ""
#: models.py:31
msgid "permission holder"
msgstr ""
#: models.py:32
msgid "permission holders"
msgstr ""
#: models.py:44 models.py:58
msgid "role"
msgstr ""
#: models.py:45
msgid "roles"
msgstr ""
#: models.py:67
msgid "role member"
msgstr ""
#: models.py:68
msgid "role members"
msgstr ""

View File

@@ -0,0 +1,71 @@
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
class Permission(models.Model):
namespace = models.CharField(max_length=64, verbose_name=_(u'namespace'))
name = models.CharField(max_length=64, verbose_name=_(u'name'))
label = models.CharField(max_length=64, verbose_name=_(u'label'))
class Meta:
unique_together = ('namespace', 'name')
verbose_name = _(u'permission')
verbose_name_plural = _(u'permissions')
def __unicode__(self):
return self.label
class PermissionHolder(models.Model):
permission = models.ForeignKey(Permission, verbose_name=_(u'permission'))
holder_type = models.ForeignKey(ContentType,
related_name='permission_holder',
limit_choices_to = {'model__in': ('user', 'group', 'role')})
holder_id = models.PositiveIntegerField()
holder_object = generic.GenericForeignKey(ct_field='holder_type', fk_field='holder_id')
class Meta:
verbose_name = _(u'permission holder')
verbose_name_plural = _(u'permission holders')
def __unicode__(self):
return unicode(self.holder_object)
class Role(models.Model):
name = models.CharField(max_length=64, unique=True)
label = models.CharField(max_length=64, unique=True, verbose_name=_(u'label'))
class Meta:
ordering = ('label',)
verbose_name = _(u'role')
verbose_name_plural = _(u'roles')
def add_member(self, member):
role_member, created = RoleMember.objects.get_or_create(
role=self,
member_type = ContentType.objects.get_for_model(member),
member_id=member.id)
def __unicode__(self):
return self.label
class RoleMember(models.Model):
role = models.ForeignKey(Role, verbose_name=_(u'role'))
member_type = models.ForeignKey(ContentType,
related_name='role_member',
limit_choices_to = {'model__in': ('user', 'group', 'role')})
member_id = models.PositiveIntegerField()
member_object = generic.GenericForeignKey(ct_field='member_type', fk_field='member_id')
class Meta:
#ordering = ('label',)
verbose_name = _(u'role member')
verbose_name_plural = _(u'role members')
def __unicode__(self):
return unicode(self.member_object)

View File

@@ -0,0 +1,37 @@
from django.template import TemplateSyntaxError, Library, \
VariableDoesNotExist, Node, Variable
from permissions.api import check_permissions as check_permission_function, Unauthorized
register = Library()
class CheckPermissionsNode(Node):
def __init__(self, requester, namespace, permission_list, *args, **kwargs):
self.requester = requester
self.namespace = namespace
self.permission_list = permission_list
def render(self, context):
requester = Variable(self.requester).resolve(context)
namespace = Variable(self.namespace).resolve(context)
permission_list = Variable(self.permission_list).resolve(context)
try:
check_permission_function(requester, namespace, permission_list)
context['permission'] = True
return ''
except Unauthorized:
context['permission'] = False
return ''
@register.tag
def check_permissions(parser, token):
try:
# Splitting by None == splitting by spaces.
tag_name, args = token.contents.split(None, 1)
except ValueError:
raise template.TemplateSyntaxError, "%r tag requires arguments" % token.contents.split()[0]
return CheckPermissionsNode(*args.split())

23
apps/permissions/tests.py Normal file
View File

@@ -0,0 +1,23 @@
"""
This file demonstrates two different styles of tests (one doctest and one
unittest). These will both pass when you run "manage.py test".
Replace these with more appropriate tests for your application.
"""
from django.test import TestCase
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.failUnlessEqual(1 + 1, 2)
__test__ = {"doctest": """
Another way to test that 1 + 1 is equal to 2.
>>> 1 + 1 == 2
True
"""}

View File

@@ -0,0 +1 @@
# Create your views here.

View File

@@ -5,3 +5,4 @@
* Changed to a liquid css grid
* Added the ability to group documents by their metadata
* New abstracted options to adjust document conversion quality (default, low, high)
* Added permissions and roles support

View File

@@ -26,6 +26,8 @@
* If theres only one document type on db skip step 1 of wizard - DONE
* Be able to delete staging file - DONE
* Group documents by metadata - DONE
* Permissions - DONE
* Roles - DONE
* Document list filtering by metadata
* Filterform date filtering widget
* Validate GET data before saving file
@@ -42,8 +44,6 @@
* MuliThreading deferred OCR
* Versioning support
* Generic document anotations using layer overlays
* Permissions
* Roles
* Workflows
* Scheduled maintenance (cleanup, deferred OCR's)
* Add tags to documents
@@ -60,6 +60,6 @@
* Support spreadsheets, wordprocessing docs using openoffice in server mode
* WebDAV support
* Handle ziped or rar archives
* Display preferences (Rotation, default zoom)
* Display preferences 'document transformations' (Rotation, default zoom)
* Gallery view for document groups
* Assign default role to new users

View File

@@ -1,6 +1,6 @@
#!/bin/sh
if [ -n "$1" ]; then
./manage.py runserver_plus $1 --adminmedia ./site_media/admin_media/
./manage.py runserver_plus $1 --adminmedia ./site_media/grappelli/
else
./manage.py runserver_plus --adminmedia ./site_media/admin_media/
./manage.py runserver_plus --adminmedia ./site_media/grappelli/
fi

View File

@@ -77,7 +77,7 @@ MEDIA_URL = '/%s-site_media/' % PROJECT_NAME
# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
# trailing slash.
# Examples: "http://foo.com/media/", "/media/".
ADMIN_MEDIA_PREFIX = MEDIA_URL + 'admin_media/'
ADMIN_MEDIA_PREFIX = MEDIA_URL + 'grappelli/'
# Make this unique, and don't share it with anybody.
SECRET_KEY = 'om^a(i8^6&h+umbd2%pt91cj!qu_@oztw117rgxmn(n2lp^*c!'
@@ -215,6 +215,9 @@ LOGIN_EXEMPT_URLS = (
# OCR
#OCR_TESSERACT_PATH = u'/usr/bin/tesseract'
# Permissions
#ROLES_DEFAULT_ROLES = []
# Override
SEARCH_SHOW_OBJECT_TYPE = False
#======== End of configuration options =======

View File

@@ -12,6 +12,7 @@ urlpatterns = patterns('',
(r'^ocr/', include('ocr.urls')),
(r'^admin/doc/', include('django.contrib.admindocs.urls')),
(r'^admin/', include(admin.site.urls)),
(r'^grappelli/', include('grappelli.urls')),
)
if settings.DEVELOPMENT: