Compute intersection of two lists
Useful for comparing capabilities with required permissions.
VCL
Use this solution in your VCL service (click RUN below to test this solution or clone it to make changes):
Compute@Edge
Use this solution in your Compute@Edge service:
- Rust
/// The name of a backend server associated with this service.const BACKEND_NAME: &str = "httpbin.org";
#[fastly::main]fn main(req: Request) -> Result<Response, Error> { // Log initial setup log_fastly::init_simple("my_log", log::LevelFilter::Info);
match do_req_with_permission_check(req) { Ok(resp) => Ok(resp), Err(e) => { log::info!("{}", e); Ok(Response::from_status(StatusCode::FORBIDDEN)) } }}
/// Request to backend if intersection of permission is foundfn do_req_with_permission_check(req: Request) -> Result<Response> { // Get permission from requestion let req_permission = get_req_permission(&req)?;
// Send request and get response from backend let resp = req.send(BACKEND_NAME)?;
// Get permission from require-group response header let require_group = resp .get_header("require-group") .ok_or_else(|| anyhow!("No require-group header found in response"))? .to_str()?;
// Check if there is any intersection between two permission sets let a_set = permissions_into_set(&req_permission); let b_set = permissions_into_set(require_group); let mut intersection_set = a_set.intersection(&b_set); if intersection_set.next().is_none() { return Err(anyhow!("No intersection in permission found")); }
Ok(resp)}
/// Get permission string from request cookiefn get_req_permission(req: &Request) -> Result<String> { let cookie_val: &str = req .get_header(header::COOKIE) .ok_or_else(|| anyhow!("No cookie found"))? .to_str()?;
// we split at ";" not "; ", in case the cookie is ending with ";" cookie_val .split(';') .find_map(|kv| { let index = kv.find('=')?; let (key, value) = kv.split_at(index); if key.trim() != "permission" { return None; }
// remove the "=" let value = value[1..].to_string(); Some(value) }) .ok_or_else(|| anyhow!("No permission found in cookie"))}
/// Parse permission string and put permissions into a HashSetfn permissions_into_set(p: &str) -> HashSet<&str> { p.split(':').filter(|s| !s.is_empty()).collect()}