This commit is contained in:
Paul Zinselmeyer 2023-10-20 00:40:24 +02:00
parent cd56e93cb0
commit a8180ba55b
Signed by: pfzetto
GPG key ID: 4EEF46A5B276E648
3 changed files with 54 additions and 24 deletions

26
Cargo.lock generated
View file

@ -181,19 +181,17 @@ dependencies = [
[[package]] [[package]]
name = "axum_oidc" name = "axum_oidc"
version = "0.1.0" version = "0.1.0"
source = "git+https://git2.zettoit.eu/pfz4/axum_oidc#89da8cc07fba48a9adcd5821fbc7c527c60ec802" source = "git+https://git2.zettoit.eu/pfz4/axum_oidc#3b9438d1f3cf58c1edb9f503aea4e6d7783194d2"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"axum", "axum",
"axum-extra", "axum-extra",
"futures-util",
"jsonwebtoken", "jsonwebtoken",
"openidconnect", "openidconnect",
"reqwest", "reqwest",
"serde", "serde",
"serde_json", "serde_json",
"thiserror", "thiserror",
"tower",
] ]
[[package]] [[package]]
@ -807,9 +805,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.14.1" version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156"
[[package]] [[package]]
name = "headers" name = "headers"
@ -1006,7 +1004,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897"
dependencies = [ dependencies = [
"equivalent", "equivalent",
"hashbrown 0.14.1", "hashbrown 0.14.2",
"serde", "serde",
] ]
@ -1728,9 +1726,9 @@ dependencies = [
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "0.38.19" version = "0.38.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "745ecfa778e66b2b63c88a61cb36e0eea109e803b0b86bf9879fbc77c70e86ed" checksum = "67ce50cb2e16c2903e30d1cbccfd8387a74b9d4c938b6a4c5ec6cc7556f7a8a0"
dependencies = [ dependencies = [
"bitflags 2.4.1", "bitflags 2.4.1",
"errno", "errno",
@ -2114,18 +2112,18 @@ dependencies = [
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.49" version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.49" version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -2294,9 +2292,9 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
[[package]] [[package]]
name = "tracing" name = "tracing"
version = "0.1.39" version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee2ef2af84856a50c1d430afce2fdded0a4ec7eda868db86409b4543df0797f9" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
dependencies = [ dependencies = [
"log", "log",
"pin-project-lite", "pin-project-lite",

View file

@ -1,4 +1,7 @@
use axum::{http::StatusCode, response::IntoResponse}; use axum::{
http::StatusCode,
response::{IntoResponse, Response},
};
use log::error; use log::error;
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
@ -26,18 +29,24 @@ pub enum Error {
#[error("encryption error")] #[error("encryption error")]
ChaCha, ChaCha,
#[error("oidc redirect")]
Oidc(Response),
} }
impl IntoResponse for Error { impl IntoResponse for Error {
fn into_response(self) -> axum::response::Response { fn into_response(self) -> axum::response::Response {
match self { match self {
Self::PhraseInvalid => (StatusCode::BAD_REQUEST, "url is not valid\n"), Self::PhraseInvalid => (StatusCode::BAD_REQUEST, "url is not valid\n").into_response(),
Self::BinNotFound => (StatusCode::NOT_FOUND, "bin does not exist\n"), Self::BinNotFound => (StatusCode::NOT_FOUND, "bin does not exist\n").into_response(),
Self::DataFileExists => (StatusCode::CONFLICT, "bin already contains data\n"), Self::DataFileExists => {
Self::ParseTtl => (StatusCode::BAD_REQUEST, "invalid ttl class\n"), (StatusCode::CONFLICT, "bin already contains data\n").into_response()
}
Self::ParseTtl => (StatusCode::BAD_REQUEST, "invalid ttl class\n").into_response(),
Self::Oidc(response) => response.into_response(),
_ => { _ => {
error!("{:?}", self); error!("{:?}", self);
(StatusCode::INTERNAL_SERVER_ERROR, "internal server error\n") (StatusCode::INTERNAL_SERVER_ERROR, "internal server error\n").into_response()
} }
} }
.into_response() .into_response()

View file

@ -12,11 +12,14 @@ use axum::{
extract::{BodyStream, FromRef, Path, Query, State}, extract::{BodyStream, FromRef, Path, Query, State},
headers::ContentType, headers::ContentType,
http::{header, HeaderMap, StatusCode}, http::{header, HeaderMap, StatusCode},
response::{Html, IntoResponse, Redirect}, response::{Html, IntoResponse, Redirect, Response},
routing::get, routing::get,
Router, TypedHeader, Router, TypedHeader,
}; };
use axum_oidc::oidc::{self, EmptyAdditionalClaims, OidcApplication, OidcExtractor}; use axum_oidc::{
jwt::{Claims, JwtApplication},
oidc::{self, EmptyAdditionalClaims, OidcApplication, OidcExtractor},
};
use chacha20::{ use chacha20::{
cipher::{KeyIvInit, StreamCipher}, cipher::{KeyIvInit, StreamCipher},
ChaCha20, ChaCha20,
@ -55,6 +58,7 @@ type HandlerResult<T> = Result<T, Error>;
pub struct AppState { pub struct AppState {
application_base: String, application_base: String,
oidc_application: OidcApplication<EmptyAdditionalClaims>, oidc_application: OidcApplication<EmptyAdditionalClaims>,
jwt_application: JwtApplication<EmptyAdditionalClaims>,
data: String, data: String,
key_salt: KeySalt, key_salt: KeySalt,
id_salt: IdSalt, id_salt: IdSalt,
@ -67,6 +71,12 @@ impl FromRef<AppState> for OidcApplication<EmptyAdditionalClaims> {
} }
} }
impl FromRef<AppState> for JwtApplication<EmptyAdditionalClaims> {
fn from_ref(input: &AppState) -> Self {
input.jwt_application.clone()
}
}
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)] #[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
pub struct ExpiryHeapItem { pub struct ExpiryHeapItem {
pub expires_at: u64, pub expires_at: u64,
@ -101,6 +111,13 @@ async fn main() {
.await .await
.expect("Oidc Authentication Client"); .expect("Oidc Authentication Client");
let jwt_application = JwtApplication::new(
issuer.to_string(),
env::var("AUDIENCE").expect("AUDIENCE env var"),
)
.await
.expect("Jwt Authentication Client");
let data_path = env::var("DATA_PATH").expect("DATA_PATH env var"); let data_path = env::var("DATA_PATH").expect("DATA_PATH env var");
let garbage_collector = GarbageCollector::new(data_path.clone()).await; let garbage_collector = GarbageCollector::new(data_path.clone()).await;
@ -109,6 +126,7 @@ async fn main() {
let state: AppState = AppState { let state: AppState = AppState {
application_base, application_base,
oidc_application, oidc_application,
jwt_application,
data: data_path, data: data_path,
key_salt: KeySalt::from_str(&env::var("KEY_SALT").expect("KEY_SALT env var")) key_salt: KeySalt::from_str(&env::var("KEY_SALT").expect("KEY_SALT env var"))
.expect("KEY SALT valid hex"), .expect("KEY SALT valid hex"),
@ -133,9 +151,14 @@ async fn main() {
async fn get_index( async fn get_index(
State(app_state): State<AppState>, State(app_state): State<AppState>,
OidcExtractor { claims, .. }: OidcExtractor<EmptyAdditionalClaims>, oidc_extractor: Result<OidcExtractor<EmptyAdditionalClaims>, axum_oidc::error::Error>,
jwt_claims: Option<Claims<EmptyAdditionalClaims>>,
) -> Result<impl IntoResponse, Error> { ) -> Result<impl IntoResponse, Error> {
let subject = claims.subject().to_string(); let subject = match (oidc_extractor, jwt_claims) {
(_, Some(claims)) => claims.sub.to_string(),
(Ok(oidc), None) => oidc.claims.subject().to_string(),
(Err(err), None) => return Err(Error::Oidc(err.into_response())),
};
//generate phrase and derive id from it //generate phrase and derive id from it
let phrase = Phrase::random(); let phrase = Phrase::random();