feat: write auth ics proxy
This commit is contained in:
commit
4b70ac331d
4 changed files with 1662 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/target
|
1574
Cargo.lock
generated
Normal file
1574
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
12
Cargo.toml
Normal file
12
Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[package]
|
||||||
|
name = "uofgcal"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
axum = "0.7.6"
|
||||||
|
color-eyre = "0.6.3"
|
||||||
|
futures = "0.3.30"
|
||||||
|
reqwest = "0.12.7"
|
||||||
|
serde = { version = "1.0.210", features = ["derive"] }
|
||||||
|
tokio = { version = "1.40.0", features = ["full"] }
|
75
src/main.rs
Normal file
75
src/main.rs
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
use axum::{
|
||||||
|
body::Bytes,
|
||||||
|
extract::{Query, State},
|
||||||
|
http::StatusCode,
|
||||||
|
response::{AppendHeaders, IntoResponse},
|
||||||
|
routing::get,
|
||||||
|
Router,
|
||||||
|
};
|
||||||
|
use color_eyre::Result;
|
||||||
|
use reqwest::{header, Client};
|
||||||
|
use serde::Deserialize;
|
||||||
|
use std::borrow::Cow;
|
||||||
|
use tokio::net::TcpListener;
|
||||||
|
|
||||||
|
const PORT: u16 = 8080;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct CalendarPayload {
|
||||||
|
calendar: Cow<'static, str>,
|
||||||
|
filename: Option<Cow<'static, str>>,
|
||||||
|
username: Cow<'static, str>,
|
||||||
|
password: Cow<'static, str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_calender(
|
||||||
|
Query(auth): Query<CalendarPayload>,
|
||||||
|
State(client): State<Client>,
|
||||||
|
) -> impl IntoResponse {
|
||||||
|
if let Ok(resp) = client
|
||||||
|
.get(auth.calendar.as_ref())
|
||||||
|
.basic_auth(auth.username.as_ref(), Some(auth.password.as_ref()))
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok((
|
||||||
|
AppendHeaders([
|
||||||
|
(
|
||||||
|
header::CONTENT_TYPE,
|
||||||
|
"text/calendar; charset=utf-8".to_string(),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
header::CONTENT_DISPOSITION,
|
||||||
|
format!(
|
||||||
|
r#"attachment; filename="{}""#,
|
||||||
|
auth.filename.unwrap_or_else(|| {
|
||||||
|
if auth.calendar.ends_with(".ics") {
|
||||||
|
Cow::Borrowed(&auth.calendar.split('/').last().unwrap())
|
||||||
|
} else {
|
||||||
|
Cow::Borrowed("calendar.ics")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
resp.bytes().await.ok().unwrap_or_default(),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
Err((
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
"Failed to fetch calendar".to_string(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> Result<()> {
|
||||||
|
color_eyre::install()?;
|
||||||
|
let tcp_listener = TcpListener::bind(format!("0.0.0.0:{PORT}")).await?;
|
||||||
|
let client = Client::new();
|
||||||
|
let router = Router::new()
|
||||||
|
.route("/", get(get_calender))
|
||||||
|
.with_state(client);
|
||||||
|
axum::serve(tcp_listener, router).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
Loading…
Reference in a new issue