use crate::keys::KeyProvider;
use crate::message::SesameError;
pub fn parse_scope_channel(scope: &str) -> Option<&str> {
scope.strip_prefix("channel=").map(str::trim)
}
pub fn authorize(
provider: &dyn KeyProvider,
key_id: &str,
scope: &str,
target_channel: Option<&str>,
) -> Result<String, SesameError> {
let declared = parse_scope_channel(scope).ok_or(SesameError::ScopeDenied)?;
if let Some(target) = target_channel {
if !declared.eq(target) {
return Err(SesameError::ScopeDenied);
}
}
if provider.is_authorized(key_id, declared) {
Ok(declared.to_string())
} else {
Err(SesameError::ScopeDenied)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::keys::{ChannelScope, HmacKey, StaticKeyProvider};
fn provider() -> StaticKeyProvider {
StaticKeyProvider::new().with_signing_key(
"sas-east-01",
HmacKey(b"k".to_vec()),
ChannelScope::list(["SportsFeed-East"]),
)
}
#[test]
fn parse_scope() {
assert_eq!(
parse_scope_channel("channel=SportsFeed-East"),
Some("SportsFeed-East")
);
assert_eq!(parse_scope_channel("nope"), None);
}
#[test]
fn authorized_channel_accepted() {
let p = provider();
assert_eq!(
authorize(
&p,
"sas-east-01",
"channel=SportsFeed-East",
Some("SportsFeed-East")
),
Ok("SportsFeed-East".to_string())
);
}
#[test]
fn unauthorized_channel_denied() {
let p = provider();
assert_eq!(
authorize(
&p,
"sas-east-01",
"channel=PremiumFeed",
Some("PremiumFeed")
),
Err(SesameError::ScopeDenied)
);
}
#[test]
fn scope_target_mismatch_denied() {
let p = provider();
assert_eq!(
authorize(
&p,
"sas-east-01",
"channel=SportsFeed-East",
Some("PremiumFeed")
),
Err(SesameError::ScopeDenied)
);
}
}