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