mirror of
https://github.com/sadoyan/aralez.git
synced 2026-04-29 22:38:36 +08:00
Path level authentication
This commit is contained in:
@@ -57,22 +57,23 @@ fn validate(auth: &dyn AuthValidator, session: &Session) -> bool {
|
||||
auth.validate(session)
|
||||
}
|
||||
|
||||
pub fn authenticate(c: &[Arc<str>], session: &Session) -> bool {
|
||||
match &*c[0] {
|
||||
// pub fn authenticate(c: &[Arc<str>], session: &Session) -> bool {
|
||||
pub fn authenticate(auth_type: &Arc<str>, credentials: &Arc<str>, session: &Session) -> bool {
|
||||
match &*auth_type.clone() {
|
||||
"basic" => {
|
||||
let auth = BasicAuth(&*c[1]);
|
||||
let auth = BasicAuth(&*credentials.clone());
|
||||
validate(&auth, session)
|
||||
}
|
||||
"apikey" => {
|
||||
let auth = ApiKeyAuth(&*c[1]);
|
||||
let auth = ApiKeyAuth(&*credentials.clone());
|
||||
validate(&auth, session)
|
||||
}
|
||||
"jwt" => {
|
||||
let auth = JwtAuth(&*c[1]);
|
||||
let auth = JwtAuth(&*credentials.clone());
|
||||
validate(&auth, session)
|
||||
}
|
||||
_ => {
|
||||
println!("Unsupported authentication mechanism : {}", c[0]);
|
||||
println!("Unsupported authentication mechanism : {}", auth_type);
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ async fn build_upstreams(fullist: &UpstreamsDashMap, method: &str, client: &Clie
|
||||
to_https: upstream.to_https,
|
||||
rate_limit: upstream.rate_limit,
|
||||
healthcheck: upstream.healthcheck,
|
||||
authorization: upstream.authorization.clone(),
|
||||
};
|
||||
|
||||
if scheme.healthcheck.unwrap_or(true) {
|
||||
|
||||
@@ -35,6 +35,7 @@ pub async fn for_consul(url: String, token: Option<String>, conf: &ServiceMappin
|
||||
to_https: conf.to_https.unwrap_or(false),
|
||||
rate_limit: conf.rate_limit,
|
||||
healthcheck: None,
|
||||
authorization: None,
|
||||
});
|
||||
inner_vec.push(to_add);
|
||||
}
|
||||
@@ -68,6 +69,7 @@ pub async fn for_kuber(url: &str, token: &str, conf: &ServiceMapping) -> Option<
|
||||
to_https: conf.to_https.unwrap_or(false),
|
||||
rate_limit: conf.rate_limit,
|
||||
healthcheck: None,
|
||||
authorization: None,
|
||||
});
|
||||
inner_vec.push(to_add);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,10 @@ pub async fn load_configuration(d: &str, kind: &str) -> (Option<Configuration>,
|
||||
};
|
||||
|
||||
let parsed: Config = match serde_yaml::from_str(&yaml_data) {
|
||||
Ok(cfg) => cfg,
|
||||
Ok(cfg) => {
|
||||
// println!("{:#?}", cfg);
|
||||
cfg
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to parse upstreams file: {}", e);
|
||||
return (None, e.to_string());
|
||||
@@ -97,6 +100,7 @@ async fn populate_headers_and_auth(config: &mut Configuration, parsed: &Config)
|
||||
info!("Applied Global Rate Limit : {} request per second", rate);
|
||||
}
|
||||
|
||||
// ======================================================================================== //
|
||||
if let Some(auth) = &parsed.authorization {
|
||||
let name = auth.get("type").unwrap_or(&"".to_string()).to_string();
|
||||
let creds = auth.get("creds").unwrap_or(&"".to_string()).to_string();
|
||||
@@ -107,6 +111,7 @@ async fn populate_headers_and_auth(config: &mut Configuration, parsed: &Config)
|
||||
} else {
|
||||
config.extraparams.authentication = DashMap::new();
|
||||
}
|
||||
// ======================================================================================== //
|
||||
}
|
||||
|
||||
async fn populate_file_upstreams(config: &mut Configuration, parsed: &Config) {
|
||||
@@ -126,9 +131,17 @@ async fn populate_file_upstreams(config: &mut Configuration, parsed: &Config) {
|
||||
build_headers(&path_config.server_headers, config, &mut sl);
|
||||
client_header_list.insert(Arc::from(path.as_str()), hl);
|
||||
server_header_list.insert(Arc::from(path.as_str()), sl);
|
||||
|
||||
let mut server_list = Vec::new();
|
||||
for server in &path_config.servers {
|
||||
let mut path_auth: Option<Arc<InnerAuth>> = None;
|
||||
if let Some(pa) = &path_config.authorization {
|
||||
let y: InnerAuth = InnerAuth {
|
||||
auth_type: Arc::from(pa.auth_type.clone()),
|
||||
auth_cred: Arc::from(pa.auth_cred.clone()),
|
||||
};
|
||||
path_auth = Some(Arc::from(y));
|
||||
}
|
||||
|
||||
if let Some((ip, port_str)) = server.split_once(':') {
|
||||
if let Ok(port) = port_str.parse::<u16>() {
|
||||
server_list.push(Arc::from(InnerMap {
|
||||
@@ -139,6 +152,7 @@ async fn populate_file_upstreams(config: &mut Configuration, parsed: &Config) {
|
||||
to_https: path_config.to_https.unwrap_or(false),
|
||||
rate_limit: path_config.rate_limit,
|
||||
healthcheck: path_config.healthcheck,
|
||||
authorization: path_auth,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ pub struct Extraparams {
|
||||
pub to_https: Option<bool>,
|
||||
pub sticky_sessions: bool,
|
||||
pub authentication: DashMap<Arc<str>, Vec<Arc<str>>>,
|
||||
// pub authentication: InnerAuth,
|
||||
pub rate_limit: Option<isize>,
|
||||
}
|
||||
|
||||
@@ -70,7 +71,13 @@ pub struct HostConfig {
|
||||
pub paths: HashMap<String, PathConfig>,
|
||||
pub rate_limit: Option<isize>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
|
||||
pub struct Auth {
|
||||
#[serde(rename = "type")]
|
||||
pub auth_type: String,
|
||||
#[serde(rename = "creds")]
|
||||
pub auth_cred: String,
|
||||
}
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
pub struct PathConfig {
|
||||
pub servers: Vec<String>,
|
||||
@@ -80,6 +87,8 @@ pub struct PathConfig {
|
||||
pub server_headers: Option<Vec<String>>,
|
||||
pub rate_limit: Option<isize>,
|
||||
pub healthcheck: Option<bool>,
|
||||
// pub authorization: Option<HashMap<String, String>>,
|
||||
pub authorization: Option<Auth>,
|
||||
}
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Configuration {
|
||||
@@ -116,7 +125,13 @@ pub struct AppConfig {
|
||||
pub rungroup: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||
pub struct InnerAuth {
|
||||
pub auth_type: Arc<str>,
|
||||
pub auth_cred: Arc<str>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct InnerMap {
|
||||
pub address: Arc<str>,
|
||||
pub port: u16,
|
||||
@@ -125,6 +140,8 @@ pub struct InnerMap {
|
||||
pub to_https: bool,
|
||||
pub rate_limit: Option<isize>,
|
||||
pub healthcheck: Option<bool>,
|
||||
// pub authorization: Option<DashMap<Arc<str>, Arc<str>>>,
|
||||
pub authorization: Option<Arc<InnerAuth>>,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
@@ -139,6 +156,7 @@ impl InnerMap {
|
||||
to_https: Default::default(),
|
||||
rate_limit: Default::default(),
|
||||
healthcheck: Default::default(),
|
||||
authorization: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,11 +124,23 @@ pub fn compare_dashmaps(map1: &UpstreamsDashMap, map2: &UpstreamsDashMap) -> boo
|
||||
return false; // Path exists in map1 but not in map2
|
||||
};
|
||||
let (vec2, _counter2) = entry2.value();
|
||||
let set1: HashSet<_> = vec1.iter().collect();
|
||||
let set2: HashSet<_> = vec2.iter().collect();
|
||||
if set1 != set2 {
|
||||
|
||||
if vec1.len() != vec2.len() {
|
||||
return false;
|
||||
}
|
||||
for item in vec1.iter() {
|
||||
let count1 = vec1.iter().filter(|&x| x == item).count();
|
||||
let count2 = vec2.iter().filter(|&x| x == item).count();
|
||||
if count1 != count2 {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// let set1: HashSet<_> = vec1.iter().collect();
|
||||
// let set2: HashSet<_> = vec2.iter().collect();
|
||||
// if set1 != set2 {
|
||||
// return false;
|
||||
// }
|
||||
}
|
||||
}
|
||||
true
|
||||
@@ -168,6 +180,7 @@ pub fn clone_idmap_into(original: &UpstreamsDashMap, cloned: &UpstreamsIdMap) {
|
||||
to_https: false,
|
||||
rate_limit: None,
|
||||
healthcheck: None,
|
||||
authorization: None,
|
||||
};
|
||||
|
||||
cloned.insert(id, Arc::from(to_add));
|
||||
|
||||
Reference in New Issue
Block a user