Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cedar-policy-validator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ wasm = ["serde-wasm-bindgen", "tsify", "wasm-bindgen"]
similar-asserts = "1.5.0"
cool_asserts = "2.0"
cedar-policy-core = { version = "=4.0.0", path = "../cedar-policy-core", features = ["test-util"] }
miette = { version = "7.1.0", features = ["fancy"] }

[build-dependencies]
lalrpop = "0.20.0"
2 changes: 1 addition & 1 deletion cedar-policy-validator/src/cedar_schema/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ pub fn json_schema_to_cedar_schema_str<N: Display>(
.common_types
.keys()
.map(|ty_name| {
RawName::new_from_unreserved(ty_name.clone())
RawName::new_from_unreserved(ty_name.clone().into())
.qualify_with_name(name.as_ref())
.to_smolstr()
})
Expand Down
14 changes: 6 additions & 8 deletions cedar-policy-validator/src/cedar_schema/to_json_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ use super::{
ToJsonSchemaError, ToJsonSchemaErrors,
},
};
use crate::{cedar_schema, json_schema, RawName};
use crate::{
cedar_schema,
json_schema::{self, is_reserved_schema_keyword, CommonTypeId},
RawName,
};

impl From<cedar_schema::Path> for RawName {
fn from(p: cedar_schema::Path) -> Self {
Expand Down Expand Up @@ -234,12 +238,6 @@ fn convert_namespace(
Ok((ns_name, def))
}

// Test if this id is a reserved JSON schema keyword.
// Issue: https://github.com/cedar-policy/cedar/issues/1070
fn is_reserved_schema_keyword(id: &UnreservedId) -> bool {
matches!(id.as_ref(), "Set" | "Record" | "Entity" | "Extension")
}

impl TryFrom<Namespace> for json_schema::NamespaceDefinition<RawName> {
type Error = ToJsonSchemaErrors;

Expand Down Expand Up @@ -268,7 +266,7 @@ impl TryFrom<Namespace> for json_schema::NamespaceDefinition<RawName> {
Err(ToJsonSchemaError::reserved_keyword(id, name_loc))
} else {
Ok((
id,
CommonTypeId::unchecked(id),
cedar_type_to_json_type(decl.def).map_err(EAMapError::from)?,
))
}
Expand Down
56 changes: 55 additions & 1 deletion cedar-policy-validator/src/json_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,60 @@ impl<N: Display> Fragment<N> {
}
}

/// An [`UnreservedId`] that cannot be reserved JSON schema keywords
/// like `Set`, `Long`, and etc.
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)]
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
#[cfg_attr(feature = "wasm", tsify(into_wasm_abi, from_wasm_abi))]
pub struct CommonTypeId(#[cfg_attr(feature = "wasm", tsify(type = "string"))] UnreservedId);

impl From<CommonTypeId> for UnreservedId {
fn from(value: CommonTypeId) -> Self {
value.0
}
}

impl CommonTypeId {
pub(crate) fn unchecked(id: UnreservedId) -> Self {
Self(id)
}
}

impl Display for CommonTypeId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}

// Test if this id is a reserved JSON schema keyword.
// Issues:
// https://github.com/cedar-policy/cedar/issues/1070
// https://github.com/cedar-policy/cedar/issues/1139
pub(crate) fn is_reserved_schema_keyword(id: &UnreservedId) -> bool {
matches!(
id.as_ref(),
"Bool" | "Boolean" | "Entity" | "Extension" | "Long" | "Record" | "Set" | "String"
)
}

/// Deserialize a [`CommonTypeId`]
impl<'de> Deserialize<'de> for CommonTypeId {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: Deserializer<'de>,
{
UnreservedId::deserialize(deserializer).and_then(|id| {
if is_reserved_schema_keyword(&id) {
Err(serde::de::Error::custom(format!(
"Used reserved schema keyword: {id} "
)))
} else {
Ok(Self(id))
}
})
}
}

/// A single namespace definition from a Fragment.
/// This is composed of common types, entity types, and action definitions.
///
Expand All @@ -194,7 +248,7 @@ pub struct NamespaceDefinition<N> {
#[serde(default)]
#[serde(skip_serializing_if = "HashMap::is_empty")]
#[serde(with = "::serde_with::rust::maps_duplicate_key_is_error")]
pub common_types: HashMap<UnreservedId, Type<N>>,
pub common_types: HashMap<CommonTypeId, Type<N>>,
#[serde(with = "::serde_with::rust::maps_duplicate_key_is_error")]
pub entity_types: HashMap<UnreservedId, EntityType<N>>,
#[serde(with = "::serde_with::rust::maps_duplicate_key_is_error")]
Expand Down
Loading
Loading