zenstack/packages/plugins/policy/plugin.zmodel
Yiming Cao e4b79d0c6f
feat: field-level access control (#557)
* WIP

* WIP: implement read policies

* fix tests

* Update packages/plugins/policy/src/policy-handler.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix name mapper

* fix tests

* fix build

* implement update field-level policies

* update tests

* update tests

* add more tests

* add more tests

* simplify queries

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-05 18:14:23 +08:00

71 lines
3.4 KiB
Text

/**
* Defines an access policy that allows a set of operations when the given condition is true.
*
* @param operation: comma-separated list of "create", "read", "update", "post-update", "delete". Use "all" to denote all operations.
* @param condition: a boolean expression that controls if the operation should be allowed.
*/
attribute @@allow(_ operation: String @@@completionHint(["'create'", "'read'", "'update'", "'post-update'","'delete'", "'all'"]), _ condition: Boolean)
/**
* Defines an access policy that allows the annotated field to be read or updated.
* You can pass a third argument as `true` to make it override the model-level policies.
*
* @param operation: comma-separated list of "read", "update". Use "all" to denote all operations.
* @param condition: a boolean expression that controls if the operation should be allowed.
*/
attribute @allow(_ operation: String @@@completionHint(["'read'", "'update'", "'all'"]), _ condition: Boolean)
/**
* Defines an access policy that denies a set of operations when the given condition is true.
*
* @param operation: comma-separated list of "create", "read", "update", "post-update", "delete". Use "all" to denote all operations.
* @param condition: a boolean expression that controls if the operation should be denied.
*/
attribute @@deny(_ operation: String @@@completionHint(["'create'", "'read'", "'update'", "'post-update'","'delete'", "'all'"]), _ condition: Boolean)
/**
* Defines an access policy that denies the annotated field to be read or updated.
*
* @param operation: comma-separated list of "read", "update". Use "all" to denote all operations.
* @param condition: a boolean expression that controls if the operation should be denied.
*/
attribute @deny(_ operation: String @@@completionHint(["'read'", "'update'", "'all'"]), _ condition: Boolean)
/**
* Delegates the access control decision to a relation. Only to-one relations are supported.
*
* @param field: The relation field to delegate to.
* @param operation: The operation to check access for. Can be "read", "create", "update", "post-update", or "delete". If the operation is not provided,
* it defaults the operation of the containing policy rule.
*/
function check(field: Any, operation: String?): Boolean {
} @@@expressionContext([AccessPolicy])
/**
* Gets entity's value before an update. Only valid when used in a "post-update" policy rule.
*/
function before(): Any {
} @@@expressionContext([AccessPolicy])
/**
* The name of the model for which the policy rule is defined. If the rule is
* inherited to a sub model, this function returns the name of the sub model.
*
* @param optional parameter to control the casing of the returned value. Valid
* values are "original", "upper", "lower", "capitalize", "uncapitalize". Defaults
* to "original".
*/
function currentModel(casing: String?): String {
} @@@expressionContext([AccessPolicy])
/**
* The operation for which the policy rule is defined for. Note that a rule with
* "all" operation is expanded to "create", "read", "update", and "delete" rules,
* and the function returns corresponding value for each expanded version.
*
* @param optional parameter to control the casing of the returned value. Valid
* values are "original", "upper", "lower", "capitalize", "uncapitalize". Defaults
* to "original".
*/
function currentOperation(casing: String?): String {
} @@@expressionContext([AccessPolicy])