feat(gpodder): add create_user method to AuthStore

main
Jef Roosens 2025-03-19 10:46:34 +01:00
parent 2a8917f21d
commit b44a47fefd
No known key found for this signature in database
GPG Key ID: 21FD3D77D56BAF49
4 changed files with 40 additions and 7 deletions

View File

@ -1,8 +1,8 @@
use std::{collections::HashSet, sync::Arc};
use argon2::{Argon2, PasswordHash, PasswordVerifier};
use argon2::{password_hash::SaltString, Argon2, PasswordHash, PasswordHasher, PasswordVerifier};
use chrono::{DateTime, TimeDelta, Utc};
use rand::Rng;
use rand::{rngs::OsRng, Rng};
use crate::{
models,
@ -41,6 +41,17 @@ impl GpodderRepository {
self.store.get_user(username)?.ok_or(AuthErr::UnknownUser)
}
pub fn create_user(&self, username: &str, password: &str) -> Result<models::User, AuthErr> {
let salt = SaltString::generate(&mut OsRng);
let password_hash = Argon2::default()
.hash_password(password.as_bytes(), &salt)
.unwrap()
.to_string();
self.store.insert_user(username, &password_hash)
}
pub fn validate_credentials(
&self,
username: &str,

View File

@ -41,6 +41,9 @@ pub trait AuthStore {
/// Retrieve the user with the given username
fn get_user(&self, username: &str) -> Result<Option<User>, AuthErr>;
/// Insert a new user into the data store
fn insert_user(&self, username: &str, password_hash: &str) -> Result<User, AuthErr>;
/// Create a new session for a user with the given session ID
fn insert_session(&self, session: &Session) -> Result<(), AuthErr>;

View File

@ -14,9 +14,9 @@ pub struct User {
#[derive(Insertable)]
#[diesel(table_name = users)]
#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
pub struct NewUser {
pub username: String,
pub password_hash: String,
pub struct NewUser<'a> {
pub username: &'a str,
pub password_hash: &'a str,
}
// impl NewUser {

View File

@ -4,7 +4,10 @@ use gpodder::AuthErr;
use super::SqliteRepository;
use crate::{
models::{session::Session, user::User},
models::{
session::Session,
user::{NewUser, User},
},
schema::*,
DbError,
};
@ -30,18 +33,34 @@ impl gpodder::AuthStore for SqliteRepository {
.map(gpodder::User::from))
}
fn insert_user(&self, username: &str, password_hash: &str) -> Result<gpodder::User, AuthErr> {
let conn = &mut self.pool.get().map_err(DbError::from)?;
Ok(diesel::insert_into(users::table)
.values(NewUser {
username,
password_hash,
})
.returning(User::as_returning())
.get_result(conn)
.map(gpodder::User::from)
.map_err(DbError::from)?)
}
fn get_session(&self, session_id: i64) -> Result<Option<gpodder::models::Session>, AuthErr> {
match sessions::table
.inner_join(users::table)
.filter(sessions::id.eq(session_id))
.select((Session::as_select(), User::as_select()))
.get_result(&mut self.pool.get().map_err(DbError::from)?)
.optional()
{
Ok((session, user)) => Ok(Some(gpodder::Session {
Ok(Some((session, user))) => Ok(Some(gpodder::Session {
id: session.id,
last_seen: DateTime::from_timestamp(session.last_seen, 0).unwrap(),
user: user.into(),
})),
Ok(None) => Ok(None),
Err(err) => Err(DbError::from(err).into()),
}
}