Split out a support library

This commit is contained in:
Savanni D'Gerinel 2023-10-03 16:18:19 -04:00
parent f3940111c4
commit 1b161435df
6 changed files with 71 additions and 56 deletions

View File

@ -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" }

View File

@ -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,

6
file-service/src/lib.rs Normal file
View File

@ -0,0 +1,6 @@
mod store;
pub use store::{
AuthDB, AuthError, AuthToken, FileHandle, FileId, FileInfo, ReadFileError, SessionToken, Store,
Username, WriteFileError,
};

View File

@ -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<Username, warp::Rejection> {
@ -112,6 +112,45 @@ async fn handle_upload(
}
*/
#[derive(Clone)]
pub struct App {
authdb: Arc<RwLock<AuthDB>>,
store: Arc<RwLock<Store>>,
}
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<Option<SessionToken>, AuthError> {
self.authdb.read().await.auth_token(token).await
}
pub async fn auth_session(&self, token: SessionToken) -> Result<Option<Username>, AuthError> {
self.authdb.read().await.auth_session(token).await
}
pub async fn list_files(&self) -> Result<HashSet<FileId>, ReadFileError> {
self.store.read().await.list_files()
}
pub async fn get_file(&self, id: &FileId) -> Result<FileHandle, ReadFileError> {
self.store.read().await.get_file(id)
}
pub async fn add_file(
&self,
filename: String,
content: Vec<u8>,
) -> Result<FileHandle, WriteFileError> {
self.store.write().await.add_file(filename, content)
}
}
fn with_app(app: App) -> impl Filter<Extract = (App,), Error = Infallible> + Clone {
warp::any().map(move || app.clone())
}

View File

@ -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<String>) -> build_html::HtmlPage {
build_html::HtmlPage::new()

View File

@ -242,45 +242,6 @@ impl FileRoot for Context {
}
}
#[derive(Clone)]
pub struct App {
authdb: Arc<RwLock<AuthDB>>,
store: Arc<RwLock<Store>>,
}
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<Option<SessionToken>, AuthError> {
self.authdb.read().await.auth_token(token).await
}
pub async fn auth_session(&self, token: SessionToken) -> Result<Option<Username>, AuthError> {
self.authdb.read().await.auth_session(token).await
}
pub async fn list_files(&self) -> Result<HashSet<FileId>, ReadFileError> {
self.store.read().await.list_files()
}
pub async fn get_file(&self, id: &FileId) -> Result<FileHandle, ReadFileError> {
self.store.read().await.get_file(id)
}
pub async fn add_file(
&self,
filename: String,
content: Vec<u8>,
) -> Result<FileHandle, WriteFileError> {
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<AuthToken, AuthError> {
pub async fn add_user(&self, username: Username) -> Result<AuthToken, AuthError> {
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<Vec<Username>, AuthError> {
pub async fn list_users(&self) -> Result<Vec<Username>, 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<Option<SessionToken>, AuthError> {
pub async fn auth_token(&self, token: AuthToken) -> Result<Option<SessionToken>, 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<Option<Username>, AuthError> {
pub async fn auth_session(&self, token: SessionToken) -> Result<Option<Username>, AuthError> {
let rows = sqlx::query(
"SELECT users.username FROM sessions INNER JOIN users ON sessions.user_id = users.id WHERE sessions.token = $1",
)