Welcome | Get started | Dive | Contribute | Topics | Reference | Changes | More
Introduction to user management¶
This page explains to developers and server administrators how to get started with Lino’s functionality for managing the users of a Lino site.
It assumes that you have read the end-user documentation about The users plugin.
See users : user management for detailed developer documentation.
Side note: Code snippets (lines starting with >>>
) in this document get
tested as part of our development workflow. The following
initialization snippet tells you which demo project is being used in
this document.
>>> 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 “Administrator” as user type, which gives them permission to edit the list of site users.
On a default Lino site this permission is given only to the “Administrator”
user type. More precisely this permission is given by the
SiteAdmin
user role, which is
inherited by the “Administrator” user type, and an application can use
a custom user_types_module to
define other user types.
The most Linoish way to create a site manager and a set of demo
users is to run pm 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 The users plugin.
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
pm 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="2rgXx2EdJp", new2="2rgXx2EdJp")
>>> rv = ses.run(u.change_password, action_param_values=values)
>>> print(rv['message'])
New password has been set for test.
>>> u.delete()
Password validation¶
A Lino site defaults to use the four password validators that come included with Django:
>>> pprint(settings.AUTH_PASSWORD_VALIDATORS)
[{'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator'},
{'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator'},
{'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator'},
{'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator'}]
See also the Django docs about Password validation
Note that password validators are being run only in situations where a
potentially naive end user is being asked to provide a password. They do
not apply e.g. when a user is created programmatically or when the password is
set at the command line using pm passwd
.
That’s why the demo fixtures of the lino.modlib.users
plugin can
create users with such a terrible password as “1234”.
A server administrator can customize password validation by manually
setting a custom AUTH_PASSWORD_VALIDATORS
. To disable password
validation alltogether, just add the following line at the end of your
settings.py
file:
AUTH_PASSWORD_VALIDATORS = []