feat(protocol): define native session credentials
This commit is contained in:
@@ -9,10 +9,10 @@ fn values(input: &str) -> std::collections::BTreeMap<String, String> {
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn evaluate(kind: &str, input: &str) -> &'static str {
|
||||
fn evaluate(version: &str, kind: &str, input: &str) -> &'static str {
|
||||
let values = values(input);
|
||||
match kind {
|
||||
"version" if matches!(input, "1" | "0" | "-1") => "valid",
|
||||
"version" if matches!(input, "2" | "1" | "0") => "valid",
|
||||
"version" => "invalid:unsupported_version",
|
||||
"page" => match values.get("limit").and_then(|value| value.parse::<i64>().ok()) {
|
||||
Some(limit) if (1..=100).contains(&limit) => "valid",
|
||||
@@ -24,12 +24,62 @@ fn evaluate(kind: &str, input: &str) -> &'static str {
|
||||
"manifest"
|
||||
if values.get("version").map(String::as_str) == Some("1")
|
||||
&& values.contains_key("gateway_id")
|
||||
&& values.contains_key("public_identity")
|
||||
&& values.get("grant").map_or(false, |value| value.len() >= 43)
|
||||
&& values.get("purpose").map(String::as_str) == Some("launch") => "valid",
|
||||
"manifest" => "invalid:invalid_manifest",
|
||||
"clipboard" if values.get("encoding").map(String::as_str) == Some("utf-8")
|
||||
&& !values.contains_key("file") => "valid",
|
||||
"clipboard" => "invalid:unsupported_clipboard",
|
||||
"session_request" if version != "2" => "invalid:unsupported_version",
|
||||
"session_request" if values.contains_key("policy_snapshot") => "invalid:forbidden_field",
|
||||
"session_request" => match SessionRequest::new(
|
||||
values.get("client_device_id").cloned().unwrap_or_default(),
|
||||
values.get("device_key_id").cloned().unwrap_or_default(),
|
||||
values.get("pool_id").cloned().unwrap_or_default(),
|
||||
values.get("idempotency_key").cloned().unwrap_or_default(),
|
||||
None,
|
||||
) {
|
||||
Ok(_) => "valid",
|
||||
Err(_) => "invalid:required",
|
||||
},
|
||||
"browser_authenticated_session" if values.contains_key("client_device_id") || values.contains_key("device_key_id") => "invalid:forbidden_field",
|
||||
"browser_authenticated_session" => match BrowserAuthenticatedSession::new(
|
||||
values.get("username").cloned().unwrap_or_default(),
|
||||
values.get("provider").cloned().unwrap_or_default(),
|
||||
vec![values.get("roles").cloned().unwrap_or_default()],
|
||||
values.get("role").cloned().unwrap_or_default(),
|
||||
) {
|
||||
Ok(_) => "valid",
|
||||
Err(_) => "invalid:invalid_session",
|
||||
},
|
||||
"native_authenticated_session" if !values.contains_key("client_device_id") || !values.contains_key("device_key_id") => "invalid:required",
|
||||
"native_authenticated_session" => {
|
||||
let identity = match NativeSessionIdentity::new(values["client_device_id"].clone(), values["device_key_id"].clone()) {
|
||||
Ok(identity) => identity,
|
||||
Err(_) => return "invalid:required",
|
||||
};
|
||||
match NativeAuthenticatedSession::new(
|
||||
values.get("username").cloned().unwrap_or_default(),
|
||||
values.get("provider").cloned().unwrap_or_default(),
|
||||
vec![values.get("roles").cloned().unwrap_or_default()],
|
||||
values.get("role").cloned().unwrap_or_default(),
|
||||
identity,
|
||||
) {
|
||||
Ok(_) => "valid",
|
||||
Err(_) => "invalid:invalid_session",
|
||||
}
|
||||
}
|
||||
"native_tunnel_credential" => match NativeTunnelCredential::new(
|
||||
values.get("client_device_id").cloned().unwrap_or_default(),
|
||||
values.get("device_key_id").cloned().unwrap_or_default(),
|
||||
values.get("certificate_chain_pem").cloned().unwrap_or_default(),
|
||||
values.get("trust_bundle_pem").cloned().unwrap_or_default(),
|
||||
values.get("expires_at").cloned().unwrap_or_default(),
|
||||
) {
|
||||
Ok(_) => "valid",
|
||||
Err(_) => "invalid:invalid_credential",
|
||||
},
|
||||
"event" if values.get("version").map(String::as_str) != Some("1") => {
|
||||
"invalid:unsupported_version"
|
||||
}
|
||||
@@ -46,9 +96,9 @@ fn evaluate(kind: &str, input: &str) -> &'static str {
|
||||
"event" if values.get("sequence").and_then(|value| value.parse::<i64>().ok()).map_or(true, |sequence| sequence < 1)
|
||||
|| !values.contains_key("correlation_id") => "invalid:required",
|
||||
"event" => "valid",
|
||||
"tunnel" if matches!(values.get("offered").map(String::as_str), Some("1") | Some("0") | Some("-1"))
|
||||
&& matches!(values.get("feature").map(String::as_str), Some("control.v1") | Some("display.request.v1") | Some("input.absolute.v1") | Some("input.scroll.v1")) => "valid",
|
||||
"tunnel" if !matches!(values.get("feature").map(String::as_str), Some("control.v1") | Some("display.request.v1") | Some("input.absolute.v1") | Some("input.scroll.v1")) => {
|
||||
"tunnel" if matches!(values.get("offered").map(String::as_str), Some("2") | Some("1") | Some("0"))
|
||||
&& matches!(values.get("feature").map(String::as_str), Some("control.v1") | Some("control.v2") | Some("display.request.v1") | Some("input.absolute.v1") | Some("input.scroll.v1")) => "valid",
|
||||
"tunnel" if !matches!(values.get("feature").map(String::as_str), Some("control.v1") | Some("control.v2") | Some("display.request.v1") | Some("input.absolute.v1") | Some("input.scroll.v1")) => {
|
||||
"invalid:unsupported_feature"
|
||||
}
|
||||
"tunnel" => "invalid:unsupported_version",
|
||||
@@ -283,7 +333,7 @@ fn main() {
|
||||
for line in lines {
|
||||
let fields: Vec<&str> = line.split('\t').collect();
|
||||
assert_eq!(fields.len(), 5);
|
||||
let actual = evaluate(fields[2], fields[3]);
|
||||
let actual = evaluate(fields[1], fields[2], fields[3]);
|
||||
assert_eq!(actual, fields[4], "{}", fields[0]);
|
||||
results.push(format!("{}\t{}", fields[0], actual));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user