add: icon resolver
add: config "no_track" file list option add: rainbeam-shared -> tetratto-shared add: l10n
This commit is contained in:
parent
b6fe2fba37
commit
d2ca9e23d3
40 changed files with 1107 additions and 583 deletions
71
crates/core/src/model/auth.rs
Normal file
71
crates/core/src/model/auth.rs
Normal file
|
@ -0,0 +1,71 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use tetratto_shared::{
|
||||
hash::{hash_salted, salt},
|
||||
snow::AlmostSnowflake,
|
||||
unix_epoch_timestamp,
|
||||
};
|
||||
|
||||
/// `(ip, token, creation timestamp)`
|
||||
pub type Token = (String, String, usize);
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct User {
|
||||
pub id: usize,
|
||||
pub created: usize,
|
||||
pub username: String,
|
||||
pub password: String,
|
||||
pub salt: String,
|
||||
pub settings: UserSettings,
|
||||
pub tokens: Vec<Token>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct UserSettings;
|
||||
|
||||
impl Default for UserSettings {
|
||||
fn default() -> Self {
|
||||
Self {}
|
||||
}
|
||||
}
|
||||
|
||||
impl User {
|
||||
/// Create a new [`User`].
|
||||
pub fn new(username: String, password: String) -> Self {
|
||||
let salt = salt();
|
||||
let password = hash_salted(password, salt.clone());
|
||||
|
||||
Self {
|
||||
id: AlmostSnowflake::new(1234567890)
|
||||
.to_string()
|
||||
.parse::<usize>()
|
||||
.unwrap(),
|
||||
created: unix_epoch_timestamp() as usize,
|
||||
username,
|
||||
password,
|
||||
salt,
|
||||
settings: UserSettings::default(),
|
||||
tokens: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new token
|
||||
///
|
||||
/// # Returns
|
||||
/// `(unhashed id, token)`
|
||||
pub fn create_token(ip: &str) -> (String, Token) {
|
||||
let unhashed = tetratto_shared::hash::uuid();
|
||||
(
|
||||
unhashed.clone(),
|
||||
(
|
||||
ip.to_string(),
|
||||
tetratto_shared::hash::hash(unhashed),
|
||||
unix_epoch_timestamp() as usize,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
/// Check if the given password is correct for the user.
|
||||
pub fn check_password(&self, against: String) -> bool {
|
||||
self.password == hash_salted(against, self.salt.clone())
|
||||
}
|
||||
}
|
56
crates/core/src/model/mod.rs
Normal file
56
crates/core/src/model/mod.rs
Normal file
|
@ -0,0 +1,56 @@
|
|||
pub mod auth;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct ApiReturn<T>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
pub ok: bool,
|
||||
pub message: String,
|
||||
pub payload: T,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
DatabaseConnection(String),
|
||||
UserNotFound,
|
||||
RegistrationDisabled,
|
||||
DatabaseError(String),
|
||||
IncorrectPassword,
|
||||
AlreadyAuthenticated,
|
||||
DataTooLong(String),
|
||||
DataTooShort(String),
|
||||
Unknown,
|
||||
}
|
||||
|
||||
impl ToString for Error {
|
||||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
Error::DatabaseConnection(msg) => msg.to_owned(),
|
||||
Error::DatabaseError(msg) => format!("Database error: {msg}"),
|
||||
Error::UserNotFound => "Unable to find user with given parameters".to_string(),
|
||||
Error::RegistrationDisabled => "Registration is disabled".to_string(),
|
||||
Error::IncorrectPassword => "The given password is invalid".to_string(),
|
||||
Error::AlreadyAuthenticated => "Already authenticated".to_string(),
|
||||
Error::DataTooLong(name) => format!("Given {name} is too long!"),
|
||||
Error::DataTooShort(name) => format!("Given {name} is too short!"),
|
||||
_ => format!("An unknown error as occurred: ({:?})", self),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Into<ApiReturn<T>> for Error
|
||||
where
|
||||
T: Default + Serialize,
|
||||
{
|
||||
fn into(self) -> ApiReturn<T> {
|
||||
ApiReturn {
|
||||
ok: false,
|
||||
message: self.to_string(),
|
||||
payload: T::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
Loading…
Add table
Add a link
Reference in a new issue