@spinajs/authz-fs 0.0.0-stage → 3.0.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/README.md +30 -2
- package/lib/cjs/access-config/acl-config.d.ts +23 -0
- package/lib/cjs/access-config/acl-config.d.ts.map +1 -0
- package/lib/cjs/access-config/acl-config.js +36 -0
- package/lib/cjs/access-config/acl-config.js.map +1 -0
- package/lib/cjs/access-config/index.d.ts +34 -0
- package/lib/cjs/access-config/index.d.ts.map +1 -0
- package/lib/cjs/access-config/index.js +89 -0
- package/lib/cjs/access-config/index.js.map +1 -0
- package/lib/cjs/access-config/schema.d.ts +31 -0
- package/lib/cjs/access-config/schema.d.ts.map +1 -0
- package/lib/cjs/access-config/schema.js +55 -0
- package/lib/cjs/access-config/schema.js.map +1 -0
- package/lib/cjs/acl/facade.d.ts +39 -0
- package/lib/cjs/acl/facade.d.ts.map +1 -0
- package/lib/cjs/acl/facade.js +73 -0
- package/lib/cjs/acl/facade.js.map +1 -0
- package/lib/cjs/acl/index.d.ts +6 -0
- package/lib/cjs/acl/index.d.ts.map +1 -0
- package/lib/cjs/acl/index.js +25 -0
- package/lib/cjs/acl/index.js.map +1 -0
- package/lib/cjs/acl/orm-store.d.ts +31 -0
- package/lib/cjs/acl/orm-store.d.ts.map +1 -0
- package/lib/cjs/acl/orm-store.js +199 -0
- package/lib/cjs/acl/orm-store.js.map +1 -0
- package/lib/cjs/acl/relation.d.ts +29 -0
- package/lib/cjs/acl/relation.d.ts.map +1 -0
- package/lib/cjs/acl/relation.js +60 -0
- package/lib/cjs/acl/relation.js.map +1 -0
- package/lib/cjs/acl/shared.d.ts +36 -0
- package/lib/cjs/acl/shared.d.ts.map +1 -0
- package/lib/cjs/acl/shared.js +91 -0
- package/lib/cjs/acl/shared.js.map +1 -0
- package/lib/cjs/acl/store.d.ts +43 -0
- package/lib/cjs/acl/store.d.ts.map +1 -0
- package/lib/cjs/acl/store.js +12 -0
- package/lib/cjs/acl/store.js.map +1 -0
- package/lib/cjs/adapter/index.d.ts +33 -0
- package/lib/cjs/adapter/index.d.ts.map +1 -0
- package/lib/cjs/adapter/index.js +76 -0
- package/lib/cjs/adapter/index.js.map +1 -0
- package/lib/cjs/checks.d.ts +5 -0
- package/lib/cjs/checks.d.ts.map +1 -0
- package/lib/cjs/checks.js +20 -0
- package/lib/cjs/checks.js.map +1 -0
- package/lib/cjs/http/from-fs-path.d.ts +15 -0
- package/lib/cjs/http/from-fs-path.d.ts.map +1 -0
- package/lib/cjs/http/from-fs-path.js +43 -0
- package/lib/cjs/http/from-fs-path.js.map +1 -0
- package/lib/cjs/http/index.d.ts +3 -0
- package/lib/cjs/http/index.d.ts.map +1 -0
- package/lib/cjs/http/index.js +19 -0
- package/lib/cjs/http/index.js.map +1 -0
- package/lib/cjs/http/upload.d.ts +29 -0
- package/lib/cjs/http/upload.d.ts.map +1 -0
- package/lib/cjs/http/upload.js +67 -0
- package/lib/cjs/http/upload.js.map +1 -0
- package/lib/cjs/index.d.ts +9 -0
- package/lib/cjs/index.d.ts.map +1 -0
- package/lib/cjs/index.js +25 -0
- package/lib/cjs/index.js.map +1 -0
- package/lib/cjs/middleware/decide.d.ts +32 -0
- package/lib/cjs/middleware/decide.d.ts.map +1 -0
- package/lib/cjs/middleware/decide.js +51 -0
- package/lib/cjs/middleware/decide.js.map +1 -0
- package/lib/cjs/middleware/index.d.ts +53 -0
- package/lib/cjs/middleware/index.d.ts.map +1 -0
- package/lib/cjs/middleware/index.js +236 -0
- package/lib/cjs/middleware/index.js.map +1 -0
- package/lib/cjs/middleware/owner.d.ts +10 -0
- package/lib/cjs/middleware/owner.d.ts.map +1 -0
- package/lib/cjs/middleware/owner.js +20 -0
- package/lib/cjs/middleware/owner.js.map +1 -0
- package/lib/cjs/middleware/signed-url.d.ts +22 -0
- package/lib/cjs/middleware/signed-url.d.ts.map +1 -0
- package/lib/cjs/middleware/signed-url.js +36 -0
- package/lib/cjs/middleware/signed-url.js.map +1 -0
- package/lib/cjs/migrations/AuthzFsAcl_2026_10_17_00_00_00.d.ts +8 -0
- package/lib/cjs/migrations/AuthzFsAcl_2026_10_17_00_00_00.d.ts.map +1 -0
- package/lib/cjs/migrations/AuthzFsAcl_2026_10_17_00_00_00.js +45 -0
- package/lib/cjs/migrations/AuthzFsAcl_2026_10_17_00_00_00.js.map +1 -0
- package/lib/cjs/migrations/index.d.ts +2 -0
- package/lib/cjs/migrations/index.d.ts.map +1 -0
- package/lib/cjs/migrations/index.js +18 -0
- package/lib/cjs/migrations/index.js.map +1 -0
- package/lib/cjs/package.json +1 -0
- package/lib/cjs/permissions/index.d.ts +3 -0
- package/lib/cjs/permissions/index.d.ts.map +1 -0
- package/lib/cjs/permissions/index.js +7 -0
- package/lib/cjs/permissions/index.js.map +1 -0
- package/lib/cjs/refs/index.d.ts +3 -0
- package/lib/cjs/refs/index.d.ts.map +1 -0
- package/lib/cjs/refs/index.js +21 -0
- package/lib/cjs/refs/index.js.map +1 -0
- package/lib/cjs/refs/refs.d.ts +34 -0
- package/lib/cjs/refs/refs.d.ts.map +1 -0
- package/lib/cjs/refs/refs.js +79 -0
- package/lib/cjs/refs/refs.js.map +1 -0
- package/lib/mjs/access-config/acl-config.d.ts +23 -0
- package/lib/mjs/access-config/acl-config.d.ts.map +1 -0
- package/lib/mjs/access-config/acl-config.js +32 -0
- package/lib/mjs/access-config/acl-config.js.map +1 -0
- package/lib/mjs/access-config/index.d.ts +34 -0
- package/lib/mjs/access-config/index.d.ts.map +1 -0
- package/lib/mjs/access-config/index.js +71 -0
- package/lib/mjs/access-config/index.js.map +1 -0
- package/lib/mjs/access-config/schema.d.ts +31 -0
- package/lib/mjs/access-config/schema.d.ts.map +1 -0
- package/lib/mjs/access-config/schema.js +52 -0
- package/lib/mjs/access-config/schema.js.map +1 -0
- package/lib/mjs/acl/facade.d.ts +39 -0
- package/lib/mjs/acl/facade.d.ts.map +1 -0
- package/lib/mjs/acl/facade.js +69 -0
- package/lib/mjs/acl/facade.js.map +1 -0
- package/lib/mjs/acl/index.d.ts +6 -0
- package/lib/mjs/acl/index.d.ts.map +1 -0
- package/lib/mjs/acl/index.js +6 -0
- package/lib/mjs/acl/index.js.map +1 -0
- package/lib/mjs/acl/orm-store.d.ts +31 -0
- package/lib/mjs/acl/orm-store.d.ts.map +1 -0
- package/lib/mjs/acl/orm-store.js +196 -0
- package/lib/mjs/acl/orm-store.js.map +1 -0
- package/lib/mjs/acl/relation.d.ts +29 -0
- package/lib/mjs/acl/relation.d.ts.map +1 -0
- package/lib/mjs/acl/relation.js +56 -0
- package/lib/mjs/acl/relation.js.map +1 -0
- package/lib/mjs/acl/shared.d.ts +36 -0
- package/lib/mjs/acl/shared.d.ts.map +1 -0
- package/lib/mjs/acl/shared.js +73 -0
- package/lib/mjs/acl/shared.js.map +1 -0
- package/lib/mjs/acl/store.d.ts +43 -0
- package/lib/mjs/acl/store.d.ts.map +1 -0
- package/lib/mjs/acl/store.js +8 -0
- package/lib/mjs/acl/store.js.map +1 -0
- package/lib/mjs/adapter/index.d.ts +33 -0
- package/lib/mjs/adapter/index.d.ts.map +1 -0
- package/lib/mjs/adapter/index.js +73 -0
- package/lib/mjs/adapter/index.js.map +1 -0
- package/lib/mjs/checks.d.ts +5 -0
- package/lib/mjs/checks.d.ts.map +1 -0
- package/lib/mjs/checks.js +16 -0
- package/lib/mjs/checks.js.map +1 -0
- package/lib/mjs/http/from-fs-path.d.ts +15 -0
- package/lib/mjs/http/from-fs-path.d.ts.map +1 -0
- package/lib/mjs/http/from-fs-path.js +40 -0
- package/lib/mjs/http/from-fs-path.js.map +1 -0
- package/lib/mjs/http/index.d.ts +3 -0
- package/lib/mjs/http/index.d.ts.map +1 -0
- package/lib/mjs/http/index.js +3 -0
- package/lib/mjs/http/index.js.map +1 -0
- package/lib/mjs/http/upload.d.ts +29 -0
- package/lib/mjs/http/upload.d.ts.map +1 -0
- package/lib/mjs/http/upload.js +64 -0
- package/lib/mjs/http/upload.js.map +1 -0
- package/lib/mjs/index.d.ts +9 -0
- package/lib/mjs/index.d.ts.map +1 -0
- package/lib/mjs/index.js +9 -0
- package/lib/mjs/index.js.map +1 -0
- package/lib/mjs/middleware/decide.d.ts +32 -0
- package/lib/mjs/middleware/decide.d.ts.map +1 -0
- package/lib/mjs/middleware/decide.js +42 -0
- package/lib/mjs/middleware/decide.js.map +1 -0
- package/lib/mjs/middleware/index.d.ts +53 -0
- package/lib/mjs/middleware/index.d.ts.map +1 -0
- package/lib/mjs/middleware/index.js +231 -0
- package/lib/mjs/middleware/index.js.map +1 -0
- package/lib/mjs/middleware/owner.d.ts +10 -0
- package/lib/mjs/middleware/owner.d.ts.map +1 -0
- package/lib/mjs/middleware/owner.js +16 -0
- package/lib/mjs/middleware/owner.js.map +1 -0
- package/lib/mjs/middleware/signed-url.d.ts +22 -0
- package/lib/mjs/middleware/signed-url.d.ts.map +1 -0
- package/lib/mjs/middleware/signed-url.js +31 -0
- package/lib/mjs/middleware/signed-url.js.map +1 -0
- package/lib/mjs/migrations/AuthzFsAcl_2026_10_17_00_00_00.d.ts +8 -0
- package/lib/mjs/migrations/AuthzFsAcl_2026_10_17_00_00_00.d.ts.map +1 -0
- package/lib/mjs/migrations/AuthzFsAcl_2026_10_17_00_00_00.js +42 -0
- package/lib/mjs/migrations/AuthzFsAcl_2026_10_17_00_00_00.js.map +1 -0
- package/lib/mjs/migrations/index.d.ts +2 -0
- package/lib/mjs/migrations/index.d.ts.map +1 -0
- package/lib/mjs/migrations/index.js +2 -0
- package/lib/mjs/migrations/index.js.map +1 -0
- package/lib/mjs/package.json +1 -0
- package/lib/mjs/permissions/index.d.ts +3 -0
- package/lib/mjs/permissions/index.d.ts.map +1 -0
- package/lib/mjs/permissions/index.js +4 -0
- package/lib/mjs/permissions/index.js.map +1 -0
- package/lib/mjs/refs/index.d.ts +3 -0
- package/lib/mjs/refs/index.d.ts.map +1 -0
- package/lib/mjs/refs/index.js +3 -0
- package/lib/mjs/refs/index.js.map +1 -0
- package/lib/mjs/refs/refs.d.ts +34 -0
- package/lib/mjs/refs/refs.d.ts.map +1 -0
- package/lib/mjs/refs/refs.js +71 -0
- package/lib/mjs/refs/refs.js.map +1 -0
- package/lib/tsconfig.cjs.tsbuildinfo +1 -0
- package/lib/tsconfig.mjs.tsbuildinfo +1 -0
- package/package.json +74 -4
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.OrmFileAclStore = void 0;
|
|
13
|
+
const node_crypto_1 = require("node:crypto");
|
|
14
|
+
const authz_1 = require("@spinajs/authz");
|
|
15
|
+
const di_1 = require("@spinajs/di");
|
|
16
|
+
const exceptions_1 = require("@spinajs/exceptions");
|
|
17
|
+
const orm_1 = require("@spinajs/orm");
|
|
18
|
+
const util_1 = require("@spinajs/util");
|
|
19
|
+
const acl_config_js_1 = require("../access-config/acl-config.js");
|
|
20
|
+
const shared_js_1 = require("./shared.js");
|
|
21
|
+
const store_js_1 = require("./store.js");
|
|
22
|
+
const IN_CHUNK = 500;
|
|
23
|
+
/**
|
|
24
|
+
* FileAclStore over `fs_acl` (migration AuthzFsAcl_2026_10_17_00_00_00). Reads are narrowed in SQL by `path_hash`
|
|
25
|
+
* (the indexed key) and decided by an exact comparison of `path` in code, and rows change by id, so a table created
|
|
26
|
+
* with a case-insensitive collation never merges two paths.
|
|
27
|
+
*/
|
|
28
|
+
let OrmFileAclStore = class OrmFileAclStore extends store_js_1.FileAclStore {
|
|
29
|
+
constructor(opts = {}) {
|
|
30
|
+
super();
|
|
31
|
+
this.opts = opts;
|
|
32
|
+
}
|
|
33
|
+
async holds(fs, paths, subjectKeys, relation, at) {
|
|
34
|
+
const f = (0, shared_js_1.aclFs)(fs);
|
|
35
|
+
const r = (0, shared_js_1.aclRelation)(relation);
|
|
36
|
+
const wanted = [...new Set(paths.map(shared_js_1.aclPath))];
|
|
37
|
+
const keys = [...new Set(subjectKeys)];
|
|
38
|
+
if (wanted.length === 0 || keys.length === 0)
|
|
39
|
+
return false;
|
|
40
|
+
const hashes = wanted.map(shared_js_1.aclPathHash);
|
|
41
|
+
const driver = await this.driver();
|
|
42
|
+
for (const part of (0, util_1.chunk)(keys, IN_CHUNK)) {
|
|
43
|
+
const rows = ((await driver.select().from(shared_js_1.FS_ACL_TABLE).where({ fs: f, relation: r }).whereIn('path_hash', hashes).whereIn('subject_key', part)) ?? []);
|
|
44
|
+
if (rows.some((row) => row.fs === f && row.relation === r && wanted.includes(row.path) && part.includes(row.subject_key) && live(row, at)))
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
async list(fs, path) {
|
|
50
|
+
const f = (0, shared_js_1.aclFs)(fs);
|
|
51
|
+
const p = (0, shared_js_1.aclPath)(path);
|
|
52
|
+
return (await exactRows(await this.driver(), f, p)).map(rowOf);
|
|
53
|
+
}
|
|
54
|
+
async grant(row) {
|
|
55
|
+
const key = { fs: (0, shared_js_1.aclFs)(row.fs), path: (0, shared_js_1.aclPath)(row.path), subject_key: (0, shared_js_1.aclSubjectKey)(row.subject), relation: (0, shared_js_1.aclRelation)(row.relation) };
|
|
56
|
+
const values = { expires_at: (0, shared_js_1.aclExpiry)(row.expiresAt), granted_by: row.grantedBy === undefined ? null : (0, shared_js_1.fits)(row.grantedBy, 'granted_by') };
|
|
57
|
+
const driver = await this.driver();
|
|
58
|
+
await driver.transaction(async (tx) => {
|
|
59
|
+
const found = (await exactRows(tx, key.fs, key.path)).find((r) => r.subject_key === key.subject_key && r.relation === key.relation);
|
|
60
|
+
if (found)
|
|
61
|
+
await tx.update().in(shared_js_1.FS_ACL_TABLE).update(values).where({ id: found.id });
|
|
62
|
+
else
|
|
63
|
+
await tx.insert().into(shared_js_1.FS_ACL_TABLE).values({ id: (0, node_crypto_1.randomUUID)(), ...key, path_hash: (0, shared_js_1.aclPathHash)(key.path), ...values, created_at: new Date() });
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
async revoke(fs, path, subjectKey, relation) {
|
|
67
|
+
const f = (0, shared_js_1.aclFs)(fs);
|
|
68
|
+
const p = (0, shared_js_1.aclPath)(path);
|
|
69
|
+
const r = (0, shared_js_1.aclRelation)(relation);
|
|
70
|
+
const driver = await this.driver();
|
|
71
|
+
await driver.transaction(async (tx) => deleteIds(tx, (await exactRows(tx, f, p)).filter((row) => row.subject_key === subjectKey && row.relation === r).map((row) => row.id)));
|
|
72
|
+
}
|
|
73
|
+
async ownerOf(fs, path) {
|
|
74
|
+
const rows = (await exactRows(await this.driver(), (0, shared_js_1.aclFs)(fs), (0, shared_js_1.aclPath)(path))).filter((r) => r.relation === acl_config_js_1.FS_ACL_OWNER && !(0, shared_js_1.isWildcardKey)(r.subject_key));
|
|
75
|
+
for (const row of oldestFirst(rows)) {
|
|
76
|
+
const subject = (0, shared_js_1.subjectOfKey)(row.subject_key, `${shared_js_1.FS_ACL_TABLE} row ${row.id}`);
|
|
77
|
+
if (!('set' in subject))
|
|
78
|
+
return { type: subject.type, id: subject.id };
|
|
79
|
+
}
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
async setOwnerIfAbsent(fs, path, owner) {
|
|
83
|
+
const key = { fs: (0, shared_js_1.aclFs)(fs), path: (0, shared_js_1.aclPath)(path), subject_key: (0, shared_js_1.aclOwnerKey)(owner), relation: acl_config_js_1.FS_ACL_OWNER };
|
|
84
|
+
const driver = await this.driver();
|
|
85
|
+
await driver.transaction(async (tx) => {
|
|
86
|
+
if ((await exactRows(tx, key.fs, key.path)).some((r) => r.relation === acl_config_js_1.FS_ACL_OWNER))
|
|
87
|
+
return;
|
|
88
|
+
await tx.insert().into(shared_js_1.FS_ACL_TABLE).values({ id: (0, node_crypto_1.randomUUID)(), ...key, path_hash: (0, shared_js_1.aclPathHash)(key.path), expires_at: null, granted_by: null, created_at: new Date() });
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
async deleteTree(fs, path) {
|
|
92
|
+
const f = (0, shared_js_1.aclFs)(fs);
|
|
93
|
+
const p = (0, shared_js_1.aclPath)(path);
|
|
94
|
+
const driver = await this.driver();
|
|
95
|
+
await driver.transaction(async (tx) => deleteIds(tx, (await tree(tx, f, p)).map((r) => r.id)));
|
|
96
|
+
}
|
|
97
|
+
async deletePath(fs, path) {
|
|
98
|
+
const f = (0, shared_js_1.aclFs)(fs);
|
|
99
|
+
const p = (0, shared_js_1.aclPath)(path);
|
|
100
|
+
const driver = await this.driver();
|
|
101
|
+
await driver.transaction(async (tx) => deleteIds(tx, (await exactRows(tx, f, p)).map((r) => r.id)));
|
|
102
|
+
}
|
|
103
|
+
async moveTree(fromFs, from, toFs, to) {
|
|
104
|
+
const src = { fs: (0, shared_js_1.aclFs)(fromFs), path: (0, shared_js_1.aclPath)(from) };
|
|
105
|
+
const dst = { fs: (0, shared_js_1.aclFs)(toFs), path: (0, shared_js_1.aclPath)(to) };
|
|
106
|
+
if (src.fs === dst.fs && src.path === dst.path)
|
|
107
|
+
return;
|
|
108
|
+
(0, shared_js_1.checkMove)(src.fs, src.path, dst.fs, dst.path);
|
|
109
|
+
const driver = await this.driver();
|
|
110
|
+
await driver.transaction(async (tx) => {
|
|
111
|
+
const rows = await tree(tx, src.fs, src.path);
|
|
112
|
+
const landing = rows.map((row) => ({ row, path: (0, shared_js_1.movedPath)(src.path, dst.path, row.path) }));
|
|
113
|
+
// A row too long for the path column goes: what it named falls under the moved parents' rows.
|
|
114
|
+
const moves = landing.filter((m) => m.path.length <= shared_js_1.FS_ACL_LIMITS.path);
|
|
115
|
+
// Only a move onto an ancestor can land one moved row on another; no provider moves a directory there.
|
|
116
|
+
const sources = new Set(rows.map((r) => r.path));
|
|
117
|
+
if (src.fs === dst.fs && moves.some((m) => sources.has(m.path)))
|
|
118
|
+
throw new exceptions_1.InvalidArgument(`cannot move ${src.fs}:${src.path} onto ${dst.path}, which holds it`, 'to');
|
|
119
|
+
const taken = new Set(moves.map((m) => rowKey(m.path, m.row)));
|
|
120
|
+
const replaced = (await tree(tx, dst.fs, dst.path)).filter((r) => taken.has(rowKey(r.path, r))).map((r) => r.id);
|
|
121
|
+
const dropped = landing.filter((m) => !moves.includes(m)).map((m) => m.row.id);
|
|
122
|
+
await deleteIds(tx, [...replaced, ...dropped]);
|
|
123
|
+
for (const m of moves)
|
|
124
|
+
await tx.update().in(shared_js_1.FS_ACL_TABLE).update({ fs: dst.fs, path: m.path, path_hash: (0, shared_js_1.aclPathHash)(m.path) }).where({ id: m.row.id });
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
async movePath(fromFs, from, toFs, to) {
|
|
128
|
+
const src = { fs: (0, shared_js_1.aclFs)(fromFs), path: (0, shared_js_1.aclPath)(from) };
|
|
129
|
+
const dst = { fs: (0, shared_js_1.aclFs)(toFs), path: (0, shared_js_1.aclPath)(to) };
|
|
130
|
+
if (src.fs === dst.fs && src.path === dst.path)
|
|
131
|
+
return;
|
|
132
|
+
const driver = await this.driver();
|
|
133
|
+
await driver.transaction(async (tx) => {
|
|
134
|
+
// The destination's equal rows go first, else the UPDATE would break the unique key.
|
|
135
|
+
const moving = new Set((await exactRows(tx, src.fs, src.path)).map((r) => rowKey(dst.path, r)));
|
|
136
|
+
await deleteIds(tx, (await exactRows(tx, dst.fs, dst.path)).filter((r) => moving.has(rowKey(r.path, r))).map((r) => r.id));
|
|
137
|
+
await tx.update().in(shared_js_1.FS_ACL_TABLE).update({ fs: dst.fs, path: dst.path, path_hash: (0, shared_js_1.aclPathHash)(dst.path) }).where({ fs: src.fs, path_hash: (0, shared_js_1.aclPathHash)(src.path), path: src.path });
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
async driver() {
|
|
141
|
+
const container = this.opts.container ?? di_1.DI.RootContainer;
|
|
142
|
+
const name = this.opts.connection ?? (0, acl_config_js_1.fsAclConfig)(container).connection;
|
|
143
|
+
const orm = (await container.resolve(orm_1.Orm));
|
|
144
|
+
const driver = orm.Connections.get(name);
|
|
145
|
+
if (!driver)
|
|
146
|
+
throw new authz_1.AuthzConfigError(`OrmFileAclStore: ${acl_config_js_1.FS_ACL_CONNECTION_KEY} names connection ${JSON.stringify(name)}, which the ORM does not have (connections: ${[...orm.Connections.keys()].join(', ') || 'none'})`);
|
|
147
|
+
return driver;
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
exports.OrmFileAclStore = OrmFileAclStore;
|
|
151
|
+
exports.OrmFileAclStore = OrmFileAclStore = __decorate([
|
|
152
|
+
(0, di_1.Injectable)(store_js_1.FileAclStore),
|
|
153
|
+
__metadata("design:paramtypes", [Object])
|
|
154
|
+
], OrmFileAclStore);
|
|
155
|
+
const rowKey = (path, r) => `${path}\0${r.subject_key}\0${r.relation}`;
|
|
156
|
+
// Rows are read without a model, so no column converter runs: SQLite hands back ISO text, the others a Date.
|
|
157
|
+
function toDate(value, column) {
|
|
158
|
+
if (value === null || value === undefined)
|
|
159
|
+
return null;
|
|
160
|
+
const instant = (0, orm_1.instantFromDb)(value);
|
|
161
|
+
if (!instant)
|
|
162
|
+
throw new authz_1.AuthzConfigError(`${shared_js_1.FS_ACL_TABLE}.${column} holds an unreadable datetime ${JSON.stringify(value)}`);
|
|
163
|
+
return instant.toJSDate();
|
|
164
|
+
}
|
|
165
|
+
function live(row, at) {
|
|
166
|
+
const until = toDate(row.expires_at, 'expires_at');
|
|
167
|
+
return until === null || until.getTime() > at.getTime();
|
|
168
|
+
}
|
|
169
|
+
const oldestFirst = (rows) => [...rows].sort((a, b) => (toDate(a.created_at, 'created_at')?.getTime() ?? 0) - (toDate(b.created_at, 'created_at')?.getTime() ?? 0));
|
|
170
|
+
function rowOf(row) {
|
|
171
|
+
const expiresAt = toDate(row.expires_at, 'expires_at');
|
|
172
|
+
return Object.freeze({
|
|
173
|
+
fs: row.fs,
|
|
174
|
+
path: row.path,
|
|
175
|
+
subject: (0, shared_js_1.subjectOfKey)(row.subject_key, `${shared_js_1.FS_ACL_TABLE} row ${row.id}`),
|
|
176
|
+
relation: row.relation,
|
|
177
|
+
...(expiresAt ? { expiresAt } : {}),
|
|
178
|
+
...(row.granted_by ? { grantedBy: row.granted_by } : {}),
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
async function exactRows(driver, fs, path) {
|
|
182
|
+
const rows = ((await driver.select().from(shared_js_1.FS_ACL_TABLE).where({ fs, path_hash: (0, shared_js_1.aclPathHash)(path), path })) ?? []);
|
|
183
|
+
return rows.filter((r) => r.fs === fs && r.path === path);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* The rows at `path` and under it ('' = every row of the filesystem). `whereStartsWith` only narrows the read (it may
|
|
187
|
+
* ignore case under the column's collation); the exact test in code decides.
|
|
188
|
+
*/
|
|
189
|
+
async function tree(driver, fs, path) {
|
|
190
|
+
if (path === '')
|
|
191
|
+
return ((await driver.select().from(shared_js_1.FS_ACL_TABLE).where({ fs })) ?? []).filter((r) => r.fs === fs);
|
|
192
|
+
const below = ((await driver.select().from(shared_js_1.FS_ACL_TABLE).where({ fs }).whereStartsWith('path', `${path}/`)) ?? []);
|
|
193
|
+
return [...(await exactRows(driver, fs, path)), ...below.filter((r) => r.fs === fs && r.path.startsWith(`${path}/`))];
|
|
194
|
+
}
|
|
195
|
+
async function deleteIds(driver, ids) {
|
|
196
|
+
for (const part of (0, util_1.chunk)(ids, IN_CHUNK))
|
|
197
|
+
await driver.del().from(shared_js_1.FS_ACL_TABLE).whereIn('id', part);
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=orm-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orm-store.js","sourceRoot":"","sources":["../../../src/acl/orm-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { RelationResolver } from '@spinajs/authz';
|
|
2
|
+
import type { Principal, ResourceRef } from '@spinajs/authz';
|
|
3
|
+
import type { IContainer } from '@spinajs/di';
|
|
4
|
+
import type { FsRefType } from '../refs/index.js';
|
|
5
|
+
/**
|
|
6
|
+
* `relation` on fs refs of `type`, read from the file ACL (fs middleware design §2.2): holds when a live row of the
|
|
7
|
+
* relation at the path, a parent directory or the filesystem root names one of the principal's subject keys. The
|
|
8
|
+
* subject the engine passes is ignored: a caller-built row could claim anything.
|
|
9
|
+
*
|
|
10
|
+
* Known limit: `holds` never sees a check's `fresh` flag, so subjectKeysOf reads assignments through the RBAC
|
|
11
|
+
* model's cache and a set membership may lag by its TTL.
|
|
12
|
+
*/
|
|
13
|
+
export declare class FsAclRelation extends RelationResolver {
|
|
14
|
+
readonly type: FsRefType;
|
|
15
|
+
readonly relation: string;
|
|
16
|
+
/** Where the Configuration, AuthzDomains and the FileAclStore are resolved. */
|
|
17
|
+
protected readonly container: IContainer;
|
|
18
|
+
constructor(type: FsRefType, relation: string,
|
|
19
|
+
/** Where the Configuration, AuthzDomains and the FileAclStore are resolved. */
|
|
20
|
+
container?: IContainer);
|
|
21
|
+
holds(principal: Principal, ref: ResourceRef): Promise<boolean>;
|
|
22
|
+
/**
|
|
23
|
+
* From the RbacService registered in the domain or a parent (sets, companions, wildcards, the ceiling applied),
|
|
24
|
+
* used only when it is the service of a model the domain's AuthzService runs: a child domain without one must not match
|
|
25
|
+
* set rows through its parent's service. Otherwise the principal and its type wildcard.
|
|
26
|
+
*/
|
|
27
|
+
protected subjectKeys(principal: Principal, domain: string, at: Date): Promise<readonly string[]>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=relation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relation.d.ts","sourceRoot":"","sources":["../../../src/acl/relation.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAC9E,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAI7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAM9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAGlD;;;;;;;GAOG;AACH,qBAAa,aAAc,SAAQ,gBAAgB;IAE/C,QAAQ,CAAC,IAAI,EAAE,SAAS;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM;IACzB,+EAA+E;IAC/E,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,UAAU;IAJ1C,YACW,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,MAAM;IACzB,+EAA+E;IAC5D,SAAS,GAAE,UAA6B,EAG5D;IAEK,KAAK,CAAC,SAAS,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAUpE;IAED;;;;OAIG;IACH,UAAgB,WAAW,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAQtG;CACF"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FsAclRelation = void 0;
|
|
4
|
+
const authz_1 = require("@spinajs/authz");
|
|
5
|
+
const authz_rbac_1 = require("@spinajs/authz-rbac");
|
|
6
|
+
const configuration_1 = require("@spinajs/configuration");
|
|
7
|
+
const di_1 = require("@spinajs/di");
|
|
8
|
+
const index_js_1 = require("../access-config/index.js");
|
|
9
|
+
const decide_js_1 = require("../middleware/decide.js");
|
|
10
|
+
const owner_js_1 = require("../middleware/owner.js");
|
|
11
|
+
const index_js_2 = require("../refs/index.js");
|
|
12
|
+
const shared_js_1 = require("./shared.js");
|
|
13
|
+
/**
|
|
14
|
+
* `relation` on fs refs of `type`, read from the file ACL (fs middleware design §2.2): holds when a live row of the
|
|
15
|
+
* relation at the path, a parent directory or the filesystem root names one of the principal's subject keys. The
|
|
16
|
+
* subject the engine passes is ignored: a caller-built row could claim anything.
|
|
17
|
+
*
|
|
18
|
+
* Known limit: `holds` never sees a check's `fresh` flag, so subjectKeysOf reads assignments through the RBAC
|
|
19
|
+
* model's cache and a set membership may lag by its TTL.
|
|
20
|
+
*/
|
|
21
|
+
class FsAclRelation extends authz_1.RelationResolver {
|
|
22
|
+
constructor(type, relation,
|
|
23
|
+
/** Where the Configuration, AuthzDomains and the FileAclStore are resolved. */
|
|
24
|
+
container = di_1.DI.RootContainer) {
|
|
25
|
+
super();
|
|
26
|
+
this.type = type;
|
|
27
|
+
this.relation = relation;
|
|
28
|
+
this.container = container;
|
|
29
|
+
}
|
|
30
|
+
async holds(principal, ref) {
|
|
31
|
+
if (ref?.type !== this.type || owner_js_1.FS_NO_OWNER_TYPES.has(principal.type))
|
|
32
|
+
return false;
|
|
33
|
+
const parsed = (0, index_js_2.parseFsRef)(ref);
|
|
34
|
+
if (!parsed || parsed.fs.length > shared_js_1.FS_ACL_LIMITS.fs)
|
|
35
|
+
return false;
|
|
36
|
+
// No row can exist for a path past the column width, and the store refuses one.
|
|
37
|
+
const chain = (0, shared_js_1.aclPathChain)(parsed.path).filter((p) => p.length <= shared_js_1.FS_ACL_LIMITS.path);
|
|
38
|
+
const domain = this.container.get(configuration_1.Configuration) ? (0, index_js_1.fsAccessConfig)(parsed.fs, this.container).domain : 'root';
|
|
39
|
+
const at = await (0, decide_js_1.domainNow)(this.container, domain);
|
|
40
|
+
const keys = await this.subjectKeys(principal, domain, at);
|
|
41
|
+
return (await (0, shared_js_1.fileAclStore)(this.container)).holds(parsed.fs, chain, keys, this.relation, at);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* From the RbacService registered in the domain or a parent (sets, companions, wildcards, the ceiling applied),
|
|
45
|
+
* used only when it is the service of a model the domain's AuthzService runs: a child domain without one must not match
|
|
46
|
+
* set rows through its parent's service. Otherwise the principal and its type wildcard.
|
|
47
|
+
*/
|
|
48
|
+
async subjectKeys(principal, domain, at) {
|
|
49
|
+
const own = [(0, authz_rbac_1.principalSubjectKey)(principal), (0, authz_rbac_1.subjectKeyOf)({ type: principal.type, id: '*' })];
|
|
50
|
+
const domains = domain === 'root' ? undefined : (await this.container.resolve(authz_1.AuthzDomains));
|
|
51
|
+
const scope = domains ? domains.container(domain) : this.container;
|
|
52
|
+
if (!scope.hasRegistered(authz_rbac_1.RbacService))
|
|
53
|
+
return own;
|
|
54
|
+
const rbac = (await scope.resolve(authz_rbac_1.RbacService));
|
|
55
|
+
const authz = domains ? await domains.service(domain) : (await scope.resolve(authz_1.AuthzService));
|
|
56
|
+
return authz.models().includes(rbac.model) ? rbac.subjectKeysOf(principal, at) : own;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.FsAclRelation = FsAclRelation;
|
|
60
|
+
//# sourceMappingURL=relation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relation.js","sourceRoot":"","sources":["../../../src/acl/relation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { AssignmentSubject, PrincipalRef } from '@spinajs/authz';
|
|
2
|
+
import type { IContainer } from '@spinajs/di';
|
|
3
|
+
import { FileAclStore } from './store.js';
|
|
4
|
+
export declare const FS_ACL_TABLE = "fs_acl";
|
|
5
|
+
export declare const FS_ACL_LIMITS: Readonly<{
|
|
6
|
+
fs: 64;
|
|
7
|
+
path: 512;
|
|
8
|
+
subject_key: 200;
|
|
9
|
+
relation: 64;
|
|
10
|
+
granted_by: 100;
|
|
11
|
+
}>;
|
|
12
|
+
type Column = keyof typeof FS_ACL_LIMITS;
|
|
13
|
+
export declare function fits(value: string, column: Column): string;
|
|
14
|
+
export declare const aclFs: (fs: unknown) => string;
|
|
15
|
+
export declare const aclPath: (path: string) => string;
|
|
16
|
+
/** `fs_acl.path_hash`: keeps the unique key short enough for every driver (path alone is 2048 bytes in MySQL utf8mb4). */
|
|
17
|
+
export declare const aclPathHash: (normalised: string) => string;
|
|
18
|
+
export declare const aclRelation: (relation: unknown) => string;
|
|
19
|
+
export declare const aclSubjectKey: (subject: AssignmentSubject) => string;
|
|
20
|
+
/** An owner is one principal: its own key, never the type wildcard (a principal whose id is '*' stays itself). */
|
|
21
|
+
export declare function aclOwnerKey(owner: PrincipalRef): string;
|
|
22
|
+
export declare function aclExpiry(expiresAt: unknown): Date | null;
|
|
23
|
+
/** `type:*`: every principal of the type. */
|
|
24
|
+
export declare const isWildcardKey: (key: string) => boolean;
|
|
25
|
+
/** The subject a stored key names: a set (`type:id#role`), a principal, or a type wildcard. */
|
|
26
|
+
export declare function subjectOfKey(key: string, at: string): AssignmentSubject;
|
|
27
|
+
/** `path`, its parent directories nearest first, then '' (D7: a row on a directory or the root covers what is under it). */
|
|
28
|
+
export declare function aclPathChain(path: string): string[];
|
|
29
|
+
export declare const isUnder: (path: string, root: string) => boolean;
|
|
30
|
+
/** Where `path` (at or under `from`) lands when `from` moves to `to`. */
|
|
31
|
+
export declare function movedPath(from: string, to: string, path: string): string;
|
|
32
|
+
export declare function checkMove(fromFs: string, from: string, toFs: string, to: string): void;
|
|
33
|
+
/** The FileAclStore of `container`: the last one registered (OrmFileAclStore unless an app or a test adds one). */
|
|
34
|
+
export declare function fileAclStore(container: IContainer): Promise<FileAclStore>;
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/acl/shared.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAO9C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI1C,eAAO,MAAM,YAAY,WAAW,CAAC;AAErC,eAAO,MAAM,aAAa;;;;;;EAA2G,CAAC;AAEtI,KAAK,MAAM,GAAG,MAAM,OAAO,aAAa,CAAC;AAEzC,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAG1D;AAED,eAAO,MAAM,KAAK,OAAQ,OAAO,KAAG,MAAqC,CAAC;AAE1E,eAAO,MAAM,OAAO,SAAU,MAAM,KAAG,MAA6C,CAAC;AAErF,0HAA0H;AAC1H,eAAO,MAAM,WAAW,eAAgB,MAAM,KAAG,MAA4B,CAAC;AAE9E,eAAO,MAAM,WAAW,aAAc,OAAO,KAAG,MAAgG,CAAC;AAEjJ,eAAO,MAAM,aAAa,YAAa,iBAAiB,KAAG,MAAoD,CAAC;AAEhH,kHAAkH;AAClH,wBAAgB,WAAW,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAKvD;AAED,wBAAgB,SAAS,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,GAAG,IAAI,CAIzD;AAED,6CAA6C;AAC7C,eAAO,MAAM,aAAa,QAAS,MAAM,KAAG,OAA6B,CAAC;AAE1E,+FAA+F;AAC/F,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,iBAAiB,CAIvE;AAED,4HAA4H;AAC5H,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAOnD;AAED,eAAO,MAAM,OAAO,SAAU,MAAM,QAAQ,MAAM,KAAG,OAAsE,CAAC;AAE5H,yEAAyE;AACzE,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAIxE;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAEtF;AAED,mHAAmH;AACnH,wBAAsB,YAAY,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAE/E"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isUnder = exports.isWildcardKey = exports.aclSubjectKey = exports.aclRelation = exports.aclPathHash = exports.aclPath = exports.aclFs = exports.FS_ACL_LIMITS = exports.FS_ACL_TABLE = void 0;
|
|
4
|
+
exports.fits = fits;
|
|
5
|
+
exports.aclOwnerKey = aclOwnerKey;
|
|
6
|
+
exports.aclExpiry = aclExpiry;
|
|
7
|
+
exports.subjectOfKey = subjectOfKey;
|
|
8
|
+
exports.aclPathChain = aclPathChain;
|
|
9
|
+
exports.movedPath = movedPath;
|
|
10
|
+
exports.checkMove = checkMove;
|
|
11
|
+
exports.fileAclStore = fileAclStore;
|
|
12
|
+
const authz_1 = require("@spinajs/authz");
|
|
13
|
+
const authz_rbac_1 = require("@spinajs/authz-rbac");
|
|
14
|
+
const exceptions_1 = require("@spinajs/exceptions");
|
|
15
|
+
const fs_1 = require("@spinajs/fs");
|
|
16
|
+
const util_1 = require("@spinajs/util");
|
|
17
|
+
const crypto_1 = require("@spinajs/util/crypto");
|
|
18
|
+
const checks_js_1 = require("../checks.js");
|
|
19
|
+
const store_js_1 = require("./store.js");
|
|
20
|
+
// Internal to the ACL stores, the relation and the middleware; the barrel exports the two constants only.
|
|
21
|
+
exports.FS_ACL_TABLE = 'fs_acl';
|
|
22
|
+
exports.FS_ACL_LIMITS = Object.freeze({ fs: 64, path: 512, subject_key: authz_rbac_1.SUBJECT_KEY_MAX_LENGTH, relation: 64, granted_by: 100 });
|
|
23
|
+
function fits(value, column) {
|
|
24
|
+
if (value.length > exports.FS_ACL_LIMITS[column])
|
|
25
|
+
throw new exceptions_1.InvalidArgument(`${JSON.stringify(value.slice(0, 40))}… does not fit ${exports.FS_ACL_TABLE}.${column} (${exports.FS_ACL_LIMITS[column]} characters)`, column);
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
28
|
+
const aclFs = (fs) => fits((0, checks_js_1.checkFsName)(fs), 'fs');
|
|
29
|
+
exports.aclFs = aclFs;
|
|
30
|
+
const aclPath = (path) => fits((0, fs_1.normalizeFsPath)(path), 'path');
|
|
31
|
+
exports.aclPath = aclPath;
|
|
32
|
+
/** `fs_acl.path_hash`: keeps the unique key short enough for every driver (path alone is 2048 bytes in MySQL utf8mb4). */
|
|
33
|
+
const aclPathHash = (normalised) => (0, crypto_1.sha256)(normalised);
|
|
34
|
+
exports.aclPathHash = aclPathHash;
|
|
35
|
+
const aclRelation = (relation) => fits((0, util_1._check_arg)((0, util_1._is_string)((0, util_1._non_empty)()))(relation, 'relation'), 'relation');
|
|
36
|
+
exports.aclRelation = aclRelation;
|
|
37
|
+
const aclSubjectKey = (subject) => fits((0, authz_rbac_1.subjectKeyOf)(subject), 'subject_key');
|
|
38
|
+
exports.aclSubjectKey = aclSubjectKey;
|
|
39
|
+
/** An owner is one principal: its own key, never the type wildcard (a principal whose id is '*' stays itself). */
|
|
40
|
+
function aclOwnerKey(owner) {
|
|
41
|
+
if (owner === null || typeof owner !== 'object' || typeof owner.type !== 'string' || owner.type === '' || typeof owner.id !== 'string' || owner.id === '') {
|
|
42
|
+
throw new exceptions_1.InvalidArgument(`an owner is a principal { type, id } with non-empty strings, got ${JSON.stringify(owner)}`, 'owner');
|
|
43
|
+
}
|
|
44
|
+
return fits((0, authz_rbac_1.principalSubjectKey)({ type: owner.type, id: owner.id }), 'subject_key');
|
|
45
|
+
}
|
|
46
|
+
function aclExpiry(expiresAt) {
|
|
47
|
+
if (expiresAt === undefined || expiresAt === null)
|
|
48
|
+
return null;
|
|
49
|
+
if (!(expiresAt instanceof Date) || Number.isNaN(expiresAt.getTime()))
|
|
50
|
+
throw new exceptions_1.InvalidArgument(`expiresAt must be a valid Date, got ${String(expiresAt)}`, 'expiresAt');
|
|
51
|
+
return expiresAt;
|
|
52
|
+
}
|
|
53
|
+
/** `type:*`: every principal of the type. */
|
|
54
|
+
const isWildcardKey = (key) => key.endsWith(':*');
|
|
55
|
+
exports.isWildcardKey = isWildcardKey;
|
|
56
|
+
/** The subject a stored key names: a set (`type:id#role`), a principal, or a type wildcard. */
|
|
57
|
+
function subjectOfKey(key, at) {
|
|
58
|
+
const subject = (0, authz_rbac_1.parseSetKey)(key) ?? (0, authz_rbac_1.parsePrincipalSubjectKey)(key) ?? ((0, exports.isWildcardKey)(key) ? (0, authz_rbac_1.parsePrincipalKey)(key) : undefined);
|
|
59
|
+
if (!subject)
|
|
60
|
+
throw new authz_1.AuthzConfigError(`${at}: ${JSON.stringify(key)} is not a subject key`);
|
|
61
|
+
return subject;
|
|
62
|
+
}
|
|
63
|
+
/** `path`, its parent directories nearest first, then '' (D7: a row on a directory or the root covers what is under it). */
|
|
64
|
+
function aclPathChain(path) {
|
|
65
|
+
if (path === '')
|
|
66
|
+
return [''];
|
|
67
|
+
const segments = path.split('/');
|
|
68
|
+
const chain = [];
|
|
69
|
+
for (let n = segments.length; n > 0; n--)
|
|
70
|
+
chain.push(segments.slice(0, n).join('/'));
|
|
71
|
+
chain.push('');
|
|
72
|
+
return chain;
|
|
73
|
+
}
|
|
74
|
+
const isUnder = (path, root) => root === '' || path === root || path.startsWith(`${root}/`);
|
|
75
|
+
exports.isUnder = isUnder;
|
|
76
|
+
/** Where `path` (at or under `from`) lands when `from` moves to `to`. */
|
|
77
|
+
function movedPath(from, to, path) {
|
|
78
|
+
const rest = from === '' ? path : path.slice(from.length + 1);
|
|
79
|
+
if (to === '')
|
|
80
|
+
return rest;
|
|
81
|
+
return rest === '' ? to : `${to}/${rest}`;
|
|
82
|
+
}
|
|
83
|
+
function checkMove(fromFs, from, toFs, to) {
|
|
84
|
+
if (fromFs === toFs && from !== to && (from === '' || to.startsWith(`${from}/`)))
|
|
85
|
+
throw new exceptions_1.InvalidArgument(`cannot move ${fromFs}:${from} into itself (${to})`, 'to');
|
|
86
|
+
}
|
|
87
|
+
/** The FileAclStore of `container`: the last one registered (OrmFileAclStore unless an app or a test adds one). */
|
|
88
|
+
async function fileAclStore(container) {
|
|
89
|
+
return (await container.resolve(store_js_1.FileAclStore));
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/acl/shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { AssignmentSubject, PrincipalRef } from '@spinajs/authz';
|
|
2
|
+
/** One row of the file ACL: `subject` holds `relation` on `path` of `fs` and on everything under it (D7). */
|
|
3
|
+
export interface FsAclRow {
|
|
4
|
+
readonly fs: string;
|
|
5
|
+
/** Normalised; '' is the filesystem root. */
|
|
6
|
+
readonly path: string;
|
|
7
|
+
/** A principal, `{ type, id: '*' }` for every principal of a type, or a subject set (D8). */
|
|
8
|
+
readonly subject: AssignmentSubject;
|
|
9
|
+
readonly relation: string;
|
|
10
|
+
readonly expiresAt?: Date;
|
|
11
|
+
/** principalKey of whoever granted the row. */
|
|
12
|
+
readonly grantedBy?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The file ACL (fs middleware design §3.1). Paths are normalised without a base path ('' = the root); subject keys
|
|
16
|
+
* are authz-rbac `subjectKeyOf` keys. AuthzFsMiddleware keeps it in step with the files; system code may call it
|
|
17
|
+
* directly, apps go through FsAcl.
|
|
18
|
+
*/
|
|
19
|
+
export declare abstract class FileAclStore {
|
|
20
|
+
/** Whether a live row of `relation` at one of `paths` names one of `subjectKeys` at `at`. */
|
|
21
|
+
abstract holds(fs: string, paths: readonly string[], subjectKeys: readonly string[], relation: string, at: Date): Promise<boolean>;
|
|
22
|
+
/** The rows at exactly `path`, expired ones included. */
|
|
23
|
+
abstract list(fs: string, path: string): Promise<readonly FsAclRow[]>;
|
|
24
|
+
/** Idempotent on (fs, path, subject, relation): a second grant replaces `expiresAt` and `grantedBy`. */
|
|
25
|
+
abstract grant(row: FsAclRow): Promise<void>;
|
|
26
|
+
abstract revoke(fs: string, path: string, subjectKey: string, relation: string): Promise<void>;
|
|
27
|
+
/** The principal of the oldest `owner` row at exactly `path` (set and wildcard rows skipped); null without one. */
|
|
28
|
+
abstract ownerOf(fs: string, path: string): Promise<PrincipalRef | null>;
|
|
29
|
+
/** Adds an `owner` row for `owner` unless `path` has an owner row already (first writer wins). */
|
|
30
|
+
abstract setOwnerIfAbsent(fs: string, path: string, owner: PrincipalRef): Promise<void>;
|
|
31
|
+
/** The rows at `path` and under it; '' takes every row of the filesystem. */
|
|
32
|
+
abstract deleteTree(fs: string, path: string): Promise<void>;
|
|
33
|
+
/** The rows at exactly `path`. */
|
|
34
|
+
abstract deletePath(fs: string, path: string): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Moves the rows at `from` and under it to `to` on `toFs`; a moved row replaces an equal one there. A row whose new
|
|
37
|
+
* path would be longer than FS_ACL_LIMITS.path is deleted.
|
|
38
|
+
*/
|
|
39
|
+
abstract moveTree(fromFs: string, from: string, toFs: string, to: string): Promise<void>;
|
|
40
|
+
/** Moves the rows at exactly `from` (none under it) to `to` on `toFs`; a moved row replaces an equal one there. */
|
|
41
|
+
abstract movePath(fromFs: string, from: string, toFs: string, to: string): Promise<void>;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/acl/store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEtE,6GAA6G;AAC7G,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,6FAA6F;IAC7F,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC;IAC1B,+CAA+C;IAC/C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;GAIG;AACH,8BAAsB,YAAY;IAChC,6FAA6F;IAC7F,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,WAAW,EAAE,SAAS,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnI,yDAAyD;IACzD,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,QAAQ,EAAE,CAAC,CAAC;IACtE,wGAAwG;IACxG,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/F,mHAAmH;IACnH,QAAQ,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IACzE,kGAAkG;IAClG,QAAQ,CAAC,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxF,6EAA6E;IAC7E,QAAQ,CAAC,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D,kCAAkC;IAClC,QAAQ,CAAC,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzF,mHAAmH;IACnH,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1F"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FileAclStore = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* The file ACL (fs middleware design §3.1). Paths are normalised without a base path ('' = the root); subject keys
|
|
6
|
+
* are authz-rbac `subjectKeyOf` keys. AuthzFsMiddleware keeps it in step with the files; system code may call it
|
|
7
|
+
* directly, apps go through FsAcl.
|
|
8
|
+
*/
|
|
9
|
+
class FileAclStore {
|
|
10
|
+
}
|
|
11
|
+
exports.FileAclStore = FileAclStore;
|
|
12
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/acl/store.ts"],"names":[],"mappings":";;;AAeA;;;;GAIG;AACH;CAuBC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ResourceAdapter } from '@spinajs/authz';
|
|
2
|
+
import type { PermissionDef, RelationResolver, ResourceRef, ResourceType } from '@spinajs/authz';
|
|
3
|
+
import type { IContainer } from '@spinajs/di';
|
|
4
|
+
import type { FsPathKind, FsRow } from '../refs/index.js';
|
|
5
|
+
export interface FsResourceTarget {
|
|
6
|
+
readonly fs: string;
|
|
7
|
+
readonly path: string;
|
|
8
|
+
/** Default: 'dir' for a row (load) of type 'dir', else 'file'. */
|
|
9
|
+
readonly kind?: FsPathKind;
|
|
10
|
+
}
|
|
11
|
+
/** Refs, ancestors, rows and permissions of the filesystems; registered in the root container. */
|
|
12
|
+
export declare class FsResourceAdapter extends ResourceAdapter<FsResourceTarget> {
|
|
13
|
+
protected readonly container: IContainer;
|
|
14
|
+
readonly kind = "fs";
|
|
15
|
+
readonly types: readonly ResourceType[];
|
|
16
|
+
/** Where the published fs providers and the Configuration are looked up. */
|
|
17
|
+
constructor(container?: IContainer);
|
|
18
|
+
accepts(target: unknown): target is FsResourceTarget;
|
|
19
|
+
refOf(target: FsResourceTarget): ResourceRef;
|
|
20
|
+
/** Does not know which filesystems exist, so an fs name with no provider still gets a chain (it grants nothing). */
|
|
21
|
+
ancestors(ref: ResourceRef): Promise<readonly ResourceRef[] | null>;
|
|
22
|
+
/** The row AuthzFsMiddleware passes as the subject of every check, built without IO. */
|
|
23
|
+
load(ref: ResourceRef): Promise<FsRow | null>;
|
|
24
|
+
attribute(subject: unknown, field: string): unknown;
|
|
25
|
+
/**
|
|
26
|
+
* One FsAclRelation per fs type and `authz.fsAcl` relation: boot rule 8 needs a resolver for every relation a grant
|
|
27
|
+
* names, on every type of the permission, known at boot.
|
|
28
|
+
*/
|
|
29
|
+
relations(): readonly RelationResolver[];
|
|
30
|
+
permissions(): readonly Omit<PermissionDef, 'source'>[];
|
|
31
|
+
protected basePathOf(fsName: string): string | undefined;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapter/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEjG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAO9C,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE1D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,kEAAkE;IAClE,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC;CAC5B;AAID,kGAAkG;AAClG,qBACa,iBAAkB,SAAQ,eAAe,CAAC,gBAAgB,CAAC;IAK1D,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,UAAU;IAJpD,QAAQ,CAAC,IAAI,QAAQ;IACrB,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAqB;IAE5D,4EAA4E;IAC5E,YAA+B,SAAS,GAAE,UAA6B,EAEtE;IAED,OAAO,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,IAAI,gBAAgB,CAMnD;IAED,KAAK,CAAC,MAAM,EAAE,gBAAgB,GAAG,WAAW,CAG3C;IAED,oHAAoH;IAC9G,SAAS,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,WAAW,EAAE,GAAG,IAAI,CAAC,CAExE;IAED,wFAAwF;IAClF,IAAI,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAElD;IAED,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAElD;IAED;;;OAGG;IACH,SAAS,IAAI,SAAS,gBAAgB,EAAE,CAGvC;IAED,WAAW,IAAI,SAAS,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,EAAE,CAEtD;IAGD,SAAS,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGvD;CACF"}
|