diff --git a/file-service/Cargo.toml b/file-service/Cargo.toml index e026c4d..0aabb3c 100644 --- a/file-service/Cargo.toml +++ b/file-service/Cargo.toml @@ -6,6 +6,16 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[features] +auth-cli = [ "clap" ] + +[[bin]] +name = "auth-cli" +path = "src/bin/cli.rs" +required-features = [ "auth-cli" ] + +[target.auth-cli.dependencies] + [dependencies] build_html = { version = "2" } bytes = { version = "1" } @@ -28,6 +38,7 @@ tokio = { version = "1", features = [ "full" ] } uuid = { version = "0.4", features = [ "serde", "v4" ] } warp = { version = "0.3" } base64ct = { version = "1", features = [ "alloc" ] } +clap = { version = "4", features = [ "derive" ], optional = true } [dev-dependencies] cool_asserts = { version = "2" } diff --git a/file-service/src/handlers.rs b/file-service/src/handlers.rs index 7d8fb22..824d1da 100644 --- a/file-service/src/handlers.rs +++ b/file-service/src/handlers.rs @@ -1,9 +1,9 @@ use build_html::Html; use http::{Error, StatusCode}; -use std::{collections::HashMap, future::Future}; +use std::collections::HashMap; use warp::http::Response; -use crate::{pages, App, AuthToken, FileHandle, FileId, FileInfo, ReadFileError, SessionToken}; +use crate::{pages, App, AuthToken, FileId, FileInfo, ReadFileError, SessionToken}; pub async fn handle_index( app: App, diff --git a/file-service/src/lib.rs b/file-service/src/lib.rs new file mode 100644 index 0000000..a19f54c --- /dev/null +++ b/file-service/src/lib.rs @@ -0,0 +1,6 @@ +mod store; + +pub use store::{ + AuthDB, AuthError, AuthToken, FileHandle, FileId, FileInfo, ReadFileError, SessionToken, Store, + Username, WriteFileError, +}; diff --git a/file-service/src/main.rs b/file-service/src/main.rs index 6dd12f5..8c885de 100644 --- a/file-service/src/main.rs +++ b/file-service/src/main.rs @@ -8,25 +8,25 @@ use http::status::StatusCode; use bytes::Buf; use futures_util::StreamExt; use std::{ - collections::HashMap, + collections::HashSet, convert::Infallible, io::Read, net::{IpAddr, Ipv4Addr, SocketAddr}, path::PathBuf, - sync::{Arc, RwLock}, + sync::Arc, }; -use store::Username; +use tokio::sync::RwLock; use warp::{filters::multipart::Part, Filter, Rejection}; mod handlers; mod html; mod pages; -mod store; -pub use handlers::handle_index; -pub use store::{ - App, AuthDB, AuthToken, FileHandle, FileId, FileInfo, ReadFileError, SessionToken, Store, +pub use file_service::{ + AuthDB, AuthError, AuthToken, FileHandle, FileId, FileInfo, ReadFileError, SessionToken, Store, + Username, WriteFileError, }; +pub use handlers::handle_index; /* async fn authenticate_user(app: App, auth_token: String) -> Result { @@ -112,6 +112,45 @@ async fn handle_upload( } */ +#[derive(Clone)] +pub struct App { + authdb: Arc>, + store: Arc>, +} + +impl App { + pub fn new(authdb: AuthDB, store: Store) -> Self { + Self { + authdb: Arc::new(RwLock::new(authdb)), + store: Arc::new(RwLock::new(store)), + } + } + + pub async fn auth_token(&self, token: AuthToken) -> Result, AuthError> { + self.authdb.read().await.auth_token(token).await + } + + pub async fn auth_session(&self, token: SessionToken) -> Result, AuthError> { + self.authdb.read().await.auth_session(token).await + } + + pub async fn list_files(&self) -> Result, ReadFileError> { + self.store.read().await.list_files() + } + + pub async fn get_file(&self, id: &FileId) -> Result { + self.store.read().await.get_file(id) + } + + pub async fn add_file( + &self, + filename: String, + content: Vec, + ) -> Result { + self.store.write().await.add_file(filename, content) + } +} + fn with_app(app: App) -> impl Filter + Clone { warp::any().map(move || app.clone()) } diff --git a/file-service/src/pages.rs b/file-service/src/pages.rs index 45d5fdf..ba1b586 100644 --- a/file-service/src/pages.rs +++ b/file-service/src/pages.rs @@ -1,8 +1,6 @@ -use crate::{ - html::*, - store::{FileHandle, FileId, ReadFileError}, -}; +use crate::html::*; use build_html::{self, Container, ContainerType, Html, HtmlContainer}; +use file_service::{FileHandle, FileId, ReadFileError}; pub fn auth(_message: Option) -> build_html::HtmlPage { build_html::HtmlPage::new() diff --git a/file-service/src/store/mod.rs b/file-service/src/store/mod.rs index 7a60a0e..b5a1eeb 100644 --- a/file-service/src/store/mod.rs +++ b/file-service/src/store/mod.rs @@ -242,45 +242,6 @@ impl FileRoot for Context { } } -#[derive(Clone)] -pub struct App { - authdb: Arc>, - store: Arc>, -} - -impl App { - pub fn new(authdb: AuthDB, store: Store) -> Self { - Self { - authdb: Arc::new(RwLock::new(authdb)), - store: Arc::new(RwLock::new(store)), - } - } - - pub async fn auth_token(&self, token: AuthToken) -> Result, AuthError> { - self.authdb.read().await.auth_token(token).await - } - - pub async fn auth_session(&self, token: SessionToken) -> Result, AuthError> { - self.authdb.read().await.auth_session(token).await - } - - pub async fn list_files(&self) -> Result, ReadFileError> { - self.store.read().await.list_files() - } - - pub async fn get_file(&self, id: &FileId) -> Result { - self.store.read().await.get_file(id) - } - - pub async fn add_file( - &self, - filename: String, - content: Vec, - ) -> Result { - self.store.write().await.add_file(filename, content) - } -} - #[derive(Clone)] pub struct AuthDB { pool: SqlitePool, @@ -294,7 +255,7 @@ impl AuthDB { Ok(Self { pool }) } - async fn add_user(&self, username: Username) -> Result { + pub async fn add_user(&self, username: Username) -> Result { let mut hasher = Sha256::new(); hasher.update(Uuid::new_v4().hyphenated().to_string()); hasher.update(username.to_string()); @@ -309,7 +270,7 @@ impl AuthDB { Ok(AuthToken::from(auth_token)) } - async fn list_users(&self) -> Result, AuthError> { + pub async fn list_users(&self) -> Result, AuthError> { let usernames = sqlx::query_as::<_, Username>("SELECT (username) FROM users") .fetch_all(&self.pool) .await?; @@ -317,7 +278,7 @@ impl AuthDB { Ok(usernames) } - async fn auth_token(&self, token: AuthToken) -> Result, AuthError> { + pub async fn auth_token(&self, token: AuthToken) -> Result, AuthError> { let results = sqlx::query("SELECT * FROM users WHERE token = $1") .bind(token.to_string()) .fetch_all(&self.pool) @@ -347,7 +308,7 @@ impl AuthDB { Ok(Some(SessionToken::from(session_token))) } - async fn auth_session(&self, token: SessionToken) -> Result, AuthError> { + pub async fn auth_session(&self, token: SessionToken) -> Result, AuthError> { let rows = sqlx::query( "SELECT users.username FROM sessions INNER JOIN users ON sessions.user_id = users.id WHERE sessions.token = $1", )