remove global config on oab

master
veypi 1 year ago
parent bd03910ab8
commit 72c864a854

@ -11,18 +11,18 @@ use serde::{Deserialize, Serialize};
use crate::{ use crate::{
models::{self, app}, models::{self, app},
Error, Result, CONFIG, AppState, Error, Result,
}; };
use chrono::NaiveDateTime; use chrono::NaiveDateTime;
#[get("/app/{id}")] #[get("/app/{id}")]
#[access_read("app")] #[access_read("app")]
pub async fn get(id: web::Path<String>) -> Result<impl Responder> { pub async fn get(id: web::Path<String>, stat: web::Data<AppState>) -> Result<impl Responder> {
let n = id.into_inner(); let n = id.into_inner();
if !n.is_empty() { if !n.is_empty() {
let s = sqlx::query_as::<_, app::Model>("select * from app where id = ?") let s = sqlx::query_as::<_, app::Model>("select * from app where id = ?")
.bind(n) .bind(n)
.fetch_one(CONFIG.sqlx()) .fetch_one(stat.sqlx())
.await?; .await?;
Ok(web::Json(s)) Ok(web::Json(s))
} else { } else {
@ -52,11 +52,11 @@ pub struct App {
#[get("/app/")] #[get("/app/")]
#[access_read("app")] #[access_read("app")]
pub async fn list() -> Result<impl Responder> { pub async fn list(stat: web::Data<AppState>) -> Result<impl Responder> {
let result = sqlx::query_as::<_, App>( let result = sqlx::query_as::<_, App>(
"select app.id,app.created, app.updated, app.icon, app.name, app.des, app.user_count, app.hide,app.join_method, app.role_id, app.redirect, app.status, app_user.status as u_status from app left join app_user on app_user.user_id = ? && app_user.app_id = app.id", "select app.id,app.created, app.updated, app.icon, app.name, app.des, app.user_count, app.hide,app.join_method, app.role_id, app.redirect, app.status, app_user.status as u_status from app left join app_user on app_user.user_id = ? && app_user.app_id = app.id",
).bind(_auth_token.id) ).bind(_auth_token.id)
.fetch_all(CONFIG.sqlx()) .fetch_all(stat.sqlx())
.await?; .await?;
Ok(web::Json(result)) Ok(web::Json(result))

@ -12,12 +12,15 @@ use tracing::info;
use crate::{ use crate::{
models::{self, app_user}, models::{self, app_user},
Error, Result, CONFIG, AppState, Error, Result,
}; };
#[get("/app/{aid}/user/{uid}")] #[get("/app/{aid}/user/{uid}")]
#[access_read("app")] #[access_read("app")]
pub async fn get(params: web::Path<(String, String)>) -> Result<impl Responder> { pub async fn get(
params: web::Path<(String, String)>,
stat: web::Data<AppState>,
) -> Result<impl Responder> {
let (mut aid, mut uid) = params.into_inner(); let (mut aid, mut uid) = params.into_inner();
if uid == "-" { if uid == "-" {
uid = "".to_string(); uid = "".to_string();
@ -35,7 +38,7 @@ pub async fn get(params: web::Path<(String, String)>) -> Result<impl Responder>
) )
.bind(aid) .bind(aid)
.bind(uid) .bind(uid)
.fetch_all(CONFIG.sqlx()) .fetch_all(stat.sqlx())
.await?; .await?;
Ok(web::Json(s)) Ok(web::Json(s))
} }

@ -9,7 +9,7 @@ use std::fmt::Debug;
use crate::{ use crate::{
models::{self, access, app, app_user, user, UserPlugin}, models::{self, access, app, app_user, user, UserPlugin},
AppState, Error, Result, CONFIG, AppState, Error, Result,
}; };
use actix_web::{delete, get, head, http, post, web, HttpResponse, Responder}; use actix_web::{delete, get, head, http, post, web, HttpResponse, Responder};
use base64; use base64;
@ -21,9 +21,9 @@ use tracing::info;
#[get("/user/{id}")] #[get("/user/{id}")]
#[access_read("user", id = "&id.clone()")] #[access_read("user", id = "&id.clone()")]
pub async fn get(id: web::Path<String>, data: web::Data<AppState>) -> Result<impl Responder> { pub async fn get(id: web::Path<String>, stat: web::Data<AppState>) -> Result<impl Responder> {
let n = id.into_inner(); let n = id.into_inner();
let db = &data.db; let db = stat.db();
if !n.is_empty() { if !n.is_empty() {
let d: Option<models::entity::user::Model> = let d: Option<models::entity::user::Model> =
models::entity::user::Entity::find_by_id(n).one(db).await?; models::entity::user::Entity::find_by_id(n).one(db).await?;
@ -35,26 +35,27 @@ pub async fn get(id: web::Path<String>, data: web::Data<AppState>) -> Result<imp
#[get("/user/")] #[get("/user/")]
#[access_read("user")] #[access_read("user")]
pub async fn list() -> Result<impl Responder> { pub async fn list(stat: web::Data<AppState>) -> Result<impl Responder> {
let result = sqlx::query!( let res: Vec<user::Model> = user::Entity::find().all(stat.db()).await?;
"select id,updated,created,username,nickname,email,icon,status, used, space from user", // let result = sqlx::query!(
) // "select id,updated,created,username,nickname,email,icon,status, used, space from user",
.map(|row| models::user::Model { // )
id: row.id, // .map(|row| models::user::Model {
created: row.created, // id: row.id,
updated: row.updated, // created: row.created,
username: row.username, // updated: row.updated,
nickname: row.nickname, // username: row.username,
email: row.email, // nickname: row.nickname,
status: row.status, // email: row.email,
used: row.used, // status: row.status,
space: row.space, // used: row.used,
icon: row.icon, // space: row.space,
..Default::default() // icon: row.icon,
}) // ..Default::default()
.fetch_all(CONFIG.sqlx()) // })
.await?; // .fetch_all(CONFIG.sqlx())
Ok(web::Json(result)) // .await?;
Ok(web::Json(res))
} }
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Deserialize, Serialize)]
@ -67,9 +68,9 @@ pub struct LoginOpt {
pub async fn login( pub async fn login(
q: web::Query<LoginOpt>, q: web::Query<LoginOpt>,
id: web::Path<String>, id: web::Path<String>,
data: web::Data<AppState>, stat: web::Data<AppState>,
) -> Result<HttpResponse> { ) -> Result<HttpResponse> {
let db = &data.db; let db = stat.db();
let id = id.into_inner(); let id = id.into_inner();
let q = q.into_inner(); let q = q.into_inner();
let filter = match q.typ { let filter = match q.typ {
@ -96,7 +97,7 @@ pub async fn login(
u.check_pass(p)?; u.check_pass(p)?;
let au: Option<app_user::Model> = app_user::Entity::find() let au: Option<app_user::Model> = app_user::Entity::find()
.filter(app_user::Column::AppId.eq(&CONFIG.uuid)) .filter(app_user::Column::AppId.eq(&stat.uuid))
.filter(app_user::Column::UserId.eq(&u.id)) .filter(app_user::Column::UserId.eq(&u.id))
.one(db) .one(db)
.await?; .await?;
@ -121,7 +122,7 @@ pub async fn login(
} }
}, },
None => { None => {
let app_obj: app::Model = app::Entity::find_by_id(CONFIG.uuid.clone()) let app_obj: app::Model = app::Entity::find_by_id(stat.uuid.clone())
.one(db) .one(db)
.await? .await?
.unwrap(); .unwrap();
@ -143,7 +144,7 @@ values ( ?, ?, ? )
.bind(&app_obj.id) .bind(&app_obj.id)
.bind(&u.id) .bind(&u.id)
.bind(&s) .bind(&s)
.execute(CONFIG.sqlx()) .execute(stat.sqlx())
.await?; .await?;
match s { match s {
models::AUStatus::OK => 0, models::AUStatus::OK => 0,
@ -157,15 +158,15 @@ values ( ?, ?, ? )
"select access.name,access.rid,access.level from access, user_role, role WHERE user_role.user_id = ? && access.role_id=user_role.role_id && role.id=user_role.role_id && role.app_id = ?", "select access.name,access.rid,access.level from access, user_role, role WHERE user_role.user_id = ? && access.role_id=user_role.role_id && role.id=user_role.role_id && role.app_id = ?",
) )
.bind(&u.id) .bind(&u.id)
.bind(CONFIG.uuid.clone()) .bind(stat.uuid.clone())
.fetch_all(CONFIG.sqlx()) .fetch_all(stat.sqlx())
.await?; .await?;
Ok(HttpResponse::build(http::StatusCode::OK) Ok(HttpResponse::build(http::StatusCode::OK)
.insert_header(("auth_token", u.token(result).to_string()?)) .insert_header(("auth_token", u.token(result).to_string()?))
.body("".to_string())) .body("".to_string()))
} else { } else {
Ok(HttpResponse::build(http::StatusCode::OK) Ok(HttpResponse::build(http::StatusCode::OK)
.insert_header(("data", "applying")) .insert_header(("stat", "applying"))
.body("".to_string())) .body("".to_string()))
} }
} }
@ -177,14 +178,14 @@ pub struct RegisterOpt {
} }
#[post("/user/")] #[post("/user/")]
pub async fn register(q: web::Json<RegisterOpt>) -> Result<String> { pub async fn register(q: web::Json<RegisterOpt>, stat: web::Data<AppState>) -> Result<String> {
let q = q.into_inner(); let q = q.into_inner();
// let mut tx = dbtx().await; // let mut tx = dbtx().await;
info!("{:#?}", q); info!("{:#?}", q);
let u: Option<models::user::Model> = let u: Option<models::user::Model> =
sqlx::query_as::<_, models::user::Model>("select * from user where username = ?") sqlx::query_as::<_, models::user::Model>("select * from user where username = ?")
.bind(q.username.clone()) .bind(q.username.clone())
.fetch_optional(CONFIG.sqlx()) .fetch_optional(stat.sqlx())
.await?; .await?;
let u: models::user::Model = match u { let u: models::user::Model = match u {
Some(_) => return Err(Error::ArgDuplicated(format!("username: {}", q.username))), Some(_) => return Err(Error::ArgDuplicated(format!("username: {}", q.username))),
@ -209,8 +210,8 @@ pub async fn register(q: web::Json<RegisterOpt>) -> Result<String> {
} }
}; };
let oa: app::Model = sqlx::query_as::<_, app::Model>("select * from app where id = ?") let oa: app::Model = sqlx::query_as::<_, app::Model>("select * from app where id = ?")
.bind(CONFIG.uuid.clone()) .bind(stat.uuid.clone())
.fetch_one(CONFIG.sqlx()) .fetch_one(stat.sqlx())
.await?; .await?;
let mut au = app_user::Model::default(); let mut au = app_user::Model::default();
@ -223,7 +224,7 @@ pub async fn register(q: web::Json<RegisterOpt>) -> Result<String> {
} }
models::AppJoin::Applying => au.status = models::AUStatus::Applying as i32, models::AppJoin::Applying => au.status = models::AUStatus::Applying as i32,
} }
let mut c = CONFIG.sqlx().begin().await?; let mut c = stat.sqlx().begin().await?;
// 创建用户 // 创建用户
sqlx::query!( sqlx::query!(
r#" r#"

@ -25,9 +25,9 @@ lazy_static! {
pub static ref CLI: AppCli = AppCli::new(); pub static ref CLI: AppCli = AppCli::new();
} }
lazy_static! { // lazy_static! {
pub static ref CONFIG: ApplicationConfig = ApplicationConfig::new(); // pub static ref CONFIG: ApplicationConfig = ApplicationConfig::new();
} // }
#[derive(Debug, Parser)] #[derive(Debug, Parser)]
#[clap(name = "oab")] #[clap(name = "oab")]
@ -58,13 +58,14 @@ impl AppCli {
} }
} }
#[derive(Debug, Clone)] #[derive(Debug, serde::Serialize, serde::Deserialize, Clone)]
pub struct AppState { pub struct ApplicationConfig {
#[serde(skip)]
pub db: DatabaseConnection, pub db: DatabaseConnection,
} }
#[derive(Debug, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct ApplicationConfig { pub struct AppState {
pub uuid: String, pub uuid: String,
pub key: String, pub key: String,
pub debug: bool, pub debug: bool,
@ -82,10 +83,12 @@ pub struct ApplicationConfig {
pub jwt_secret: Option<String>, pub jwt_secret: Option<String>,
#[serde(skip)] #[serde(skip)]
pub sqlx_pool: Option<Pool<sqlx::MySql>>, pub _sqlx: Option<Pool<sqlx::MySql>>,
#[serde(skip)]
pub _db: Option<DatabaseConnection>,
} }
impl ApplicationConfig { impl AppState {
pub fn new() -> Self { pub fn new() -> Self {
let mut res = Self::defaut(); let mut res = Self::defaut();
let mut f = match File::open(CLI.cfg.clone()) { let mut f = match File::open(CLI.cfg.clone()) {
@ -126,29 +129,37 @@ impl ApplicationConfig {
log_pack_compress: None, log_pack_compress: None,
log_level: None, log_level: None,
jwt_secret: None, jwt_secret: None,
sqlx_pool: None, _sqlx: None,
_db: None,
} }
} }
pub fn save(&self) {} pub fn save(&self) {}
pub fn db(&self) -> &DatabaseConnection {
match &self._db {
Some(d) => d,
None => panic!("failed"),
}
}
pub fn sqlx(&self) -> &sqlx::MySqlPool { pub fn sqlx(&self) -> &sqlx::MySqlPool {
match &self.sqlx_pool { match &self._sqlx {
Some(d) => d, Some(d) => d,
None => panic!("failed"), None => panic!("failed"),
} }
} }
fn connect_sqlx(&mut self) -> Result<()> {
pub fn connect_sqlx(&mut self) -> Result<()> {
let url = format!( let url = format!(
"mysql://{}:{}@{}/{}", "mysql://{}:{}@{}/{}",
self.db_user, self.db_pass, self.db_url, self.db_name self.db_user, self.db_pass, self.db_url, self.db_name
); );
let p = MySqlPoolOptions::new() let p = MySqlPoolOptions::new()
.max_connections(5) .max_connections(5)
.connect_lazy(&url) .connect_lazy(&url)?;
.unwrap(); self._sqlx = Some(p);
self.sqlx_pool = Some(p);
Ok(()) Ok(())
} }
pub async fn connect(&self) -> Result<DatabaseConnection> { pub async fn connect(&mut self) -> Result<()> {
let url = format!( let url = format!(
"mysql://{}:{}@{}/{}", "mysql://{}:{}@{}/{}",
self.db_user, self.db_pass, self.db_url, self.db_name self.db_user, self.db_pass, self.db_url, self.db_name
@ -161,8 +172,9 @@ impl ApplicationConfig {
.idle_timeout(Duration::from_secs(8)) .idle_timeout(Duration::from_secs(8))
.max_lifetime(Duration::from_secs(8)); .max_lifetime(Duration::from_secs(8));
let db = Database::connect(opt).await?; self._db = Some(Database::connect(opt).await?);
Ok(db)
Ok(())
} }
} }

@ -10,5 +10,5 @@ mod cfg;
pub mod libs; pub mod libs;
pub mod models; pub mod models;
mod result; mod result;
pub use cfg::{init_log, AppState, ApplicationConfig, Clis, CLI, CONFIG}; pub use cfg::{init_log, AppState, ApplicationConfig, Clis, CLI};
pub use result::{Error, Result}; pub use result::{Error, Result};

@ -13,29 +13,31 @@ use actix_web::{
App, HttpServer, App, HttpServer,
}; };
use oab::{api, init_log, libs, models, AppState, Clis, Result, CLI, CONFIG}; use oab::{api, init_log, libs, models, AppState, Clis, Result, CLI};
use tracing::{error, info, warn}; use tracing::{error, info, warn};
#[tokio::main] #[tokio::main]
async fn main() -> Result<()> { async fn main() -> Result<()> {
init_log(); init_log();
let mut data = AppState::new();
data.connect().await?;
data.connect_sqlx()?;
if let Some(c) = &CLI.command { if let Some(c) = &CLI.command {
match c { match c {
Clis::Init => { Clis::Init => {
models::init().await; models::init(data).await;
return Ok(()); return Ok(());
} }
_ => {} _ => {}
}; };
}; };
web().await?; web(data).await?;
Ok(()) Ok(())
} }
async fn web() -> Result<()> { async fn web(data: AppState) -> Result<()> {
let db = CONFIG.connect().await?;
let data = AppState { db };
std::env::set_var("RUST_LOG", "info"); std::env::set_var("RUST_LOG", "info");
std::env::set_var("RUST_BACKTRACE", "1"); std::env::set_var("RUST_BACKTRACE", "1");
let url = data.server_url.clone();
let serv = HttpServer::new(move || { let serv = HttpServer::new(move || {
let logger = middleware::Logger::default(); let logger = middleware::Logger::default();
let json_config = web::JsonConfig::default() let json_config = web::JsonConfig::default()
@ -53,7 +55,7 @@ async fn web() -> Result<()> {
let app = App::new(); let app = App::new();
app.wrap(logger) app.wrap(logger)
.wrap(middleware::Compress::default()) .wrap(middleware::Compress::default())
.service(fs::Files::new("/media", CONFIG.media_path.clone()).show_files_listing()) .service(fs::Files::new("/media", data.media_path.clone()).show_files_listing())
.service( .service(
web::scope("api") web::scope("api")
.app_data(web::Data::new(data.clone())) .app_data(web::Data::new(data.clone()))
@ -66,8 +68,8 @@ async fn web() -> Result<()> {
.configure(api::routes), .configure(api::routes),
) )
}); });
info!("listen to {}", CONFIG.server_url); info!("listen to {}", url);
serv.bind(CONFIG.server_url.clone())?.run().await?; serv.bind(url)?.run().await?;
Ok(()) Ok(())
} }

@ -16,9 +16,9 @@ pub use app_plugin::{AUStatus, AppJoin};
pub use entity::{access, app, app_user, user}; pub use entity::{access, app, app_user, user};
pub use user_plugin::{AccessLevel, Token, UserPlugin}; pub use user_plugin::{AccessLevel, Token, UserPlugin};
use crate::CONFIG; use crate::AppState;
pub async fn init() { pub async fn init(data: AppState) {
info!("init database"); info!("init database");
sqlx::migrate!().run(CONFIG.sqlx()).await.unwrap(); sqlx::migrate!().run(data.sqlx()).await.unwrap();
} }

Loading…
Cancel
Save