You've already forked AstralRinth
forked from didirus/AstralRinth
Authentication (#37)
* Initial authentication implementation * Store user info in the database, improve encapsulation in profiles * Add user list, remove unused dependencies, add spantraces * Implement user remove, update UUID crate * Add user set-default * Revert submodule macro usage * Make tracing significantly less verbose
This commit is contained in:
79
theseus/src/state/users.rs
Normal file
79
theseus/src/state/users.rs
Normal file
@@ -0,0 +1,79 @@
|
||||
//! User login info
|
||||
use crate::{auth::Credentials, config::BINCODE_CONFIG};
|
||||
|
||||
const USER_DB_TREE: &[u8] = b"users";
|
||||
|
||||
/// The set of users stored in the launcher
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct Users(pub(crate) sled::Tree);
|
||||
|
||||
impl Users {
|
||||
#[tracing::instrument(skip(db))]
|
||||
pub fn init(db: &sled::Db) -> crate::Result<Self> {
|
||||
Ok(Self(db.open_tree(USER_DB_TREE)?))
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub fn insert(
|
||||
&mut self,
|
||||
credentials: &Credentials,
|
||||
) -> crate::Result<&Self> {
|
||||
let id = credentials.id.as_bytes();
|
||||
self.0.insert(
|
||||
id,
|
||||
bincode::encode_to_vec(credentials, *BINCODE_CONFIG)?,
|
||||
)?;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub fn contains(&self, id: uuid::Uuid) -> crate::Result<bool> {
|
||||
Ok(self.0.contains_key(id.as_bytes())?)
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub fn get(&self, id: uuid::Uuid) -> crate::Result<Option<Credentials>> {
|
||||
self.0.get(id.as_bytes())?.map_or(Ok(None), |prof| {
|
||||
bincode::decode_from_slice(&prof, *BINCODE_CONFIG)
|
||||
.map_err(crate::Error::from)
|
||||
.map(|it| Some(it.0))
|
||||
})
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub fn remove(&mut self, id: uuid::Uuid) -> crate::Result<&Self> {
|
||||
self.0.remove(id.as_bytes())?;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> UserIter<impl UserInnerIter> {
|
||||
UserIter(self.0.iter().values(), false)
|
||||
}
|
||||
}
|
||||
|
||||
alias_trait! {
|
||||
pub UserInnerIter: Iterator<Item = sled::Result<sled::IVec>>, Send, Sync
|
||||
}
|
||||
|
||||
/// An iterator over the set of users
|
||||
#[derive(Debug)]
|
||||
pub struct UserIter<I: UserInnerIter>(I, bool);
|
||||
|
||||
impl<I: UserInnerIter> Iterator for UserIter<I> {
|
||||
type Item = crate::Result<Credentials>;
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.1 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let it = self.0.next()?;
|
||||
let res = it.map_err(crate::Error::from).and_then(|it| {
|
||||
Ok(bincode::decode_from_slice(&it, *BINCODE_CONFIG)?.0)
|
||||
});
|
||||
|
||||
self.1 = res.is_err();
|
||||
Some(res)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user