Move current user views and add user events

Move the current user detail and edit views from the common app
to the user_management app. Add the user created and edited events.
Add an user detail view.

Signed-off-by: Roberto Rosario <Roberto.Rosario@mayan-edms.com>
This commit is contained in:
Roberto Rosario
2018-12-24 04:21:25 -04:00
parent 931b17a447
commit fd7e937cef
15 changed files with 185 additions and 116 deletions

View File

@@ -25,11 +25,9 @@ from .handlers import (
)
from .licenses import * # NOQA
from .links import (
link_about, link_check_version, link_current_user_details,
link_current_user_edit, link_current_user_locale_profile_edit,
link_about, link_check_version, link_current_user_locale_profile_edit,
link_license, link_object_error_list_clear, link_packages_licenses,
link_setup, link_tools, separator_system, separator_user_label,
text_user_label
link_setup, link_tools, separator_system
)
from .literals import DELETE_STALE_UPLOADS_INTERVAL, MESSAGE_SQLITE_WARNING
from .menus import (
@@ -132,10 +130,8 @@ class CommonApp(MayanAppConfig):
)
menu_user.bind_links(
links=(
text_user_label, separator_user_label,
link_current_user_details, link_current_user_edit,
link_current_user_locale_profile_edit,
)
), position=50
)
menu_about.bind_links(

View File

@@ -159,24 +159,3 @@ class PackagesLicensesForm(FileDisplayForm):
self.fields['text'].initial = '\n\n'.join(
['{}\n{}'.format(package.label, package.license_text) for package in Package.get_all()]
)
class UserForm(forms.ModelForm):
"""
Form used to edit an user's mininal fields by the user himself
"""
class Meta:
fields = ('username', 'first_name', 'last_name', 'email')
model = get_user_model()
class UserForm_view(DetailForm):
"""
Form used to display an user's public details
"""
class Meta:
fields = (
'username', 'first_name', 'last_name', 'email', 'last_login',
'date_joined', 'groups'
)
model = get_user_model()

View File

@@ -6,8 +6,6 @@ icon_about = Icon(driver_name='fontawesome', symbol='info')
icon_assign_remove_add = Icon(driver_name='fontawesome', symbol='plus')
icon_assign_remove_remove = Icon(driver_name='fontawesome', symbol='minus')
icon_check_version = Icon(driver_name='fontawesome', symbol='sync')
icon_current_user_details = Icon(driver_name='fontawesome', symbol='user')
icon_current_user_edit = Icon(driver_name='fontawesome', symbol='user')
icon_current_user_locale_profile_details = Icon(
driver_name='fontawesome', symbol='globe'
)

View File

@@ -7,14 +7,12 @@ from mayan.apps.navigation import Link
from mayan.apps.navigation.classes import Separator, Text
from .icons import (
icon_about, icon_check_version, icon_current_user_details,
icon_current_user_edit, icon_current_user_locale_profile_details,
icon_about, icon_check_version, icon_current_user_locale_profile_details,
icon_current_user_locale_profile_edit, icon_documentation, icon_forum,
icon_license, icon_object_error_list, icon_packages_licenses,
icon_setup, icon_source_code, icon_support, icon_tools
)
from .permissions_runtime import permission_error_log_view
from .utils import get_user_label_text
def get_kwargs_factory(variable_name):
@@ -42,14 +40,6 @@ link_check_version = Link(
icon_class=icon_check_version, text=_('Check for updates'),
view='common:check_version_view'
)
link_current_user_details = Link(
icon_class=icon_current_user_details, text=_('User details'),
view='common:current_user_details'
)
link_current_user_edit = Link(
icon_class=icon_current_user_edit, text=_('Edit details'),
view='common:current_user_edit'
)
link_current_user_locale_profile_details = Link(
icon_class=icon_current_user_locale_profile_details,
text=_('Locale profile'),
@@ -101,5 +91,3 @@ link_tools = Link(
icon_class=icon_tools, text=_('Tools'), view='common:tools_list'
)
separator_system = Separator()
separator_user_label = Separator()
text_user_label = Text(text=get_user_label_text)

View File

@@ -5,10 +5,9 @@ from django.views.i18n import javascript_catalog, set_language
from .api_views import APIContentTypeList, APITemplateView
from .views import (
AboutView, CheckVersionView, CurrentUserDetailsView, CurrentUserEditView,
CurrentUserLocaleProfileDetailsView, CurrentUserLocaleProfileEditView,
FaviconRedirectView, HomeView, LicenseView,
ObjectErrorLogEntryListClearView, ObjectErrorLogEntryListView,
AboutView, CheckVersionView, CurrentUserLocaleProfileDetailsView,
CurrentUserLocaleProfileEditView, FaviconRedirectView, HomeView,
LicenseView, ObjectErrorLogEntryListClearView, ObjectErrorLogEntryListView,
PackagesLicensesView, RootView, SetupListView, ToolsListView,
multi_object_action_view
)
@@ -32,14 +31,6 @@ urlpatterns = [
),
url(r'^setup/$', SetupListView.as_view(), name='setup_list'),
url(r'^tools/$', ToolsListView.as_view(), name='tools_list'),
url(
r'^user/$', CurrentUserDetailsView.as_view(),
name='current_user_details'
),
url(
r'^user/edit/$', CurrentUserEditView.as_view(),
name='current_user_edit'
),
url(
r'^user/locale/$', CurrentUserLocaleProfileDetailsView.as_view(),
name='current_user_locale_profile_details'

View File

@@ -68,13 +68,6 @@ def encapsulate(function):
return lambda: function
def get_user_label_text(context):
if not context['request'].user.is_authenticated:
return _('Anonymous')
else:
return context['request'].user.get_full_name() or context['request'].user
def fs_cleanup(filename, file_descriptor=None, suppress_exceptions=True):
"""
Tries to remove the given filename. Ignores non-existent files

View File

@@ -19,7 +19,7 @@ from mayan.apps.acls.models import AccessControlList
from .exceptions import NotLatestVersion, UnknownLatestVersion
from .forms import (
LicenseForm, LocaleProfileForm, LocaleProfileForm_view,
PackagesLicensesForm, UserForm, UserForm_view
PackagesLicensesForm
)
from .generics import ( # NOQA
AssignRemoveView, ConfirmView, FormView, MultiFormView,
@@ -65,28 +65,6 @@ class CheckVersionView(SimpleView):
}
class CurrentUserDetailsView(SingleObjectDetailView):
form_class = UserForm_view
def get_object(self):
return self.request.user
def get_extra_context(self, **kwargs):
return {
'object': None,
'title': _('Current user details'),
}
class CurrentUserEditView(SingleObjectEditView):
extra_context = {'object': None, 'title': _('Edit current user details')}
form_class = UserForm
post_action_redirect = reverse_lazy('common:current_user_details')
def get_object(self):
return self.request.user
class CurrentUserLocaleProfileDetailsView(TemplateView):
template_name = 'appearance/generic_form.html'

View File

@@ -9,22 +9,31 @@ from mayan.apps.acls import ModelPermission
from mayan.apps.acls.links import link_acl_list
from mayan.apps.acls.permissions import permission_acl_edit, permission_acl_view
from mayan.apps.common import (
menu_list_facet, menu_multi_item, menu_object, menu_secondary, menu_setup
menu_list_facet, menu_multi_item, menu_object, menu_secondary, menu_setup,
menu_user
)
from mayan.apps.common.apps import MayanAppConfig
from mayan.apps.common.widgets import TwoStateWidget
from mayan.apps.events import ModelEventType
from mayan.apps.events.links import (
link_events_for_object, link_object_event_types_user_subcriptions_list
)
from mayan.apps.metadata import MetadataLookup
from mayan.apps.navigation import SourceColumn
from mayan.apps.rest_api.fields import DynamicSerializerField
from .events import event_user_edited
from .handlers import handler_initialize_new_user_options
from .links import (
link_group_create, link_group_delete, link_group_edit, link_group_list,
link_group_members, link_group_setup, link_user_create, link_user_delete,
link_user_edit, link_user_groups, link_user_list,
link_user_multiple_delete, link_user_multiple_set_password,
link_user_set_options, link_user_set_password, link_user_setup
link_current_user_details, link_current_user_edit, link_group_create,
link_group_delete, link_group_edit, link_group_list, link_group_members,
link_group_setup, link_user_create, link_user_delete, link_user_edit,
link_user_groups, link_user_list, link_user_multiple_delete,
link_user_multiple_set_password, link_user_set_options,
link_user_set_password, link_user_setup, text_user_label,
separator_user_label
)
from .methods import method_get_absolute_url
from .permissions import (
permission_group_delete, permission_group_edit,
permission_group_view, permission_user_delete, permission_user_edit,
@@ -62,6 +71,11 @@ class UserManagementApp(MayanAppConfig):
description=_('All the users.'), name='users',
value=get_users
)
ModelEventType.register(
model=User, event_types=(event_user_edited,)
)
ModelPermission.register(
model=Group, permissions=(
permission_acl_edit, permission_acl_view,
@@ -82,7 +96,10 @@ class UserManagementApp(MayanAppConfig):
attribute='user_set.count', label=_('Users'), source=Group
)
SourceColumn(attribute='username', is_identifier=True, source=User)
SourceColumn(
attribute='username', is_absolute_url=True, is_identifier=True,
label=_('Username'), source=User
)
SourceColumn(
attribute='get_full_name', label=_('Full name'), source=User
)
@@ -99,16 +116,25 @@ class UserManagementApp(MayanAppConfig):
source=User, widget=TwoStateWidget
)
User.add_to_class(
name='get_absolute_url', value=method_get_absolute_url
)
menu_list_facet.bind_links(
links=(
link_acl_list, link_group_members,
), sources=(Group,)
)
menu_list_facet.bind_links(
links=(
link_acl_list, link_user_groups
), sources=(User,)
link_acl_list, link_events_for_object,
link_object_event_types_user_subcriptions_list,
link_user_groups,
),
sources=(User,)
)
menu_multi_item.bind_links(
links=(link_user_multiple_set_password, link_user_multiple_delete),
sources=('user_management:user_list',)
@@ -142,6 +168,12 @@ class UserManagementApp(MayanAppConfig):
)
)
menu_setup.bind_links(links=(link_user_setup, link_group_setup))
menu_user.bind_links(
links=(
text_user_label, separator_user_label,
link_current_user_details, link_current_user_edit,
), position=0
)
post_save.connect(
dispatch_uid='user_management_handler_initialize_new_user_options',

View File

@@ -0,0 +1,16 @@
from __future__ import absolute_import, unicode_literals
from django.utils.translation import ugettext_lazy as _
from mayan.apps.events import EventTypeNamespace
namespace = EventTypeNamespace(
name='user_management', label=_('User management')
)
event_user_created = namespace.add_event_type(
label=_('User created'), name='created'
)
event_user_edited = namespace.add_event_type(
label=_('User edited'), name='edited'
)

View File

@@ -2,6 +2,8 @@ from __future__ import absolute_import, unicode_literals
from mayan.apps.appearance.classes import Icon
icon_current_user_details = Icon(driver_name='fontawesome', symbol='user')
icon_current_user_edit = Icon(driver_name='fontawesome', symbol='user')
icon_group = Icon(driver_name='fontawesome', symbol='users')
icon_group_create = Icon(driver_name='fontawesome', symbol='plus')
icon_group_members = Icon(driver_name='fontawesome', symbol='user')

View File

@@ -2,17 +2,19 @@ from __future__ import unicode_literals
from django.utils.translation import ugettext_lazy as _
from mayan.apps.navigation import Link
from mayan.apps.navigation import Link, Separator, Text
from .icons import (
icon_group, icon_group_create, icon_group_members, icon_group_setup,
icon_user_create, icon_user_setup
icon_current_user_details, icon_current_user_edit, icon_group,
icon_group_create, icon_group_members, icon_group_setup, icon_user_create,
icon_user_setup
)
from .permissions import (
permission_group_create, permission_group_delete, permission_group_edit,
permission_group_view, permission_user_create, permission_user_delete,
permission_user_edit, permission_user_view
)
from .utils import get_user_label_text
def condition_is_not_superuser(context):
@@ -20,6 +22,14 @@ def condition_is_not_superuser(context):
return not user.is_superuser and not user.is_staff
link_current_user_details = Link(
icon_class=icon_current_user_details, text=_('User details'),
view='user_management:current_user_details'
)
link_current_user_edit = Link(
icon_class=icon_current_user_edit, text=_('Edit details'),
view='user_management:current_user_edit'
)
link_group_create = Link(
icon_class=icon_group_create, permissions=(permission_group_create,),
text=_('Create new group'), view='user_management:group_create'
@@ -86,3 +96,6 @@ link_user_setup = Link(
icon_class=icon_user_setup, permissions=(permission_user_view,),
text=_('Users'), view='user_management:user_list'
)
separator_user_label = Separator()
text_user_label = Text(text=get_user_label_text)

View File

@@ -0,0 +1,8 @@
from __future__ import unicode_literals
from django.apps import apps
from django.shortcuts import reverse
def method_get_absolute_url(self):
return reverse(viewname='user_management:user_details', args=(self.pk,))

View File

@@ -7,52 +7,65 @@ from .api_views import (
APIUserListView, APIUserView
)
from .views import (
GroupCreateView, GroupDeleteView, GroupEditView, GroupListView,
GroupMembersView, UserCreateView, UserDeleteView, UserEditView,
CurrentUserDetailsView, CurrentUserEditView, GroupCreateView,
GroupDeleteView, GroupEditView, GroupListView, GroupMembersView,
UserCreateView, UserDeleteView, UserDetailsView, UserEditView,
UserGroupsView, UserListView, UserOptionsEditView, UserSetPasswordView
)
urlpatterns = [
url(r'^group/list/$', GroupListView.as_view(), name='group_list'),
url(r'^group/create/$', GroupCreateView.as_view(), name='group_create'),
url(r'^groups/list/$', GroupListView.as_view(), name='group_list'),
url(r'^groups/create/$', GroupCreateView.as_view(), name='group_create'),
url(
r'^group/(?P<pk>\d+)/edit/$', GroupEditView.as_view(),
r'^groups/(?P<pk>\d+)/edit/$', GroupEditView.as_view(),
name='group_edit'
),
url(
r'^group/(?P<pk>\d+)/delete/$', GroupDeleteView.as_view(),
r'^groups/(?P<pk>\d+)/delete/$', GroupDeleteView.as_view(),
name='group_delete'
),
url(
r'^group/(?P<pk>\d+)/members/$', GroupMembersView.as_view(),
r'^groups/(?P<pk>\d+)/members/$', GroupMembersView.as_view(),
name='group_members'
),
url(r'^user/list/$', UserListView.as_view(), name='user_list'),
url(r'^user/create/$', UserCreateView.as_view(), name='user_create'),
url(r'^user/(?P<pk>\d+)/edit/$', UserEditView.as_view(), name='user_edit'),
url(
r'^user/(?P<pk>\d+)/delete/$', UserDeleteView.as_view(),
name='user_delete'
r'^users/current/$', CurrentUserDetailsView.as_view(),
name='current_user_details'
),
url(
r'^user/multiple/delete/$', UserDeleteView.as_view(),
r'^users/current/edit/$', CurrentUserEditView.as_view(),
name='current_user_edit'
),
url(r'^users/list/$', UserListView.as_view(), name='user_list'),
url(r'^users/create/$', UserCreateView.as_view(), name='user_create'),
url(
r'^users/(?P<pk>\d+)/delete/$', UserDeleteView.as_view(),
name='user_delete'
),
url(r'^users/(?P<pk>\d+)/edit/$', UserEditView.as_view(), name='user_edit'),
url(
r'^users/(?P<pk>\d+)/$', UserDetailsView.as_view(),
name='user_details'
),
url(
r'^users/multiple/delete/$', UserDeleteView.as_view(),
name='user_multiple_delete'
),
url(
r'^user/(?P<pk>\d+)/set_password/$', UserSetPasswordView.as_view(),
r'^users/(?P<pk>\d+)/set_password/$', UserSetPasswordView.as_view(),
name='user_set_password'
),
url(
r'^user/multiple/set_password/$', UserSetPasswordView.as_view(),
r'^users/multiple/set_password/$', UserSetPasswordView.as_view(),
name='user_multiple_set_password'
),
url(
r'^user/(?P<pk>\d+)/groups/$', UserGroupsView.as_view(),
r'^users/(?P<pk>\d+)/groups/$', UserGroupsView.as_view(),
name='user_groups'
),
url(
r'^user/(?P<pk>\d+)/options/$',
r'^users/(?P<pk>\d+)/options/$',
UserOptionsEditView.as_view(),
name='user_options'
),

View File

@@ -16,3 +16,10 @@ def get_users():
for user in get_user_model().objects.all()
]
)
def get_user_label_text(context):
if not context['request'].user.is_authenticated:
return _('Anonymous')
else:
return context['request'].user.get_full_name() or context['request'].user

View File

@@ -15,10 +15,12 @@ from django.utils.translation import ungettext, ugettext_lazy as _
from mayan.apps.common.views import (
AssignRemoveView, MultipleObjectConfirmActionView,
MultipleObjectFormActionView, SingleObjectCreateView,
SingleObjectDeleteView, SingleObjectEditView, SingleObjectListView
SingleObjectDeleteView, SingleObjectDetailView, SingleObjectEditView,
SingleObjectListView
)
from .forms import UserForm
from .events import event_user_created, event_user_edited
from .forms import UserForm, UserForm_view
from .icons import icon_group_setup, icon_user_setup
from .links import link_group_create, link_user_create
from .permissions import (
@@ -28,6 +30,31 @@ from .permissions import (
)
class CurrentUserDetailsView(SingleObjectDetailView):
fields = (
'username', 'first_name', 'last_name', 'email', 'last_login',
'date_joined', 'groups'
)
def get_object(self):
return self.request.user
def get_extra_context(self, **kwargs):
return {
'object': None,
'title': _('Current user details'),
}
class CurrentUserEditView(SingleObjectEditView):
extra_context = {'object': None, 'title': _('Edit current user details')}
form_class = UserForm
post_action_redirect = reverse_lazy('user_management:current_user_details')
def get_object(self):
return self.request.user
class GroupCreateView(SingleObjectCreateView):
extra_context = {'title': _('Create new group')}
fields = ('name',)
@@ -141,6 +168,11 @@ class UserCreateView(SingleObjectCreateView):
user = form.save(commit=False)
user.set_unusable_password()
user.save()
event_user_created.commit(
actor=self.request.user, target=user
)
messages.success(
self.request, _('User "%s" created successfully.') % user
)
@@ -205,6 +237,23 @@ class UserDeleteView(MultipleObjectConfirmActionView):
)
class UserDetailsView(SingleObjectDetailView):
fields = (
'username', 'first_name', 'last_name', 'email', 'last_login',
'date_joined', 'groups',
)
object_permission = permission_user_view
queryset = get_user_model().objects.filter(
is_superuser=False, is_staff=False
)
def get_extra_context(self, **kwargs):
return {
'object': self.get_object(),
'title': _('Details of user: %s') % self.get_object()
}
class UserEditView(SingleObjectEditView):
fields = ('username', 'first_name', 'last_name', 'email', 'is_active',)
object_permission = permission_user_edit
@@ -213,6 +262,12 @@ class UserEditView(SingleObjectEditView):
is_superuser=False, is_staff=False
)
def form_valid(self, form):
event_user_edited.commit(
actor=self.request.user, target=self.get_object()
)
return super(UserEditView, self).form_valid(form=form)
def get_extra_context(self):
return {
'object': self.get_object(),