From 45df4d0d9b577fecee798d672695fe24ff57fb1b Mon Sep 17 00:00:00 2001 From: mo khan Date: Tue, 15 Jul 2025 16:37:08 -0600 Subject: feat: migrate from Cedar to SpiceDB authorization system This is a major architectural change that replaces the Cedar policy-based authorization system with SpiceDB's relation-based authorization. Key changes: - Migrate from Rust to Go implementation - Replace Cedar policies with SpiceDB schema and relationships - Switch from envoy `ext_authz` with Cedar to SpiceDB permission checks - Update build system and dependencies for Go ecosystem - Maintain Envoy integration for external authorization This change enables more flexible permission modeling through SpiceDB's Google Zanzibar inspired relation-based system, supporting complex hierarchical permissions that were difficult to express in Cedar. Breaking change: Existing Cedar policies and Rust-based configuration will no longer work and need to be migrated to SpiceDB schema. --- vendor/time/src/sys/local_offset_at/imp.rs | 8 -- vendor/time/src/sys/local_offset_at/mod.rs | 23 ----- vendor/time/src/sys/local_offset_at/unix.rs | 101 ---------------------- vendor/time/src/sys/local_offset_at/wasm_js.rs | 16 ---- vendor/time/src/sys/local_offset_at/windows.rs | 113 ------------------------- vendor/time/src/sys/mod.rs | 11 --- vendor/time/src/sys/refresh_tz/imp.rs | 9 -- vendor/time/src/sys/refresh_tz/mod.rs | 17 ---- vendor/time/src/sys/refresh_tz/unix.rs | 48 ----------- 9 files changed, 346 deletions(-) delete mode 100644 vendor/time/src/sys/local_offset_at/imp.rs delete mode 100644 vendor/time/src/sys/local_offset_at/mod.rs delete mode 100644 vendor/time/src/sys/local_offset_at/unix.rs delete mode 100644 vendor/time/src/sys/local_offset_at/wasm_js.rs delete mode 100644 vendor/time/src/sys/local_offset_at/windows.rs delete mode 100644 vendor/time/src/sys/mod.rs delete mode 100644 vendor/time/src/sys/refresh_tz/imp.rs delete mode 100644 vendor/time/src/sys/refresh_tz/mod.rs delete mode 100644 vendor/time/src/sys/refresh_tz/unix.rs (limited to 'vendor/time/src/sys') diff --git a/vendor/time/src/sys/local_offset_at/imp.rs b/vendor/time/src/sys/local_offset_at/imp.rs deleted file mode 100644 index 251fa667..00000000 --- a/vendor/time/src/sys/local_offset_at/imp.rs +++ /dev/null @@ -1,8 +0,0 @@ -//! A fallback for any OS not covered. - -use crate::{OffsetDateTime, UtcOffset}; - -#[allow(clippy::missing_docs_in_private_items)] -pub(super) fn local_offset_at(_datetime: OffsetDateTime) -> Option { - None -} diff --git a/vendor/time/src/sys/local_offset_at/mod.rs b/vendor/time/src/sys/local_offset_at/mod.rs deleted file mode 100644 index 04cfffd5..00000000 --- a/vendor/time/src/sys/local_offset_at/mod.rs +++ /dev/null @@ -1,23 +0,0 @@ -//! A method to obtain the local offset from UTC. - -#![allow(clippy::missing_const_for_fn)] - -#[cfg_attr(target_family = "windows", path = "windows.rs")] -#[cfg_attr(target_family = "unix", path = "unix.rs")] -#[cfg_attr( - all( - target_family = "wasm", - not(any(target_os = "emscripten", target_os = "wasi")), - feature = "wasm-bindgen" - ), - path = "wasm_js.rs" -)] -mod imp; - -use crate::{OffsetDateTime, UtcOffset}; - -/// Attempt to obtain the system's UTC offset. If the offset cannot be determined, `None` is -/// returned. -pub(crate) fn local_offset_at(datetime: OffsetDateTime) -> Option { - imp::local_offset_at(datetime) -} diff --git a/vendor/time/src/sys/local_offset_at/unix.rs b/vendor/time/src/sys/local_offset_at/unix.rs deleted file mode 100644 index d036a0e0..00000000 --- a/vendor/time/src/sys/local_offset_at/unix.rs +++ /dev/null @@ -1,101 +0,0 @@ -//! Get the system's UTC offset on Unix. - -use core::mem::MaybeUninit; - -use crate::{OffsetDateTime, UtcOffset}; - -/// Convert the given Unix timestamp to a `libc::tm`. Returns `None` on any error. -fn timestamp_to_tm(timestamp: i64) -> Option { - // The exact type of `timestamp` beforehand can vary, so this conversion is necessary. - #[allow(clippy::useless_conversion)] - let timestamp = timestamp.try_into().ok()?; - - let mut tm = MaybeUninit::uninit(); - - // Safety: We are calling a system API, which mutates the `tm` variable. If a null - // pointer is returned, an error occurred. - let tm_ptr = unsafe { libc::localtime_r(×tamp, tm.as_mut_ptr()) }; - - if tm_ptr.is_null() { - None - } else { - // Safety: The value was initialized, as we no longer have a null pointer. - Some(unsafe { tm.assume_init() }) - } -} - -/// Convert a `libc::tm` to a `UtcOffset`. Returns `None` on any error. -// This is available to any target known to have the `tm_gmtoff` extension. -#[cfg(any( - target_os = "redox", - target_os = "linux", - target_os = "l4re", - target_os = "android", - target_os = "emscripten", - target_os = "macos", - target_os = "ios", - target_os = "watchos", - target_os = "freebsd", - target_os = "dragonfly", - target_os = "openbsd", - target_os = "netbsd", - target_os = "haiku", -))] -fn tm_to_offset(_unix_timestamp: i64, tm: libc::tm) -> Option { - let seconds = tm.tm_gmtoff.try_into().ok()?; - UtcOffset::from_whole_seconds(seconds).ok() -} - -/// Convert a `libc::tm` to a `UtcOffset`. Returns `None` on any error. -/// -/// This method can return an incorrect value, as it only approximates the `tm_gmtoff` field. The -/// reason for this is that daylight saving time does not start on the same date every year, nor are -/// the rules for daylight saving time the same for every year. This implementation assumes 1970 is -/// equivalent to every other year, which is not always the case. -#[cfg(not(any( - target_os = "redox", - target_os = "linux", - target_os = "l4re", - target_os = "android", - target_os = "emscripten", - target_os = "macos", - target_os = "ios", - target_os = "watchos", - target_os = "freebsd", - target_os = "dragonfly", - target_os = "openbsd", - target_os = "netbsd", - target_os = "haiku", -)))] -fn tm_to_offset(unix_timestamp: i64, tm: libc::tm) -> Option { - use crate::Date; - - let mut tm = tm; - if tm.tm_sec == 60 { - // Leap seconds are not currently supported. - tm.tm_sec = 59; - } - - let local_timestamp = - Date::from_ordinal_date(1900 + tm.tm_year, u16::try_from(tm.tm_yday).ok()? + 1) - .ok()? - .with_hms( - tm.tm_hour.try_into().ok()?, - tm.tm_min.try_into().ok()?, - tm.tm_sec.try_into().ok()?, - ) - .ok()? - .assume_utc() - .unix_timestamp(); - - let diff_secs = (local_timestamp - unix_timestamp).try_into().ok()?; - - UtcOffset::from_whole_seconds(diff_secs).ok() -} - -/// Obtain the system's UTC offset. -pub(super) fn local_offset_at(datetime: OffsetDateTime) -> Option { - let unix_timestamp = datetime.unix_timestamp(); - let tm = timestamp_to_tm(unix_timestamp)?; - tm_to_offset(unix_timestamp, tm) -} diff --git a/vendor/time/src/sys/local_offset_at/wasm_js.rs b/vendor/time/src/sys/local_offset_at/wasm_js.rs deleted file mode 100644 index a985e7c4..00000000 --- a/vendor/time/src/sys/local_offset_at/wasm_js.rs +++ /dev/null @@ -1,16 +0,0 @@ -use num_conv::prelude::*; - -use crate::convert::*; -use crate::{OffsetDateTime, UtcOffset}; - -/// Obtain the system's UTC offset. -pub(super) fn local_offset_at(datetime: OffsetDateTime) -> Option { - let js_date: js_sys::Date = datetime.into(); - // The number of minutes returned by getTimezoneOffset() is positive if the local time zone - // is behind UTC, and negative if the local time zone is ahead of UTC. For example, - // for UTC+10, -600 will be returned. - let timezone_offset = - (js_date.get_timezone_offset() as i32) * -Minute::per(Hour).cast_signed().extend::(); - - UtcOffset::from_whole_seconds(timezone_offset).ok() -} diff --git a/vendor/time/src/sys/local_offset_at/windows.rs b/vendor/time/src/sys/local_offset_at/windows.rs deleted file mode 100644 index d1442920..00000000 --- a/vendor/time/src/sys/local_offset_at/windows.rs +++ /dev/null @@ -1,113 +0,0 @@ -//! Get the system's UTC offset on Windows. - -use core::mem::MaybeUninit; - -use num_conv::prelude::*; - -use crate::convert::*; -use crate::{OffsetDateTime, UtcOffset}; - -// ffi: WINAPI FILETIME struct -#[repr(C)] -#[allow(non_snake_case, clippy::missing_docs_in_private_items)] -struct FileTime { - dwLowDateTime: u32, - dwHighDateTime: u32, -} - -// ffi: WINAPI SYSTEMTIME struct -#[repr(C)] -#[allow(non_snake_case, clippy::missing_docs_in_private_items)] -struct SystemTime { - wYear: u16, - wMonth: u16, - wDayOfWeek: u16, - wDay: u16, - wHour: u16, - wMinute: u16, - wSecond: u16, - wMilliseconds: u16, -} - -#[link(name = "kernel32")] -extern "system" { - // https://docs.microsoft.com/en-us/windows/win32/api/timezoneapi/nf-timezoneapi-systemtimetofiletime - fn SystemTimeToFileTime(lpSystemTime: *const SystemTime, lpFileTime: *mut FileTime) -> i32; - - // https://docs.microsoft.com/en-us/windows/win32/api/timezoneapi/nf-timezoneapi-systemtimetotzspecificlocaltime - fn SystemTimeToTzSpecificLocalTime( - lpTimeZoneInformation: *const core::ffi::c_void, // We only pass `nullptr` here - lpUniversalTime: *const SystemTime, - lpLocalTime: *mut SystemTime, - ) -> i32; -} - -/// Convert a `SYSTEMTIME` to a `FILETIME`. Returns `None` if any error occurred. -fn systemtime_to_filetime(systime: &SystemTime) -> Option { - let mut ft = MaybeUninit::uninit(); - - // Safety: `SystemTimeToFileTime` is thread-safe. - if 0 == unsafe { SystemTimeToFileTime(systime, ft.as_mut_ptr()) } { - // failed - None - } else { - // Safety: The call succeeded. - Some(unsafe { ft.assume_init() }) - } -} - -/// Convert a `FILETIME` to an `i64`, representing a number of seconds. -fn filetime_to_secs(filetime: &FileTime) -> i64 { - /// FILETIME represents 100-nanosecond intervals - const FT_TO_SECS: u64 = Nanosecond::per(Second) as u64 / 100; - ((filetime.dwHighDateTime.extend::() << 32 | filetime.dwLowDateTime.extend::()) - / FT_TO_SECS) as i64 -} - -/// Convert an [`OffsetDateTime`] to a `SYSTEMTIME`. -fn offset_to_systemtime(datetime: OffsetDateTime) -> SystemTime { - let (_, month, day_of_month) = datetime.to_offset(UtcOffset::UTC).date().to_calendar_date(); - SystemTime { - wYear: datetime.year().cast_unsigned().truncate(), - wMonth: u8::from(month).extend(), - wDay: day_of_month.extend(), - wDayOfWeek: 0, // ignored - wHour: datetime.hour().extend(), - wMinute: datetime.minute().extend(), - wSecond: datetime.second().extend(), - wMilliseconds: datetime.millisecond(), - } -} - -/// Obtain the system's UTC offset. -pub(super) fn local_offset_at(datetime: OffsetDateTime) -> Option { - // This function falls back to UTC if any system call fails. - let systime_utc = offset_to_systemtime(datetime.to_offset(UtcOffset::UTC)); - - // Safety: `local_time` is only read if it is properly initialized, and - // `SystemTimeToTzSpecificLocalTime` is thread-safe. - let systime_local = unsafe { - let mut local_time = MaybeUninit::uninit(); - - if 0 == SystemTimeToTzSpecificLocalTime( - core::ptr::null(), // use system's current timezone - &systime_utc, - local_time.as_mut_ptr(), - ) { - // call failed - return None; - } else { - local_time.assume_init() - } - }; - - // Convert SYSTEMTIMEs to FILETIMEs so we can perform arithmetic on them. - let ft_system = systemtime_to_filetime(&systime_utc)?; - let ft_local = systemtime_to_filetime(&systime_local)?; - - let diff_secs = (filetime_to_secs(&ft_local) - filetime_to_secs(&ft_system)) - .try_into() - .ok()?; - - UtcOffset::from_whole_seconds(diff_secs).ok() -} diff --git a/vendor/time/src/sys/mod.rs b/vendor/time/src/sys/mod.rs deleted file mode 100644 index 76ca93b5..00000000 --- a/vendor/time/src/sys/mod.rs +++ /dev/null @@ -1,11 +0,0 @@ -//! Functions with a common interface that rely on system calls. - -#[cfg(feature = "local-offset")] -mod local_offset_at; -#[cfg(feature = "local-offset")] -mod refresh_tz; - -#[cfg(feature = "local-offset")] -pub(crate) use self::local_offset_at::local_offset_at; -#[cfg(feature = "local-offset")] -pub(crate) use self::refresh_tz::{refresh_tz, refresh_tz_unchecked}; diff --git a/vendor/time/src/sys/refresh_tz/imp.rs b/vendor/time/src/sys/refresh_tz/imp.rs deleted file mode 100644 index 6f8b1328..00000000 --- a/vendor/time/src/sys/refresh_tz/imp.rs +++ /dev/null @@ -1,9 +0,0 @@ -//! A fallback for any OS not covered. - -#[allow(clippy::missing_docs_in_private_items)] -pub(super) unsafe fn refresh_tz_unchecked() {} - -#[allow(clippy::missing_docs_in_private_items)] -pub(super) fn refresh_tz() -> Option<()> { - Some(()) -} diff --git a/vendor/time/src/sys/refresh_tz/mod.rs b/vendor/time/src/sys/refresh_tz/mod.rs deleted file mode 100644 index 90ddaa99..00000000 --- a/vendor/time/src/sys/refresh_tz/mod.rs +++ /dev/null @@ -1,17 +0,0 @@ -#[cfg_attr(target_family = "unix", path = "unix.rs")] -mod imp; - -/// Update time zone information from the system. -/// -/// For safety documentation, see [`time::util::refresh_tz`]. -pub(crate) unsafe fn refresh_tz_unchecked() { - // Safety: The caller must uphold the safety requirements. - unsafe { imp::refresh_tz_unchecked() } -} - -/// Attempt to update time zone information from the system. -/// -/// Returns `None` if the call is not known to be sound. -pub(crate) fn refresh_tz() -> Option<()> { - imp::refresh_tz() -} diff --git a/vendor/time/src/sys/refresh_tz/unix.rs b/vendor/time/src/sys/refresh_tz/unix.rs deleted file mode 100644 index 6c9813e2..00000000 --- a/vendor/time/src/sys/refresh_tz/unix.rs +++ /dev/null @@ -1,48 +0,0 @@ -/// Whether the operating system has a thread-safe environment. This allows bypassing the check for -/// if the process is multi-threaded. -// This is the same value as `cfg!(target_os = "x")`. -// Use byte-strings to work around current limitations of const eval. -const OS_HAS_THREAD_SAFE_ENVIRONMENT: bool = match std::env::consts::OS.as_bytes() { - // https://github.com/illumos/illumos-gate/blob/0fb96ba1f1ce26ff8b286f8f928769a6afcb00a6/usr/src/lib/libc/port/gen/getenv.c - b"illumos" - // https://github.com/NetBSD/src/blob/f45028636a44111bc4af44d460924958a4460844/lib/libc/stdlib/getenv.c - // https://github.com/NetBSD/src/blob/f45028636a44111bc4af44d460924958a4460844/lib/libc/stdlib/setenv.c - | b"netbsd" - => true, - _ => false, -}; - -/// Update time zone information from the system. -/// -/// For safety documentation, see [`time::util::refresh_tz`]. -pub(super) unsafe fn refresh_tz_unchecked() { - extern "C" { - #[cfg_attr(target_os = "netbsd", link_name = "__tzset50")] - fn tzset(); - } - - // Safety: The caller must uphold the safety requirements. - unsafe { tzset() }; -} - -/// Attempt to update time zone information from the system. Returns `None` if the call is not known -/// to be sound. -pub(super) fn refresh_tz() -> Option<()> { - // Refresh $TZ if and only if the call is known to be sound. - // - // Soundness can be guaranteed either by knowledge of the operating system or knowledge that the - // process is single-threaded. If the process is single-threaded, then the environment cannot - // be mutated by a different thread in the process while execution of this function is taking - // place, which can cause a segmentation fault by dereferencing a dangling pointer. - // - // If the `num_threads` crate is incapable of determining the number of running threads, then - // we conservatively return `None` to avoid a soundness bug. - - if OS_HAS_THREAD_SAFE_ENVIRONMENT || num_threads::is_single_threaded() == Some(true) { - // Safety: The caller must uphold the safety requirements. - unsafe { refresh_tz_unchecked() }; - Some(()) - } else { - None - } -} -- cgit v1.2.3