Import and update the file service application and orizentic #72
|
@ -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" }
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
mod store;
|
||||
|
||||
pub use store::{
|
||||
AuthDB, AuthError, AuthToken, FileHandle, FileId, FileInfo, ReadFileError, SessionToken, Store,
|
||||
Username, WriteFileError,
|
||||
};
|
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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",
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue