Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into feature/shaobo/rfc53
Browse files Browse the repository at this point in the history
Signed-off-by: Shaobo He <[email protected]>
  • Loading branch information
shaobo-he-aws committed Jan 14, 2025
2 parents 8811f1a + 875ba48 commit df04187
Show file tree
Hide file tree
Showing 38 changed files with 1,323 additions and 1,156 deletions.
344 changes: 0 additions & 344 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion cedar-policy-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ prost = { version = "0.13", optional = true }

[features]
# by default, enable all Cedar extensions
default = ["ipaddr", "decimal", "datetime"]
default = ["ipaddr", "decimal"]
ipaddr = []
decimal = ["dep:regex"]
datetime = ["dep:chrono", "dep:regex"]
Expand Down
36 changes: 14 additions & 22 deletions cedar-policy-core/src/ast/extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,15 @@
* limitations under the License.
*/

pub use names::TYPES_WITH_OPERATOR_OVERLOADING;

use crate::ast::*;
use crate::entities::SchemaType;
use crate::evaluator;
use std::any::Any;
use std::collections::HashMap;
use std::collections::{BTreeSet, HashMap};
use std::fmt::Debug;
use std::panic::{RefUnwindSafe, UnwindSafe};
use std::sync::Arc;

// PANIC SAFETY: `Name`s in here are valid `Name`s
#[allow(clippy::expect_used)]
mod names {
use std::collections::BTreeSet;

use super::Name;

lazy_static::lazy_static! {
/// Extension type names that support operator overloading
// INVARIANT: this set must not be empty.
pub static ref TYPES_WITH_OPERATOR_OVERLOADING : BTreeSet<Name> =
BTreeSet::from_iter(
[Name::parse_unqualified_name("datetime").expect("valid identifier"),
Name::parse_unqualified_name("duration").expect("valid identifier")]
);
}
}

/// Cedar extension.
///
/// An extension can define new types and functions on those types. (Currently,
Expand All @@ -54,14 +34,21 @@ pub struct Extension {
name: Name,
/// Extension functions. These are legal to call in Cedar expressions.
functions: HashMap<Name, ExtensionFunction>,
/// Types with operator overloading
types_with_operator_overloading: BTreeSet<Name>,
}

impl Extension {
/// Create a new `Extension` with the given name and extension functions
pub fn new(name: Name, functions: impl IntoIterator<Item = ExtensionFunction>) -> Self {
pub fn new(
name: Name,
functions: impl IntoIterator<Item = ExtensionFunction>,
types_with_operator_overloading: impl IntoIterator<Item = Name>,
) -> Self {
Self {
name,
functions: functions.into_iter().map(|f| (f.name.clone(), f)).collect(),
types_with_operator_overloading: types_with_operator_overloading.into_iter().collect(),
}
}

Expand All @@ -86,6 +73,11 @@ impl Extension {
pub fn ext_types(&self) -> impl Iterator<Item = &Name> + '_ {
self.funcs().flat_map(|func| func.ext_types())
}

/// Iterate over extension types with operator overloading
pub fn types_with_operator_overloading(&self) -> impl Iterator<Item = &Name> + '_ {
self.types_with_operator_overloading.iter()
}
}

impl std::fmt::Debug for Extension {
Expand Down
82 changes: 40 additions & 42 deletions cedar-policy-core/src/authorizer/partial_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,23 +337,11 @@ impl PartialResponse {
) -> Result<Request, ConcretizationError> {
let mut context = self.request.context.clone();

let principal = if let Some((key, val)) = mapping.get_key_value("principal") {
self.request.principal().concretize(key, val)?
} else {
self.request.principal().clone()
};
let principal = self.request.principal().concretize("principal", mapping)?;

let action = if let Some((key, val)) = mapping.get_key_value("action") {
self.request.action().concretize(key, val)?
} else {
self.request.action().clone()
};
let action = self.request.action.concretize("action", mapping)?;

let resource = if let Some((key, val)) = mapping.get_key_value("resource") {
self.request.resource().concretize(key, val)?
} else {
self.request.resource().clone()
};
let resource = self.request.resource.concretize("resource", mapping)?;

if let Some((key, val)) = mapping.get_key_value("context") {
if let Ok(attrs) = val.get_as_record() {
Expand Down Expand Up @@ -406,38 +394,48 @@ impl PartialResponse {
}

impl EntityUIDEntry {
fn concretize(&self, key: &SmolStr, val: &Value) -> Result<Self, ConcretizationError> {
if let Ok(uid) = val.get_as_entity() {
match self {
EntityUIDEntry::Known { euid, .. } => Err(ConcretizationError::VarConfictError {
id: key.to_owned(),
existing_value: euid.as_ref().clone().into(),
given_value: val.clone(),
}),
EntityUIDEntry::Unknown { ty: None, .. } => {
Ok(EntityUIDEntry::known(uid.clone(), None))
}
EntityUIDEntry::Unknown {
ty: Some(type_of_unknown),
..
} => {
if type_of_unknown == uid.entity_type() {
Ok(EntityUIDEntry::known(uid.clone(), None))
} else {
Err(ConcretizationError::EntityTypeConfictError {
id: key.to_owned(),
existing_value: type_of_unknown.clone(),
given_value: val.to_owned(),
fn concretize(
&self,
key: &str,
mapping: &HashMap<SmolStr, Value>,
) -> Result<Self, ConcretizationError> {
if let Some(val) = mapping.get(key) {
if let Ok(uid) = val.get_as_entity() {
match self {
EntityUIDEntry::Known { euid, .. } => {
Err(ConcretizationError::VarConfictError {
id: key.into(),
existing_value: euid.as_ref().clone().into(),
given_value: val.clone(),
})
}
EntityUIDEntry::Unknown { ty: None, .. } => {
Ok(EntityUIDEntry::known(uid.clone(), None))
}
EntityUIDEntry::Unknown {
ty: Some(type_of_unknown),
..
} => {
if type_of_unknown == uid.entity_type() {
Ok(EntityUIDEntry::known(uid.clone(), None))
} else {
Err(ConcretizationError::EntityTypeConfictError {
id: key.into(),
existing_value: type_of_unknown.clone(),
given_value: val.to_owned(),
})
}
}
}
} else {
Err(ConcretizationError::ValueError {
id: key.into(),
expected_type: "entity",
given_value: val.to_owned(),
})
}
} else {
Err(ConcretizationError::ValueError {
id: key.to_owned(),
expected_type: "entity",
given_value: val.to_owned(),
})
Ok(self.clone())
}
}
}
Expand Down
Loading

0 comments on commit df04187

Please sign in to comment.