Class: ACLUtils
Defined in: service-core/src/security/ACLUtils.ts:25
Common utility functions for working with AccessControlList objects and validating user permissions.
Constructors
Constructor
new ACLUtils():
ACLUtils
Returns
ACLUtils
Properties
_objectFactory?
protectedoptional_objectFactory?:ObjectFactory
Defined in: service-core/src/security/ACLUtils.ts:27
enabled
enabled:
boolean=true
Defined in: service-core/src/security/ACLUtils.ts:30
Methods
checkRequestPerms()
checkRequestPerms(
uid,user,req):Promise<boolean>
Defined in: service-core/src/security/ACLUtils.ts:106
Validates that the user has permission to perform the request operation against the URL path for the
provided request. If ACLUtils has not been initialized or the acl datasource has not been configured
then always returns true.
Parameters
uid
string
The uid of the access control list to verify against.
user
JWTUser | undefined
The user to validate.
req
The HTTP request to check permissions for.
Returns
Promise<boolean>
findACL()
findACL(
entityId,parentUids?,options?):Promise<AccessControlList|undefined>
Defined in: service-core/src/security/ACLUtils.ts:201
Retrieves the access control list with the associated identifier and populates the parent(s).
Deliberately not @Transactional and never participates in a caller's transaction: it's on the hot path
for every permission check (hasPermission/checkRequestPerms), not just writes, so wrapping it would
add a session open/close to every authorization check. It also has no way to safely reuse a caller's
transaction context.
Parameters
entityId
string
The unique identifier of the ACL to retrieve.
parentUids?
string[] = []
The list of already found parent UIDs. This is used to break circular dependencies.
options?
Set skipCache: true to bypass the cache and always read the current database state —
mirrors RepoUtils's RepoFindOptions.skipCache. The result is still written back into the cache
afterward, same as a normal (non-skipped) lookup.
skipCache?
boolean
Returns
Promise<AccessControlList | undefined>
getRecord()
getRecord(
acl,user):ACLRecord|null
Defined in: service-core/src/security/ACLUtils.ts:603
Retrieves the most specific record in the provided ACL associated with the provided user: an exact
uid/anonymous match beats a role match, which beats a wildcard (.*/*) match — regardless of where
each record sits in acl.records. Without this, a wildcard grant authored before a specific record
(a natural authoring order) would silently shadow that more specific record. Only falls back to the
parent ACL when nothing in this ACL's own records matches at all.
Parameters
acl
The access control list that will be searched.
user
JWTUser | undefined
The user to find a record for.
Returns
ACLRecord | null
The ACL record associated with the given user if found, otherwise undefined.
hasPermission()
hasPermission(
user,acl,action):Promise<boolean>
Defined in: service-core/src/security/ACLUtils.ts:158
Validates that the user has permission to perform the provided action using the given access control list.
Parameters
user
JWTUser | undefined
The user to validate permissions of.
acl
string | AccessControlList
The ACL or uid of an ACL to validate permissions against.
action
string
The action that the user desires permission for.
Returns
Promise<boolean>
true if the user has at least one of the permissions granted for the given entity, otherwise false.
populateParent()
populateParent(
acl,parentUids?):Promise<void>
Defined in: service-core/src/security/ACLUtils.ts:636
Attempts to retrieve the parent access control list for the given ACL object.
Parameters
acl
The access control list whose parents will be populated.
parentUids?
string[] = []
The list of already found parent UIDs. This is used to break circular dependencies.
Returns
Promise<void>
removeACL()
removeACL(
uid):Promise<AccessControlList|undefined>
Defined in: service-core/src/security/ACLUtils.ts:264
Deletes the ACL with the given identifier from the database, returning the document that was actually
deleted (or undefined if none existed) — captured atomically as part of the delete itself (Mongo:
findOneAndDelete; SQL: a findOne immediately followed by the delete, both inside this method's own
acl transaction), not a separate, earlier read. A caller using the return value as a restore snapshot
(see RepoUtils.delete()/truncate()'s registerRollbackHook() usage) always gets the exact row that
was removed, never a possibly-stale one raced by a concurrent legitimate write between an earlier read
and this delete — and restoring it later still goes through saveACL()'s own optimistic-lock version
check, so a restore attempt can't clobber a newer row that appeared after this delete either.
Runs in its own transaction scoped to the acl connection (see Transactional) rather than trying to
join whatever transaction the caller is itself in — acl is frequently configured as its own, separate
datastore (a documented, supported deployment shape), so a caller's session/entityManager almost never
actually belongs to the same physical connection this repo does. Reusing it directly used to throw
(Mongo) or silently target the wrong connection (SQL).
Parameters
uid
string
The unique identifier of the ACL to remove.
Returns
Promise<AccessControlList | undefined>
removeACLs()
removeACLs(
uids):Promise<AccessControlList[]>
Defined in: service-core/src/security/ACLUtils.ts:563
Atomic removal of multiple ACLs in a single acl-scoped transaction (see @Transactional), returning
whichever of them actually existed to be deleted (see removeACL()'s doc comment for why the returned
documents — not a separate, earlier read — are the right thing to snapshot for a possible restore).
Deliberately sequential, not batched-concurrent: every removeACL() call below resolves to this same
acl datasource, so @Transactional's merge logic joins all of them onto the one MongoDB
ClientSession/SQL EntityManager this method opened. Running these with Promise.all
would issue overlapping commands against one session, which drivers reject or misorder.
Parameters
uids
string[]
The unique identifiers of the ACLs to remove.
Returns
Promise<AccessControlList[]>
saveACL()
saveACL(
acl,options?):Promise<AccessControlList|null>
Defined in: service-core/src/security/ACLUtils.ts:396
Stores the given access control list into the ACL database. By default, bumps the version for optimistic
locking (see below) — pass preserveVersion: true to instead write acl back with its own version
exactly as given, for restoring a known-good snapshot (see RepoUtils.delete()/truncate()'s
registerRollbackHook() usage) rather than applying a new change on top of whatever's currently stored.
A restore only ever targets a uid with nothing currently at it (that's the point — the entity-side
transaction it was tied to is being rolled back, so the row it deleted should no longer exist); if
something does exist there already, the restore is refused rather than silently clobbering it.
Runs in its own transaction scoped to the acl connection (see Transactional) rather than trying to
join whatever transaction the caller is itself in — see removeACL's doc comment for why. Callers that
need the entity-side write and this ACL save to stay consistent should register a compensating action
via registerRollbackHook().
Parameters
acl
The ACL to store.
options?
Set preserveVersion: true to restore acl exactly as given (see above) instead of the
normal optimistic-locking update semantics.
preserveVersion?
boolean
Returns
Promise<AccessControlList | null>
Returns the ACL that was stored in the database.
saveACLs()
saveACLs(
acls):Promise<void>
Defined in: service-core/src/security/ACLUtils.ts:586
Atomic save of multiple ACLs in a single acl-scoped transaction (see Transactional). Used to restore
a batch of ACL snapshots — e.g. by a registerRollbackHook() compensating action — if the entity-side
transaction they were removed alongside subsequently fails. Always restores each ACL's own version as
given (see saveACL()'s preserveVersion option) rather than bumping it, since this is a restore, not
a new change.
Deliberately sequential. See removeACLs()'s doc comment for why.
Parameters
acls
The ACLs to store.
Returns
Promise<void>
saveDefaultACL()
saveDefaultACL(
acl):Promise<AccessControlList|null>
Defined in: service-core/src/security/ACLUtils.ts:493
Stores the given default access control list into the ACL database. A default ACL is a special type of ACL
that is primarily defined and maintained within the code but allows for user-specific overrides. To accomplish
this, the provided ACL is split in two. A new record is automatically created with the uid of the form
default_<uid> that stores the exact record as provided by code. Then a second ACL record is created
with the uid being that of what is passed as the argument. This second ACL is used to store user-defined
overrides. As the default_<uid> record is always overwritten with the lastest version of the code, any
user-defined changes made to it are lost on service restart.
Parameters
acl
Returns
Promise<AccessControlList | null>