cleaning up
This commit is contained in:
parent
1d6270c551
commit
50e85f7de9
4 changed files with 64 additions and 18 deletions
55
src/auth.rs
55
src/auth.rs
|
@ -23,7 +23,7 @@ pub struct User {
|
|||
pub email: Option<String>,
|
||||
|
||||
/// Hashed password
|
||||
pub password: Option<Vec<u8>>,
|
||||
pub password: Option<String>,
|
||||
|
||||
/// User's chosen displayed name
|
||||
pub display_name: Option<String>,
|
||||
|
@ -43,6 +43,55 @@ pub struct User {
|
|||
pub deleted_at: Option<DateTime<Utc>>,
|
||||
}
|
||||
|
||||
impl Default for User {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
id: Uuid::nil(),
|
||||
name: Default::default(),
|
||||
email: Default::default(),
|
||||
password: Default::default(),
|
||||
display_name: Default::default(),
|
||||
bio: Default::default(),
|
||||
roles: Default::default(),
|
||||
created_at: Default::default(),
|
||||
modified_at: Default::default(),
|
||||
deleted_at: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl User {
|
||||
pub async fn create(
|
||||
pool: &Pool<Postgres>,
|
||||
username: &str,
|
||||
password: &str,
|
||||
roles: &Vec<Uuid>,
|
||||
) -> Result<Self> {
|
||||
let result = sqlx::query!(
|
||||
r#"INSERT INTO users ( name, password, roles ) VALUES ( $1,$2,$3 ) RETURNING id, created_at"#,
|
||||
username,
|
||||
hash(&password)?,
|
||||
roles,
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.await?;
|
||||
Ok(Self {
|
||||
id: result.id,
|
||||
name: username.to_owned(),
|
||||
roles: roles.to_owned(),
|
||||
created_at: result.created_at.and_utc(),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn find(pool: &Pool<Postgres>, name: &str) -> Result<Option<Self>> {
|
||||
Ok(sqlx::query_as("SELECT * FROM users WHERE name = $1")
|
||||
.bind(name)
|
||||
.fetch_optional(pool)
|
||||
.await?)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, FromRow)]
|
||||
pub struct Role {
|
||||
/// Role ID
|
||||
|
@ -137,7 +186,7 @@ pub fn random() -> String {
|
|||
SaltString::generate(&mut OsRng).to_string()
|
||||
}
|
||||
|
||||
pub fn hash(plaintext: &String) -> Result<String> {
|
||||
pub fn hash(plaintext: &str) -> Result<String> {
|
||||
let salt = SaltString::generate(&mut OsRng);
|
||||
let hashed = Argon2::default()
|
||||
.hash_password(plaintext.as_bytes(), &salt)
|
||||
|
@ -146,7 +195,7 @@ pub fn hash(plaintext: &String) -> Result<String> {
|
|||
Ok(hashed)
|
||||
}
|
||||
|
||||
pub fn verify(plaintext: &String, hash: &String) -> Result<bool> {
|
||||
pub fn verify(plaintext: &str, hash: &str) -> Result<bool> {
|
||||
let parsed_hash = PasswordHash::new(hash).map_err(|err| anyhow!(err))?;
|
||||
Ok(Argon2::default()
|
||||
.verify_password(plaintext.as_bytes(), &parsed_hash)
|
||||
|
|
|
@ -4,7 +4,7 @@ use axum::Json;
|
|||
use serde_json::{json, Value};
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::auth::{hash, random};
|
||||
use crate::auth::{random, User};
|
||||
use crate::error::AppError;
|
||||
use crate::roles::ROLE_SUPERADMIN;
|
||||
use crate::state::AppState;
|
||||
|
@ -29,14 +29,12 @@ pub async fn bootstrap(State(state): State<Arc<AppState>>) -> Result<Json<Value>
|
|||
let username = "admin";
|
||||
let password = random();
|
||||
|
||||
sqlx::query!(
|
||||
r#"INSERT INTO users ( name, display_name, password, roles ) VALUES ( $1, $2, $3, $4 ) RETURNING id"#,
|
||||
username,
|
||||
"Administrator",
|
||||
hash(&password)?,
|
||||
&[ROLE_SUPERADMIN],
|
||||
User::create(
|
||||
&state.database,
|
||||
&username,
|
||||
&password,
|
||||
&[ROLE_SUPERADMIN].to_vec(),
|
||||
)
|
||||
.fetch_one(&state.database)
|
||||
.await?;
|
||||
|
||||
Ok(Json(json!({"username": username, "password": password})))
|
||||
|
|
|
@ -5,7 +5,7 @@ use serde_json::{json, Value};
|
|||
use std::sync::Arc;
|
||||
|
||||
use crate::{
|
||||
auth::{verify, Session},
|
||||
auth::{verify, Session, User},
|
||||
error::AppError,
|
||||
state::AppState,
|
||||
};
|
||||
|
@ -20,9 +20,7 @@ pub async fn login(
|
|||
State(state): State<Arc<AppState>>,
|
||||
Json(payload): Json<LoginRequest>,
|
||||
) -> Result<Json<Value>, AppError> {
|
||||
let user = sqlx::query!("SELECT * FROM users WHERE name = $1", payload.username)
|
||||
.fetch_optional(&state.database)
|
||||
.await?;
|
||||
let user = User::find(&state.database, payload.username.as_str()).await?;
|
||||
|
||||
let invalid = || -> AppError {
|
||||
AppError::ClientError {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use crate::{content::Page, error::AppError, state::AppState};
|
||||
use axum::extract::{Path, State};
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::{content::Page, error::AppError, state::AppState};
|
||||
|
||||
pub async fn page(
|
||||
State(state): State<Arc<AppState>>,
|
||||
Path((site, slug)): Path<(String, String)>,
|
||||
|
|
Loading…
Reference in a new issue