diff --git a/plinth/modules/users/__init__.py b/plinth/modules/users/__init__.py
index 747dae9c5..b43087580 100644
--- a/plinth/modules/users/__init__.py
+++ b/plinth/modules/users/__init__.py
@@ -24,7 +24,8 @@ from django.utils.translation import ugettext_lazy as _
from plinth import action_utils, actions
from plinth import app as app_module
-from plinth import menu
+from plinth import cfg, menu
+from plinth.utils import format_lazy
version = 2
@@ -45,6 +46,20 @@ first_boot_steps = [
name = _('Users and Groups')
+description = [
+ _('Create and managed user accounts. These accounts serve as centralized '
+ 'authentication mechanism for most apps. Some apps further require a '
+ 'user account to be part of a group to authorize the user to access the '
+ 'app.'),
+ format_lazy(
+ _('Any user may login to {box_name} web interface to see a list of '
+ 'apps relevant to them in the home page. However, only users of '
+ 'the admin group may alter apps or system settings.'),
+ box_name=_(cfg.box_name))
+]
+
+manual_page = 'Users'
+
# All FreedomBox user groups
groups = dict()
diff --git a/plinth/modules/users/templates/users_list.html b/plinth/modules/users/templates/users_list.html
index 9b026e758..4137f6598 100644
--- a/plinth/modules/users/templates/users_list.html
+++ b/plinth/modules/users/templates/users_list.html
@@ -1,4 +1,4 @@
-{% extends "base.html" %}
+{% extends "app.html" %}
{% comment %}
#
# This file is part of FreedomBox.
@@ -33,7 +33,17 @@
{% endblock %}
-{% block content %}
+{% block status %}
+
+
+ {% trans 'Create User' %}
+
+{% endblock %}
+
+{% block configuration %}
+
+
{% trans "Users" %}
@@ -64,7 +74,6 @@
{% endfor %}
- {% include "diagnostics_button.html" with module="users" enabled=True %}
diff --git a/plinth/modules/users/views.py b/plinth/modules/users/views.py
index 55c611d13..284b1ab90 100644
--- a/plinth/modules/users/views.py
+++ b/plinth/modules/users/views.py
@@ -29,29 +29,21 @@ from django.views.generic.edit import (CreateView, DeleteView, FormView,
from plinth import actions
from plinth.errors import ActionError
-from plinth.modules import first_boot
+from plinth.modules import first_boot, users
from plinth.utils import is_user_admin
+from plinth.views import AppView
from . import get_last_admin_user
from .forms import (CreateUserForm, FirstBootForm, UserChangePasswordForm,
UserUpdateForm)
-subsubmenu = [{
- 'url': reverse_lazy('users:index'),
- 'text': ugettext_lazy('Users')
-}, {
- 'url': reverse_lazy('users:create'),
- 'text': ugettext_lazy('Create User')
-}]
-
class ContextMixin(object):
- """Mixin to add 'subsubmenu' and 'title' to the context."""
+ """Mixin to add 'title' to the template context."""
def get_context_data(self, **kwargs):
- """Use self.title and the module-level subsubmenu"""
+ """Add self.title to template context."""
context = super(ContextMixin, self).get_context_data(**kwargs)
- context['subsubmenu'] = subsubmenu
context['title'] = getattr(self, 'title', '')
return context
@@ -76,11 +68,17 @@ class UserCreate(ContextMixin, SuccessMessageMixin, CreateView):
return reverse('users:index')
-class UserList(ContextMixin, django.views.generic.ListView):
+class UserList(AppView, ContextMixin, django.views.generic.ListView):
"""View to list users."""
model = User
template_name = 'users_list.html'
title = ugettext_lazy('Users')
+ name = users.name
+ description = users.description
+ app_id = 'users'
+ show_status_block = False
+ diagnostics_module_name = 'users'
+ manual_page = users.manual_page
def get_context_data(self, *args, **kwargs):
context = super(UserList, self).get_context_data(*args, **kwargs)
@@ -129,13 +127,6 @@ class UserUpdate(ContextMixin, SuccessMessageMixin, UpdateView):
"""Return the URL to redirect to in case of successful updation."""
return reverse('users:edit', kwargs={'slug': self.object.username})
- def get_context_data(self, **kwargs):
- """Use self.title and the module-level subsubmenu"""
- context = super(UserUpdate, self).get_context_data(**kwargs)
- if not is_user_admin(self.request):
- del context['subsubmenu']
- return context
-
class UserDelete(ContextMixin, DeleteView):
"""Handle deleting users, showing a confirmation dialog first.
@@ -207,13 +198,6 @@ class UserChangePassword(ContextMixin, SuccessMessageMixin, FormView):
update_session_auth_hash(self.request, form.user)
return super(UserChangePassword, self).form_valid(form)
- def get_context_data(self, **kwargs):
- """Remove subsubmenu for non-admin users."""
- context = super(UserChangePassword, self).get_context_data(**kwargs)
- if not is_user_admin(self.request):
- del context['subsubmenu']
- return context
-
class FirstBootView(django.views.generic.CreateView):
"""Create user account and log the user in."""