create-feltdb 0.8.7 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/package-versions.js +1 -1
- package/dist/server-source/crates/feltdb/src/lib.rs +343 -1
- package/dist/server-source/crates/feltdb/src/state_contract.rs +465 -107
- package/dist/server-source/crates/feltdb/src/state_model.rs +15 -2
- package/dist/server-source/crates/feltdb-server/src/control_plane.rs +845 -0
- package/dist/server-source/crates/feltdb-server/src/lib.rs +1 -0
- package/dist/server-source/crates/feltdb-server/src/main.rs +1349 -5
- package/dist/server-source/crates/feltdb-server/src/principals.rs +37 -0
- package/dist/server-source/crates/feltdb-wasm/src/lib.rs +1 -1
- package/package.json +1 -1
|
@@ -160,6 +160,43 @@ impl PrincipalStore {
|
|
|
160
160
|
.cloned()
|
|
161
161
|
.collect())
|
|
162
162
|
}
|
|
163
|
+
/// One principal's own audit trail: grants, creations, and the
|
|
164
|
+
/// authorization decisions taken for it.
|
|
165
|
+
///
|
|
166
|
+
/// The store has recorded these since it existed and nothing read them
|
|
167
|
+
/// back. A human governing an agent needs exactly this — what the agent was
|
|
168
|
+
/// allowed to do, when, and who allowed it — so it is readable under the
|
|
169
|
+
/// same application authorization as listing principals.
|
|
170
|
+
pub fn audit_for(
|
|
171
|
+
&self,
|
|
172
|
+
actor: &str,
|
|
173
|
+
tenancy: &TenancyStore,
|
|
174
|
+
application_id: &str,
|
|
175
|
+
principal_id: Option<&str>,
|
|
176
|
+
limit: usize,
|
|
177
|
+
) -> Result<Vec<PrincipalAuditEvent>, String> {
|
|
178
|
+
let tenant_id = Self::application_context(tenancy, application_id)?;
|
|
179
|
+
if !tenancy.authorize_application(actor, &tenant_id, application_id, "applications:read") {
|
|
180
|
+
return Err("forbidden".into());
|
|
181
|
+
}
|
|
182
|
+
let records = self
|
|
183
|
+
.records
|
|
184
|
+
.read()
|
|
185
|
+
.map_err(|_| "principal store lock poisoned")?;
|
|
186
|
+
let mut events: Vec<PrincipalAuditEvent> = records
|
|
187
|
+
.audit
|
|
188
|
+
.iter()
|
|
189
|
+
.filter(|event| event.application_id == application_id)
|
|
190
|
+
.filter(|event| principal_id.is_none_or(|id| event.principal_id == id))
|
|
191
|
+
.cloned()
|
|
192
|
+
.collect();
|
|
193
|
+
// Newest first: an operator reads the most recent decision, then
|
|
194
|
+
// works backwards.
|
|
195
|
+
events.reverse();
|
|
196
|
+
events.truncate(limit);
|
|
197
|
+
Ok(events)
|
|
198
|
+
}
|
|
199
|
+
|
|
163
200
|
pub fn create(
|
|
164
201
|
&self,
|
|
165
202
|
actor: &str,
|
|
@@ -302,7 +302,7 @@ impl JsDb {
|
|
|
302
302
|
serde_json::from_str(authorization).map_err(|e| e.to_string())?;
|
|
303
303
|
let query: feltdb::state_contract::CanonicalQuery =
|
|
304
304
|
serde_json::from_str(query).map_err(|e| e.to_string())?;
|
|
305
|
-
let context = feltdb::state_contract::
|
|
305
|
+
let context = feltdb::state_contract::begin_query_read(
|
|
306
306
|
&self.db,
|
|
307
307
|
&schema,
|
|
308
308
|
state_namespace,
|