diff --git a/Cargo.toml b/Cargo.toml index 920aa91..4e76e73 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,6 @@ http = [] glob = ["dep:wax"] graph = [] jsonschema = ["dep:jsonschema"] -jwt = ["dep:jsonwebtoken", "dep:data-encoding", "dep:itertools"] no_std = ["lazy_static/spin_no_std"] opa-runtime = [] regex = ["dep:regex"] @@ -53,7 +52,6 @@ full-opa = [ "graph", "hex", "http", - "jwt", "jsonschema", "opa-runtime", "regex", @@ -117,8 +115,6 @@ uuid = { version = "1.15.1", default-features = false, features = ["v4", "fast-r jsonschema = { version = "0.29.0", default-features = false, optional = true } chrono = { version = "0.4.40", optional = true } chrono-tz = { version = "0.10.1", optional = true } -jsonwebtoken = { version = "9.3.1", optional = true } -itertools = { version = "0.14.0", default-features = false, optional = true } serde_yaml = {version = "0.9.16", default-features = false, optional = true } # Specify thread_rng for in order to use random_range diff --git a/README.md b/README.md index 73b6598..c12f3c7 100644 --- a/README.md +++ b/README.md @@ -298,8 +298,11 @@ The following test suites don't pass fully due to missing builtins: - `graphql` - `invalidkeyerror` - `jsonpatch` +- `jwtbuiltins` - `jwtdecodeverify` - `jwtencodesign` +- `jwtencodesignheadererrors` +- `jwtencodesignpayloaderrors` - `jwtencodesignraw` - `jwtverifyhs256` - `jwtverifyhs384` @@ -319,10 +322,9 @@ The following test suites don't pass fully due to missing builtins: - `regoparsemodule` - `rendertemplate` -Cryptographically insecure `sha1` related builtins are intentionally not supported to discourage their use. - They are captured in the following [github issues](https://github.com/microsoft/regorus/issues?q=is%3Aopen+is%3Aissue+label%3Alib). +Cryptographically insecure `sha1` related builtins are intentionally not supported to discourage their use. ### Grammar diff --git a/bindings/wasm/Cargo.toml b/bindings/wasm/Cargo.toml index c67e07b..ee7c30a 100644 --- a/bindings/wasm/Cargo.toml +++ b/bindings/wasm/Cargo.toml @@ -25,7 +25,8 @@ wasm-bindgen = "0.2.100" # when targeting wasm32-unknown-unknown. uuid = { version = "1.15.1", default-features = false, features = ["v4", "fast-rng", "js"]} # Enable wasm_js. See https://docs.rs/getrandom/latest/getrandom/#webassembly-support -getrandom = { version = "0.3", features = ["std", "wasm_js"] } +getrandom_for_jsonschema = { package = "getrandom", version = "0.2.15", features = ["std", "js"] } +getrandom = { version = "0.3.1", features = ["std", "wasm_js"] } [dev-dependencies] wasm-bindgen-test = "0.3.40" diff --git a/src/builtins/jwt.rs b/src/builtins/jwt.rs deleted file mode 100644 index 3cfa594..0000000 --- a/src/builtins/jwt.rs +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -use crate::ast::{Expr, Ref}; -use crate::builtins; -use crate::builtins::utils::{ensure_args_count, ensure_string}; -use crate::*; - -use crate::lexer::Span; -use crate::value::Value; - -use itertools::Itertools; - -use anyhow::{bail, Result}; - -pub fn register(m: &mut builtins::BuiltinsMap<&'static str, builtins::BuiltinFcn>) { - m.insert("io.jwt.decode", (jwt_decode, 1)); - m.insert("io.jwt.decode_verify", (jwt_decode_verify, 2)); -} - -fn decode(span: &Span, jwt: String, strict: bool) -> Result { - let Some((Ok(header), Ok(payload), Ok(signature))) = jwt - .split('.') - .map(|p| data_encoding::BASE64URL_NOPAD.decode(p.as_bytes())) - .collect_tuple() - else { - if strict { - bail!(span.error("invalid jwt token")); - } - return Ok(Value::Undefined); - }; - - let header = String::from_utf8_lossy(&header).to_string(); - let payload = String::from_utf8_lossy(&payload).to_string(); - let signature = data_encoding::HEXLOWER_PERMISSIVE.encode(&signature); - - let signature = Value::String(signature.into()); - let header = Value::from_json_str(&header)?; - - if header["enc"] != Value::Undefined { - bail!(span.error("JWT is a JWE object, which is not supported")); - } - - if header["cty"] == "JWT".into() { - if payload.len() <= 2 || !payload.starts_with('"') || !payload.ends_with('"') { - bail!(span.error("invalid nested JWT")); - } - // Ignore "" - decode(span, payload[1..payload.len() - 1].to_string(), strict) - } else { - let payload = Value::from_json_str(&payload)?; - Ok(Value::from_array([header, payload, signature].into())) - } -} - -fn jwt_decode(span: &Span, params: &[Ref], args: &[Value], strict: bool) -> Result { - let name = "io.jwt.decode"; - ensure_args_count(span, name, params, args, 1)?; - let jwt = ensure_string(name, ¶ms[0], &args[0])?; - - decode(span, jwt.to_string(), strict) //header, payload, signature, strict) -} - -fn jwt_decode_verify( - span: &Span, - params: &[Ref], - args: &[Value], - _strict: bool, -) -> Result { - let name = "io.jwt.decode_verify"; - ensure_args_count(span, name, params, args, 2)?; - Ok(Value::Undefined) -} diff --git a/src/builtins/mod.rs b/src/builtins/mod.rs index adf6c89..5b984f1 100644 --- a/src/builtins/mod.rs +++ b/src/builtins/mod.rs @@ -18,8 +18,6 @@ mod glob; mod graph; #[cfg(feature = "http")] mod http; -#[cfg(feature = "jwt")] -mod jwt; pub mod numbers; mod objects; #[cfg(feature = "opa-runtime")] @@ -83,8 +81,6 @@ lazy_static! { //units::register(&mut m); types::register(&mut m); encoding::register(&mut m); - #[cfg(feature = "jwt")] - jwt::register(&mut m); #[cfg(feature = "time")] time::register(&mut m); diff --git a/src/builtins/opa.rs b/src/builtins/opa.rs index b427b77..56acca5 100644 --- a/src/builtins/opa.rs +++ b/src/builtins/opa.rs @@ -67,8 +67,6 @@ fn opa_runtime(span: &Span, params: &[Ref], args: &[Value], _strict: bool) "hex", #[cfg(feature = "http")] "http", - #[cfg(feature = "jwt")] - "jwt", #[cfg(feature = "jsonschema")] "jsonschema", #[cfg(feature = "opa-runtime")] diff --git a/tests/opa.passing b/tests/opa.passing index 9a41649..ee212a1 100644 --- a/tests/opa.passing +++ b/tests/opa.passing @@ -52,7 +52,6 @@ v0/jsonfilteridempotent v0/jsonremove v0/jsonremoveidempotent v0/jsonschema -v0/jwtbuiltins v0/negation v0/nestedreferences v0/numbersrange @@ -165,7 +164,6 @@ v1/jsonfilteridempotent v1/jsonremove v1/jsonremoveidempotent v1/jsonschema -v1/jwtbuiltins v1/negation v1/nestedreferences v1/numbersrange diff --git a/tests/opa.rs b/tests/opa.rs index e46bd37..7595a7d 100644 --- a/tests/opa.rs +++ b/tests/opa.rs @@ -210,6 +210,10 @@ fn run_opa_tests(opa_tests_dir: String, folders: &[String]) -> Result<()> { if let Some(ref mut want_result) = &mut case.want_result { want_result.as_array_mut()?.sort(); } + } else if case.note == "withkeyword/builtin: nested, multiple mocks" { + // Mocks non-existent jwt builtin. + println!("skipping mock test for io.jwt.decode_verify: {}", case.note); + continue; } // Normalize for comparison.