mirror of
https://github.com/Hopiu/django-rosetta.git
synced 2026-05-28 13:58:19 +00:00
Allow access control function to be replaced
The current access control function `can_translate` is not always sufficient. For instance, some projects require access to translation to be controlled using a permission rather than using groups. This change introduces a new setting `ROSETTA_ACCESS_CONTROL_FUNCTION` that allows an alternative predicate to be specified. The default is to use the current function so this change is backwards compatible.
This commit is contained in:
parent
b4ac8057cc
commit
718f9430ad
5 changed files with 60 additions and 17 deletions
|
|
@ -61,6 +61,7 @@ Rosetta can be configured via the following parameters, to be defined in your pr
|
|||
* ``ROSETTA_REQUIRES_AUTH``: Require authentication for all Rosetta views. Defaults to ``True``.
|
||||
* ``ROSETTA_POFILE_WRAP_WIDTH``: Sets the line-length of the edited PO file. Set this to ``0`` to mimic ``makemessage``'s ``--no-wrap`` option. Defaults to ``78``.
|
||||
* ``ROSETTA_STORAGE_CLASS``: See the note below on Storages. Defaults to ``rosetta.storage.CacheRosettaStorage``
|
||||
* ``ROSETTA_ACCESS_CONTROL_FUNCTION``: An alternative function that determines if a given user can access the translation views.
|
||||
|
||||
********
|
||||
Storages
|
||||
|
|
|
|||
36
rosetta/access.py
Normal file
36
rosetta/access.py
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
from django.conf import settings
|
||||
from django.utils import importlib
|
||||
|
||||
|
||||
def can_translate(user):
|
||||
return get_access_control_function()(user)
|
||||
|
||||
|
||||
def get_access_control_function():
|
||||
"""
|
||||
Return a predicate for determining if a user can access the Rosetta views
|
||||
"""
|
||||
fn_path = getattr(settings, 'ROSETTA_ACCESS_CONTROL_FUNCTION', None)
|
||||
if fn_path is None:
|
||||
return is_superuser_staff_or_in_translators_group
|
||||
# Dynamically load a permissions function
|
||||
perm_module, perm_func = fn_path.rsplit('.', 1)
|
||||
perm_module = importlib.import_module(perm_module)
|
||||
return getattr(perm_module, perm_func)
|
||||
|
||||
|
||||
# Default access control test
|
||||
def is_superuser_staff_or_in_translators_group(user):
|
||||
if not getattr(settings, 'ROSETTA_REQUIRES_AUTH', True):
|
||||
return True
|
||||
if not user.is_authenticated():
|
||||
return False
|
||||
elif user.is_superuser and user.is_staff:
|
||||
return True
|
||||
else:
|
||||
try:
|
||||
from django.contrib.auth.models import Group
|
||||
translators = Group.objects.get(name='translators')
|
||||
return translators in user.groups.all()
|
||||
except Group.DoesNotExist:
|
||||
return False
|
||||
|
|
@ -16,6 +16,9 @@ MAIN_LANGUAGE = getattr(settings, 'ROSETTA_MAIN_LANGUAGE', None)
|
|||
MESSAGES_SOURCE_LANGUAGE_CODE = getattr(settings, 'ROSETTA_MESSAGES_SOURCE_LANGUAGE_CODE', 'en')
|
||||
MESSAGES_SOURCE_LANGUAGE_NAME = getattr(settings, 'ROSETTA_MESSAGES_SOURCE_LANGUAGE_NAME', 'English')
|
||||
|
||||
ACCESS_CONTROL_FUNCTION = getattr(
|
||||
settings, 'ROSETTA_ACCESS_CONTROL_FUNCTION', None)
|
||||
|
||||
|
||||
"""
|
||||
When running WSGI daemon mode, using mod_wsgi 2.0c5 or later, this setting
|
||||
|
|
|
|||
|
|
@ -537,3 +537,22 @@ class RosettaTestCase(TestCase):
|
|||
r = self.client.post(reverse('rosetta-home'), dict(m_e48f149a8b2e8baa81b816c0edf93890='Hello, world', _next='_next'))
|
||||
r = self.client.get(reverse('rosetta-home'))
|
||||
self.assertTrue('Progress: 25.00%' in str(r.content))
|
||||
|
||||
def test_24_replace_access_control(self):
|
||||
# Test default access control allows access
|
||||
url = reverse('rosetta-home')
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(200, response.status_code)
|
||||
|
||||
# Now replace access control, and check we get redirected
|
||||
settings.ROSETTA_ACCESS_CONTROL_FUNCTION = 'rosetta.tests.no_access'
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(302, response.status_code)
|
||||
|
||||
# Restore setting to default
|
||||
settings.ROSETTA_ACCESS_CONTROL_FUNCTION = None
|
||||
|
||||
|
||||
# Stubbed access control function
|
||||
def no_access(user):
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ from rosetta.polib import pofile
|
|||
from rosetta.poutil import find_pos, pagination_range, timestamp_with_timezone
|
||||
from rosetta.signals import entry_changed, post_save
|
||||
from rosetta.storage import get_storage
|
||||
from rosetta.access import can_translate
|
||||
import re
|
||||
import rosetta
|
||||
import unicodedata
|
||||
|
|
@ -392,20 +393,3 @@ def lang_sel(request, langid, idx):
|
|||
storage.set('rosetta_i18n_write', False)
|
||||
|
||||
return HttpResponseRedirect(reverse('rosetta-home'))
|
||||
|
||||
|
||||
def can_translate(user):
|
||||
if not getattr(settings, 'ROSETTA_REQUIRES_AUTH', True):
|
||||
return True
|
||||
if not user.is_authenticated():
|
||||
return False
|
||||
elif user.is_superuser and user.is_staff:
|
||||
return True
|
||||
else:
|
||||
try:
|
||||
from django.contrib.auth.models import Group
|
||||
translators = Group.objects.get(name='translators')
|
||||
return translators in user.groups.all()
|
||||
except Group.DoesNotExist:
|
||||
return False
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue