|
|
|
|
@@ -12,6 +12,11 @@ use axum_oidc::{
|
|
|
|
|
EmptyAdditionalClaims, OidcAuthLayer, OidcClaims, OidcClient, OidcLoginLayer,
|
|
|
|
|
OidcRpInitiatedLogout, error::MiddlewareError,
|
|
|
|
|
};
|
|
|
|
|
use base64::{
|
|
|
|
|
Engine,
|
|
|
|
|
alphabet::STANDARD,
|
|
|
|
|
engine::{GeneralPurpose, GeneralPurposeConfig},
|
|
|
|
|
};
|
|
|
|
|
use clap::Command;
|
|
|
|
|
use dioxus::prelude::*;
|
|
|
|
|
use mize::Mize;
|
|
|
|
|
@@ -99,7 +104,8 @@ pub async fn start_server(mize: &mut Mize) -> MizeResult<()> {
|
|
|
|
|
.layer(session_layer)
|
|
|
|
|
.layer(tower_http::trace::TraceLayer::new_for_http())
|
|
|
|
|
// not authenticated routes
|
|
|
|
|
.route("/", get(ppc_main_page));
|
|
|
|
|
.route("/", get(ppc_main_page))
|
|
|
|
|
.route("/oidc_display_code_and_state", get(display_code_and_state));
|
|
|
|
|
|
|
|
|
|
tracing::info!("Running on http://localhost:3000");
|
|
|
|
|
|
|
|
|
|
@@ -136,3 +142,55 @@ async fn maybe_authenticated(
|
|
|
|
|
async fn logout(logout: OidcRpInitiatedLogout) -> impl IntoResponse {
|
|
|
|
|
logout.with_post_logout_redirect(Uri::from_static("https://localhost:3000"))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// src/web_callback.rs
|
|
|
|
|
use axum::{extract::Query, response::Html};
|
|
|
|
|
use html_escape::encode_text;
|
|
|
|
|
use serde::Deserialize;
|
|
|
|
|
use serde::Serialize;
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
|
pub struct CallbackParams {
|
|
|
|
|
pub code: Option<String>,
|
|
|
|
|
pub state: Option<String>,
|
|
|
|
|
pub error: Option<String>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
|
struct Combined<'a> {
|
|
|
|
|
code: &'a str,
|
|
|
|
|
state: &'a str,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async fn display_code_and_state(Query(params): Query<CallbackParams>) -> Html<String> {
|
|
|
|
|
// Safe fallbacks
|
|
|
|
|
let code = params.code.clone().unwrap_or_default();
|
|
|
|
|
let state = params.state.clone().unwrap_or_default();
|
|
|
|
|
let error = params.error.clone().unwrap_or_default();
|
|
|
|
|
|
|
|
|
|
// Create JSON object and base64 encode it
|
|
|
|
|
let combined = Combined {
|
|
|
|
|
code: &code,
|
|
|
|
|
state: &state,
|
|
|
|
|
};
|
|
|
|
|
// serde_json::to_string should succeed for simple strings; fallback to empty JSON on error
|
|
|
|
|
let json = serde_json::to_string(&combined)
|
|
|
|
|
.unwrap_or_else(|_| "{\"code\":\"\",\"state\":\"\"}".into());
|
|
|
|
|
let base64_engine = GeneralPurpose::new(
|
|
|
|
|
&STANDARD,
|
|
|
|
|
GeneralPurposeConfig::new().with_encode_padding(false),
|
|
|
|
|
);
|
|
|
|
|
let b64 = base64_engine.encode(json);
|
|
|
|
|
|
|
|
|
|
let b64_escaped = encode_text(&b64);
|
|
|
|
|
let error_escaped = encode_text(&error);
|
|
|
|
|
println!("err: {}", error_escaped);
|
|
|
|
|
println!("b: {}", b64_escaped);
|
|
|
|
|
|
|
|
|
|
let html = match error_escaped.as_ref() {
|
|
|
|
|
"" => format!("Copy this into your client: {}", b64_escaped),
|
|
|
|
|
_ => format!("An Error occured: {}", error_escaped),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Html(html)
|
|
|
|
|
}
|
|
|
|
|
|