proper regex
This commit is contained in:
parent
f5fdc0d865
commit
1d724b6972
2 changed files with 25 additions and 11 deletions
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue