diff --git a/Cargo.toml b/Cargo.toml index de183b5..5a1d4d0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,6 @@ repository = "https://github.com/panicbit/northstar" documentation = "https://docs.rs/northstar" [features] -# default = ["user_management"] user_management = ["sled", "bincode", "serde/derive", "bcrypt", "crc32fast"] [dependencies] diff --git a/src/user_management/manager.rs b/src/user_management/manager.rs index 2dacd35..4f93e5e 100644 --- a/src/user_management/manager.rs +++ b/src/user_management/manager.rs @@ -46,7 +46,7 @@ impl UserManager { }) } - /// Produce a u32 hash from a certificate, used for [`lookup_certficate()`] + /// Produce a u32 hash from a certificate, used for [`lookup_certificate()`](Self::lookup_certificate()) pub fn hash_certificate(cert: &Certificate) -> u32 { let mut hasher = crc32fast::Hasher::new(); hasher.update(cert.0.as_ref()); diff --git a/src/user_management/mod.rs b/src/user_management/mod.rs index 8569b2b..4384355 100644 --- a/src/user_management/mod.rs +++ b/src/user_management/mod.rs @@ -1,7 +1,30 @@ +//! Tools for registering users & persisting arbitrary user data +//! +//! Many Gemini applications use some form of a login method in order to allow users to +//! persist personal data, authenticate themselves, and login from multiple devices using +//! multiple certificates. +//! +//! This module contains tools to help you build a system like this without stress. A +//! typical workflow looks something like this: +//! +//! * Call [`Request::user()`] to retrieve information about a user +//! * Direct any users without a certificate to create a certificate +//! * Ask users with a certificate not yet linked to an account to create an account using +//! [`NotSignedInUser::register()`] or link their certificate to an existing account +//! with a password using [`NotSignedInUser::attach()`]. +//! * You should now have a [`SignedInUser`] either from registering/attaching a +//! [`NotSignedInUser`] or because the user was already registered +//! * Access and modify user data using [`SignedInUser::as_mut()`], changes are +//! automatically persisted to the database (on user drop). +//! +//! Use of this module requires the `user_management` feature to be enabled pub mod user; mod manager; pub use manager::UserManager; pub use user::User; +pub use manager::CertificateData; +use crate::types::Request; +use user::{NotSignedInUser, SignedInUser}; #[derive(Debug)] pub enum UserManagerError { diff --git a/src/user_management/user.rs b/src/user_management/user.rs index cb2d036..ca61472 100644 --- a/src/user_management/user.rs +++ b/src/user_management/user.rs @@ -1,3 +1,23 @@ +//! Several structs representing data about users +//! +//! This module contains any structs needed to store and retrieve data about users. The +//! different varieties have different purposes and come from different places. +//! +//! [`User`] is the most common for of user struct, and typically comes from calling +//! [`Request::user()`](crate::types::Request::user()). This is an enum with several +//! variants, and can be specialized into a [`NotSignedInUser`] or a [`SignedInUser`] if +//! the user has presented a certificate. These two subtypes have more specific +//! information, like the user's username and active certificate. +//! +//! [`SignedInUser`] is particularly signifigant in that this is the struct used to modify +//! the data stored for the current user. This is accomplished through the +//! [`as_mut()`](SignedInUser::as_mut) method. Changes made this way must be persisted +//! using [`save()`](SignedInUser::save()) or by dropping the user. +//! +//! [`PartialUser`] is the main way of modifying data stored for users who aren't +//! currently connecting. These are mainly obtained through the +//! [`UserManager::lookup_user()`] method. Unlinke with [`SignedInUser`], these are not +//! committed on drop, and [`PartialUser::store()`] must be manually called use rustls::Certificate; use serde::{Deserialize, Serialize}; use sled::Transactional; @@ -21,7 +41,7 @@ impl PartialUser { /// A list of certificate hashes registered to this user /// - /// Can be looked up using [`UserManager::lookup_certficate`] to get full information + /// Can be looked up using [`UserManager::lookup_certificate()`] to get full information pub fn certificates(&self) -> &Vec { &self.certificates } @@ -94,7 +114,11 @@ pub struct NotSignedInUser { } impl NotSignedInUser { - /// Register a new user with this certificate + /// Register a new user with this certificate. + /// + /// This creates a new user & user data entry in the database with the given username. + /// From now on, when this user logs in with this certificate, they will be + /// automatically authenticated, and their user data automatically retrieved. /// /// # Errors /// The provided username must be unique, or else an error will be raised. @@ -150,7 +174,13 @@ impl NotSignedInUser { /// Attach this certificate to an existing user /// - /// Try to add this certificate to another user using a username and password + /// Try to add this certificate to another user using a username and password. If + /// successful, the user this certificate is attached to will be able to automatically + /// log in with either this certificate or any of the certificates they already had + /// registered. + /// + /// This method returns the new SignedInUser instance representing the now-attached + /// user. /// /// # Errors /// This will error if the username and password are incorrect, or if the user has yet