aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock28
-rw-r--r--Cargo.toml2
-rw-r--r--src/main.rs54
3 files changed, 83 insertions, 1 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 0bc6063..978714c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,6 +1,15 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
+name = "aho-corasick"
+version = "0.7.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -207,11 +216,13 @@ dependencies = [
name = "google-calendar-rsvp"
version = "0.0.1"
dependencies = [
+ "base64",
"exitcode",
"google-calendar3",
"home",
"hyper",
"hyper-rustls",
+ "regex",
"serde_json",
"tokio",
"yup-oauth2",
@@ -606,6 +617,23 @@ dependencies = [
]
[[package]]
+name = "regex"
+version = "1.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
+
+[[package]]
name = "ring"
version = "0.16.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index c4a54ac..ab4ed89 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,11 +4,13 @@ version = "0.0.1"
edition = "2018"
[dependencies]
+base64 = "0.13.0"
exitcode = "1.1.2"
google-calendar3 = "2.0.4+20210327"
home = "0.5.3"
hyper = "0.14.7"
hyper-rustls = "0.22.1"
+regex = "1.5.4"
serde_json = "1.0.64"
tokio = { version = "1.6.0", features = ["rt-multi-thread"] }
yup-oauth2 = "5.1.0"
diff --git a/src/main.rs b/src/main.rs
index db82151..9f4ad6a 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,8 +1,10 @@
+use base64;
use google_calendar3::api::{Event, EventAttendee};
use google_calendar3::CalendarHub;
use home;
use hyper;
use hyper_rustls;
+use regex::Regex;
use tokio;
use yup_oauth2 as oauth2;
@@ -10,6 +12,7 @@ use std::env;
use std::fmt;
use std::fs;
use std::process;
+use std::str;
#[derive(Debug)]
@@ -71,7 +74,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}
for event_id in &event_ids {
- rsvp(event_id, &action).await;
+ rsvp(
+ &event_id_from_base64(event_id),
+ &action,
+ ).await;
}
Ok(())
@@ -145,3 +151,49 @@ fn secret_from_file() -> oauth2::ApplicationSecret {
None => todo!(),
}
}
+
+fn event_id_from_base64(event_id: &str) -> String {
+ // Base64-matching regex from Xuanyuanzhiyuan
+ // (https://stackoverflow.com/users/1076906/xuanyuanzhiyuan) on Stack
+ // Overflow:
+ // https://stackoverflow.com/questions/8571501/how-to-check-whether-a-string-is-base64-encoded-or-not/8571649#8571649
+ let re = Regex::new(
+ "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$",
+ ).unwrap();
+
+ if !re.is_match(event_id) {
+ return event_id.to_owned();
+ }
+
+ let decoded = &base64::decode(event_id).unwrap();
+ let id_email_pair = str::from_utf8(decoded).unwrap();
+ let values = id_email_pair.split(" ").collect::<Vec<_>>();
+ let id = values.first().unwrap().to_string();
+
+ id
+}
+
+
+#[cfg(test)]
+mod tests {
+ use crate::*;
+
+ #[test]
+ fn test_event_id_from_base64_event_id() {
+ let expected = "1g4j1h67ndq7kddrb2bptp2cua_20210521T120000Z";
+
+ let id = event_id_from_base64(expected);
+
+ assert_eq!(expected, id);
+ }
+
+ #[test]
+ fn test_event_id_from_base64_eid() {
+ let expected = "1g4j1h67ndq7kddrb2bptp2cua";
+ let encoded = base64::encode(format!("{} rory.mercury@example.com", expected));
+
+ let id = event_id_from_base64(&encoded);
+
+ assert_eq!(expected, id);
+ }
+}