Import and update the file service application and orizentic #72
|
@ -4,4 +4,6 @@ node_modules
|
|||
dist
|
||||
result
|
||||
*.tgz
|
||||
file-service/auth.sqlite
|
||||
file-service/*.sqlite
|
||||
file-service/*.sqlite-shm
|
||||
file-service/*.sqlite-wal
|
||||
|
|
|
@ -416,7 +416,7 @@ dependencies = [
|
|||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.29",
|
||||
"syn 2.0.37",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -471,6 +471,16 @@ version = "0.9.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f"
|
||||
|
||||
[[package]]
|
||||
name = "cookie"
|
||||
version = "0.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24"
|
||||
dependencies = [
|
||||
"time 0.3.29",
|
||||
"version_check 0.9.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cool_asserts"
|
||||
version = "2.0.3"
|
||||
|
@ -661,6 +671,12 @@ dependencies = [
|
|||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946"
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
|
@ -842,6 +858,7 @@ dependencies = [
|
|||
"bytes",
|
||||
"chrono",
|
||||
"clap 4.4.6",
|
||||
"cookie",
|
||||
"cool_asserts",
|
||||
"futures-util",
|
||||
"hex-string",
|
||||
|
@ -1744,7 +1761,7 @@ dependencies = [
|
|||
"log 0.3.9",
|
||||
"mime 0.2.6",
|
||||
"num_cpus",
|
||||
"time",
|
||||
"time 0.1.45",
|
||||
"traitobject",
|
||||
"typeable",
|
||||
"unicase 1.4.2",
|
||||
|
@ -2178,7 +2195,7 @@ checksum = "6c9172cb4c2f6c52117e25570983edcbb322f130b1031ae5d5d6b1abe7eeb493"
|
|||
dependencies = [
|
||||
"iron",
|
||||
"log 0.3.9",
|
||||
"time",
|
||||
"time 0.1.45",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3942,6 +3959,34 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "426f806f4089c493dcac0d24c29c01e2c38baf8e30f1b716ee37e83d200b18fe"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
"serde 1.0.188",
|
||||
"time-core",
|
||||
"time-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-core"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20"
|
||||
dependencies = [
|
||||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinystr"
|
||||
version = "0.7.4"
|
||||
|
|
|
@ -25,9 +25,12 @@ required-features = [ "auth-cli" ]
|
|||
[target.auth-cli.dependencies]
|
||||
|
||||
[dependencies]
|
||||
base64ct = { version = "1", features = [ "alloc" ] }
|
||||
build_html = { version = "2" }
|
||||
bytes = { version = "1" }
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
clap = { version = "4", features = [ "derive" ], optional = true }
|
||||
cookie = { version = "0.17" }
|
||||
futures-util = { version = "0.3" }
|
||||
hex-string = "0.1.0"
|
||||
http = { version = "0.2" }
|
||||
|
@ -45,8 +48,6 @@ thiserror = "1.0.20"
|
|||
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" }
|
||||
|
|
|
@ -10,9 +10,9 @@ pub async fn handle_index(
|
|||
token: Option<SessionToken>,
|
||||
) -> Result<Response<String>, Error> {
|
||||
match token {
|
||||
Some(token) => match app.auth_session(token).await {
|
||||
Some(token) => match app.validate_session(token).await {
|
||||
Ok(_) => render_gallery_page(app).await,
|
||||
Err(err) => render_auth_page(Some(format!("authentication refused: {:?}", err))),
|
||||
Err(err) => render_auth_page(Some(format!("session expired: {:?}", err))),
|
||||
},
|
||||
None => render_auth_page(None),
|
||||
}
|
||||
|
@ -76,10 +76,21 @@ pub async fn handle_auth(
|
|||
) -> Result<http::Response<String>, Error> {
|
||||
match form.get("token") {
|
||||
Some(token) => match app
|
||||
.auth_token(AuthToken::from(AuthToken::from(token.clone())))
|
||||
.authenticate(AuthToken::from(AuthToken::from(token.clone())))
|
||||
.await
|
||||
{
|
||||
Ok(_session_token) => render_gallery_page(app).await,
|
||||
Ok(Some(session_token)) => Response::builder()
|
||||
.header("location", "/")
|
||||
.header(
|
||||
"set-cookie",
|
||||
format!(
|
||||
"session={}; Secure; HttpOnly; SameSite=Strict",
|
||||
session_token.to_string()
|
||||
),
|
||||
)
|
||||
.status(StatusCode::SEE_OTHER)
|
||||
.body("".to_owned()),
|
||||
Ok(None) => render_auth_page(Some(format!("no user found"))),
|
||||
Err(_) => render_auth_page(Some(format!("invalid auth token"))),
|
||||
},
|
||||
None => render_auth_page(Some(format!("no token available"))),
|
||||
|
|
|
@ -6,9 +6,10 @@ use http::status::StatusCode;
|
|||
// use mustache::{compile_path, Template};
|
||||
// use orizentic::{Permissions, ResourceName, Secret};
|
||||
use bytes::Buf;
|
||||
use cookie::Cookie;
|
||||
use futures_util::StreamExt;
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
collections::{HashMap, HashSet},
|
||||
convert::Infallible,
|
||||
io::Read,
|
||||
net::{IpAddr, Ipv4Addr, SocketAddr},
|
||||
|
@ -126,12 +127,15 @@ impl App {
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn auth_token(&self, token: AuthToken) -> Result<Option<SessionToken>, AuthError> {
|
||||
self.authdb.read().await.auth_token(token).await
|
||||
pub async fn authenticate(&self, token: AuthToken) -> Result<Option<SessionToken>, AuthError> {
|
||||
self.authdb.read().await.authenticate(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 validate_session(
|
||||
&self,
|
||||
token: SessionToken,
|
||||
) -> Result<Option<Username>, AuthError> {
|
||||
self.authdb.read().await.validate_session(token).await
|
||||
}
|
||||
|
||||
pub async fn list_files(&self) -> Result<HashSet<FileId>, ReadFileError> {
|
||||
|
@ -159,9 +163,23 @@ fn maybe_with_session() -> impl Filter<Extract = (Option<SessionToken>,), Error
|
|||
{
|
||||
warp::any()
|
||||
.and(warp::header::optional::<String>("cookie"))
|
||||
.map(|cookies| {
|
||||
println!("cookies retrieved: {:?}", cookies);
|
||||
.map(|cookies| match cookies {
|
||||
Some(cookies) => {
|
||||
let c = Cookie::split_parse(cookies)
|
||||
.collect::<Result<Vec<Cookie>, cookie::ParseError>>();
|
||||
match c {
|
||||
Ok(cookies) => {
|
||||
for c in cookies {
|
||||
if c.name() == "session" {
|
||||
return Some(SessionToken::from(c.value()));
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
Err(_) => None,
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -278,7 +278,7 @@ impl AuthDB {
|
|||
Ok(usernames)
|
||||
}
|
||||
|
||||
pub async fn auth_token(&self, token: AuthToken) -> Result<Option<SessionToken>, AuthError> {
|
||||
pub async fn authenticate(&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)
|
||||
|
@ -308,7 +308,10 @@ impl AuthDB {
|
|||
Ok(Some(SessionToken::from(session_token)))
|
||||
}
|
||||
|
||||
pub async fn auth_session(&self, token: SessionToken) -> Result<Option<Username>, AuthError> {
|
||||
pub async fn validate_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",
|
||||
)
|
||||
|
@ -498,7 +501,7 @@ mod authdb_test {
|
|||
|
||||
let token = AuthToken::from("0000000000");
|
||||
|
||||
assert_matches!(db.auth_token(token).await, Ok(None));
|
||||
assert_matches!(db.authenticate(token).await, Ok(None));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
@ -511,7 +514,7 @@ mod authdb_test {
|
|||
.await
|
||||
.expect("user to be created");
|
||||
|
||||
assert_matches!(db.auth_token(token).await, Ok(_));
|
||||
assert_matches!(db.authenticate(token).await, Ok(_));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
@ -524,13 +527,13 @@ mod authdb_test {
|
|||
.await
|
||||
.expect("user to be created");
|
||||
let session = db
|
||||
.auth_token(token)
|
||||
.authenticate(token)
|
||||
.await
|
||||
.expect("token authentication should succeed")
|
||||
.expect("session token should be found");
|
||||
|
||||
assert_matches!(
|
||||
db.auth_session(session).await,
|
||||
db.validate_session(session).await,
|
||||
Ok(Some(username)) => {
|
||||
assert_eq!(username, Username::from("savanni"));
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue