Refactor SignedInUser -> RegisteredUser

This commit is contained in:
Emi Tatsuo 2020-11-19 17:00:32 -05:00
parent 2f1196228f
commit 79b06b08ba
Signed by: Emi
GPG Key ID: 68FAB2E2E6DFC98B
3 changed files with 22 additions and 22 deletions

View File

@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize, de::DeserializeOwned};
use std::path::Path; use std::path::Path;
use crate::user_management::{User, Result}; use crate::user_management::{User, Result};
use crate::user_management::user::{SignedInUser, NotSignedInUser, PartialUser}; use crate::user_management::user::{RegisteredUser, NotSignedInUser, PartialUser};
#[derive(Debug, Clone, Deserialize, Serialize)] #[derive(Debug, Clone, Deserialize, Serialize)]
/// Data stored in the certificate tree about a certain certificate /// Data stored in the certificate tree about a certain certificate
@ -74,13 +74,13 @@ impl UserManager {
pub fn lookup_user<UserData>( pub fn lookup_user<UserData>(
&self, &self,
username: impl AsRef<str> username: impl AsRef<str>
) -> Result<Option<SignedInUser<UserData>>> ) -> Result<Option<RegisteredUser<UserData>>>
where where
UserData: Serialize + DeserializeOwned UserData: Serialize + DeserializeOwned
{ {
if let Some(bytes) = self.users.get(username.as_ref())? { if let Some(bytes) = self.users.get(username.as_ref())? {
let inner: PartialUser<UserData> = bincode::deserialize_from(bytes.as_ref())?; let inner: PartialUser<UserData> = bincode::deserialize_from(bytes.as_ref())?;
Ok(Some(SignedInUser::new(username.as_ref().to_owned(), None, self.clone(), inner))) Ok(Some(RegisteredUser::new(username.as_ref().to_owned(), None, self.clone(), inner)))
} else { } else {
Ok(None) Ok(None)
} }

View File

@ -12,9 +12,9 @@
//! * Ask users with a certificate not yet linked to an account to create an account using //! * 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 //! [`NotSignedInUser::register()`] or link their certificate to an existing account
//! with a password using [`NotSignedInUser::attach()`]. //! with a password using [`NotSignedInUser::attach()`].
//! * You should now have a [`SignedInUser`] either from registering/attaching a //! * You should now have a [`RegisteredUser`] either from registering/attaching a
//! [`NotSignedInUser`] or because the user was already registered //! [`NotSignedInUser`] or because the user was already registered
//! * Access and modify user data using [`SignedInUser::as_mut()`], changes are //! * Access and modify user data using [`RegisteredUser::as_mut()`], changes are
//! automatically persisted to the database (on user drop). //! automatically persisted to the database (on user drop).
//! //!
//! Use of this module requires the `user_management` feature to be enabled //! Use of this module requires the `user_management` feature to be enabled

View File

@ -5,14 +5,14 @@
//! //!
//! [`User`] is the most common for of user struct, and typically comes from calling //! [`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 //! [`Request::user()`](crate::types::Request::user()). This is an enum with several
//! variants, and can be specialized into a [`NotSignedInUser`] or a [`SignedInUser`] if //! variants, and can be specialized into a [`NotSignedInUser`] or a [`RegisteredUser`] if
//! the user has presented a certificate. These two subtypes have more specific //! the user has presented a certificate. These two subtypes have more specific
//! information, like the user's username and active certificate. //! information, like the user's username and active certificate.
//! //!
//! [`SignedInUser`] is particularly signifigant in that this is the struct used to modify //! [`RegisteredUser`] is particularly signifigant in that this is the struct used to modify
//! the data stored for almost all users. This is accomplished through the //! the data stored for almost all users. This is accomplished through the
//! [`as_mut()`](SignedInUser::as_mut) method. Changes made this way must be persisted //! [`as_mut()`](RegisteredUser::as_mut) method. Changes made this way must be persisted
//! using [`save()`](SignedInUser::save()) or by dropping the user. //! using [`save()`](RegisteredUser::save()) or by dropping the user.
use rustls::Certificate; use rustls::Certificate;
use serde::{Deserialize, Serialize, de::DeserializeOwned}; use serde::{Deserialize, Serialize, de::DeserializeOwned};
use sled::Transactional; use sled::Transactional;
@ -83,7 +83,7 @@ pub enum User<UserData: Serialize + DeserializeOwned> {
NotSignedIn(NotSignedInUser), NotSignedIn(NotSignedInUser),
/// A user connecting with an identified account /// A user connecting with an identified account
SignedIn(SignedInUser<UserData>), SignedIn(RegisteredUser<UserData>),
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -109,13 +109,13 @@ impl NotSignedInUser {
pub fn register<UserData: Serialize + DeserializeOwned + Default>( pub fn register<UserData: Serialize + DeserializeOwned + Default>(
self, self,
username: String, username: String,
) -> Result<SignedInUser<UserData>> { ) -> Result<RegisteredUser<UserData>> {
if self.manager.users.contains_key(username.as_str())? { if self.manager.users.contains_key(username.as_str())? {
Err(super::UserManagerError::UsernameNotUnique) Err(super::UserManagerError::UsernameNotUnique)
} else { } else {
let cert_hash = UserManager::hash_certificate(&self.certificate); let cert_hash = UserManager::hash_certificate(&self.certificate);
let newser = SignedInUser::new( let newser = RegisteredUser::new(
username.clone(), username.clone(),
Some(self.certificate.clone()), Some(self.certificate.clone()),
self.manager, self.manager,
@ -158,7 +158,7 @@ impl NotSignedInUser {
/// log in with either this certificate or any of the certificates they already had /// log in with either this certificate or any of the certificates they already had
/// registered. /// registered.
/// ///
/// This method returns the new SignedInUser instance representing the now-attached /// This method returns the new RegisteredUser instance representing the now-attached
/// user. /// user.
/// ///
/// # Errors /// # Errors
@ -170,7 +170,7 @@ impl NotSignedInUser {
pub fn attach<UserData: Serialize + DeserializeOwned>( pub fn attach<UserData: Serialize + DeserializeOwned>(
username: impl AsRef<[u8]>, username: impl AsRef<[u8]>,
password: impl AsRef<[u8]>, password: impl AsRef<[u8]>,
) -> Result<SignedInUser<UserData>> { ) -> Result<RegisteredUser<UserData>> {
todo!() todo!()
} }
} }
@ -179,16 +179,16 @@ impl NotSignedInUser {
/// Data about a logged in user /// Data about a logged in user
/// ///
/// For more information about the user lifecycle and sign-in stages, see [`User`] /// For more information about the user lifecycle and sign-in stages, see [`User`]
pub struct SignedInUser<UserData: Serialize + DeserializeOwned> { pub struct RegisteredUser<UserData: Serialize + DeserializeOwned> {
username: String, username: String,
active_certificate: Option<Certificate>, active_certificate: Option<Certificate>,
manager: UserManager, manager: UserManager,
inner: PartialUser<UserData>, inner: PartialUser<UserData>,
/// Indicates that [`SignedInUser::as_mut()`] has been called, but [`SignedInUser::save()`] has not /// Indicates that [`RegisteredUser::as_mut()`] has been called, but [`RegisteredUser::save()`] has not
has_changed: bool, has_changed: bool,
} }
impl<UserData: Serialize + DeserializeOwned> SignedInUser<UserData> { impl<UserData: Serialize + DeserializeOwned> RegisteredUser<UserData> {
/// Create a new user from parts /// Create a new user from parts
pub (crate) fn new( pub (crate) fn new(
@ -268,7 +268,7 @@ impl<UserData: Serialize + DeserializeOwned> SignedInUser<UserData> {
/// users are able to add more devices to their account, and recover their account if /// users are able to add more devices to their account, and recover their account if
/// it's lost. Note that this will completely overwrite the users old password. /// it's lost. Note that this will completely overwrite the users old password.
/// ///
/// Use [`SignedInUser::check_password()`] and [`NotSignedInUser::attach()`] to check /// Use [`RegisteredUser::check_password()`] and [`NotSignedInUser::attach()`] to check
/// the password against another one, or to link a new certificate. /// the password against another one, or to link a new certificate.
/// ///
/// Because this method uses a key derivation algorithm, this should be considered a /// Because this method uses a key derivation algorithm, this should be considered a
@ -305,7 +305,7 @@ impl<UserData: Serialize + DeserializeOwned> SignedInUser<UserData> {
} }
} }
impl<UserData: Serialize + DeserializeOwned> std::ops::Drop for SignedInUser<UserData> { impl<UserData: Serialize + DeserializeOwned> std::ops::Drop for RegisteredUser<UserData> {
fn drop(&mut self) { fn drop(&mut self) {
if self.has_changed { if self.has_changed {
if let Err(e) = self.save() { if let Err(e) = self.save() {
@ -315,14 +315,14 @@ impl<UserData: Serialize + DeserializeOwned> std::ops::Drop for SignedInUser<Use
} }
} }
impl<UserData: Serialize + DeserializeOwned> AsRef<UserData> for SignedInUser<UserData> { impl<UserData: Serialize + DeserializeOwned> AsRef<UserData> for RegisteredUser<UserData> {
fn as_ref(&self) -> &UserData { fn as_ref(&self) -> &UserData {
&self.inner.data &self.inner.data
} }
} }
impl<UserData: Serialize + DeserializeOwned> AsMut<UserData> for SignedInUser<UserData> { impl<UserData: Serialize + DeserializeOwned> AsMut<UserData> for RegisteredUser<UserData> {
/// NOTE: Changes made to the user data won't be persisted until SignedInUser::save /// NOTE: Changes made to the user data won't be persisted until RegisteredUser::save
/// is called /// is called
fn as_mut(&mut self) -> &mut UserData { fn as_mut(&mut self) -> &mut UserData {
self.has_changed = true; self.has_changed = true;