@feltdb/core 0.4.15 → 0.4.16
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/cli/index.js +1 -1
- package/dist/create/package-versions.js +1 -1
- package/dist/create/server-source/crates/feltdb/Cargo.toml +1 -1
- package/dist/create/server-source/crates/feltdb/src/application.rs +93 -0
- package/dist/create/server-source/crates/feltdb/src/authorization_security_tests.rs +787 -0
- package/dist/create/server-source/crates/feltdb/src/lib.rs +139 -0
- package/dist/create/server-source/crates/feltdb/src/policy_evaluation.rs +1669 -0
- package/dist/create/server-source/crates/feltdb/src/state_contract.rs +1269 -15
- package/dist/create/server-source/crates/feltdb/tests/pr7_self_authorization_proof.rs +406 -0
- package/dist/create/server-source/crates/feltdb/tests/pr8_vocabulary_assessment.rs +908 -0
- package/dist/create/server-source/crates/feltdb/tests/pr9_phase2_boundary_tests.rs +1028 -0
- package/dist/create/server-source/crates/feltdb/tests/pr9_phase3a_path_a_tests.rs +332 -0
- package/dist/create/server-source/crates/feltdb/tests/pr9_phase3c_authorized_mutations.rs +342 -0
- package/dist/create/server-source/crates/feltdb/tests/pr9_phase3c_role_based_authorization.rs +313 -0
- package/dist/create/server-source/crates/feltdb/tests/pr9_phase3c_simple_auth_delete.rs +90 -0
- package/dist/create/server-source/crates/feltdb/tests/pr9_phase3c_team_delete_role_authorization.rs +571 -0
- package/dist/create/server-source/crates/feltdb/tests/pr9_teams_role_based_access.rs +506 -0
- package/dist/create/server-source/crates/feltdb/tests/saas_authorization_integration.rs +81 -0
- package/dist/create/server-source/crates/feltdb/tests/saas_invitation_lifecycle.rs +434 -0
- package/dist/create/server-source/crates/feltdb-server/src/main.rs +130 -23
- package/dist/create/server-source/crates/feltdb-wasm/src/lib.rs +2 -2
- package/dist/db.d.ts +10 -0
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +3 -1
- package/dist/file-db.d.ts +69 -0
- package/dist/file-db.d.ts.map +1 -0
- package/dist/file-db.js +355 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/studio-app/assets/{feltdb_wasm-CJEJryDx.js → feltdb_wasm-CBGD0zRu.js} +1 -1
- package/dist/studio-app/assets/feltdb_wasm_bg-C6ATF9mJ.wasm +0 -0
- package/dist/studio-app/assets/{index-D_p8T7nO.js → index-D74dfBgZ.js} +9 -9
- package/dist/studio-app/index.html +1 -1
- package/dist/wasm/feltdb_wasm_bg.wasm +0 -0
- package/package.json +7 -2
- package/dist/studio-app/assets/feltdb_wasm_bg-BJxQXtoo.wasm +0 -0
package/dist/cli/index.js
CHANGED
|
@@ -23,7 +23,7 @@ import * as path from 'path';
|
|
|
23
23
|
import * as readline from 'readline';
|
|
24
24
|
import { getClient } from './api-client.js';
|
|
25
25
|
import { loadFeltDBConfig, createDefaultConfig, validateModel, } from './config.js';
|
|
26
|
-
const VERSION = '0.4.
|
|
26
|
+
const VERSION = '0.4.16';
|
|
27
27
|
function prompt(question) {
|
|
28
28
|
const rl = readline.createInterface({
|
|
29
29
|
input: process.stdin,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// One release train keeps generated applications installable. The repository
|
|
2
2
|
// validation script checks these values against every workspace manifest.
|
|
3
|
-
export const FELTDB_PACKAGE_VERSION = '0.4.
|
|
3
|
+
export const FELTDB_PACKAGE_VERSION = '0.4.16';
|
|
4
4
|
export const feltdbPackageRange = `^${FELTDB_PACKAGE_VERSION}`;
|
|
@@ -15,7 +15,7 @@ rand = "0.8"
|
|
|
15
15
|
bincode = "1"
|
|
16
16
|
|
|
17
17
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
|
18
|
-
tokio = { version = "1", features = ["net", "io-util"] }
|
|
18
|
+
tokio = { version = "1", features = ["net", "io-util", "rt-multi-thread"] }
|
|
19
19
|
|
|
20
20
|
[dev-dependencies]
|
|
21
21
|
criterion = { version = "0.5", features = ["html_reports"] }
|
|
@@ -152,6 +152,10 @@ pub struct PolicyDefinition {
|
|
|
152
152
|
pub name: String,
|
|
153
153
|
pub resource: String,
|
|
154
154
|
#[serde(default)]
|
|
155
|
+
pub read: Option<String>,
|
|
156
|
+
#[serde(default)]
|
|
157
|
+
pub write: Option<String>,
|
|
158
|
+
#[serde(default)]
|
|
155
159
|
pub capabilities: Vec<String>,
|
|
156
160
|
}
|
|
157
161
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
|
@@ -363,6 +367,10 @@ pub struct ValidationReport {
|
|
|
363
367
|
pub issues: Vec<ValidationIssue>,
|
|
364
368
|
}
|
|
365
369
|
|
|
370
|
+
fn is_valid_policy_subject(subject: &str) -> bool {
|
|
371
|
+
matches!(subject, "authenticated" | "owner" | "member")
|
|
372
|
+
}
|
|
373
|
+
|
|
366
374
|
fn unique(
|
|
367
375
|
issues: &mut Vec<ValidationIssue>,
|
|
368
376
|
category: &str,
|
|
@@ -734,6 +742,24 @@ pub fn validate_manifest(
|
|
|
734
742
|
));
|
|
735
743
|
}
|
|
736
744
|
}
|
|
745
|
+
if let Some(ref read_subject) = policy.read {
|
|
746
|
+
if !is_valid_policy_subject(read_subject) {
|
|
747
|
+
issues.push(issue(
|
|
748
|
+
"semantic",
|
|
749
|
+
format!("policies.{}.read", policy.name),
|
|
750
|
+
&format!("invalid policy subject '{}'", read_subject),
|
|
751
|
+
));
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
if let Some(ref write_subject) = policy.write {
|
|
755
|
+
if !is_valid_policy_subject(write_subject) {
|
|
756
|
+
issues.push(issue(
|
|
757
|
+
"semantic",
|
|
758
|
+
format!("policies.{}.write", policy.name),
|
|
759
|
+
&format!("invalid policy subject '{}'", write_subject),
|
|
760
|
+
));
|
|
761
|
+
}
|
|
762
|
+
}
|
|
737
763
|
}
|
|
738
764
|
let state_schema = crate::state_contract::schema_from_manifest(manifest, "validation");
|
|
739
765
|
let schema_validation = crate::state_contract::validate_schema(&state_schema);
|
|
@@ -2241,4 +2267,71 @@ mod tests {
|
|
|
2241
2267
|
Some(promotion.diff_hash.as_str())
|
|
2242
2268
|
);
|
|
2243
2269
|
}
|
|
2270
|
+
|
|
2271
|
+
#[test]
|
|
2272
|
+
fn policy_with_valid_authenticated_subject() {
|
|
2273
|
+
let mut manifest = ApplicationManifest::empty("tenant", "app", "test");
|
|
2274
|
+
manifest.policies.push(PolicyDefinition {
|
|
2275
|
+
name: "TodoPolicy".into(),
|
|
2276
|
+
resource: "Todo".into(),
|
|
2277
|
+
read: Some("authenticated".into()),
|
|
2278
|
+
write: Some("authenticated".into()),
|
|
2279
|
+
capabilities: vec![],
|
|
2280
|
+
});
|
|
2281
|
+
|
|
2282
|
+
let report = validate_manifest(&manifest, "tenant", "app", None);
|
|
2283
|
+
assert!(report.valid, "Policy with authenticated subject should be valid: {:?}", report.issues);
|
|
2284
|
+
}
|
|
2285
|
+
|
|
2286
|
+
#[test]
|
|
2287
|
+
fn policy_with_valid_owner_subject() {
|
|
2288
|
+
let mut manifest = ApplicationManifest::empty("tenant", "app", "test");
|
|
2289
|
+
manifest.policies.push(PolicyDefinition {
|
|
2290
|
+
name: "ProjectPolicy".into(),
|
|
2291
|
+
resource: "Project".into(),
|
|
2292
|
+
read: Some("authenticated".into()),
|
|
2293
|
+
write: Some("owner".into()),
|
|
2294
|
+
capabilities: vec![],
|
|
2295
|
+
});
|
|
2296
|
+
|
|
2297
|
+
let report = validate_manifest(&manifest, "tenant", "app", None);
|
|
2298
|
+
assert!(report.valid, "Policy with owner subject should be valid: {:?}", report.issues);
|
|
2299
|
+
}
|
|
2300
|
+
|
|
2301
|
+
#[test]
|
|
2302
|
+
fn policy_with_invalid_subject_rejected() {
|
|
2303
|
+
let mut manifest = ApplicationManifest::empty("tenant", "app", "test");
|
|
2304
|
+
manifest.policies.push(PolicyDefinition {
|
|
2305
|
+
name: "BadPolicy".into(),
|
|
2306
|
+
resource: "BadCollection".into(),
|
|
2307
|
+
read: Some("unknown_subject".into()),
|
|
2308
|
+
write: None,
|
|
2309
|
+
capabilities: vec![],
|
|
2310
|
+
});
|
|
2311
|
+
|
|
2312
|
+
let report = validate_manifest(&manifest, "tenant", "app", None);
|
|
2313
|
+
assert!(!report.valid, "Policy with unknown subject should be invalid");
|
|
2314
|
+
assert!(
|
|
2315
|
+
report.issues.iter().any(|i|
|
|
2316
|
+
i.path.contains("BadPolicy") && i.path.contains("read") &&
|
|
2317
|
+
i.message.contains("invalid policy subject")
|
|
2318
|
+
),
|
|
2319
|
+
"Should have error about invalid policy subject"
|
|
2320
|
+
);
|
|
2321
|
+
}
|
|
2322
|
+
|
|
2323
|
+
#[test]
|
|
2324
|
+
fn policy_without_subjects_is_valid() {
|
|
2325
|
+
let mut manifest = ApplicationManifest::empty("tenant", "app", "test");
|
|
2326
|
+
manifest.policies.push(PolicyDefinition {
|
|
2327
|
+
name: "LegacyPolicy".into(),
|
|
2328
|
+
resource: "SomeCollection".into(),
|
|
2329
|
+
read: None,
|
|
2330
|
+
write: None,
|
|
2331
|
+
capabilities: vec!["some:capability".into()],
|
|
2332
|
+
});
|
|
2333
|
+
|
|
2334
|
+
let report = validate_manifest(&manifest, "tenant", "app", None);
|
|
2335
|
+
assert!(report.valid, "Policy without subjects should be valid (backward compatible)");
|
|
2336
|
+
}
|
|
2244
2337
|
}
|