proper regex

This commit is contained in:
slonkazoid 2025-02-04 23:01:02 +03:00
parent f5fdc0d865
commit 1d724b6972
Signed by: slonk
SSH key fingerprint: SHA256:tbZfJX4IOvZ0LGWOWu5Ijo8jfMPi78TU7x1VoEeCIjM
2 changed files with 25 additions and 11 deletions

View file

@ -1,7 +1,6 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::env; use std::env;
use std::net::{IpAddr, Ipv4Addr}; use std::net::{IpAddr, Ipv4Addr};
use std::ops::Deref;
use std::path::PathBuf; use std::path::PathBuf;
use color_eyre::eyre::{self, bail, Context}; use color_eyre::eyre::{self, bail, Context};
@ -11,13 +10,18 @@ use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tracing::{error, info, instrument}; use tracing::{error, info, instrument};
#[derive(Deserialize, Serialize, Debug)] #[derive(Deserialize, Serialize, Debug)]
pub struct DomainMatcher(#[serde(with = "regex")] Regex); #[serde(untagged)]
pub enum DomainMatcher {
Regex(#[serde(with = "regex")] Regex),
Exact(String),
}
impl Deref for DomainMatcher { impl DomainMatcher {
type Target = Regex; pub fn is_match(&self, value: impl AsRef<str>) -> bool {
match self {
fn deref(&self) -> &Self::Target { Self::Regex(regex) => regex.is_match(value.as_ref()).unwrap_or(false),
&self.0 Self::Exact(exact) => exact == value.as_ref(),
}
} }
} }
@ -134,15 +138,24 @@ mod regex {
impl Visitor<'_> for RegexVisitor { impl Visitor<'_> for RegexVisitor {
type Value = Regex; type Value = Regex;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(formatter, "a regex string") write!(f, "a regex string starting and ending with slashes ('/')")
} }
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where where
E: serde::de::Error, E: serde::de::Error,
{ {
let v = v
.strip_prefix('/')
.and_then(|v| v.strip_suffix('/'))
.ok_or(serde::de::Error::invalid_value(
serde::de::Unexpected::Str(v),
&self,
))?;
let regex = Regex::new(v); let regex = Regex::new(v);
regex.map_err(|err| serde::de::Error::custom(err)) regex.map_err(|err| serde::de::Error::custom(err))
} }
} }

View file

@ -53,7 +53,8 @@ async fn update_repo_handler(
if repo.secret.as_ref().is_some_and(|secret| { if repo.secret.as_ref().is_some_and(|secret| {
headers headers
.get(&secret.header).is_none_or(|header| header != &secret.value) .get(&secret.header)
.is_none_or(|header| header != &secret.value)
}) { }) {
Ok(StatusCode::UNAUTHORIZED) Ok(StatusCode::UNAUTHORIZED)
} else { } else {
@ -77,7 +78,7 @@ async fn ask(
Query(AskQuery { domain }): Query<AskQuery>, Query(AskQuery { domain }): Query<AskQuery>,
) -> StatusCode { ) -> StatusCode {
for matcher in &config.domains { for matcher in &config.domains {
if matcher.is_match(&domain).is_ok_and(|x| x) { if matcher.is_match(&domain) {
return StatusCode::OK; return StatusCode::OK;
} }
} }