Refractored code and implemented logout
This commit is contained in:
parent
6395df6cec
commit
9eb92ffff1
49
devenv.lock
49
devenv.lock
@ -31,10 +31,31 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"git-hooks": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"gitignore": "gitignore",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1737465171,
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"rev": "9364dc02281ce2d37a1f55b6e51f7c0f65a75f17",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gitignore": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"pre-commit-hooks",
|
||||
"git-hooks",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
@ -66,32 +87,14 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"pre-commit-hooks": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"gitignore": "gitignore",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1735882644,
|
||||
"owner": "cachix",
|
||||
"repo": "pre-commit-hooks.nix",
|
||||
"rev": "a5a961387e75ae44cc20f0a57ae463da5e959656",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "cachix",
|
||||
"repo": "pre-commit-hooks.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"devenv": "devenv",
|
||||
"git-hooks": "git-hooks",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"pre-commit-hooks": "pre-commit-hooks"
|
||||
"pre-commit-hooks": [
|
||||
"git-hooks"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -11,21 +11,12 @@ use rand_chacha::ChaCha20Rng;
|
||||
use sqlx::PgPool;
|
||||
use tokio::task;
|
||||
|
||||
use crate::{
|
||||
database::model::Session,
|
||||
model::User,
|
||||
};
|
||||
use crate::{database::model::Session, model::User};
|
||||
|
||||
mod error;
|
||||
|
||||
pub async fn get_user_from_header(pool: &PgPool, headers: &HeaderMap) -> Result<User, AuthError> {
|
||||
let bearer_value = headers.get(header::AUTHORIZATION);
|
||||
let bearer_value = bearer_value
|
||||
.ok_or(AuthError::InvalidToken)?
|
||||
.to_str()
|
||||
.map_err(|_| AuthError::InvalidToken)?;
|
||||
|
||||
let token = get_token_from_bearer(bearer_value)?;
|
||||
let token = get_token_from_headers(&headers)?;
|
||||
|
||||
let session = match Session::from_token(pool, &token).await {
|
||||
Ok(s) => s,
|
||||
@ -44,7 +35,13 @@ pub async fn get_user_from_header(pool: &PgPool, headers: &HeaderMap) -> Result<
|
||||
Ok(db_user.into())
|
||||
}
|
||||
|
||||
pub fn get_token_from_bearer(bearer: &str) -> Result<String, AuthError> {
|
||||
pub fn get_token_from_headers(headers: &HeaderMap) -> Result<String, AuthError> {
|
||||
let bearer = headers.get(header::AUTHORIZATION);
|
||||
let bearer = bearer
|
||||
.ok_or(AuthError::InvalidToken)?
|
||||
.to_str()
|
||||
.map_err(|_| AuthError::InvalidToken)?;
|
||||
|
||||
match bearer.strip_prefix("Bearer ") {
|
||||
Some(token) => Ok(token.to_string()),
|
||||
None => Err(AuthError::InvalidToken),
|
||||
|
@ -43,4 +43,54 @@ impl Session {
|
||||
|
||||
Ok(session)
|
||||
}
|
||||
|
||||
pub async fn remove_many(
|
||||
session_ids: &[uuid::Uuid],
|
||||
transaction: &mut sqlx::Transaction<'_, Postgres>,
|
||||
) -> Result<(), sqlx::Error> {
|
||||
let deleted_count = sqlx::query_scalar!(
|
||||
"
|
||||
WITH deleted AS (
|
||||
DELETE FROM sessions
|
||||
WHERE session_id = ANY($1)
|
||||
RETURNING 1
|
||||
)
|
||||
SELECT COUNT(*) FROM deleted
|
||||
",
|
||||
session_ids
|
||||
)
|
||||
.fetch_one(&mut **transaction)
|
||||
.await?;
|
||||
|
||||
if !deleted_count.is_some_and(|c| c >= 1) {
|
||||
return Err(sqlx::Error::RowNotFound);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn remove_many_from_token(
|
||||
transaction: &mut sqlx::Transaction<'_, Postgres>,
|
||||
session_tokens: &[String],
|
||||
) -> Result<(), sqlx::Error> {
|
||||
let deleted_count = sqlx::query_scalar!(
|
||||
"
|
||||
WITH deleted AS (
|
||||
DELETE FROM sessions
|
||||
WHERE token = ANY($1)
|
||||
RETURNING 1
|
||||
)
|
||||
SELECT COUNT(*) FROM deleted
|
||||
",
|
||||
session_tokens
|
||||
)
|
||||
.fetch_one(&mut **transaction)
|
||||
.await?;
|
||||
|
||||
if !deleted_count.is_some_and(|c| c >= 1) {
|
||||
return Err(sqlx::Error::RowNotFound);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,12 @@
|
||||
use axum::http::HeaderMap;
|
||||
use axum::{extract::State, routing::post, Json, Router};
|
||||
use axum::{
|
||||
extract::State,
|
||||
routing::{get, post},
|
||||
Json, Router,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::auth::verify_password_hash;
|
||||
use crate::auth::{get_token_from_headers, verify_password_hash};
|
||||
use crate::auth::{get_user_from_header, AuthError};
|
||||
use crate::database::model::user::UpdateUser;
|
||||
use crate::database::model::Member as DbMember;
|
||||
@ -16,6 +20,7 @@ pub fn routes() -> Router<AppState> {
|
||||
Router::new()
|
||||
.route("/auth/login", post(login))
|
||||
.route("/auth/register", post(register))
|
||||
.route("/auth/logout", get(logout))
|
||||
.route("/auth/change_password", post(change_password))
|
||||
.route("/auth/change_email", post(change_email))
|
||||
}
|
||||
@ -88,6 +93,18 @@ pub async fn register(
|
||||
Ok(db_session.token)
|
||||
}
|
||||
|
||||
pub async fn logout(State(state): State<AppState>, headers: HeaderMap) -> Result<(), crate::Error> {
|
||||
let registration_token = get_token_from_headers(&headers)?;
|
||||
|
||||
let mut transaction = state.pool.begin().await?;
|
||||
|
||||
DbSession::remove_many_from_token(&mut transaction, &[registration_token]).await?;
|
||||
|
||||
transaction.commit().await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct ChangePasswordRequest {
|
||||
pub old_password: String,
|
||||
|
Loading…
x
Reference in New Issue
Block a user