This repository has been archived on 2024-08-23. You can view files and clone it, but cannot push or open issues or pull requests.
project/src/main.rs
2024-07-28 09:37:39 +03:00

122 lines
2.9 KiB
Rust

mod auth;
mod db;
mod endpoints;
mod errors;
mod file_storage;
mod prelude;
use std::{env, net::Ipv4Addr};
use axum::{routing::get, Router};
use file_storage::FileStorage;
use tokio::net::TcpListener;
type Pool = sqlx::postgres::PgPool;
#[derive(Clone)]
struct AppState {
pool: Pool,
storage: FileStorage,
}
async fn create_user(user_name: &str, user_email: &str, pool: &Pool) -> anyhow::Result<i32> {
let id = sqlx::query!(
"INSERT INTO users(username, email) VALUES ($1, $2) RETURNING user_id",
user_name,
user_email
)
.fetch_one(pool)
.await?
.user_id;
sqlx::query!(
"INSERT INTO folders(owner_id, folder_name) VALUES ($1, $2)",
id,
"ROOT"
)
.execute(pool)
.await?;
Ok(id)
}
async fn create_debug_users(pool: &Pool) -> anyhow::Result<()> {
let count = sqlx::query!("SELECT count(user_id) FROM users")
.fetch_one(pool)
.await?
.count
.unwrap_or(0);
if count > 0 {
return Ok(());
}
tokio::try_join!(
create_user("Test1", "test1@example.com", pool),
create_user("Test2", "test2@example.com", pool)
)?;
Ok(())
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// TODO: add utoipa and utoipauto for swagger
let _ = dotenvy::dotenv();
tracing_subscriber::fmt::init();
let pool = match env::var("DATABASE_URL") {
Ok(url) => Pool::connect(&url).await?,
Err(err) => anyhow::bail!("Error getting database url: {err}"),
};
sqlx::migrate!().run(&pool).await?;
create_debug_users(&pool).await?;
let storage = file_storage::FileStorage::new()?;
let state = AppState { pool, storage };
let router = app(state);
let addr = (Ipv4Addr::UNSPECIFIED, 3000);
let listener = TcpListener::bind(addr).await?;
axum::serve(listener, router).await?;
Ok(())
}
fn app(state: AppState) -> Router {
use axum::http::header;
use endpoints::{file, folder, permissions};
use tower_http::ServiceBuilderExt as _;
let sensitive_headers = [header::AUTHORIZATION, header::COOKIE];
let middleware = tower::ServiceBuilder::new()
.sensitive_headers(sensitive_headers)
.trace_for_http()
.compression();
// Build route service
Router::new()
.route(
"/files",
get(file::download::download)
.post(file::upload::upload)
.delete(file::delete::delete)
.patch(file::modify::modify),
)
.route(
"/folders",
get(folder::list::list)
.post(folder::create::create)
.delete(folder::delete::delete),
)
.route(
"/permissions",
get(permissions::get::get)
.post(permissions::set::set)
.delete(permissions::delete::delete),
)
.layer(middleware)
.with_state(state)
}