Extension:WikiLambda/Granular Edit Authorization
This page contains a detailed description of how user rights are used in Wikifunctions for function execution, object creation, and object editing. This documentation is mostly intended for anyone who wishes to contribute to the development or configuration of the system, as it provides technical details and in-depth explanations of the system and the configuration data. For a more user-oriented guide on rights and privileges (who can do what, and how) go to Help:Wikifunctions/User rights.
Execution rights
editaction | rights needed |
---|---|
Run function | wikilambda-execute |
Run unsaved implementation code from the implementation page | wikilambda-execute-unsaved-code |
Examples
edit- Running a function in the Special:RunFunction page requires the rights: [ wikilambda-execute ]
- Editing an implementation code and running the unsaved code requires the rights: [ wikilambda-execute, wikilambda-execute-unsaved-code ]
Creation rights
edittype | action | rights needed | |
---|---|---|---|
* | * | edit | |
* | create an object of type ZObject | wikilambda-create | |
* | create object in Z1-Z9999 Zid range | wikilambda-create-predefined | |
Boolean/Z40 | create object of type Boolean/Z40 | wikilambda-create-boolean | task T349497 |
Unit/Z21 | create object of type Unit/Z21 | wikilambda-create-unit | task T349497 |
Type/Z4 | create object of type Type/Z4 | wikilambda-create-type | |
Language/Z60 | create object of type Language/Z60 | wikilambda-create-language | |
Programming language/Z61 | create object of type Programming language/Z61 | wikilambda-create-programming | |
Function/Z8 | create object of type Function/Z8 | wikilambda-create-function | |
Implementation/Z14 | create object of type Implementation/Z14 | wikilambda-create-implementation | |
Test/Z20 | create object of type Test/Z20 | wikilambda-create-tester | |
Serialiser/Z64 | create object of type Serialiser/Z64 | wikilambda-create-converter | task T367270 |
Deserialiser/Z46 | create object of type Deserialiser/Z46 | wikilambda-create-converter | task T367270 |
Enum value | create object of an Enumeration type | wikilambda-create-enum-value | task T366610 |
Examples
edit- "Create the Boolean object True/Z41" requires the rights: [ edit, wikilambda-create, wikilambda-create-predefined, wikilambda-create-boolean ]
- "Create a new Type/Z4 in the user-provided Zid space" requires the rights: [ edit, wikilambda-create, wikilambda-create-type ]
Edit rights
editWhile editing, different parts of the Object must be protected differently. Editing some keys might heavily affect the system's behavior while others are innocuous. For this reason, the edit object system analyzes the changes in detail and requires different permissions depending on the combination of different properties. These are the features that will be analyzed to determine the collection of user rights that are needed for a given edit:
- Object Zid range: this differentiates between predefined objects (objects in the Zid range from Z1 to Z9999) and user-provided objects (Zid larger than Z10000)
- Object type: the type of the object; different objects have different restrictions
- Object state: different objects can be in different states. Currently the available states are:
- Function/Z8: running vs. not-running
- Implementation/Z14: connected vs. not-connected
- Test/Z20: connected vs. not-connected
- Edited key path: this determines which parts of an object should be more protected than others
Right discovery process
editFor every edit requests, there might be a number of different parts of the object being edited. As explained above, these different parts might be also protected by sets of different rights. Every time that a edit request is received the system separates this edit into the set of different granular edits, and for each one of them, matches a set of rules and returns the rights required to do this. The rights required for these granular edited will be collected and added to the default right edit (as reflected in the first row of the table below).
For each granular edit, a list of rules will be matched in order, and the first rule that is matched will return the required rights. To read more about the authorization rule format, see development details below.
The following table reflects this granular authorization rules.
- Note that the rules are not cumulative, but terminal. Once a granular edit is matched, the given right is return and we will proceed to analyze the following granular edit of the request.
- Also note that the rules are matched in order, so whatever change matched by a particular row, excludes all the changes matched by the previous ones. For example, the right "wikilambda-edit-boolean", which is needed to edit a boolean, only applies when the edit occurs in other keys that are not covered by the first rules in the list (not the object type, label, description or aliases)
zid range | type | state | action | rights needed | terminal |
---|---|---|---|---|---|
* | * | * | * | edit | No |
* | * | * | change the type of an object | wikilambda-edit-object-type | Yes |
change the label of an object | wikilambda-edit-object-label | Yes | |||
change the description of an object | wikilambda-edit-object-description | Yes | |||
change the aliases of an object | wikilambda-edit-object-alias | Yes | |||
Type/Z4 | * | change the key labels of a type | wikilambda-edit-key-label | Yes | |
Error type/Z50 | * | change the key labels of an error type | wikilambda-edit-error-key-label | Yes | |
Function/Z8 | * | change the input labels of a function | wikilambda-edit-argument-label | Yes | |
Boolean/Z40 | * | any other change | wikilambda-edit-boolean | Yes | |
Unit/Z21 | * | any other change | wikilambda-edit-unit | Yes | |
Language/Z60 | * | any other change | wikilambda-edit-language | Yes | |
Programming language/Z61 | * | any other change | wikilambda-edit-programming | Yes | |
Enum value | * | any other change | wikilambda-edit-enum-value | Yes | |
[Z1-Z9999] | Function/Z8 | * | any other change | wikilambda-edit-builtin-function | Yes |
* | * | any other change in a predefined object | wikilambda-edit-predefined | Yes | |
[Z10000-*) | Type/Z4 | * | any other change | wikilambda-edit-type | Yes |
Deserialiser/Z46 | connected | any other change | wikilambda-edit-connected-converter | Yes | |
* | any other change | wikilambda-edit-converter | Yes | ||
Serialiser/Z64 | connected | any other change | wikilambda-edit-connected-converter | Yes | |
* | any other change | wikilambda-edit-converter | Yes | ||
Function/Z8 | running | change inputs | wikilambda-edit-user-function
wikilambda-edit-running-function wikilambda-edit-running-function-definition |
Yes | |
change output type | wikilambda-edit-user-function
wikilambda-edit-running-function wikilambda-edit-running-function-definition |
Yes | |||
connect implementation | wikilambda-edit-user-function
wikilambda-edit-running-function wikilambda-edit-connect-implementation |
Yes | |||
disconnect implementation | wikilambda-edit-user-function
wikilambda-edit-running-function wikilambda-edit-disconnect-implementation |
Yes | |||
connect test | wikilambda-edit-user-function
wikilambda-edit-running-function wikilambda-edit-connect-test |
Yes | |||
disconnect test | wikilambda-edit-user-function
wikilambda-edit-running-function wikilambda-edit-disconnect-test |
Yes | |||
not running | connect implementation | wikilambda-edit-user-function
wikilambda-edit-connect-implementation |
Yes | ||
disconnect implementation | wikilambda-edit-user-function
wikilambda-edit-disconnect-implementation |
Yes | |||
connect test | wikilambda-edit-user-function
wikilambda-edit-connect-test |
Yes | |||
disconnect test | wikilambda-edit-user-function
wikilambda-edit-disconnect-test |
Yes | |||
* | any other change | wikilambda-edit-user-function | Yes | ||
Implementation/Z14 | connected | any other change | wikilambda-edit-attached-implementation | Yes | |
not connected | any other change | wikilambda-edit-implementation | Yes | ||
Test/Z20 | connected | any other change | wikilambda-edit-attached-tester | Yes | |
not connected | any other change | wikilambda-edit-tester | Yes | ||
* | * | any other change | wikilambda-edit | Yes |
Examples
edit- "Adding a new label, description and alias to the object True/Z41, instance of Boolean/Z40" requires the rights [ edit, wikilambda-edit-object-label, wikilambda-edit-object-description, wikilambda-edit-object-alias ], as it consists on three different granular edits:
- "Editing the object labels", which requires [ edit, wikilambda-edit-object-label ],
- "Editing the object descriptions", which requires [ edit, wikilambda-edit-object-description ], and
- "Editing the object aliases", which requires [ edit, wikilambda-edit-object-alias ]
- "Editing language ISO code of the language Spanish/Z1003 (es)" requires the rights [ edit, wikilambda-edit-language ]
- "Connecting a test to the predefined function If/Z802" requires the rights [ edit, wikilambda-edit-builtin-function ]
- "Connecting a test and an implementation to the newly added (not running) user-provided function Join strings/Z10000" requires the rights [ edit, wikilambda-edit-user-function, wikilambda-edit-connect-test, wikilambda-edit-connect-implementation ], and consists on two granular edits:
- "Connect a test to the function", which requires [ edit, wikilambda-edit-user-function, wikilambda-edit-connect-test ], and
- "Connect an implementation" which requires [ edit, wikilambda-edit-user-function, wikilambda-edit-connect-implementation ]
Granular edit diffs
editTo be able to restrict granular edits differently, first the system needs to calculate and describe the nature of these edits. Wikilambda diffing system compares two Objects and returns an array of granular diffs which have the following structure:
path
- Array of keys that identify the location of the edit.
op
- type: Change, Add or Remove
- oldvalue: old value in case of Change or Remove operations; empty if the operation is Add.
- newvalue: new value in case of Change or Add operations; empty if the operation is Remove.
Authorization rule development
editTo add more granular edit rules to the table above, edit the authorization-rules.yml configuration file and add your new rule in the right place. As explained in the Right discovery process section above, note that granular rules are terminal, which also means that the matching order is important.
The authorization rules YAML file contains a list where each item is an object with the following properties:
- path: [type: string] Contains a regular expression that matches the path where the granular edit was found. The path is formed by the sequence of nested keys separated between them by a dot. For example, if an object first label is edited, the path of the edit will be "Z2K3.Z12K1.1.Z11K2"
- type: [type: string] If present, contains a string with the object type to which this rule applies
- filter: [type: array] If present, contains the name of a filtering class and the arguments to call it. Filtering classes should be implementations of the interface Authorization/ZObjectFilter.php and should implement the method pass, which is called with the old value, the new value, the page title, and the additional arguments declared in the rule. The method pass must return a boolean that, if true, will qualify the given object to match this rule.
- operations: [type:object] Lists the rights needed for each of the possible operations, and for any of them. It has the following properties:
- any: [type: array] List of rights required for any operations that matched this rule
- add: [type: array] List of rights required for the Add operations that matched this rule
- remove: [type: array] List of rights required for the Remove operations that matched this rule
- change: [type: array] List of rights required for the Change operations that matched this rule
For example, the following YAML rule matches any change (unmatched by preceding rules) on Function/Z8 objects, that happened under the path Z2K2.Z8K4.*, and which return True when called ZObjectFilterIsRunnable::pass(), and returns the rights wikilambda-edit-user-function and wikilambda-edit-running-function added to wikilambda-edit-connect-implementation or wikilambda-edit-disconnect-implementation depending on the type of operation.
# Connect and disconnect implementations from a running user-function - path: '^Z2K2\.Z8K4\.[1-9]\d*(\..*)?$' type: Z8 filter: [ ZObjectFilterIsRunnable ] operations: any: - wikilambda-edit-user-function - wikilambda-edit-running-function add: - wikilambda-connect-implementation remove: - wikilambda-disconnect-implementation change: - wikilambda-connect-implementation - wikilambda-disconnect-implementation