Skip to content

Commit

Permalink
Have auth in wasm prop and log on unexpected type
Browse files Browse the repository at this point in the history
Signed-off-by: Alex Snaps <[email protected]>
  • Loading branch information
alexsnaps committed Oct 23, 2024
1 parent 611a900 commit f911798
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 38 deletions.
43 changes: 6 additions & 37 deletions src/data/attribute.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::data::property::Path;
use crate::data::PropertyPath;
use chrono::{DateTime, FixedOffset};
use log::{debug, error};
use log::{debug, error, warn};
use protobuf::well_known_types::Struct;
use proxy_wasm::hostcalls;
use serde_json::Value;
Expand Down Expand Up @@ -130,43 +130,8 @@ pub fn set_attribute(attr: &str, value: &[u8]) {
pub fn store_metadata(metastruct: &Struct) {
let metadata = process_metadata(metastruct, String::new());
for (key, value) in metadata {
let attr = format!("{KUADRANT_NAMESPACE}\\.{key}");
// stored into host_property: wasm.kuadrant.{key}
// example: wasm.kuadrant.identity.anonymous is how it's stored!
// but users would write the predicate: !auth.identity.anonymous
// two problems:
// - 1/ auth.identity doesn't resolve
// - 2/ the value is the string "true"

// struct User {
// foo: bool,
// bar: float, // 1 != 1.0
// name: String,
// }
//
// Admin can store this:
// authorino: export auth.identity.user.foo = expression("auth.user != null") // {"foo": true, "bar": 123, "name": "dd"}
// Or that:
// authorino: export auth.identity.foo = expression("auth.user.long.ass.path.to.some.member.within.foo")
// authorino: export auth.identity.user.bar = 123
// authorino: export auth.identity.user.name = "dd"

// predicate: !auth.identity.user.foo && auth.identity.user.bar != 443.0
// => properties [["auth", "identity", "user", "foo"], ["destination", "port"]]
// known part ["auth", "identity"] + "user", resolves the key wasm.kuadrant.identity.user ? to lookup the value
// value is a string, "{"foo": true, "bar": 123, "name": "dd"}"
// value is json literal... string "true" is the Bool(true), we need to unmarshal that value form json
// then evaluate the rest of the path against that structure and resolve the type from the value itself
// e.g. : user.foo, .foo is that part that we don't know about, .foo => what's the value?
// value is true, i.e. a boolean, so the value is cel_interpreter.Value::Bool(true)
// within the value, we need to access the member "foo"
//
// Split the work in 2:
// - deal with scalar json values in the attribute: bool, number, string, null
// - deal with: list, map, object
// e.g. support auth.identity.groups[0] == "foo"
let attr = format!("{KUADRANT_NAMESPACE}\\.auth\\.{key}");
debug!("set_attribute: {attr} = {value}");
// value is actually a json literal, e.g. 'true' != '"true"'
set_attribute(attr.as_str(), value.into_bytes().as_slice());
}
}
Expand All @@ -189,6 +154,10 @@ fn process_metadata(s: &Struct, prefix: String) -> Vec<(String, String)> {
} else if value.has_number_value() {
Some(value.get_number_value().into())
} else {
warn!(
"Don't know how to store Struct field `{}` of kind {:?}",
key, value.kind
);
None
};

Expand Down
1 change: 0 additions & 1 deletion src/data/property.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ fn host_get_property(path: &Path) -> Result<Option<Vec<u8>>, Status> {
pub fn get_property(path: &Path) -> Result<Option<Vec<u8>>, Status> {
match *path.tokens() {
["source", "remote_address"] => remote_address(),
// todo, unsure whether to drop the "auth" part here...
["auth", ..] => host_get_property(&wasm_prop(path.tokens().as_slice())),
// for auth stuff => resolve_host_props() => json string literal as Bytes
_ => host_get_property(path),
Expand Down

0 comments on commit f911798

Please sign in to comment.