98 lines
3.1 KiB
Rust
98 lines
3.1 KiB
Rust
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<String>,
|
|
permissions: HashMap<PermissionName, Permission>,
|
|
portal_domain: String,
|
|
portal_path: String,
|
|
redirected_urls: HashMap<String, String>,
|
|
theme: String,
|
|
}
|
|
|
|
impl SSOWatConfig {
|
|
pub fn permission_for_uri(&self, uri: &Url) -> Option<PermissionName> {
|
|
// 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::<str>::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<String>,
|
|
#[serde(default)]
|
|
use_remote_user_in_nginx_conf: bool,
|
|
users: Vec<Username>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
|
|
#[serde(transparent)]
|
|
pub struct PermissionName {
|
|
name: String,
|
|
}
|