aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs88
1 files changed, 68 insertions, 20 deletions
diff --git a/src/main.rs b/src/main.rs
index c1a79d0..ccfb81e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -22,13 +22,22 @@ type HttpClient = Client<hyper::client::HttpConnector>;
struct Opt {
#[structopt(short, long)]
config: String,
+
+ #[structopt(short, long, default_value = "127.0.0.1:8200")]
+ address: SocketAddr,
}
#[derive(Debug, Deserialize, StaticType, Clone)]
struct Access {
+ times: Vec<Time>,
+ hosts: Vec<String>,
+}
+
+#[derive(Debug, Deserialize, StaticType, Clone)]
+struct Time {
+ days: String,
from: String,
to: String,
- hosts: Vec<String>,
}
#[tokio::main]
@@ -42,7 +51,6 @@ async fn main() {
.parse::<Vec<Access>>()
{
Ok(config) => {
- let addr = SocketAddr::from(([127, 0, 0, 1], 8100));
let client = HttpClient::new();
let make_service = make_service_fn(move |_| {
@@ -55,9 +63,9 @@ async fn main() {
}
});
- let server = Server::bind(&addr).serve(make_service);
+ let server = Server::bind(&opt.address).serve(make_service);
- info!("Listening on http://{}", addr);
+ info!("Listening on http://{}", opt.address);
if let Err(e) = server.await {
error!("server error: {}", e);
@@ -156,6 +164,8 @@ fn block_uri(unauthorized_hosts: &Vec<String>, uri: &Uri) -> bool {
fn currently_unauthorized_hosts(config: Vec<Access>) -> Vec<String> {
let now = Local::now();
+ // Format spec: https://docs.rs/chrono/0.4.15/chrono/format/strftime/index.html
+ let day = now.format("%u").to_string().parse::<i32>().unwrap();
let hour = now.format("%H").to_string().parse::<i32>().unwrap();
let minutes = now.format("%M").to_string().parse::<i32>().unwrap();
let now = (hour, minutes);
@@ -163,27 +173,65 @@ fn currently_unauthorized_hosts(config: Vec<Access>) -> Vec<String> {
config
.into_iter()
.map(|access| {
- let from = parse_time(&access.from);
- let to = parse_time(&access.to);
-
- if is_before_or_eq(from, to) {
- if is_after_or_eq(now, from) && is_before_or_eq(now, to) {
- access.hosts.clone()
- } else {
- Vec::new()
- }
- } else {
- if is_after_or_eq(now, from) || is_before_or_eq(now, to) {
- access.hosts.clone()
- } else {
- Vec::new()
- }
- }
+ let Access { times, hosts } = access;
+
+ times
+ .into_iter()
+ .map(|time| {
+ let days = parse_days(&time.days);
+ let from = parse_time(&time.from);
+ let to = parse_time(&time.to);
+
+ if days.contains(&day) {
+ if is_before_or_eq(from, to) {
+ if is_after_or_eq(now, from) && is_before_or_eq(now, to) {
+ hosts.clone()
+ } else {
+ Vec::new()
+ }
+ } else {
+ if is_after_or_eq(now, from) || is_before_or_eq(now, to) {
+ hosts.clone()
+ } else {
+ Vec::new()
+ }
+ }
+ } else {
+ Vec::new()
+ }
+ })
+ .collect::<Vec<Vec<String>>>()
+ .concat()
})
.collect::<Vec<Vec<String>>>()
.concat()
}
+fn parse_days(str: &str) -> Vec<i32> {
+ let xs = str.split("-").collect::<Vec<&str>>();
+ let from = parse_day(xs[0]);
+ let to = parse_day(xs[1]);
+ (1..8).filter(|d| {
+ if from < to {
+ d >= &from && d <= &to
+ } else {
+ d >= &from || d <= &to
+ }
+ }).collect()
+}
+
+fn parse_day(str: &str) -> i32 {
+ match str {
+ "Monday" => 1,
+ "Tuesday" => 2,
+ "Wednesday" => 3,
+ "Thursday" => 4,
+ "Friday" => 5,
+ "Saturday" => 6,
+ _ => 7,
+ }
+}
+
fn parse_time(str: &str) -> (i32, i32) {
let regex = Regex::new(r"(\d{2}):(\d{2})").unwrap();
match regex.captures(str) {