Audit common app
Add support to override settings of the FilteredSelectionForm via subclass attributes. Add keyword arguments to calls. Signed-off-by: Roberto Rosario <Roberto.Rosario@mayan-edms.com>
This commit is contained in:
@@ -301,7 +301,9 @@ class Template(object):
|
||||
self.__class__._registry[name] = self
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('rest_api:template-detail', args=(self.name,))
|
||||
return reverse(
|
||||
viewname='rest_api:template-detail', kwargs={'template_pk': self.name}
|
||||
)
|
||||
|
||||
def render(self, request):
|
||||
context = {
|
||||
|
||||
@@ -9,6 +9,8 @@ from django.db import models
|
||||
from django.utils.module_loading import import_string
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from mayan.apps.acls.models import AccessControlList
|
||||
|
||||
from .classes import Package
|
||||
from .models import UserLocaleProfile
|
||||
from .utils import resolve_attribute
|
||||
@@ -134,12 +136,20 @@ class FilteredSelectionForm(forms.Form):
|
||||
Form to select the from a list of choice filtered by access. Can be
|
||||
configure to allow single or multiple selection.
|
||||
"""
|
||||
_field_name = None
|
||||
_label = None
|
||||
_help_text = None
|
||||
_permission = None
|
||||
_queryset = None
|
||||
_widget_class = None
|
||||
_widget_attributes = None
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
field_name = kwargs.pop('field_name', None)
|
||||
label = kwargs.pop('label', None)
|
||||
help_text = kwargs.pop('help_text', None)
|
||||
permission = kwargs.pop('permission', None)
|
||||
queryset = kwargs.pop('queryset', None)
|
||||
field_name = self._field_name or kwargs.pop('field_name', None)
|
||||
label = self._label or kwargs.pop('label', None)
|
||||
help_text = self._help_text or kwargs.pop('help_text', None)
|
||||
permission = self._permission or kwargs.pop('permission', None)
|
||||
queryset = self.get_queryset() or kwargs.pop('queryset', None)
|
||||
|
||||
if queryset is None:
|
||||
model = kwargs.pop('model', None)
|
||||
@@ -150,12 +160,19 @@ class FilteredSelectionForm(forms.Form):
|
||||
|
||||
queryset = model.objects.all()
|
||||
|
||||
user = kwargs.pop('user', None)
|
||||
widget_class = kwargs.pop('widget_class', None)
|
||||
widget_attributes = kwargs.pop('widget_attributes', {'size': '10'})
|
||||
user = self.get_user() or kwargs.pop('user', None)
|
||||
widget_class = self._widget_class or kwargs.pop('widget_class', None)
|
||||
widget_attributes = self._widget_attributes or kwargs.pop(
|
||||
'widget_attributes', {'size': '10'}
|
||||
)
|
||||
|
||||
if not widget_class:
|
||||
if kwargs.pop('allow_multiple', False):
|
||||
if self._allow_multiple is not None:
|
||||
allow_multiple = self._allow_multiple
|
||||
else:
|
||||
allow_multiple = self.kwargs.pop('allow_multiple', False)
|
||||
|
||||
if allow_multiple:
|
||||
extra_kwargs = {}
|
||||
field_class = forms.ModelMultipleChoiceField
|
||||
widget_class = forms.widgets.SelectMultiple
|
||||
@@ -177,6 +194,12 @@ class FilteredSelectionForm(forms.Form):
|
||||
widget=widget_class(attrs=widget_attributes), **extra_kwargs
|
||||
)
|
||||
|
||||
def get_queryset(self):
|
||||
return self._queryset
|
||||
|
||||
def get_user(self):
|
||||
return None
|
||||
|
||||
|
||||
class LicenseForm(FileDisplayForm):
|
||||
DIRECTORY = ()
|
||||
|
||||
@@ -46,7 +46,7 @@ class DeleteExtraDataMixin(object):
|
||||
else:
|
||||
self.object.delete()
|
||||
|
||||
return HttpResponseRedirect(success_url)
|
||||
return HttpResponseRedirect(redirect_to=success_url)
|
||||
|
||||
|
||||
class DynamicFormViewMixin(object):
|
||||
@@ -179,9 +179,9 @@ class MultipleInstanceActionMixin(object):
|
||||
|
||||
def get_success_message(self, count):
|
||||
return ungettext(
|
||||
self.success_message,
|
||||
self.success_message_plural,
|
||||
count
|
||||
singular=self.success_message,
|
||||
plural=self.success_message_plural,
|
||||
number=count
|
||||
) % {
|
||||
'count': count,
|
||||
}
|
||||
@@ -197,11 +197,11 @@ class MultipleInstanceActionMixin(object):
|
||||
count += 1
|
||||
|
||||
messages.success(
|
||||
self.request,
|
||||
self.get_success_message(count=count)
|
||||
request=self.request,
|
||||
message=self.get_success_message(count=count)
|
||||
)
|
||||
|
||||
return HttpResponseRedirect(self.get_success_url())
|
||||
return HttpResponseRedirect(redirect_to=self.get_success_url())
|
||||
|
||||
|
||||
class MultipleObjectMixin(object):
|
||||
@@ -278,9 +278,9 @@ class ObjectActionMixin(object):
|
||||
|
||||
def get_success_message(self, count):
|
||||
return ungettext(
|
||||
self.success_message,
|
||||
self.success_message_plural,
|
||||
count
|
||||
singular=self.success_message,
|
||||
plural=self.success_message_plural,
|
||||
number=count
|
||||
) % {
|
||||
'count': count,
|
||||
}
|
||||
@@ -299,14 +299,15 @@ class ObjectActionMixin(object):
|
||||
pass
|
||||
except ActionError:
|
||||
messages.error(
|
||||
self.request, self.error_message % {'instance': instance}
|
||||
request=self.request,
|
||||
message=self.error_message % {'instance': instance}
|
||||
)
|
||||
else:
|
||||
self.action_count += 1
|
||||
|
||||
messages.success(
|
||||
self.request,
|
||||
self.get_success_message(count=self.action_count)
|
||||
request=self.request,
|
||||
message=self.get_success_message(count=self.action_count)
|
||||
)
|
||||
|
||||
|
||||
@@ -321,17 +322,20 @@ class ObjectListPermissionFilterMixin(object):
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
if self.access_object_retrieve_method and self.object_permission:
|
||||
AccessControlList.objects.check_access(
|
||||
permissions=(self.object_permission,), user=request.user,
|
||||
obj=getattr(self, self.access_object_retrieve_method)()
|
||||
obj=getattr(self, self.access_object_retrieve_method)(),
|
||||
permissions=(self.object_permission,), user=request.user
|
||||
)
|
||||
return super(ObjectListPermissionFilterMixin, self).dispatch(request, *args, **kwargs)
|
||||
return super(ObjectListPermissionFilterMixin, self).dispatch(
|
||||
request, *args, **kwargs
|
||||
)
|
||||
|
||||
def get_queryset(self):
|
||||
queryset = super(ObjectListPermissionFilterMixin, self).get_queryset()
|
||||
|
||||
if not self.access_object_retrieve_method and self.object_permission:
|
||||
return AccessControlList.objects.filter_by_access(
|
||||
self.object_permission, self.request.user, queryset=queryset
|
||||
obj=self.object_permission, queryset=queryset,
|
||||
user=self.request.user
|
||||
)
|
||||
else:
|
||||
return queryset
|
||||
@@ -368,9 +372,10 @@ class ObjectPermissionCheckMixin(object):
|
||||
if self.object_permission:
|
||||
try:
|
||||
AccessControlList.objects.check_access(
|
||||
permissions=self.object_permission, user=request.user,
|
||||
obj=self.get_permission_object(),
|
||||
related=getattr(self, 'object_permission_related', None)
|
||||
permissions=self.object_permission,
|
||||
related=getattr(self, 'object_permission_related', None),
|
||||
user=request.user
|
||||
)
|
||||
except PermissionDenied:
|
||||
if self.object_permission_raise_404:
|
||||
@@ -437,8 +442,8 @@ class ViewPermissionCheckMixin(object):
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
if self.view_permission:
|
||||
Permission.check_permissions(
|
||||
requester=self.request.user,
|
||||
permissions=(self.view_permission,)
|
||||
permissions=(self.view_permission,),
|
||||
requester=self.request.user
|
||||
)
|
||||
|
||||
return super(
|
||||
|
||||
@@ -18,6 +18,7 @@ from .storages import storage_sharedupload
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
#TODO: move outside of models.py
|
||||
def upload_to(instance, filename):
|
||||
return 'shared-file-{}'.format(uuid.uuid4().hex)
|
||||
|
||||
|
||||
@@ -48,8 +48,8 @@ class PurePaginator(Paginator):
|
||||
self.allow_empty_first_page = allow_empty_first_page
|
||||
self.object_list = object_list
|
||||
self.orphans = orphans
|
||||
self.per_page = per_page
|
||||
self.page_kwarg = page_kwarg
|
||||
self.per_page = per_page
|
||||
self.request = request
|
||||
|
||||
def page(self, number):
|
||||
|
||||
@@ -7,5 +7,5 @@ from mayan.apps.permissions import PermissionNamespace
|
||||
namespace = PermissionNamespace(label=_('Common'), name='common')
|
||||
|
||||
permission_error_log_view = namespace.add_permission(
|
||||
name='error_log_view', label=_('View error log')
|
||||
label=_('View error log'), name='error_log_view'
|
||||
)
|
||||
|
||||
@@ -5,13 +5,13 @@ from django.utils.translation import ugettext_lazy as _
|
||||
from mayan.apps.task_manager.classes import CeleryQueue
|
||||
|
||||
queue_default = CeleryQueue(
|
||||
name='default', label=_('Default'), is_default_queue=True
|
||||
is_default_queue=True, label=_('Default'), name='default'
|
||||
)
|
||||
queue_tools = CeleryQueue(name='tools', label=_('Tools'))
|
||||
queue_tools = CeleryQueue(label=_('Tools'), name='tools')
|
||||
queue_common_periodic = CeleryQueue(
|
||||
name='common_periodic', label=_('Common periodic'), transient=True
|
||||
label=_('Common periodic'), name='common_periodic', transient=True
|
||||
)
|
||||
queue_common_periodic.add_task_type(
|
||||
name='mayan.apps.common.tasks.task_delete_stale_uploads',
|
||||
label=_('Delete stale uploads')
|
||||
label=_('Delete stale uploads'),
|
||||
name='mayan.apps.common.tasks.task_delete_stale_uploads'
|
||||
)
|
||||
|
||||
@@ -11,7 +11,7 @@ from mayan.apps.smart_settings import Namespace
|
||||
|
||||
from .literals import DEFAULT_COMMON_HOME_VIEW
|
||||
|
||||
namespace = Namespace(name='common', label=_('Common'))
|
||||
namespace = Namespace(label=_('Common'), name='common')
|
||||
|
||||
setting_auto_logging = namespace.add_setting(
|
||||
global_name='COMMON_AUTO_LOGGING',
|
||||
@@ -86,7 +86,7 @@ setting_temporary_directory = namespace.add_setting(
|
||||
is_path=True
|
||||
)
|
||||
|
||||
namespace = Namespace(name='django', label=_('Django'))
|
||||
namespace = Namespace(label=_('Django'), name='django')
|
||||
|
||||
setting_django_allowed_hosts = namespace.add_setting(
|
||||
global_name='ALLOWED_HOSTS', default=settings.ALLOWED_HOSTS,
|
||||
@@ -402,7 +402,7 @@ setting_django_wsgi_application = namespace.add_setting(
|
||||
),
|
||||
)
|
||||
|
||||
namespace = Namespace(name='celery', label=_('Celery'))
|
||||
namespace = Namespace(label=_('Celery'), name='celery')
|
||||
|
||||
setting_celery_always_eager = namespace.add_setting(
|
||||
global_name='CELERY_TASK_ALWAYS_EAGER',
|
||||
|
||||
@@ -37,9 +37,7 @@ class BaseTestCase(DatabaseConversionMixin, ACLBaseTestMixin, ContentTypeCheckMi
|
||||
|
||||
|
||||
class GenericViewTestCase(BaseTestCase):
|
||||
def setUp(self):
|
||||
super(GenericViewTestCase, self).setUp()
|
||||
self.has_test_view = False
|
||||
has_test_view = False
|
||||
|
||||
def tearDown(self):
|
||||
from mayan.urls import urlpatterns
|
||||
@@ -87,13 +85,10 @@ class GenericViewTestCase(BaseTestCase):
|
||||
path=path, data=data, follow=follow
|
||||
)
|
||||
|
||||
def login(self, username, password):
|
||||
logged_in = self.client.login(username=username, password=password)
|
||||
def login(self, *args, **kwargs):
|
||||
logged_in = self.client.login(*args, **kwargs)
|
||||
|
||||
user = get_user_model().objects.get(username=username)
|
||||
|
||||
self.assertTrue(logged_in)
|
||||
self.assertTrue(user.is_authenticated)
|
||||
return logged_in
|
||||
|
||||
def login_user(self):
|
||||
self.login(username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD)
|
||||
|
||||
@@ -12,7 +12,7 @@ TEST_TEMPLATE_RESULT = '<div'
|
||||
|
||||
class CommonAPITestCase(BaseAPITestCase):
|
||||
def test_content_type_list_view(self):
|
||||
response = self.client.get(reverse('rest_api:content-type-list'))
|
||||
response = self.client.get(reverse(viewname='rest_api:content-type-list'))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
@override_settings(LANGUAGE_CODE='de')
|
||||
|
||||
@@ -6,5 +6,5 @@ from mayan.apps.user_management.tests.mixins import UserTestMixin
|
||||
|
||||
class UserLocaleProfileTestCase(UserTestMixin, BaseTestCase):
|
||||
def test_natural_keys(self):
|
||||
self._create_user()
|
||||
self._create_test_user()
|
||||
self._test_database_conversion('auth', 'common')
|
||||
|
||||
@@ -40,7 +40,19 @@ class CommonViewTestCase(GenericViewTestCase):
|
||||
}, follow=True
|
||||
)
|
||||
|
||||
def test_object_error_list_view_with_permissions(self):
|
||||
def test_object_error_list_view_no_permissions(self):
|
||||
self._create_error_log_entry()
|
||||
|
||||
self.login_user()
|
||||
|
||||
response = self._request_object_error_log_list()
|
||||
|
||||
self.assertNotContains(
|
||||
response=response, text=TEST_ERROR_LOG_ENTRY_RESULT,
|
||||
status_code=403
|
||||
)
|
||||
|
||||
def test_object_error_list_view_with_access(self):
|
||||
self._create_error_log_entry()
|
||||
|
||||
self.login_user()
|
||||
@@ -54,15 +66,3 @@ class CommonViewTestCase(GenericViewTestCase):
|
||||
response=response, text=TEST_ERROR_LOG_ENTRY_RESULT,
|
||||
status_code=200
|
||||
)
|
||||
|
||||
def test_object_error_list_view_no_permissions(self):
|
||||
self._create_error_log_entry()
|
||||
|
||||
self.login_user()
|
||||
|
||||
response = self._request_object_error_log_list()
|
||||
|
||||
self.assertNotContains(
|
||||
response=response, text=TEST_ERROR_LOG_ENTRY_RESULT,
|
||||
status_code=403
|
||||
)
|
||||
|
||||
@@ -15,67 +15,69 @@ from .views import (
|
||||
)
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', RootView.as_view(), name='root'),
|
||||
url(r'^home/$', HomeView.as_view(), name='home'),
|
||||
url(r'^about/$', AboutView.as_view(), name='about_view'),
|
||||
url(regex=r'^$', name='root', view=RootView.as_view()),
|
||||
url(regex=r'^home/$', name='home', view=HomeView.as_view()),
|
||||
url(regex=r'^about/$', name='about_view', view=AboutView.as_view()),
|
||||
url(
|
||||
r'^check_version/$', CheckVersionView.as_view(),
|
||||
name='check_version_view'
|
||||
regex=r'^check_version/$', name='check_version_view',
|
||||
view=CheckVersionView.as_view()
|
||||
),
|
||||
url(r'^license/$', LicenseView.as_view(), name='license_view'),
|
||||
url(regex=r'^license/$', name='license_view', view=LicenseView.as_view()),
|
||||
url(
|
||||
r'^packages/licenses/$', PackagesLicensesView.as_view(),
|
||||
name='packages_licenses_view'
|
||||
regex=r'^packages/licenses/$', name='packages_licenses_view',
|
||||
view=PackagesLicensesView.as_view()
|
||||
),
|
||||
url(
|
||||
r'^object/multiple/action/$', multi_object_action_view,
|
||||
name='multi_object_action_view'
|
||||
regex=r'^objects/multiple/action/$', name='multi_object_action_view',
|
||||
view=multi_object_action_view
|
||||
),
|
||||
url(r'^setup/$', SetupListView.as_view(), name='setup_list'),
|
||||
url(r'^tools/$', ToolsListView.as_view(), name='tools_list'),
|
||||
url(regex=r'^setup/$', name='setup_list', view=SetupListView.as_view()),
|
||||
url(regex=r'^tools/$', name='tools_list', view=ToolsListView.as_view()),
|
||||
url(
|
||||
r'^user/locale/$', CurrentUserLocaleProfileDetailsView.as_view(),
|
||||
name='current_user_locale_profile_details'
|
||||
regex=r'^users/current/locale/$',
|
||||
name='current_user_locale_profile_details',
|
||||
view=CurrentUserLocaleProfileDetailsView.as_view()
|
||||
),
|
||||
url(
|
||||
r'^user/locale/edit/$', CurrentUserLocaleProfileEditView.as_view(),
|
||||
name='current_user_locale_profile_edit'
|
||||
regex=r'^users/current/locale/edit/$',
|
||||
name='current_user_locale_profile_edit',
|
||||
view=CurrentUserLocaleProfileEditView.as_view()
|
||||
),
|
||||
url(
|
||||
r'^object/(?P<app_label>[-\w]+)/(?P<model>[-\w]+)/(?P<object_id>\d+)/errors/$',
|
||||
ObjectErrorLogEntryListView.as_view(), name='object_error_list'
|
||||
regex=r'^objects/(?P<app_label>[-\w]+)/(?P<model>[-\w]+)/(?P<object_id>\d+)/errors/$',
|
||||
name='object_error_list', view=ObjectErrorLogEntryListView.as_view()
|
||||
),
|
||||
url(
|
||||
r'^object/(?P<app_label>[-\w]+)/(?P<model>[-\w]+)/(?P<object_id>\d+)/errors/clear/$',
|
||||
ObjectErrorLogEntryListClearView.as_view(),
|
||||
name='object_error_list_clear'
|
||||
regex=r'^objects/(?P<app_label>[-\w]+)/(?P<model>[-\w]+)/(?P<object_id>\d+)/errors/clear/$',
|
||||
name='object_error_list_clear',
|
||||
view=ObjectErrorLogEntryListClearView.as_view()
|
||||
),
|
||||
]
|
||||
|
||||
urlpatterns += [
|
||||
url(
|
||||
r'^favicon\.ico$', FaviconRedirectView.as_view()
|
||||
regex=r'^favicon\.ico$', view=FaviconRedirectView.as_view()
|
||||
),
|
||||
url(
|
||||
r'^jsi18n/(?P<packages>\S+?)/$', javascript_catalog,
|
||||
name='javascript_catalog'
|
||||
regex=r'^jsi18n/(?P<packages>\S+?)/$', name='javascript_catalog',
|
||||
view=javascript_catalog
|
||||
),
|
||||
url(
|
||||
r'^set_language/$', set_language, name='set_language'
|
||||
regex=r'^set_language/$', name='set_language', view=set_language
|
||||
),
|
||||
]
|
||||
|
||||
api_urls = [
|
||||
url(
|
||||
r'^content_types/$', APIContentTypeList.as_view(),
|
||||
name='content-type-list'
|
||||
regex=r'^content_types/$', name='content-type-list',
|
||||
view=APIContentTypeList.as_view()
|
||||
),
|
||||
url(
|
||||
r'^templates/$', APITemplateListView.as_view(),
|
||||
name='template-list'
|
||||
regex=r'^templates/$', name='template-list',
|
||||
view=APITemplateListView.as_view()
|
||||
),
|
||||
url(
|
||||
r'^templates/(?P<name>[-\w]+)/$', APITemplateView.as_view(),
|
||||
name='template-detail'
|
||||
regex=r'^templates/(?P<name>[-\w]+)/$', name='template-detail',
|
||||
view=APITemplateView.as_view()
|
||||
),
|
||||
]
|
||||
|
||||
@@ -15,6 +15,9 @@ from django.utils.translation import ugettext_lazy as _
|
||||
from django.views.generic import RedirectView, TemplateView
|
||||
|
||||
from mayan.apps.acls.models import AccessControlList
|
||||
from mayan.apps.common.mixins import (
|
||||
ContentTypeViewMixin, ExternalObjectViewMixin
|
||||
)
|
||||
|
||||
from .exceptions import NotLatestVersion, UnknownLatestVersion
|
||||
from .forms import (
|
||||
@@ -171,7 +174,9 @@ class ObjectErrorLogEntryListClearView(ConfirmView):
|
||||
)
|
||||
|
||||
|
||||
class ObjectErrorLogEntryListView(SingleObjectListView):
|
||||
class ObjectErrorLogEntryListView(ContentTypeViewMixin, ExternalObjectViewMixin, SingleObjectListView):
|
||||
#TODO: Update for MERC 6. Return 404.
|
||||
"""
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
AccessControlList.objects.check_access(
|
||||
obj=self.get_object(), permissions=permission_error_log_view,
|
||||
@@ -181,6 +186,7 @@ class ObjectErrorLogEntryListView(SingleObjectListView):
|
||||
return super(ObjectErrorLogEntryListView, self).dispatch(
|
||||
request, *args, **kwargs
|
||||
)
|
||||
"""
|
||||
|
||||
def get_extra_context(self):
|
||||
return {
|
||||
@@ -202,6 +208,7 @@ class ObjectErrorLogEntryListView(SingleObjectListView):
|
||||
'title': _('Error log entries for: %s' % self.get_object()),
|
||||
}
|
||||
|
||||
"""
|
||||
def get_object(self):
|
||||
content_type = get_object_or_404(
|
||||
klass=ContentType, app_label=self.kwargs['app_label'],
|
||||
@@ -211,9 +218,9 @@ class ObjectErrorLogEntryListView(SingleObjectListView):
|
||||
return get_object_or_404(
|
||||
klass=content_type.model_class(), pk=self.kwargs['object_id']
|
||||
)
|
||||
|
||||
"""
|
||||
def get_object_list(self):
|
||||
return self.get_object().error_logs.all()
|
||||
return self.get_external_object().error_logs.all()
|
||||
|
||||
|
||||
class PackagesLicensesView(SimpleView):
|
||||
|
||||
Reference in New Issue
Block a user