feat: implement user login functionality with session management
Some checks failed
ci/woodpecker/push/check_fmt Pipeline failed

This commit is contained in:
Mika Bomm 2025-04-03 13:58:18 +02:00
parent 34d979da86
commit 4828b7e907
7 changed files with 37 additions and 10 deletions

View file

@ -0,0 +1,18 @@
meta {
name: Verify User
type: http
seq: 2
}
post {
url: {{api_base}}/auth/login
body: json
auth: inherit
}
body:json {
{
"username": "hure",
"password": "nüttchen"
}
}

View file

@ -25,6 +25,7 @@ sea-orm = { version = "1.1", features = [
"runtime-tokio-rustls", "runtime-tokio-rustls",
"macros", "macros",
] } ] }
uuid = "1"
dotenvy = "0.15" dotenvy = "0.15"

View file

@ -1,11 +1,11 @@
use actix_session::Session; use actix_session::Session;
use actix_web::{ use actix_web::{
HttpResponse, get, post, HttpResponse, Responder, post,
web::{self, ServiceConfig}, web::{self, ServiceConfig},
}; };
use serde::Deserialize; use serde::Deserialize;
use crate::error::ApiError; use crate::{Database, error::ApiError};
#[derive(Deserialize)] #[derive(Deserialize)]
struct LoginRequest { struct LoginRequest {
@ -19,10 +19,17 @@ pub fn setup(cfg: &mut ServiceConfig) {
#[post("/login")] #[post("/login")]
async fn login( async fn login(
db: web::Data<Database>,
login_request: web::Json<LoginRequest>, login_request: web::Json<LoginRequest>,
session: Session, session: Session,
) -> Result<HttpResponse, ApiError> { ) -> Result<impl Responder, ApiError> {
let login_request = login_request.into_inner(); let login_request = login_request.into_inner();
todo!() let user_id = db
.verify_local_user(&login_request.username, &login_request.password)
.await?;
session.insert("user", user_id)?;
Ok(HttpResponse::Ok())
} }

View file

@ -1,5 +1,5 @@
use actix_web::{Result, delete, get, post, put, web}; use actix_web::{Result, delete, get, post, put, web};
use sea_orm::prelude::Uuid; use uuid::Uuid;
use validator::Validate; use validator::Validate;
use crate::db::Database; use crate::db::Database;

View file

@ -4,9 +4,9 @@ use log::debug;
use crate::entity::project; use crate::entity::project;
use sea_orm::ActiveValue::{NotSet, Set, Unchanged}; use sea_orm::ActiveValue::{NotSet, Set, Unchanged};
use sea_orm::prelude::Uuid;
use sea_orm::{ActiveModelTrait, DeleteResult, EntityTrait}; use sea_orm::{ActiveModelTrait, DeleteResult, EntityTrait};
use serde::Deserialize; use serde::Deserialize;
use uuid::Uuid;
use validator::Validate; use validator::Validate;
#[derive(Deserialize, Validate)] #[derive(Deserialize, Validate)]

View file

@ -7,13 +7,11 @@ use sea_orm::{
ActiveModelTrait, ActiveModelTrait,
ActiveValue::{NotSet, Set}, ActiveValue::{NotSet, Set},
ColumnTrait, DbErr, EntityTrait, ModelTrait, QueryFilter, TransactionTrait, ColumnTrait, DbErr, EntityTrait, ModelTrait, QueryFilter, TransactionTrait,
prelude::Uuid,
}; };
use uuid::Uuid;
use crate::{Database, entity}; use crate::{Database, entity};
use super::entity::local_auth;
impl Database { impl Database {
pub async fn create_user( pub async fn create_user(
&self, &self,
@ -81,7 +79,7 @@ impl Database {
return Err(ApiError::Unauthorized); return Err(ApiError::Unauthorized);
} }
Ok(()) Ok(user.id)
} }
pub async fn verify_ldap_user() {} pub async fn verify_ldap_user() {}

View file

@ -16,6 +16,8 @@ pub enum ApiError {
ValidationError(#[from] validator::ValidationErrors), ValidationError(#[from] validator::ValidationErrors),
#[error("Argon2 Error: {0}")] #[error("Argon2 Error: {0}")]
Argon2Error(String), Argon2Error(String),
#[error("Session insert error: {0}")]
SessionInsertError(#[from] actix_session::SessionInsertError),
} }
impl ResponseError for ApiError { impl ResponseError for ApiError {
@ -27,6 +29,7 @@ impl ResponseError for ApiError {
ApiError::BadRequest(..) => StatusCode::BAD_REQUEST, ApiError::BadRequest(..) => StatusCode::BAD_REQUEST,
ApiError::ValidationError(..) => StatusCode::BAD_REQUEST, ApiError::ValidationError(..) => StatusCode::BAD_REQUEST,
ApiError::Argon2Error(..) => StatusCode::INTERNAL_SERVER_ERROR, ApiError::Argon2Error(..) => StatusCode::INTERNAL_SERVER_ERROR,
ApiError::SessionInsertError(..) => StatusCode::INTERNAL_SERVER_ERROR,
} }
} }