2025-11-05 08:06:18 -03:00
|
|
|
|
2025-10-31 15:40:52 -03:00
|
|
|
use actix_web::{HttpRequest, HttpResponse, Result, web};
|
2025-11-04 23:11:33 -03:00
|
|
|
use log::error;
|
2025-10-18 12:01:39 -03:00
|
|
|
use std::collections::HashMap;
|
2025-10-06 10:30:17 -03:00
|
|
|
use std::sync::Arc;
|
|
|
|
|
use uuid::Uuid;
|
2025-10-18 12:01:39 -03:00
|
|
|
use crate::shared::state::AppState;
|
2025-10-12 13:27:48 -03:00
|
|
|
|
2025-11-04 23:11:33 -03:00
|
|
|
pub struct AuthService {}
|
2025-10-06 10:30:17 -03:00
|
|
|
|
|
|
|
|
impl AuthService {
|
2025-11-04 23:11:33 -03:00
|
|
|
pub fn new() -> Self {
|
|
|
|
|
Self {}
|
2025-11-01 17:56:53 -03:00
|
|
|
}
|
2025-10-06 10:30:17 -03:00
|
|
|
}
|
2025-10-18 12:01:39 -03:00
|
|
|
|
|
|
|
|
#[actix_web::get("/api/auth")]
|
|
|
|
|
async fn auth_handler(
|
2025-11-01 20:53:45 -03:00
|
|
|
_req: HttpRequest,
|
2025-10-18 12:01:39 -03:00
|
|
|
data: web::Data<AppState>,
|
|
|
|
|
web::Query(params): web::Query<HashMap<String, String>>,
|
|
|
|
|
) -> Result<HttpResponse> {
|
2025-11-01 17:56:53 -03:00
|
|
|
let bot_name = params.get("bot_name").cloned().unwrap_or_default();
|
2025-11-04 23:11:33 -03:00
|
|
|
let _token = params.get("token").cloned();
|
2025-10-21 22:43:28 -03:00
|
|
|
|
|
|
|
|
let user_id = {
|
|
|
|
|
let mut sm = data.session_manager.lock().await;
|
2025-11-04 23:11:33 -03:00
|
|
|
sm.get_or_create_anonymous_user(None).map_err(|e| {
|
|
|
|
|
error!("Failed to create anonymous user: {}", e);
|
|
|
|
|
actix_web::error::ErrorInternalServerError("Failed to create user")
|
|
|
|
|
})?
|
2025-10-21 22:43:28 -03:00
|
|
|
};
|
|
|
|
|
|
2025-11-04 23:11:33 -03:00
|
|
|
let (bot_id, bot_name) = tokio::task::spawn_blocking({
|
|
|
|
|
let bot_name = bot_name.clone();
|
|
|
|
|
let conn_arc = Arc::clone(&data.conn);
|
|
|
|
|
move || {
|
|
|
|
|
let mut db_conn = conn_arc.lock().unwrap();
|
|
|
|
|
use crate::shared::models::schema::bots::dsl::*;
|
|
|
|
|
use diesel::prelude::*;
|
|
|
|
|
|
|
|
|
|
match bots
|
|
|
|
|
.filter(name.eq(&bot_name))
|
|
|
|
|
.filter(is_active.eq(true))
|
|
|
|
|
.select((id, name))
|
|
|
|
|
.first::<(Uuid, String)>(&mut *db_conn)
|
|
|
|
|
.optional()
|
|
|
|
|
{
|
|
|
|
|
Ok(Some((id_val, name_val))) => Ok((id_val, name_val)),
|
|
|
|
|
Ok(None) => {
|
|
|
|
|
match bots
|
|
|
|
|
.filter(is_active.eq(true))
|
|
|
|
|
.select((id, name))
|
|
|
|
|
.first::<(Uuid, String)>(&mut *db_conn)
|
|
|
|
|
.optional()
|
|
|
|
|
{
|
|
|
|
|
Ok(Some((id_val, name_val))) => Ok((id_val, name_val)),
|
|
|
|
|
Ok(None) => Err("No active bots found".to_string()),
|
|
|
|
|
Err(e) => Err(format!("DB error: {}", e)),
|
2025-11-01 17:56:53 -03:00
|
|
|
}
|
|
|
|
|
}
|
2025-11-04 23:11:33 -03:00
|
|
|
Err(e) => Err(format!("DB error: {}", e)),
|
2025-11-01 17:56:53 -03:00
|
|
|
}
|
|
|
|
|
}
|
2025-11-04 23:11:33 -03:00
|
|
|
})
|
|
|
|
|
.await
|
|
|
|
|
.map_err(|e| {
|
|
|
|
|
error!("Spawn blocking failed: {}", e);
|
|
|
|
|
actix_web::error::ErrorInternalServerError("DB thread error")
|
|
|
|
|
})?
|
|
|
|
|
.map_err(|e| {
|
|
|
|
|
error!("{}", e);
|
|
|
|
|
actix_web::error::ErrorInternalServerError(e)
|
|
|
|
|
})?;
|
2025-10-18 12:01:39 -03:00
|
|
|
|
|
|
|
|
let session = {
|
|
|
|
|
let mut sm = data.session_manager.lock().await;
|
2025-11-04 23:11:33 -03:00
|
|
|
sm.get_or_create_user_session(user_id, bot_id, "Auth Session")
|
|
|
|
|
.map_err(|e| {
|
2025-10-18 12:01:39 -03:00
|
|
|
error!("Failed to create session: {}", e);
|
2025-11-04 23:11:33 -03:00
|
|
|
actix_web::error::ErrorInternalServerError(e.to_string())
|
|
|
|
|
})?
|
|
|
|
|
.ok_or_else(|| {
|
|
|
|
|
error!("Failed to create session");
|
|
|
|
|
actix_web::error::ErrorInternalServerError("Failed to create session")
|
|
|
|
|
})?
|
2025-10-18 12:01:39 -03:00
|
|
|
};
|
2025-11-04 23:11:33 -03:00
|
|
|
|
2025-10-31 15:40:52 -03:00
|
|
|
let auth_script_path = format!("./work/{}.gbai/{}.gbdialog/auth.ast", bot_name, bot_name);
|
2025-11-04 23:11:33 -03:00
|
|
|
|
|
|
|
|
if tokio::fs::metadata(&auth_script_path).await.is_ok() {
|
|
|
|
|
let auth_script = match tokio::fs::read_to_string(&auth_script_path).await {
|
2025-10-31 15:40:52 -03:00
|
|
|
Ok(content) => content,
|
|
|
|
|
Err(e) => {
|
|
|
|
|
error!("Failed to read auth script: {}", e);
|
2025-11-04 23:11:33 -03:00
|
|
|
return Ok(HttpResponse::Ok().json(serde_json::json!({
|
|
|
|
|
"user_id": session.user_id,
|
|
|
|
|
"session_id": session.id,
|
|
|
|
|
"status": "authenticated"
|
|
|
|
|
})));
|
2025-10-31 15:40:52 -03:00
|
|
|
}
|
|
|
|
|
};
|
2025-10-18 12:01:39 -03:00
|
|
|
|
2025-10-31 15:40:52 -03:00
|
|
|
let script_service = crate::basic::ScriptService::new(Arc::clone(&data), session.clone());
|
2025-11-04 23:11:33 -03:00
|
|
|
|
|
|
|
|
match tokio::time::timeout(
|
|
|
|
|
std::time::Duration::from_secs(5),
|
|
|
|
|
async {
|
|
|
|
|
script_service
|
|
|
|
|
.compile(&auth_script)
|
|
|
|
|
.and_then(|ast| script_service.run(&ast))
|
|
|
|
|
}
|
|
|
|
|
).await {
|
|
|
|
|
Ok(Ok(result)) => {
|
2025-10-31 15:40:52 -03:00
|
|
|
if result.to_string() == "false" {
|
2025-11-04 23:11:33 -03:00
|
|
|
error!("Auth script returned false");
|
2025-10-31 15:40:52 -03:00
|
|
|
return Ok(HttpResponse::Unauthorized()
|
|
|
|
|
.json(serde_json::json!({"error": "Authentication failed"})));
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-11-04 23:11:33 -03:00
|
|
|
Ok(Err(e)) => {
|
|
|
|
|
error!("Auth script execution error: {}", e);
|
2025-10-18 12:01:39 -03:00
|
|
|
}
|
2025-11-04 23:11:33 -03:00
|
|
|
Err(_) => {
|
|
|
|
|
error!("Auth script timeout");
|
2025-10-18 12:01:39 -03:00
|
|
|
}
|
|
|
|
|
}
|
2025-11-04 23:11:33 -03:00
|
|
|
}
|
2025-10-18 12:01:39 -03:00
|
|
|
|
|
|
|
|
Ok(HttpResponse::Ok().json(serde_json::json!({
|
|
|
|
|
"user_id": session.user_id,
|
|
|
|
|
"session_id": session.id,
|
|
|
|
|
"status": "authenticated"
|
|
|
|
|
})))
|
|
|
|
|
}
|
2025-11-05 08:06:18 -03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
pub mod auth_test;
|