doc: features and use cases documentation

This commit is contained in:
Éloi Rivard 2024-05-13 16:44:02 +02:00
parent d134259332
commit 18a711ef7d
No known key found for this signature in database
GPG key ID: 7EDA204EA57DD184
27 changed files with 582 additions and 142 deletions

View file

@ -148,7 +148,7 @@ The dynamical parts of the interface use `htmx <https://htmx.org/>`_.
Translations Translations
------------ ------------
.. include:: ../canaille/translations/README.rst .. include:: ../../canaille/translations/README.rst
Documentation Documentation
------------- -------------
@ -173,7 +173,7 @@ Publish a new release
1. Check that dependencies are up to date with ``poetry show --outdated --with dev,doc,demo`` and update dependencies accordingly in separated commits. 1. Check that dependencies are up to date with ``poetry show --outdated --with dev,doc,demo`` and update dependencies accordingly in separated commits.
2. Check that tests are still green for every supported python version, and that coverage is still at 100%, by running ``tox`` 2. Check that tests are still green for every supported python version, and that coverage is still at 100%, by running ``tox``
3. Check that the demo environments are still working 3. Check that the demo environments are still working
4. Check that the :ref:`changelog:Release notes` section is correctly filled up 4. Check that the :ref:`development/changelog:Release notes` section is correctly filled up
5. Increase the version number in ``pyproject.toml`` 5. Increase the version number in ``pyproject.toml``
6. Commit with ``git commit`` 6. Commit with ``git commit``
7. Publish with ``poetry publish --build`` 7. Publish with ``poetry publish --build``

5
TODO.md Normal file
View file

@ -0,0 +1,5 @@
- screenshots partout
- s'assurer qu'on reste pas trop techniques dans features.html
- s'assurer que les concepts techniques pas mentionnés dans features.html sont bien mentionnés quelque part
- écrire les usecases
- s'assurer qu'il ne reste pas de TODO ou de TBD

View file

@ -25,6 +25,18 @@ class RootSettings(BaseSettings):
- :doc:`Flask-WTF <flask-wtf:config>` - :doc:`Flask-WTF <flask-wtf:config>`
- :doc:`Flask-Babel <flask-babel:index>` - :doc:`Flask-Babel <flask-babel:index>`
- :doc:`Authlib <authlib:flask/2/authorization-server>` - :doc:`Authlib <authlib:flask/2/authorization-server>`
.. code-block:: toml
:caption: config.toml
SECRET_KEY = "very-secret"
SERVER_NAME = "auth.mydomain.example"
PREFERRED_URL_SCHEME = false
DEBUG = false
[CANAILLE]
NAME = "My organization"
...
""" """
model_config = SettingsConfigDict( model_config = SettingsConfigDict(
@ -55,8 +67,12 @@ class RootSettings(BaseSettings):
DEBUG: bool = False DEBUG: bool = False
"""The Flask :external:py:data:`DEBUG` configuration setting. """The Flask :external:py:data:`DEBUG` configuration setting.
This enables debug options. This is useful for development but This enables debug options.
should be absolutely avoided in production environments.
.. danger::
This is useful for development but should be absolutely
avoided in production environments.
""" """

View file

@ -1,4 +1,4 @@
Translations are done with [Weblate](https://hosted.weblate.org/projects/canaille/canaille/). Translations are done with `Weblate <https://hosted.weblate.org/projects/canaille/canaille>`_.
The following commands are there as documentation, only the message extraction is needed for contributors. The following commands are there as documentation, only the message extraction is needed for contributors.
All the other steps are automatically done with Weblate. All the other steps are automatically done with Weblate.

BIN
doc/_static/group-edition.webp vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
doc/_static/password-recovery.webp vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

BIN
doc/_static/user-invite.webp vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -1,54 +0,0 @@
Roadmap and changelog
#####################
Roadmap
*******
Bêta version
============
To go out of the current Alpha version we want to achieve the following tasks:
- :issue:`Configuration validation using pydantic <138>`
Stable version
==============
Before we push Canaille in stable version we want to achieve the following tasks:
Security
--------
- :issue:`Password hashing configuration <175>`
- :issue:`Authentication logging policy <177>`
- :issue:`Intruder lockout <173>`
- :issue:`Password expiry policy <176>`
- :issue:`Password compromission check <179>`
- :issue:`Multi-factor authentication: Email <47>`
- :issue:`Multi-factor authentication: SMS <47>`
- :issue:`Multi-factor authentication: OTP <47>`
Packaging
---------
- :issue:`Nix package <190>`
- :issue:`Docker / OCI package <59>`
And beyond
==========
- :issue:`OpenID Connect certification <182>`
- :issue:`SCIM support <116>`
Release notes
*************
All notable changes to this project will be documented in there.
The format is based on `Keep a Changelog <https://keepachangelog.com/en/1.0.0/>`_,
and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0.html>`_.
Alpha versions
==============
.. include:: ../CHANGES.rst

View file

@ -34,9 +34,11 @@ extensions = [
"sphinx.ext.todo", "sphinx.ext.todo",
"sphinx.ext.viewcode", "sphinx.ext.viewcode",
"sphinx_click", "sphinx_click",
"sphinx_design",
"sphinx_issues", "sphinx_issues",
"sphinx_sitemap", "sphinx_sitemap",
"sphinxcontrib.autodoc_pydantic", "sphinxcontrib.autodoc_pydantic",
"sphinxcontrib.images",
] ]
templates_path = ["_templates"] templates_path = ["_templates"]
@ -54,7 +56,8 @@ version = metadata.version("canaille")
language = "en" language = "en"
exclude_patterns = [] exclude_patterns = []
pygments_style = "sphinx" pygments_style = "sphinx"
todo_include_todos = False todo_include_todos = True
toctree_collapse = False
intersphinx_mapping = { intersphinx_mapping = {
"python": ("https://docs.python.org/3", None), "python": ("https://docs.python.org/3", None),
@ -63,6 +66,7 @@ intersphinx_mapping = {
"flask-babel": ("https://python-babel.github.io/flask-babel", None), "flask-babel": ("https://python-babel.github.io/flask-babel", None),
"flask-wtf": ("https://flask-wtf.readthedocs.io", None), "flask-wtf": ("https://flask-wtf.readthedocs.io", None),
"pydantic": ("https://docs.pydantic.dev/latest", None), "pydantic": ("https://docs.pydantic.dev/latest", None),
"pytest-iam": ("https://pytest-iam.readthedocs.io/en/latest/", None),
} }
issues_uri = "https://gitlab.com/yaal/canaille/-/issues/{issue}" issues_uri = "https://gitlab.com/yaal/canaille/-/issues/{issue}"
@ -75,20 +79,45 @@ html_theme = "shibuya"
html_static_path = ["_static"] html_static_path = ["_static"]
html_baseurl = "https://canaille.readthedocs.io/" html_baseurl = "https://canaille.readthedocs.io/"
html_theme_options = { html_theme_options = {
"globaltoc_expand_depth": 3,
"accent_color": "yellow", "accent_color": "yellow",
"light_logo": "_static/canaille-label-black.webp", "light_logo": "_static/canaille-label-black.webp",
"dark_logo": "_static/canaille-label-white.webp", "dark_logo": "_static/canaille-label-white.webp",
"gitlab_url": "https://gitlab.com/yaal/canaille", "gitlab_url": "https://gitlab.com/yaal/canaille",
"mastodon_url": "https://toot.aquilenet.fr/@yaal", "mastodon_url": "https://toot.aquilenet.fr/@yaal",
"discussion_url": "https://matrix.to/#/#canaille-discuss:yaal.coop",
"nav_links": [ "nav_links": [
{ {
"title": "Homepage", "title": "Demo",
"url": "https://canaille.yaal.coop", "children": [
"summary": "The homepage for the Canaille project", {
"title": "Canaille demo server",
"url": "https://demo.canaille.yaal.coop",
},
{
"title": "OIDC Client 1",
"url": "https://demo.client1.yaal.coop",
},
{
"title": "OIDC Client 2",
"url": "https://demo.client2.yaal.coop",
},
],
},
{"title": "PyPI", "url": "https://pypi.org/project/Canaille"},
{
"title": "Weblate",
"url": "https://hosted.weblate.org/projects/canaille/canaille",
}, },
{"title": "PyPI", "url": "https://pypi.org/project/Canaille/"},
], ],
} }
html_context = {
"source_type": "gitlab",
"source_user": "yaal",
"source_repo": "canaille",
"source_version": "main",
"source_docs_path": "/doc/",
}
# -- Options for HTMLHelp output ------------------------------------------ # -- Options for HTMLHelp output ------------------------------------------
@ -125,7 +154,7 @@ texinfo_documents = [
autosectionlabel_prefix_document = True autosectionlabel_prefix_document = True
autosectionlabel_maxdepth = 2 autosectionlabel_maxdepth = 2
# -- Options for autodo_pydantic_settings ------------------------------------------- # -- Options for autodoc_pydantic_settings -------------------------------------------
autodoc_pydantic_settings_show_json = False autodoc_pydantic_settings_show_json = False
autodoc_pydantic_settings_show_config_summary = False autodoc_pydantic_settings_show_config_summary = False
@ -133,4 +162,13 @@ autodoc_pydantic_settings_show_config_summary = False
autodoc_pydantic_settings_show_validator_summary = False autodoc_pydantic_settings_show_validator_summary = False
autodoc_pydantic_settings_show_validator_members = False autodoc_pydantic_settings_show_validator_members = False
autodoc_pydantic_settings_show_field_summary = False autodoc_pydantic_settings_show_field_summary = False
autodoc_pydantic_settings_signature_prefix = ""
autodoc_pydantic_field_signature_prefix = ""
autodoc_pydantic_field_list_validators = False autodoc_pydantic_field_list_validators = False
# -- Options for images
images_config = {
"override_image_directive": True,
"download": False,
}

View file

@ -1 +0,0 @@
.. include:: ../CONTRIBUTING.rst

View file

@ -0,0 +1,9 @@
Release notes
#############
All notable changes to this project will be documented in there.
The format is based on `Keep a Changelog <https://keepachangelog.com/en/1.0.0/>`_,
and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0.html>`_.
.. include:: ../../CHANGES.rst

View file

@ -0,0 +1 @@
.. include:: ../../CONTRIBUTING.rst

View file

@ -0,0 +1,8 @@
Development
===========
.. toctree::
specifications
contributing
changelog

314
doc/features.rst Normal file
View file

@ -0,0 +1,314 @@
.. This page should list the functional perimiter of Canaille,
without mentioning too much technical details. We should avoid giving
explicit configuration parameters for instance. However, we should put as
much links to other sections of the documentation as possible.
TODO: replace 'users with user management permission' by 'administrators'?
Features
########
Here are the different features that Canaille provides.
You can enable any of those features with the :doc:`configuration <references/configuration>` to fit any :doc:`use cases <usecases>` you may meet.
Check our :ref:`roadmap <features:Roadmap>` to see what is coming next.
Users can interact with Canaille through its :ref:`web interface <features:Web interface>` and administrators can also use its :ref:`command line interface <features:Command line interface>`.
Canaille can handle data stored in different :ref:`database backends <features:Backends>`.
Web interface
*************
Canaille web interface can be used either in :doc:`production environments <tutorial/deployment>` or locally for development purposes.
.. _feature_profile_management:
Profile management
==================
.. image:: _static/profile.webp
:width: 200px
:alt: Profile
:align: right
Canaille provides an interface to manage user profiles.
The exact list of displayed fields, and wether they are :attr:`writable <canaille.core.configuration.ACLSettings.WRITE>` or :attr:`read-only <canaille.core.configuration.ACLSettings.READ>` depends on the user :class:`Access Control List settings (ACL) <canaille.core.configuration.ACLSettings>`.
Depending on their ACL :class:`permissions <canaille.core.configuration.Permission>`, users can either be allowed to edit their own profile, edit any user profile, or do nothing at all.
.. _feature_email_confirmation:
Email confirmation
==================
If the :attr:`email confirmation feature <canaille.core.configuration.CoreSettings.EMAIL_CONFIRMATION>` is enabled, any modification or addition of a profile email will send a confirmation mail to the new address. The mail will contain a link that users will need to click on to confirm their email address.
Users with :attr:`user management permission <canaille.core.configuration.Permission.MANAGE_USERS>` can set user emails without confirmation though.
.. _feature_group_management:
Group management
================
.. image:: _static/group-edition.webp
:width: 200px
:alt: Group edition
:align: right
In a similar fashion than :ref:`profile management <feature_profile_management>` Canaille provides an interface to manage user groups.
The group management is quite simple at the moment and consists in a group name and description, and the list of its members.
Group membership can be use as :attr:`ACL Filter <canaille.core.configuration.ACLSettings.FILTER>` to define user permissions.
.. todo::
At the moment adding an user to a group can only be achieved by the user settings page, but we are :issue:`working to improve this <192>`.
Group management can be enable with a :attr:`dedicated user permission <canaille.core.configuration.Permission.MANAGE_GROUPS>`.
.. important::
Due to limitations in the :ref:`LDAP backend <tutorial/databases:LDAP>`, groups must have at least one member.
Thus it is not possible to remove the last user of a group without removing the group.
.. _feature_user_authentication:
User authentication
===================
Unless their account is :ref:`locked <feature_account_locking>`, users can authenticate with a login and a password.
.. important::
For security reasons, it won't be told to users if they try to sign in with an unexisting logging, unless explicitly :attr:`set in the configuration <canaille.core.configuration.CoreSettings.HIDE_INVALID_LOGINS>`.
.. todo:: :ref:`LDAP backend <tutorial/databases:LDAP>` users can define which :class:`user field <canaille.core.models.User>` should be used as the login (such as :attr:`~canaille.core.models.User.user_name` or :attr:`~canaille.core.models.User.emails`) using a :attr:`configuration parameter <canaille.backends.ldap.configuration.LDAPSettings.USER_FILTER>`, but other backends can only login using :attr:`~canaille.core.models.User.user_name`. We are :issue:`working to improve this <196>`.
.. _feature_user_registration:
User registration
=================
Users can create accounts on Canaille if the feature :attr:`registration feature <canaille.core.configuration.CoreSettings.ENABLE_REGISTRATION>` is enabled. They will be able to fill a registration form with the fields detailed in the default :class:`ACL settings <canaille.core.configuration.ACLSettings>`.
If :attr:`email confirmation <canaille.core.configuration.CoreSettings.EMAIL_CONFIRMATION>` is also enabled, users will be sent a confirmation link to their email address, on which they will need to click in order to finalize their registration.
.. _feature_user_invitation:
User invitation
===============
.. image:: _static/user-invite.webp
:width: 200px
:alt: User invitation
:align: right
If a :class:`mail server <canaille.core.configuration.SMTPSettings>` is configured, users with :attr:`user management permission <canaille.core.configuration.Permission.MANAGE_USERS>` can create an invitation link for one user.
The link goes to a registration form, even if regular :ref:`user registration <feature_user_registration>` is disabled.
It can be automatically sent by email to the new user.
.. _feature_account_locking:
Account locking
===============
If Canaille is plugged to a :ref:`backend <features:Backends>` that supports it, user accounts can be locked by users with :attr:`user management permission <canaille.core.configuration.Permission.MANAGE_USERS>`.
The lock date can be set instantly or at a given date in the future.
At the moment a user account is locked:
- their open sessions will be closed;
- they won't be able to sign in again;
- no new OIDC token will be issued;
User accounts must be manually unlocked by an administrator for the users to regain access to those actions.
.. _feature_account_deletion:
Account deletion
================
Users with the :attr:`account deletion permission <canaille.core.configuration.Permission.DELETE_ACCOUNT>` are allowed to delete their own account.
Users that also have the :attr:`user management permission <canaille.core.configuration.Permission.MANAGE_USERS>` are also allowed to delete other users accounts.
.. _feature_password_recovery:
Password recovery
=================
.. image:: _static/password-recovery.webp
:width: 200px
:alt: Group edition
:align: right
If a :class:`mail server <canaille.core.configuration.SMTPSettings>` is configured and the :attr:`password recovery feature <canaille.core.configuration.CoreSettings.ENABLE_PASSWORD_RECOVERY>` is enabled, then users can ask for a password reset email if they cannot remember their password.
The email will be sent to the email addresses filled in their profile, and will contain a link that will allow them to choose a new password. .
.. todo::
Check that password recovery is disabled on locked accounts.
.. _feature_password_reset:
Password reset
==============
If a :class:`mail server <canaille.core.configuration.SMTPSettings>` is configured, :attr:`user management permission <canaille.core.configuration.Permission.MANAGE_USERS>` can send password reset mails to users.
The mails contains a link that allow users to choose a new password without having to retrieve the old one.
.. _feature_password_initialization:
Password initialization
=======================
User :attr:`passwords <canaille.core.models.User.password>` are optional.
If a :class:`mail server <canaille.core.configuration.SMTPSettings>` is configured, when users with no password attempt to sign in, they are invited to click a button that will send them a password initialization mail.
The mail contains a link that leads to a form that allows users to choose a password.
.. _feature_i18n:
Internationalization
====================
.. image:: https://hosted.weblate.org/widgets/canaille/-/canaille/multi-blue.svg
:alt: Translation state
:align: right
:width: 600px
Canaile will display in your :attr:`preferred language <canaille.core.models.User.preferred_language>` if available, or your browser language if available (and if it is not you can :ref:`help us with the translation <development/contributing:Translations>`).
If you prefer, you can also :attr:`force a language <canaille.core.configuration.CoreSettings.FAVICON>` for every users.
.. _feature_ui:
Lightweight
===========
The web interface is lightweight, so everything should load quickly.
There is a few Javascript here and there to smooth the experience, but no Javascript at all is needed to use Canaille.
Customizable
============
The default theme should be good enough for most usages.
It has a dark theme, display well on mobile, and let you choose a :attr:`logo <canaille.core.configuration.CoreSettings.LOGO>` and a :attr:`favicon <canaille.core.configuration.CoreSettings.FAVICON>`.
If you need more you can also use a :attr:`custom theme <canaille.core.configuration.CoreSettings.THEME>`.
.. _feature_oidc:
OpenID Connect
**************
Canaille implements a :ref:`subset<development/specifications:State of the specs in Canaille>` of the OAuth2/OpenID Connect specifications .
This allows to provide :abbr:`SSO (Single Sign-On)` and :abbr:`SLO (Single Log-On)` to applications plugged to Canaille.
Consent management
==================
.. image:: _static/consent.webp
:width: 200px
:alt: Profile
:align: right
Users can give their consent to application requesting access to their personal information,
and then revoke those consent at their will.
Application management
======================
Users with the right :attr:`permission <canaille.core.configuration.Permission.MANAGE_OIDC>` can manager OIDC clients through the web interface.
In some cases, it might be useful to avoid the consent page for some trusted applications, so clients can be pre-consented.
Discovery
=========
Canaille implements the :doc:`Discovery specifications <development/specifications>` so most of the applications plugged to Canaille can auto-configure themselves.
Dynamic Client Registration
===========================
Canaille implements the :doc:`Dynamic Client Registration specifications <development/specifications>`, so when the :attr:`feature is enabled <canaille.oidc.configuration.OIDCSettings.DYNAMIC_CLIENT_REGISTRATION_OPEN>`, clients can register themselves on Canaille without an administrator intervention.
.. _feature_cli:
Command Line Interface
**********************
Canaille comes with a :abbr:`CLI (Command Line Interface)` to help administrators in hosting and management.
There are tools to :ref:`check your configuration <cli_check>` or to :ref:`install missing parts <cli_install>`.
You can use the CLI to :ref:`create <cli_create>`, :ref:`read <cli_get>`, :ref:`update <cli_set>` and :ref:`delete <cli_delete>` models such as :class:`users <canaille.core.models.User>`, :class:`groups <canaille.core.models.Group>` or :class:`OIDC clients <canaille.oidc.basemodels.Client>`.
There are also tools to :ref:`fill your database <cli_populate>` with random objects, for tests purpose for instance.
.. _feature_backends:
Backends
********
Canaille can handle data from the most :ref:`common SQL databases <tutorial/databases:SQL>` such as PostgreSQL, MariaDB or SQLite, as well as :ref:`OpenLDAP <tutorial/databases:LDAP>`.
It also comes with a no-dependency :ref:`in-memory database <tutorial/databases:Memory>` that can be used in unit tests suites.
Miscellaneous
*************
.. _feature_logging:
Logging
=======
Canaille writes :attr:`logs <canaille.core.configuration.CoreSettings.LOGGING>` for every important event happening, to help administrators understand what is going on and debug funky situations.
.. _feature_development:
A tool for your development and tests
=====================================
Thanks to its lightweight :ref:`in-memory database <tutorial/databases:Memory>` and its curated :ref:`dependency list <tutorial/install:Get the code>`, Canaille can be used in the unit test suite of your application, so you can check how it behaves against a real world OpenID Connect server. If you work with python you might want to check :doc:`pytest-iam:index`.
It can also being launched in your development environment, if you find that launching a Keycloak in a Docker container is too heavy for your little web application.
It also fits well in continuous integration scenarios. Thanks to its :ref:`CLI <feature_cli>`, you can prepare data in Canaille, let your application interract with it, and then check the side effects.
Roadmap
*******
Bêta version
============
To go out of the current Alpha version we want to achieve the following tasks:
- :issue:`Configuration validation using pydantic <138>`
Stable version
==============
Before we push Canaille in stable version we want to achieve the following tasks:
Security
--------
- :issue:`Password hashing configuration <175>`
- :issue:`Authentication logging policy <177>`
- :issue:`Intruder lockout <173>`
- :issue:`Password expiry policy <176>`
- :issue:`Password compromission check <179>`
- :issue:`Multi-factor authentication: Email <47>`
- :issue:`Multi-factor authentication: SMS <47>`
- :issue:`Multi-factor authentication: OTP <47>`
Packaging
---------
- :issue:`Nix package <190>`
- :issue:`Docker / OCI package <59>`
And beyond
==========
- :issue:`OpenID Connect certification <182>`
- :issue:`SCIM support <116>`

View file

@ -1,3 +1,5 @@
:layout: landing
.. figure:: _static/canaille-full-black.webp .. figure:: _static/canaille-full-black.webp
:width: 400 :width: 400
:figclass: light-only :figclass: light-only
@ -8,53 +10,71 @@
:figclass: dark-only :figclass: dark-only
:align: center :align: center
.. rst-class:: lead
Lightweight Identity and Autorization Management
----
**Canaille** is a French word meaning *rascal*. It is roughly pronounced **Can I?**, **Canaille** is a French word meaning *rascal*. It is roughly pronounced **Can I?**,
as in *Can I access your data?* Canaille is a lightweight identity and authorization management software. as in *Can I access your data?* Canaille is a lightweight identity and authorization management software.
It aims to be very light, simple to install and simple to maintain. Its main features are : It aims to be very light, simple to install and simple to maintain. Its main features are :
- User profile and groups management; .. grid:: 3
- Authentication, registration, email confirmation, "I forgot my password" emails; :gutter: 2
- OpenID Connect identity provider; :padding: 0
- postgresql, mariadb and OpenLDAP first-class citizenship;
- Customizable, themable;
- The code is easy to read and easy to edit!
Screenshots .. grid-item-card:: Profile management
=========== :link-type: ref
:link: feature_profile_management
.. image:: _static/login.webp User profile and groups management,
:width: 225 Basic permissions
:alt: Login
.. image:: _static/profile.webp .. grid-item-card:: User authentication
:width: 225 :link-type: ref
:alt: Profile :link: feature_user_authentication
.. image:: _static/consent.webp Authentication, registration, email confirmation, "I forgot my password" emails
:width: 225
:alt: Consent
Table of contents .. grid-item-card:: :abbr:`SSO (Single Sign-On)`
================= :link-type: ref
:link: feature_oidc
OpenID Connect identity provider
.. grid-item-card:: Multi-database support
:link-type: ref
:link: feature_backends
PostgreSQL, Mariadb and OpenLDAP first-class citizenship
.. grid-item-card:: Customization
:link-type: ref
:link: feature_ui
Put Canaille at yours colors by choosing a logo or use a custom theme!
.. grid-item-card:: Developers friendliness
:link-type: ref
:link: feature_development
Canaille can easily fit in your unit tests suite or in your Continuous Integration.
.. container:: buttons
:doc:`Full feature list <features>`
.. rst-class:: lead
Documentation
----
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
install features
deployment tutorial/index
databases references/index
configuration development/index
commands
troubleshooting
reference
specifications
contributing
changelog
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View file

@ -3,34 +3,50 @@ Command Line Interface
Canaille provide several commands to help administrator manage their data. Canaille provide several commands to help administrator manage their data.
.. _cli_check:
.. click:: canaille.app.commands:check .. click:: canaille.app.commands:check
:prog: canaille check :prog: canaille check
:nested: full :nested: full
.. _cli_clean:
.. click:: canaille.oidc.commands:clean .. click:: canaille.oidc.commands:clean
:prog: canaille clean :prog: canaille clean
:nested: full :nested: full
.. _cli_install:
.. click:: canaille.app.commands:install .. click:: canaille.app.commands:install
:prog: canaille install :prog: canaille install
:nested: full :nested: full
.. _cli_populate:
.. click:: canaille.core.commands:populate .. click:: canaille.core.commands:populate
:prog: canaille populate :prog: canaille populate
:nested: full :nested: full
.. _cli_get:
.. click:: doc.commands:get .. click:: doc.commands:get
:prog: canaille get :prog: canaille get
:nested: full :nested: full
.. _cli_set:
.. click:: doc.commands:set .. click:: doc.commands:set
:prog: canaille set :prog: canaille set
:nested: full :nested: full
.. _cli_create:
.. click:: doc.commands:create .. click:: doc.commands:create
:prog: canaille create :prog: canaille create
:nested: full :nested: full
.. _cli_delete:
.. click:: doc.commands:delete .. click:: doc.commands:delete
:prog: canaille delete :prog: canaille delete
:nested: full :nested: full

View file

@ -1,12 +1,15 @@
Configuration Configuration
############# #############
Canaille can be configured either by a environment variables, or by a `toml` configuration file which path is passed in the ``CONFIG`` environment variable. Canaille can be configured either by a environment variables, environment file, or by a configuration file.
Toml file Configuration file
========= ==================
:: The configuration can be written in `toml` configuration file which path is passed in the :envvar:`CONFIG` environment variable.
.. code-block:: toml
:caption: config.toml
SECRET_KEY = "very-secret" SECRET_KEY = "very-secret"
@ -17,7 +20,7 @@ Toml file
DATABASE_URI = "postgresql://user:password@localhost/database" DATABASE_URI = "postgresql://user:password@localhost/database"
... ...
You can have a look at the :ref:`configuration:Example file` for inspiration. You can have a look at the :ref:`example file <references/configuration:Example file>` for inspiration.
Environment variables Environment variables
===================== =====================
@ -25,17 +28,20 @@ Environment variables
In addition, parameters that have not been set in the configuration file can be read from environment variables. In addition, parameters that have not been set in the configuration file can be read from environment variables.
The way environment variables are parsed can be read from the `pydantic-settings documentation <https://docs.pydantic.dev/latest/concepts/pydantic_settings/#parsing-environment-variable-values>`_. The way environment variables are parsed can be read from the `pydantic-settings documentation <https://docs.pydantic.dev/latest/concepts/pydantic_settings/#parsing-environment-variable-values>`_.
Settings will also be read from a local ``.env`` file if present. Environment file
================
Any environment variable can also be written in a ``.env``, and will be read if present.
.. TODO: Uncomment this when pydantic-settings implements nested secrets directories .. TODO: Uncomment this when pydantic-settings implements nested secrets directories
https://github.com/pydantic/pydantic-settings/issues/154 https://github.com/pydantic/pydantic-settings/issues/154
Secret parameters Secret parameters
================= =================
A ``SECRETS_DIR`` environment variable can be passed as an environment variable, being a path to a directory in which are stored files named after the configuration settings. A :envvar:`SECRETS_DIR` environment variable can be passed as an environment variable, being a path to a directory in which are stored files named after the configuration settings.
For instance, you can set ``SECRETS_DIR=/run/secrets`` and put your secret key in the file ``/run/secrets/SECRET_KEY``. For instance, you can set ``SECRETS_DIR=/run/secrets`` and put your secret key in the file ``/run/secrets/SECRET_KEY``.
Parameters Parameters
========== ==========
@ -61,5 +67,6 @@ Example file
Here is a configuration file example: Here is a configuration file example:
.. literalinclude :: ../canaille/config.sample.toml .. literalinclude :: ../../canaille/config.sample.toml
:language: toml :language: toml
:caption: config.toml

8
doc/references/index.rst Normal file
View file

@ -0,0 +1,8 @@
References
==========
.. toctree::
configuration
commands
models

View file

@ -1,5 +1,5 @@
Reference Data models
######### ###########
This reference details the data models used by Canaille. This reference details the data models used by Canaille.
This is mostly useful for developers. This is mostly useful for developers.

View file

@ -4,9 +4,6 @@ Databases
Canaille can read and save data in different databases. Canaille can read and save data in different databases.
This page presents the different database backends and their specificities: This page presents the different database backends and their specificities:
.. contents::
:local:
Memory Memory
====== ======
@ -21,7 +18,10 @@ SQL
Canaille can use any database supported by `SQLAlchemy <https://www.sqlalchemy.org/>`_, such as Canaille can use any database supported by `SQLAlchemy <https://www.sqlalchemy.org/>`_, such as
sqlite, postgresql or mariadb. sqlite, postgresql or mariadb.
It is used when the ``CANAILLE_SQL`` configuration parameter is defined. For instance:: It is used when the ``CANAILLE_SQL`` configuration parameter is defined. For instance:
.. code-block:: toml
:caption: config.toml
[CANAILLE_SQL] [CANAILLE_SQL]
SQL_DATABASE_URI = "postgresql://user:password@localhost/database" SQL_DATABASE_URI = "postgresql://user:password@localhost/database"
@ -32,7 +32,10 @@ LDAP
==== ====
Canaille can use OpenLDAP as its main database. Canaille can use OpenLDAP as its main database.
It is used when the ``CANAILLE_LDAP`` configuration parameter is defined. For instance:: It is used when the ``CANAILLE_LDAP`` configuration parameter is defined. For instance:
.. code-block:: toml
:caption: config.toml
[CANAILLE_LDAP] [CANAILLE_LDAP]
URI = "ldap://ldap" URI = "ldap://ldap"
@ -67,11 +70,11 @@ overlays are needed for the Canaille group membership to work correctly.
Here is a configuration example compatible with canaille: Here is a configuration example compatible with canaille:
.. literalinclude :: ../demo/ldif/memberof-config.ldif .. literalinclude :: ../..//demo/ldif/memberof-config.ldif
:language: ldif :language: ldif
:caption: memberof-config.ldif :caption: memberof-config.ldif
.. literalinclude :: ../demo/ldif/refint-config.ldif .. literalinclude :: ../..//demo/ldif/refint-config.ldif
:language: ldif :language: ldif
:caption: refint-config.ldif :caption: refint-config.ldif
@ -90,11 +93,11 @@ If the `ppolicy <https://www.ietf.org/archive/id/draft-behera-ldap-password-poli
Here is a configuration example compatible with canaille: Here is a configuration example compatible with canaille:
.. literalinclude :: ../demo/ldif/ppolicy-config.ldif .. literalinclude :: ../../demo/ldif/ppolicy-config.ldif
:language: ldif :language: ldif
:caption: ppolicy-config.ldif :caption: ppolicy-config.ldif
.. literalinclude :: ../demo/ldif/ppolicy.ldif .. literalinclude :: ../../demo/ldif/ppolicy.ldif
:language: ldif :language: ldif
:caption: ppolicy.ldif :caption: ppolicy.ldif

View file

@ -10,7 +10,9 @@ Here are some WSGI server configuration examples you can pick. Do not forget to
gunicorn gunicorn
-------- --------
TBD .. todo::
Write a gunicorn configuration sample file.
uwsgi uwsgi
----- -----
@ -111,7 +113,9 @@ Nginx
Apache Apache
------ ------
TBD .. todo::
Write a Apache configuration file.
Recurrent jobs Recurrent jobs
============== ==============
@ -131,10 +135,10 @@ You may want to configure a `WebFinger`_ endpoint on your main website to allow
The difficulty here is that the WebFinger endpoint must be hosted at the top-level domain (i.e. ``mydomain.tld``) while the authentication server might be hosted on a sublevel (i.e. ``auth.mydomain.tld``). Canaille provides a WebFinger endpoint, but if it is not hosted at the top-level domain, a web redirection is required on the ``/.well-known/webfinger`` path. The difficulty here is that the WebFinger endpoint must be hosted at the top-level domain (i.e. ``mydomain.tld``) while the authentication server might be hosted on a sublevel (i.e. ``auth.mydomain.tld``). Canaille provides a WebFinger endpoint, but if it is not hosted at the top-level domain, a web redirection is required on the ``/.well-known/webfinger`` path.
Nginx Here are configuration examples for Nginx or Apache:
-----
.. code-block:: nginx .. code-block:: nginx
:caption: Nginx webfinger configuration for a top level domain
server { server {
listen 443; listen 443;
@ -142,10 +146,8 @@ Nginx
rewrite ^/.well-known/webfinger https://auth.mydomain.tld/.well-known/webfinger permanent; rewrite ^/.well-known/webfinger https://auth.mydomain.tld/.well-known/webfinger permanent;
} }
Apache
------
.. code-block:: apache .. code-block:: apache
:caption: Apache webfinger configuration for a top level domain
<VirtualHost *:443> <VirtualHost *:443>
ServerName mydomain.tld ServerName mydomain.tld
@ -156,10 +158,11 @@ Apache
Create the first user Create the first user
===================== =====================
Once canaille is installed, you have several ways to populate the database. The obvious one is by adding Once canaille is installed, soon enough you will need to add users.
directly users and group into your LDAP directory. You might also want to temporarily enable then the To create your first user you can use the :ref:`canaille create <cli_create>` CLI.
:attr:`~canaille.core.configuration.CoreSettings.ENABLE_REGISTRATION` configuration parameter to allow you to create your first users. Then, if you
have configured your ACLs properly then you will be able to manage users and groups through the Canaille .. code-block:: bash
interface.
canaille create user --user-name admin --password admin --emails admin@mydomain.example --first-name George --last-name Abitbol
.. _WebFinger: https://www.rfc-editor.org/rfc/rfc7033.html .. _WebFinger: https://www.rfc-editor.org/rfc/rfc7033.html

10
doc/tutorial/index.rst Normal file
View file

@ -0,0 +1,10 @@
Tutorial
########
.. toctree::
:maxdepth: 2
install
deployment
databases
troubleshooting

View file

@ -7,9 +7,6 @@ Installation
The installation of canaille consist in several steps, some of which you can do manually or with command line tool: The installation of canaille consist in several steps, some of which you can do manually or with command line tool:
.. contents::
:local:
Get the code Get the code
============ ============
@ -45,7 +42,7 @@ Choose a path where to store your configuration file. You can pass any configura
sudo mkdir --parents "$CANAILLE_CONF_DIR" sudo mkdir --parents "$CANAILLE_CONF_DIR"
sudo cp $CANAILLE_INSTALL_DIR/env/lib/python*/site-packages/canaille/config.sample.toml "$CANAILLE_CONF_DIR/config.toml" sudo cp $CANAILLE_INSTALL_DIR/env/lib/python*/site-packages/canaille/config.sample.toml "$CANAILLE_CONF_DIR/config.toml"
You should then edit your configuration file to adapt the values to your needs. Look at the configuration details in the :doc:`configuration` page. You should then edit your configuration file to adapt the values to your needs. Look at the configuration details in the :doc:`configuration <../references/configuration>` page.
Install and check Install and check
================= =================

40
poetry.lock generated
View file

@ -1913,6 +1913,29 @@ click = ">=8.0"
docutils = "*" docutils = "*"
sphinx = ">=4.0" sphinx = ">=4.0"
[[package]]
name = "sphinx-design"
version = "0.5.0"
description = "A sphinx extension for designing beautiful, view size responsive web components."
optional = false
python-versions = ">=3.8"
files = [
{file = "sphinx_design-0.5.0-py3-none-any.whl", hash = "sha256:1af1267b4cea2eedd6724614f19dcc88fe2e15aff65d06b2f6252cee9c4f4c1e"},
{file = "sphinx_design-0.5.0.tar.gz", hash = "sha256:e8e513acea6f92d15c6de3b34e954458f245b8e761b45b63950f65373352ab00"},
]
[package.dependencies]
sphinx = ">=5,<8"
[package.extras]
code-style = ["pre-commit (>=3,<4)"]
rtd = ["myst-parser (>=1,<3)"]
testing = ["myst-parser (>=1,<3)", "pytest (>=7.1,<8.0)", "pytest-cov", "pytest-regressions"]
theme-furo = ["furo (>=2023.7.0,<2023.8.0)"]
theme-pydata = ["pydata-sphinx-theme (>=0.13.0,<0.14.0)"]
theme-rtd = ["sphinx-rtd-theme (>=1.0,<2.0)"]
theme-sbt = ["sphinx-book-theme (>=1.0,<2.0)"]
[[package]] [[package]]
name = "sphinx-issues" name = "sphinx-issues"
version = "4.1.0" version = "4.1.0"
@ -1996,6 +2019,21 @@ lint = ["docutils-stubs", "flake8", "mypy"]
standalone = ["Sphinx (>=5)"] standalone = ["Sphinx (>=5)"]
test = ["html5lib", "pytest"] test = ["html5lib", "pytest"]
[[package]]
name = "sphinxcontrib-images"
version = "0.9.4"
description = "Sphinx extension for thumbnails"
optional = false
python-versions = "*"
files = [
{file = "sphinxcontrib-images-0.9.4.tar.gz", hash = "sha256:f6c237d0430793e65d91dbddb13b1fb26a2cf838040a9deeb52112969fbc4a4b"},
{file = "sphinxcontrib_images-0.9.4-py2.py3-none-any.whl", hash = "sha256:8863e8e8533a116f45cb92523938ab25879cc31dc594f5de4c3dbd9ab3d440b0"},
]
[package.dependencies]
requests = ">2.2,<3"
sphinx = {version = ">=2.0", markers = "python_version >= \"3.0\""}
[[package]] [[package]]
name = "sphinxcontrib-jsmath" name = "sphinxcontrib-jsmath"
version = "1.0.1" version = "1.0.1"
@ -2463,4 +2501,4 @@ sql = ["passlib", "sqlalchemy", "sqlalchemy-json", "sqlalchemy-utils"]
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.9" python-versions = "^3.9"
content-hash = "c0cd43822b196a493e086b80389c22e1be6a488ae2ce8bcc21354895b2c10e67" content-hash = "ba6d179f761bb617fb6f4f435b71a8a98d9267bb656aa0f24520a931b0f3effe"

View file

@ -73,9 +73,11 @@ optional = true
autodoc-pydantic = "^2.0.1" autodoc-pydantic = "^2.0.1"
shibuya = "^2024.3.1" shibuya = "^2024.3.1"
sphinx = "^7.0.0" sphinx = "^7.0.0"
sphinx-design = "^0.5.0"
sphinx-sitemap = "^2.5.1" sphinx-sitemap = "^2.5.1"
sphinx-issues = "^4.0.0" sphinx-issues = "^4.0.0"
sphinx-click = "^6.0.0" sphinx-click = "^6.0.0"
sphinxcontrib-images = "^0.9.4"
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]
coverage = {version = "*", extras=["toml"]} coverage = {version = "*", extras=["toml"]}