diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index 6da50793..a53ce1c9 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -148,7 +148,7 @@ The dynamical parts of the interface use `htmx `_.
Translations
------------
-.. include:: ../canaille/translations/README.rst
+.. include:: ../../canaille/translations/README.rst
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.
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
-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``
6. Commit with ``git commit``
7. Publish with ``poetry publish --build``
diff --git a/TODO.md b/TODO.md
new file mode 100644
index 00000000..484f6ade
--- /dev/null
+++ b/TODO.md
@@ -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
diff --git a/canaille/app/configuration.py b/canaille/app/configuration.py
index bddee471..75e2dc4e 100644
--- a/canaille/app/configuration.py
+++ b/canaille/app/configuration.py
@@ -25,6 +25,18 @@ class RootSettings(BaseSettings):
- :doc:`Flask-WTF `
- :doc:`Flask-Babel `
- :doc:`Authlib `
+
+ .. 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(
@@ -55,8 +67,12 @@ class RootSettings(BaseSettings):
DEBUG: bool = False
"""The Flask :external:py:data:`DEBUG` configuration setting.
- This enables debug options. This is useful for development but
- should be absolutely avoided in production environments.
+ This enables debug options.
+
+ .. danger::
+
+ This is useful for development but should be absolutely
+ avoided in production environments.
"""
diff --git a/canaille/translations/README.rst b/canaille/translations/README.rst
index a158ef38..9c8101e7 100644
--- a/canaille/translations/README.rst
+++ b/canaille/translations/README.rst
@@ -1,4 +1,4 @@
-Translations are done with [Weblate](https://hosted.weblate.org/projects/canaille/canaille/).
+Translations are done with `Weblate `_.
The following commands are there as documentation, only the message extraction is needed for contributors.
All the other steps are automatically done with Weblate.
diff --git a/doc/_static/group-edition.webp b/doc/_static/group-edition.webp
new file mode 100644
index 00000000..49837859
Binary files /dev/null and b/doc/_static/group-edition.webp differ
diff --git a/doc/_static/password-recovery.webp b/doc/_static/password-recovery.webp
new file mode 100644
index 00000000..015b968a
Binary files /dev/null and b/doc/_static/password-recovery.webp differ
diff --git a/doc/_static/user-invite.webp b/doc/_static/user-invite.webp
new file mode 100644
index 00000000..9487ea58
Binary files /dev/null and b/doc/_static/user-invite.webp differ
diff --git a/doc/changelog.rst b/doc/changelog.rst
deleted file mode 100644
index 2569d171..00000000
--- a/doc/changelog.rst
+++ /dev/null
@@ -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 `_,
-and this project adheres to `Semantic Versioning `_.
-
-Alpha versions
-==============
-
-.. include:: ../CHANGES.rst
diff --git a/doc/conf.py b/doc/conf.py
index e6c2b73c..05f20da0 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -34,9 +34,11 @@ extensions = [
"sphinx.ext.todo",
"sphinx.ext.viewcode",
"sphinx_click",
+ "sphinx_design",
"sphinx_issues",
"sphinx_sitemap",
"sphinxcontrib.autodoc_pydantic",
+ "sphinxcontrib.images",
]
templates_path = ["_templates"]
@@ -54,7 +56,8 @@ version = metadata.version("canaille")
language = "en"
exclude_patterns = []
pygments_style = "sphinx"
-todo_include_todos = False
+todo_include_todos = True
+toctree_collapse = False
intersphinx_mapping = {
"python": ("https://docs.python.org/3", None),
@@ -63,6 +66,7 @@ intersphinx_mapping = {
"flask-babel": ("https://python-babel.github.io/flask-babel", None),
"flask-wtf": ("https://flask-wtf.readthedocs.io", 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}"
@@ -75,20 +79,45 @@ html_theme = "shibuya"
html_static_path = ["_static"]
html_baseurl = "https://canaille.readthedocs.io/"
html_theme_options = {
+ "globaltoc_expand_depth": 3,
"accent_color": "yellow",
"light_logo": "_static/canaille-label-black.webp",
"dark_logo": "_static/canaille-label-white.webp",
"gitlab_url": "https://gitlab.com/yaal/canaille",
"mastodon_url": "https://toot.aquilenet.fr/@yaal",
+ "discussion_url": "https://matrix.to/#/#canaille-discuss:yaal.coop",
"nav_links": [
{
- "title": "Homepage",
- "url": "https://canaille.yaal.coop",
- "summary": "The homepage for the Canaille project",
+ "title": "Demo",
+ "children": [
+ {
+ "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 ------------------------------------------
@@ -125,7 +154,7 @@ texinfo_documents = [
autosectionlabel_prefix_document = True
autosectionlabel_maxdepth = 2
-# -- Options for autodo_pydantic_settings -------------------------------------------
+# -- Options for autodoc_pydantic_settings -------------------------------------------
autodoc_pydantic_settings_show_json = 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_members = False
autodoc_pydantic_settings_show_field_summary = False
+autodoc_pydantic_settings_signature_prefix = ""
+autodoc_pydantic_field_signature_prefix = ""
autodoc_pydantic_field_list_validators = False
+
+# -- Options for images
+
+images_config = {
+ "override_image_directive": True,
+ "download": False,
+}
diff --git a/doc/contributing.rst b/doc/contributing.rst
deleted file mode 100644
index e582053e..00000000
--- a/doc/contributing.rst
+++ /dev/null
@@ -1 +0,0 @@
-.. include:: ../CONTRIBUTING.rst
diff --git a/doc/development/changelog.rst b/doc/development/changelog.rst
new file mode 100644
index 00000000..e1d739b1
--- /dev/null
+++ b/doc/development/changelog.rst
@@ -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 `_,
+and this project adheres to `Semantic Versioning `_.
+
+.. include:: ../../CHANGES.rst
diff --git a/doc/development/contributing.rst b/doc/development/contributing.rst
new file mode 100644
index 00000000..ac7b6bcf
--- /dev/null
+++ b/doc/development/contributing.rst
@@ -0,0 +1 @@
+.. include:: ../../CONTRIBUTING.rst
diff --git a/doc/development/index.rst b/doc/development/index.rst
new file mode 100644
index 00000000..8a881b3d
--- /dev/null
+++ b/doc/development/index.rst
@@ -0,0 +1,8 @@
+Development
+===========
+
+.. toctree::
+
+ specifications
+ contributing
+ changelog
diff --git a/doc/specifications.rst b/doc/development/specifications.rst
similarity index 100%
rename from doc/specifications.rst
rename to doc/development/specifications.rst
diff --git a/doc/features.rst b/doc/features.rst
new file mode 100644
index 00000000..16c43110
--- /dev/null
+++ b/doc/features.rst
@@ -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 ` to fit any :doc:`use cases ` you may meet.
+Check our :ref:`roadmap ` to see what is coming next.
+
+Users can interact with Canaille through its :ref:`web interface ` and administrators can also use its :ref:`command line interface `.
+Canaille can handle data stored in different :ref:`database backends `.
+
+Web interface
+*************
+
+Canaille web interface can be used either in :doc:`production environments ` 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 ` or :attr:`read-only ` depends on the user :class:`Access Control List settings (ACL) `.
+
+Depending on their ACL :class:`permissions `, 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 ` 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 ` 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 ` 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 ` 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 `.
+
+.. important::
+ Due to limitations in the :ref:`LDAP backend `, 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 `, 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 `.
+
+.. todo:: :ref:`LDAP backend ` users can define which :class:`user field ` 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 `, 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 ` is enabled. They will be able to fill a registration form with the fields detailed in the default :class:`ACL settings `.
+
+If :attr:`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 ` is configured, users with :attr:`user management permission ` can create an invitation link for one user.
+
+The link goes to a registration form, even if regular :ref:`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 ` that supports it, user accounts can be locked by users with :attr:`user management permission `.
+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 ` are allowed to delete their own account.
+
+Users that also have the :attr:`user management permission ` 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 ` is configured and the :attr:`password recovery feature ` 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 ` is configured, :attr:`user management permission ` 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 ` are optional.
+If a :class:`mail server ` 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 ` if available, or your browser language if available (and if it is not you can :ref:`help us with the translation `).
+If you prefer, you can also :attr:`force a language ` 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 ` and a :attr:`favicon `.
+
+If you need more you can also use a :attr:`custom theme `.
+
+.. _feature_oidc:
+
+OpenID Connect
+**************
+
+Canaille implements a :ref:`subset` 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 ` 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 ` so most of the applications plugged to Canaille can auto-configure themselves.
+
+Dynamic Client Registration
+===========================
+
+Canaille implements the :doc:`Dynamic Client Registration specifications `, so when the :attr:`feature is enabled `, 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 ` or to :ref:`install missing parts `.
+You can use the CLI to :ref:`create `, :ref:`read `, :ref:`update ` and :ref:`delete ` models such as :class:`users `, :class:`groups ` or :class:`OIDC clients `.
+
+There are also tools to :ref:`fill your database ` with random objects, for tests purpose for instance.
+
+.. _feature_backends:
+
+Backends
+********
+
+Canaille can handle data from the most :ref:`common SQL databases ` such as PostgreSQL, MariaDB or SQLite, as well as :ref:`OpenLDAP `.
+It also comes with a no-dependency :ref:`in-memory database ` that can be used in unit tests suites.
+
+Miscellaneous
+*************
+
+.. _feature_logging:
+
+Logging
+=======
+
+Canaille writes :attr:`logs ` 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 ` and its curated :ref:`dependency list `, 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 `, 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>`
diff --git a/doc/index.rst b/doc/index.rst
index 301fa196..c2e5a0be 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -1,3 +1,5 @@
+:layout: landing
+
.. figure:: _static/canaille-full-black.webp
:width: 400
:figclass: light-only
@@ -8,53 +10,71 @@
:figclass: dark-only
:align: center
+.. rst-class:: lead
+
+ Lightweight Identity and Autorization Management
+
+----
+
**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.
-
It aims to be very light, simple to install and simple to maintain. Its main features are :
-- User profile and groups management;
-- Authentication, registration, email confirmation, "I forgot my password" emails;
-- OpenID Connect identity provider;
-- postgresql, mariadb and OpenLDAP first-class citizenship;
-- Customizable, themable;
-- The code is easy to read and easy to edit!
+.. grid:: 3
+ :gutter: 2
+ :padding: 0
-Screenshots
-===========
+ .. grid-item-card:: Profile management
+ :link-type: ref
+ :link: feature_profile_management
-.. image:: _static/login.webp
- :width: 225
- :alt: Login
+ User profile and groups management,
+ Basic permissions
-.. image:: _static/profile.webp
- :width: 225
- :alt: Profile
+ .. grid-item-card:: User authentication
+ :link-type: ref
+ :link: feature_user_authentication
-.. image:: _static/consent.webp
- :width: 225
- :alt: Consent
+ Authentication, registration, email confirmation, "I forgot my password" emails
-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 `
+
+.. rst-class:: lead
+
+ Documentation
+
+----
.. toctree::
:maxdepth: 2
- install
- deployment
- databases
- configuration
- commands
- troubleshooting
- reference
- specifications
- contributing
- changelog
-
-Indices and tables
-==================
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
+ features
+ tutorial/index
+ references/index
+ development/index
diff --git a/doc/commands.rst b/doc/references/commands.rst
similarity index 85%
rename from doc/commands.rst
rename to doc/references/commands.rst
index 4350fc1c..9b613952 100644
--- a/doc/commands.rst
+++ b/doc/references/commands.rst
@@ -3,34 +3,50 @@ Command Line Interface
Canaille provide several commands to help administrator manage their data.
+.. _cli_check:
+
.. click:: canaille.app.commands:check
:prog: canaille check
:nested: full
+.. _cli_clean:
+
.. click:: canaille.oidc.commands:clean
:prog: canaille clean
:nested: full
+.. _cli_install:
+
.. click:: canaille.app.commands:install
:prog: canaille install
:nested: full
+.. _cli_populate:
+
.. click:: canaille.core.commands:populate
:prog: canaille populate
:nested: full
+.. _cli_get:
+
.. click:: doc.commands:get
:prog: canaille get
:nested: full
+.. _cli_set:
+
.. click:: doc.commands:set
:prog: canaille set
:nested: full
+.. _cli_create:
+
.. click:: doc.commands:create
:prog: canaille create
:nested: full
+.. _cli_delete:
+
.. click:: doc.commands:delete
:prog: canaille delete
:nested: full
diff --git a/doc/configuration.rst b/doc/references/configuration.rst
similarity index 60%
rename from doc/configuration.rst
rename to doc/references/configuration.rst
index c6339c59..c78b0107 100644
--- a/doc/configuration.rst
+++ b/doc/references/configuration.rst
@@ -1,12 +1,15 @@
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"
@@ -17,7 +20,7 @@ Toml file
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 ` for inspiration.
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.
The way environment variables are parsed can be read from the `pydantic-settings documentation `_.
-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
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
==========
@@ -61,5 +67,6 @@ Example file
Here is a configuration file example:
-.. literalinclude :: ../canaille/config.sample.toml
+.. literalinclude :: ../../canaille/config.sample.toml
:language: toml
+ :caption: config.toml
diff --git a/doc/references/index.rst b/doc/references/index.rst
new file mode 100644
index 00000000..62d4d298
--- /dev/null
+++ b/doc/references/index.rst
@@ -0,0 +1,8 @@
+References
+==========
+
+.. toctree::
+
+ configuration
+ commands
+ models
diff --git a/doc/reference.rst b/doc/references/models.rst
similarity index 94%
rename from doc/reference.rst
rename to doc/references/models.rst
index 28be1303..a54d097d 100644
--- a/doc/reference.rst
+++ b/doc/references/models.rst
@@ -1,5 +1,5 @@
-Reference
-#########
+Data models
+###########
This reference details the data models used by Canaille.
This is mostly useful for developers.
diff --git a/doc/databases.rst b/doc/tutorial/databases.rst
similarity index 90%
rename from doc/databases.rst
rename to doc/tutorial/databases.rst
index 63ccbe64..33c1d0a3 100644
--- a/doc/databases.rst
+++ b/doc/tutorial/databases.rst
@@ -4,9 +4,6 @@ Databases
Canaille can read and save data in different databases.
This page presents the different database backends and their specificities:
-.. contents::
- :local:
-
Memory
======
@@ -21,7 +18,10 @@ SQL
Canaille can use any database supported by `SQLAlchemy `_, such as
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]
SQL_DATABASE_URI = "postgresql://user:password@localhost/database"
@@ -32,7 +32,10 @@ LDAP
====
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]
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:
-.. literalinclude :: ../demo/ldif/memberof-config.ldif
+.. literalinclude :: ../..//demo/ldif/memberof-config.ldif
:language: ldif
:caption: memberof-config.ldif
-.. literalinclude :: ../demo/ldif/refint-config.ldif
+.. literalinclude :: ../..//demo/ldif/refint-config.ldif
:language: ldif
:caption: refint-config.ldif
@@ -90,11 +93,11 @@ If the `ppolicy
ServerName mydomain.tld
@@ -156,10 +158,11 @@ Apache
Create the first user
=====================
-Once canaille is installed, you have several ways to populate the database. The obvious one is by adding
-directly users and group into your LDAP directory. You might also want to temporarily enable then the
-: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
-interface.
+Once canaille is installed, soon enough you will need to add users.
+To create your first user you can use the :ref:`canaille create ` CLI.
+
+.. code-block:: bash
+
+ 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
diff --git a/doc/tutorial/index.rst b/doc/tutorial/index.rst
new file mode 100644
index 00000000..27abe826
--- /dev/null
+++ b/doc/tutorial/index.rst
@@ -0,0 +1,10 @@
+Tutorial
+########
+
+.. toctree::
+ :maxdepth: 2
+
+ install
+ deployment
+ databases
+ troubleshooting
diff --git a/doc/install.rst b/doc/tutorial/install.rst
similarity index 98%
rename from doc/install.rst
rename to doc/tutorial/install.rst
index d2972811..fd3af07f 100644
--- a/doc/install.rst
+++ b/doc/tutorial/install.rst
@@ -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:
-.. contents::
- :local:
-
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 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
=================
diff --git a/doc/troubleshooting.rst b/doc/tutorial/troubleshooting.rst
similarity index 100%
rename from doc/troubleshooting.rst
rename to doc/tutorial/troubleshooting.rst
diff --git a/poetry.lock b/poetry.lock
index b0e21174..cdc5f0a1 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1913,6 +1913,29 @@ click = ">=8.0"
docutils = "*"
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]]
name = "sphinx-issues"
version = "4.1.0"
@@ -1996,6 +2019,21 @@ lint = ["docutils-stubs", "flake8", "mypy"]
standalone = ["Sphinx (>=5)"]
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]]
name = "sphinxcontrib-jsmath"
version = "1.0.1"
@@ -2463,4 +2501,4 @@ sql = ["passlib", "sqlalchemy", "sqlalchemy-json", "sqlalchemy-utils"]
[metadata]
lock-version = "2.0"
python-versions = "^3.9"
-content-hash = "c0cd43822b196a493e086b80389c22e1be6a488ae2ce8bcc21354895b2c10e67"
+content-hash = "ba6d179f761bb617fb6f4f435b71a8a98d9267bb656aa0f24520a931b0f3effe"
diff --git a/pyproject.toml b/pyproject.toml
index 12fbb967..9081f651 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -73,9 +73,11 @@ optional = true
autodoc-pydantic = "^2.0.1"
shibuya = "^2024.3.1"
sphinx = "^7.0.0"
+sphinx-design = "^0.5.0"
sphinx-sitemap = "^2.5.1"
sphinx-issues = "^4.0.0"
sphinx-click = "^6.0.0"
+sphinxcontrib-images = "^0.9.4"
[tool.poetry.group.dev.dependencies]
coverage = {version = "*", extras=["toml"]}