use regex::Regex; use serde::{Serialize, Deserialize}; use url::Url; use std::collections::HashMap; use crate::Username; #[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] pub struct SSOWatConfig { domains: Vec, permissions: HashMap, portal_domain: String, portal_path: String, redirected_urls: HashMap, theme: String, } impl SSOWatConfig { pub fn permission_for_uri(&self, uri: &Url) -> Option { // First check if the domain is actually managed by SSOWat if let Some(domain) = uri.domain() { if ! self.domains.contains(&domain.to_string()) { // Domain not managed return None; } // Strip protocol but keep full URL let stripped_uri = AsRef::::as_ref(uri) .trim_start_matches("http") .trim_start_matches("s") .trim_start_matches("://"); // Check which app matches this URI, to find corresponding permission for (key, val) in &self.permissions { for uri_format in &val.uris { if uri_format.starts_with("re:") { let uri_format = uri_format.trim_start_matches("re:"); // TODO: generate regex in advance // TODO: error let re = Regex::new(uri_format).unwrap(); if re.is_match(stripped_uri) { return Some(key.clone()); } } else { if stripped_uri.starts_with(uri_format) { return Some(key.clone()); } } } } // No app URI matched return None; } else { // No domain (eg. http://8.8.8.8/) return None; } } pub fn user_has_permission_for_uri(&self, username: Option<&Username>, uri: &Url) -> bool { if let Some(permission_name) = self.permission_for_uri(uri) { let permission = self.permissions.get(&permission_name).unwrap(); if permission.public { return true; } if let Some(username) = username { permission.users.contains(username) } else { // User is not logged-in. Non-public URIs are not authorized false } } else { // No permission matching this URI false } } } #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct Permission { auth_header: bool, label: String, public: bool, show_tile: bool, uris: Vec, #[serde(default)] use_remote_user_in_nginx_conf: bool, users: Vec, } #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] #[serde(transparent)] pub struct PermissionName { name: String, }