.. doctest docs/dev/myroles.rst .. _lino.tutorials.myroles: ============================================ Local customizations to the user permissions ============================================ This page explains how to locally override a user types module. .. contents:: :depth: 1 :local: .. include:: /../docs/shared/include/tested.rst >>> from lino import startup >>> startup('lino_book.projects.myroles.settings') >>> from lino.api.doctest import * .. flush the database to remove data from a previous test run >>> from django.core.management import call_command >>> call_command('initdb', interactive=False) #doctest: +ELLIPSIS `initdb ` started on database .../lino_book/projects/myroles/default.db. ... The example =========== For example on a standard Lino Polly site (:mod:`lino_book.projects.polly`), only a :term:`site administrator` can see the global list of all polls. This list is visible through :menuselection:`Explorer --> Polls --> Polls`. A normal user does not see that menu command. We are going to apply a local customization. In our variant of a Lino Polly application, *every* authenticated user (not only site admins) can see that table. Here is the :xfile:`settings.py` file used by this tutorial: .. literalinclude:: ../../lino_book/projects/myroles/settings.py In our :xfile:`settings.py` file, we override the :attr:`user_types_module ` of the Polly :class:`Site` class and set it to the Python path of our :file:`myroles.py` file:: user_types_module = 'mysite.myroles' Now we create this module, i.e. a file named :file:`myroles.py` with the following content: .. literalinclude:: ../../lino_book/projects/myroles/myroles.py The first line imports everything from the standard module:: from lino_xl.lib.xl.user_types import * How did we know that the name of the standard user types module of a Lino Polly is :mod:`lino_xl.lib.xl.user_types`? For example like this: >>> from lino_book.projects.polly.settings import Site >>> print(Site.user_types_module) lino_xl.lib.xl.user_types The following lines basically just set the :attr:`required_roles` of the :class:`polls.AllPolls` table require the :class:`PollsUser` role:: AllPolls.required_roles = dd.login_required(PollsUser) Testing it ========== Yes our local :file:`myroles.py` module is being imported at startup: >>> print(settings.SITE.user_types_module) lino_book.projects.myroles.myroles The following code snippets are to test whether a normal user now really can see all polls (i.e. has the :menuselection:`Explorer --> Polls --> Polls` menu command): >>> u = users.User(username="user", user_type="100") >>> u.full_clean() >>> u.save() >>> show_menu('user') ... #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE +REPORT_UDIFF - Polls : My Polls, My Responses - Explorer : - Polls : Polls - Site : About