Extension:WikiGuard

From mediawiki.org
MediaWiki extensions manual
WikiGuard
Release status: beta
Implementation User rights
Description Advanced permission policy management for MediaWiki
Author(s) Marijn van Wezel (Wikibase Solutions) (Xxmarijnwtalk)
Latest version 0.2.0 (2023-08-02)
Compatibility policy Master maintains backward compatibility.
MediaWiki >=1.35.6
PHP >=7.4
Database changes No
License GNU General Public License 2.0 or later
Download

The WikiGuard extension implements an advanced permission policy management system for MediaWiki. It allows you to define so-called permission policies that determine whether a user is allowed to perform a request, and apply these policies to specific actions (view, edit, delete, etc.) globally, on selected namespaces or on selected pages.

Policies in detail[edit]

A policy is a set of rules that are evaluated from top-to-bottom to determine whether a request is allowed. A rule consists of two basic parts, the conditional and the consequent. The conditional determines whether a rule matches the given request, and the consequent determines whether the request should be allowed or denied when it does. For example, a rule may take the form of the following if-statement: if the user is an admin then we allow the request. How to write these rules such that WikiGuard can understand it will be discussed in the #Writing policies section below.

Since the rules are evaluated from top-to-bottom, the last rule in the list that matches will be the one that determines whether the request is actually allowed. This means that the order in which the rules appear is relevant. For example, suppose we implement a policy that denies all (logged-in) users, unless they are also in the sysop user group:

  • if the user is logged in then deny
  • if the user is an admin then allow

If we were to swap these rules, it would no longer work, as the last rule would deny any logged-in user (even administrators).

Default behaviour[edit]

By default, if no rules match, the request is allowed. However, since WikiGuard never overrides the default protections of the wiki, the request may still be blocked by MediaWiki or another extension.

Inheritance[edit]

Policies inherit the rules of their parent. This means that WikiGuard, for any action, will first evaluate the rules of the policy applied to the entire wiki, then those of the policy applied to the corresponding namespace and finally the rules of the policy applied to the page itself.

For example, if you want to view the main page, it will first evaluate the rules of the wiki-wide view policy (if it exists), then the rules of the main namespace's view policy (if it exists) and finally the rules of the main page's view policy (if it exists).

Writing policies[edit]

The wikiguard-edit-policy user right is required to edit policies.

No user interface has been implemented to edit policies yet, which means that you have to edit raw JSON to create or edit a policy (luckily, a JSON schema is provided).

To create or edit a policy, create or edit the appropriate page in the Policy namespace. A policy consists of a (possibly empty) ordered list of rule objects, where each rule object specifies a rule.

Rule objects[edit]

A rule object, in its most basic form, has a rule key, specifying the type of the rule (see #Rule types below), and a consequent key, specifying the consequent of the rule (true/false). For example, the rule if the user is an admin then allow would be serialised as such:

{
    "rule": "issysop",
    "consequent": true
}

A rule may require a parameters key, specifying additional parameters for the rule. Which parameters are required and what their type must be differs for each rule. For example, the hasusername rule, which matches if the user is in a list of usernames, requires the username parameter, which must be an array of strings:

{
    "rule": "hasusername",
    "consequent": "false",
    "parameters": {
        "usernames": [
            "Blocked user 1",
            "Blocked user 2",
            "Xxmarijnw"
        ]
    }
}

Additionally, it is possible to specify an alternative key, specifying whether the request is allowed if the rule doesn't match. Finally, it is possible to negate the condition of the rule by setting the negate key to true. For example, the rule if the user is not an admin then deny otherwise allow would be serialised as such:

{
    "rule": "issysop",
    "consequent": false,
    "alternative": true,
    "negate": true
}

Rule types[edit]

hasusername[edit]

The "has username" rule checks if the current user has one of the specified usernames as their username.

Parameters[edit]
usernames : string[]
The usernames to match.
Example[edit]
{
    "rule": "hasusername",
    "consequent": true,
    "parameters": {
        "usernames": ["Pietje Bell", "John Doe"]
    }
}

inallgroups[edit]

The "in all groups" rule checks if the current user is a member of all the specified groups.

Parameters[edit]
groups : string[]
The groups the user must be in.
Example[edit]
{
    "rule": "inallgroups",
    "consequent": true,
    "parameters": {
        "groups": ["sysop", "interfaceadministrator"]
    }
}

inanygroups[edit]

The "in any groups" rule checks if the current user is a member of any of the specified groups.

Parameters[edit]
groups : array<string>
The groups the user may be in.
Example[edit]
{
    "rule": "inanygroups",
    "consequent": true,
    "parameters": {
        "groups": ["sysop", "administrator", "developer"]
    }
}

isregistered[edit]

The "is registered" rule checks if the current user is a registered user.

Example[edit]
{
    "rule": "isregistered",
    "consequent": true
}

issysop[edit]

The "is sysop" rule checks if the current user is a member of the group "sysop".

Example[edit]
{
    "rule": "issysop",
    "consequent": true
}

lunarphase[edit]

The "lunar phase" rule matches based on the current phase of the moon.

Parameters[edit]
moonPhase : "full"|"new"|"waxing"|"waning"
The phase the moon must be in.
Example[edit]
{
    "rule": "lunarphase",
    "consequent": true,
    "parameters": {
        "moonPhase": "waning"
    }
}

template[edit]

The "template" rule parses a template and checks if the returned value is true-ish ("true"/"yes"/"on"/"1").

Parameters[edit]
template : integer
The ID of the template to parse.
Example[edit]
{
    "rule": "template",
    "consequent": false,
    "parameters": {
        "template": 3827
    }
}

Example[edit]

[
    {
        "rule": "template",
        "consequent": false,
        "parameters": {
            "template": 3827
        }
    },
    {
        "rule": "issysop",
        "consequent": true
    },
    {
        "rule": "lunarphase",
        "negate": true,
        "consequent": true,
        "parameters": {
            "moonPhase": "full"
        }
    }
]

Applying policies[edit]

Policies can be applied by using the "Edit policies" link in the sidebar, or by going to the ManagePermissionPolicies special page. Unfortunately, a search feature is not yet implemented. Therefore, to edit the policies of a particular object (the wiki, a namespace or a page), you must append the ID of the object to the special page's URL. The IDs have the following structure:

  • wk - for the entire wiki
  • ns-xxx - for a namespace; replace xxx with the ID of the namespace
  • ns-special - for the Special namespace
  • pg-xxx - for a page; replace xxx with the ID of the page
  • sp-xxx - for a special page; replace xxx with the name of the special page

For example, to edit the permission policies of Special:Watchlist, you need to visit Special:ManagePermissionPolicies/sp-Watchlist.

Installation[edit]

  • Download and place the file(s) in a directory called WikiGuard in your extensions/ folder.
  • Add the following code at the bottom of your LocalSettings.php file:
    wfLoadExtension( 'WikiGuard' );
    
  • Run the update script which will automatically create the necessary database tables that this extension needs.
  • Yes Done – Navigate to Special:Version on your wiki to verify that the extension is successfully installed.

See also[edit]