Added session creating
This commit is contained in:
parent
30bf08986d
commit
36c785e8f2
5
server/Cargo.lock
generated
5
server/Cargo.lock
generated
@ -1650,6 +1650,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "6a007b6936676aa9ab40207cde35daab0a04b823be8ae004368c0793b96a61e0"
|
checksum = "6a007b6936676aa9ab40207cde35daab0a04b823be8ae004368c0793b96a61e0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
|
"chrono",
|
||||||
"crc",
|
"crc",
|
||||||
"crossbeam-queue",
|
"crossbeam-queue",
|
||||||
"either",
|
"either",
|
||||||
@ -1727,6 +1728,7 @@ dependencies = [
|
|||||||
"bitflags",
|
"bitflags",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
"chrono",
|
||||||
"crc",
|
"crc",
|
||||||
"digest",
|
"digest",
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
@ -1769,6 +1771,7 @@ dependencies = [
|
|||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
"chrono",
|
||||||
"crc",
|
"crc",
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
"etcetera",
|
"etcetera",
|
||||||
@ -1804,6 +1807,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "f85ca71d3a5b24e64e1d08dd8fe36c6c95c339a896cc33068148906784620540"
|
checksum = "f85ca71d3a5b24e64e1d08dd8fe36c6c95c339a896cc33068148906784620540"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atoi",
|
"atoi",
|
||||||
|
"chrono",
|
||||||
"flume",
|
"flume",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
@ -2474,6 +2478,7 @@ dependencies = [
|
|||||||
"dotenvy",
|
"dotenvy",
|
||||||
"itertools",
|
"itertools",
|
||||||
"rand 0.9.0",
|
"rand 0.9.0",
|
||||||
|
"rand_chacha 0.9.0",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sqlx",
|
"sqlx",
|
||||||
|
@ -8,7 +8,7 @@ edition = "2021"
|
|||||||
axum = { version = "0.8", features = [ "macros", "json" ] }
|
axum = { version = "0.8", features = [ "macros", "json" ] }
|
||||||
axum-extra = { version = "0.10.0", features = [ "typed-header" ] }
|
axum-extra = { version = "0.10.0", features = [ "typed-header" ] }
|
||||||
tokio = { version = "1.43", features = [ "rt-multi-thread", "macros" ] }
|
tokio = { version = "1.43", features = [ "rt-multi-thread", "macros" ] }
|
||||||
sqlx = { version = "0.8", features = [ "runtime-tokio", "postgres", "uuid" ] }
|
sqlx = { version = "0.8", features = [ "runtime-tokio", "postgres", "uuid", "chrono" ] }
|
||||||
|
|
||||||
# Secondary crates
|
# Secondary crates
|
||||||
csv = { version = "1.3" }
|
csv = { version = "1.3" }
|
||||||
@ -21,10 +21,11 @@ argon2 = "0.5"
|
|||||||
# Tertiary crates
|
# Tertiary crates
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
tracing-subscriber = "0.3"
|
tracing-subscriber = "0.3"
|
||||||
chrono = "0.4.39"
|
chrono = "0.4"
|
||||||
uuid = { version = "1.12.0", features = ["v4", "fast-rng"] }
|
uuid = { version = "1.12", features = ["v4", "fast-rng"] }
|
||||||
serde_json = "1.0.137"
|
serde_json = "1.0.137"
|
||||||
rand = "0.9"
|
rand = "0.9"
|
||||||
|
rand_chacha = "0.9"
|
||||||
thiserror = { version = "2.0" }
|
thiserror = { version = "2.0" }
|
||||||
itertools = "0.14"
|
itertools = "0.14"
|
||||||
|
|
||||||
|
7
server/migrations/003_create_sessions.sql
Normal file
7
server/migrations/003_create_sessions.sql
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
CREATE TABLE "sessions" (
|
||||||
|
session_id uuid NOT NULL PRIMARY KEY,
|
||||||
|
user_id uuid NOT NULL REFERENCES users (user_id) ON UPDATE cascade ON DELETE cascade,
|
||||||
|
token text NOT NULL UNIQUE,
|
||||||
|
expires_at timestamptz NOT NULL,
|
||||||
|
created_at timestamptz NOT NULL
|
||||||
|
);
|
@ -12,6 +12,9 @@ use axum_extra::{
|
|||||||
};
|
};
|
||||||
use bearer::verify_bearer;
|
use bearer::verify_bearer;
|
||||||
pub use error::AuthError;
|
pub use error::AuthError;
|
||||||
|
use rand::distr::Alphanumeric;
|
||||||
|
use rand::prelude::*;
|
||||||
|
use rand_chacha::ChaCha20Rng;
|
||||||
use tokio::task;
|
use tokio::task;
|
||||||
|
|
||||||
mod bearer;
|
mod bearer;
|
||||||
@ -72,3 +75,13 @@ pub async fn generate_password_hash(
|
|||||||
|
|
||||||
Ok(password_hash?)
|
Ok(password_hash?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn generate_session_token() -> String {
|
||||||
|
let session = ChaCha20Rng::from_os_rng()
|
||||||
|
.sample_iter(&Alphanumeric)
|
||||||
|
.take(60)
|
||||||
|
.map(char::from)
|
||||||
|
.collect::<String>();
|
||||||
|
|
||||||
|
session
|
||||||
|
}
|
||||||
|
@ -3,5 +3,6 @@ pub mod session;
|
|||||||
pub mod user;
|
pub mod user;
|
||||||
|
|
||||||
pub use member::Member;
|
pub use member::Member;
|
||||||
|
pub use session::Session;
|
||||||
pub use user::User;
|
pub use user::User;
|
||||||
pub use user::UserMember;
|
pub use user::UserMember;
|
||||||
|
@ -1,6 +1,37 @@
|
|||||||
struct Session {
|
use chrono::{DateTime, Utc};
|
||||||
id: u32,
|
use sqlx::Postgres;
|
||||||
user_id: u32,
|
|
||||||
token: String,
|
pub struct Session {
|
||||||
expires: chrono::NaiveDateTime,
|
pub session_id: uuid::Uuid,
|
||||||
|
pub user_id: uuid::Uuid,
|
||||||
|
pub token: String,
|
||||||
|
pub expires_at: DateTime<Utc>,
|
||||||
|
pub created_at: DateTime<Utc>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Session {
|
||||||
|
pub async fn insert(
|
||||||
|
&self,
|
||||||
|
transaction: &mut sqlx::Transaction<'_, Postgres>,
|
||||||
|
) -> Result<(), sqlx::Error> {
|
||||||
|
sqlx::query!(
|
||||||
|
"
|
||||||
|
INSERT INTO sessions (
|
||||||
|
session_id, user_id, token, expires_at, created_at
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
$1, $2, $3, $4, $5
|
||||||
|
)
|
||||||
|
",
|
||||||
|
&self.session_id,
|
||||||
|
&self.user_id,
|
||||||
|
&self.token,
|
||||||
|
&self.expires_at,
|
||||||
|
&self.created_at
|
||||||
|
)
|
||||||
|
.execute(&mut **transaction)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,54 @@
|
|||||||
|
use chrono::{DateTime, Duration, Utc};
|
||||||
|
|
||||||
|
use crate::auth::generate_session_token;
|
||||||
|
|
||||||
|
pub struct Session {
|
||||||
|
pub session_id: uuid::Uuid,
|
||||||
|
pub user_id: uuid::Uuid,
|
||||||
|
pub token: String,
|
||||||
|
pub expires_at: DateTime<Utc>,
|
||||||
|
pub created_at: DateTime<Utc>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Session {
|
||||||
|
pub fn new(user_id: uuid::Uuid) -> Self {
|
||||||
|
let session_id = uuid::Uuid::new_v4();
|
||||||
|
let token = generate_session_token();
|
||||||
|
|
||||||
|
let created_at = Utc::now();
|
||||||
|
let expires_at = Utc::now() + Duration::days(7);
|
||||||
|
|
||||||
|
return Self {
|
||||||
|
session_id,
|
||||||
|
user_id,
|
||||||
|
token,
|
||||||
|
expires_at,
|
||||||
|
created_at,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
use crate::database::model::Session as DbSession;
|
||||||
|
impl From<DbSession> for Session {
|
||||||
|
fn from(db_session: DbSession) -> Self {
|
||||||
|
Self {
|
||||||
|
session_id: db_session.session_id,
|
||||||
|
user_id: db_session.user_id,
|
||||||
|
token: db_session.token,
|
||||||
|
expires_at: db_session.expires_at,
|
||||||
|
created_at: db_session.created_at,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Session> for DbSession {
|
||||||
|
fn from(session: Session) -> Self {
|
||||||
|
Self {
|
||||||
|
session_id: session.session_id,
|
||||||
|
user_id: session.user_id,
|
||||||
|
token: session.token,
|
||||||
|
expires_at: session.expires_at,
|
||||||
|
created_at: session.created_at,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,8 +2,10 @@ use axum::{extract::State, routing::post, Json, Router};
|
|||||||
|
|
||||||
use crate::database::model::member::SearchMember;
|
use crate::database::model::member::SearchMember;
|
||||||
use crate::database::model::Member as DbMember;
|
use crate::database::model::Member as DbMember;
|
||||||
|
use crate::database::model::Session as DbSession;
|
||||||
use crate::database::model::User as DbUser;
|
use crate::database::model::User as DbUser;
|
||||||
use crate::database::model::UserMember as DbUserMember;
|
use crate::database::model::UserMember as DbUserMember;
|
||||||
|
use crate::model::session::Session;
|
||||||
use crate::{
|
use crate::{
|
||||||
auth::{generate_password_hash, Permissions},
|
auth::{generate_password_hash, Permissions},
|
||||||
AppState,
|
AppState,
|
||||||
@ -34,7 +36,7 @@ pub async fn register<'a>(
|
|||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
permissions: Permissions<'a>,
|
permissions: Permissions<'a>,
|
||||||
Json(auth_request): Json<AuthRequest>,
|
Json(auth_request): Json<AuthRequest>,
|
||||||
) -> Result<(), crate::Error> {
|
) -> Result<String, crate::Error> {
|
||||||
// Get all the members to link with the user
|
// Get all the members to link with the user
|
||||||
let members = DbMember::search(
|
let members = DbMember::search(
|
||||||
&state.pool,
|
&state.pool,
|
||||||
@ -61,7 +63,11 @@ pub async fn register<'a>(
|
|||||||
let user_ids: Vec<uuid::Uuid> = vec![user_id; member_ids.len()];
|
let user_ids: Vec<uuid::Uuid> = vec![user_id; member_ids.len()];
|
||||||
DbUserMember::insert_many(&mut transaction, &user_ids, &member_ids).await?;
|
DbUserMember::insert_many(&mut transaction, &user_ids, &member_ids).await?;
|
||||||
|
|
||||||
|
// Create a new session
|
||||||
|
let db_session: DbSession = Session::new(user_id).into();
|
||||||
|
db_session.insert(&mut transaction).await?;
|
||||||
|
|
||||||
transaction.commit().await?;
|
transaction.commit().await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(db_session.token)
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,19 @@
|
|||||||
use axum::{routing::post, Router};
|
use axum::{extract::State, routing::post, Router};
|
||||||
|
|
||||||
use crate::AppState;
|
use crate::{auth::Permissions, AppState};
|
||||||
|
|
||||||
pub mod migrate;
|
pub mod migrate;
|
||||||
|
|
||||||
pub fn routes() -> Router<AppState> {
|
pub fn routes() -> Router<AppState> {
|
||||||
Router::new()
|
Router::new()
|
||||||
.route("/members/migrate_request", post(migrate::migrate_request))
|
// .route("/members/migrate_request", post(migrate::migrate_request))
|
||||||
.route("/members/migrate_confirm", post(migrate::migrate_confirm))
|
// .route("/members/migrate_confirm", post(migrate::migrate_confirm))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_members<'a>(
|
||||||
|
State(state): State<AppState>,
|
||||||
|
permissions: Permissions<'a>,
|
||||||
|
body: String,
|
||||||
|
) -> Result<(), crate::Error> {
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user