User management à la Lino

This document explains to developers and site maintainers how to get started with Lino's user management system. See users : user management for detailed developer documentation. See users : Managing users for end-user documentation.

This is a tested document. The following instructions are used for initialization:

>>> from lino import startup
>>> startup('lino_book.projects.min1.settings')
>>> from lino.api.doctest import *
>>> from atelier.sheller import Sheller
>>> shell = Sheller("lino_book/projects/min1")

Creating a site manager

A site manager is any site user having a User.user_type.role that inherits from lino.core.roles.SiteAdmin.

The most Linoish way to create a site manager and a set of demo users is to run prep. This will reset the database to a virgin state and then load the demo fixture, which will create the demo users Robin, Rolf, Romain, Rando, Rik, Ronaldo ... depending on your site's language distribution (lino.core.site.Site.languages).

Once you have a site manager, you can sign in via the web interface and work as described in users : Managing users.

Managing users from the command line

Django has a django-admin command named createsuperuser but this is quite limited. Lino gives a more useful command passwd.

passwd

Update or optionally create password, name and type of a user. The default action displays and optionally edits the user. Specify -c to create a new user.

Usage: go to your project directory and say:

$ python manage.py passwd [options] USERNAME

Where USERNAME is the username of the user to process. Default value for USERNAME is your system username.

Options

-c, --create

Create the given user. Fail if that username exists already.

--batch

Run in batch mode, i.e. without asking any questions. Assume yes to all questions.

>>> shell("python manage.py show users.AllUsers")
... 
========== ===================== ============ ===========
 Username   User type             First name   Last name
---------- --------------------- ------------ -----------
 robin      900 (Administrator)   Robin        Rood
 rolf       900 (Administrator)   Rolf         Rompen
 romain     900 (Administrator)   Romain       Raffault
========== ===================== ============ ===========
>>> shell("python manage.py passwd -c test --batch")
Creating new user
User test has been saved.
>>> shell("python manage.py show users.AllUsers")
... 
========== ===================== ============ ===========
 Username   User type             First name   Last name
---------- --------------------- ------------ -----------
 robin      900 (Administrator)   Robin        Rood
 rolf       900 (Administrator)   Rolf         Rompen
 romain     900 (Administrator)   Romain       Raffault
 test
========== ===================== ============ ===========
>>> u = users.User.objects.get(username="test")
>>> u.has_usable_password()
False

Managing users programmatically

For more fancy situations you can write a Python script and run it with run. For example:

from lino.api.shell import users
obj = users.User(username="root")
obj.set_password("1234!")
obj.full_clean()
obj.save()

Passwords of new users

The password field of a newly created user is empty, and the account therefore cannot be used to sign in. When you created a new user manually using the web interface, you must click their ChangePassword action and set their password.

>>> u = users.User(username="test")
>>> u.full_clean()
>>> u.save()

Since we didn't set a password, Django stores a "non usable" password, and the User.check_password() method returns False:

>>> u.password  
'!...'
>>> u.check_password('')
False
>>> u.has_usable_password()
False

When setting the password for a newly created user, leave the field Current password empty.

>>> ses = rt.login('robin')
>>> values = dict(current="", new1="1234", new2="1234")
>>> rv = ses.run(u.change_password, action_param_values=values)
>>> print(rv['message'])
New password has been set for test.