aep-tower 0.1.1

Tower integration for Agent Enrollment Protocol Services.
Documentation
use std::net::IpAddr;

use http::Uri;
use url::Url;

use crate::TowerError;

pub(crate) fn validate_origin(
    origin: &Url,
    allow_insecure_loopback: bool,
) -> Result<(), TowerError> {
    let secure = origin.scheme() == "https";
    let loopback = allow_insecure_loopback
        && origin.scheme() == "http"
        && origin.host_str().is_some_and(is_loopback);
    if (!secure && !loopback)
        || origin.host_str().is_none()
        || !origin.username().is_empty()
        || origin.password().is_some()
        || origin.path() != "/"
        || origin.query().is_some()
        || origin.fragment().is_some()
    {
        return Err(TowerError::InvalidConfiguration(
            "protected-resource origin must be an HTTPS origin".to_owned(),
        ));
    }
    Ok(())
}

pub(crate) fn request_url(origin: &Url, uri: &Uri) -> Result<Url, TowerError> {
    let path = uri.path_and_query().map_or("/", |value| value.as_str());
    origin.join(path).map_err(TowerError::from)
}

fn is_loopback(host: &str) -> bool {
    host.eq_ignore_ascii_case("localhost")
        || host
            .parse::<IpAddr>()
            .is_ok_and(|address| address.is_loopback())
}