Page MenuHomePhabricator

Add wgUserRights to mw.config object
Closed, DeclinedPublic

Description

While wgUserGroups can be used to establish certain levels of access (e.g. you can check if a user is in the sysop group before showing them a JS tool that has to do with page deletions), it is not sufficient (e.g. other groups may also have page deletion right, such as the eliminator group on fawiki). Therefore, we should make it easy for JS code to determine the rights a user has. I propose adding a property to`mw.config` called wgUserRights which would be an array of rights.

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald Transcript

To check for permissions, it is indeed more stable to check user rights instead of group membership.

For this reason, the mw.user interface has a getRights() method (Documentation).

mw.user.getRights().then(function (rights) {
  console.log('Rights:', rights);
});

Note that adding it specifically to mw.config poses a performance problem, as it would require this data to be preloaded on all page views, which is not acceptable. I've recently declined T86858 for the same reason. See also T219342, T220926.

Let me know if the mw.user method works for you. If not, let us know too, so that it can be improved.

The mw.user.getRights() approach works (and thanks for educating me on it). However, it is an async solution. Having something like mw.config.get('wgUserRights') that is available as soon as the page is loaded and can be used in a synchronous way would be awesome. Indeed, I don't see much value in the getRight being asynch because typically we don't expect a user's rights (or group memberships, for that matter) to change so often that we would want to query the API each time.

If it is for a gadget, the rights filter might be a good option (documentation).

If it is a gadget that is also works without the right, or if it is a user script; and the information is needed on most pages that the user visits, then you might want to cache it in a cookie. This way, it is only checked once a week or once a month. The user can clear their cookies if their rights change and need the gadget to see it.

var allowedStr = $.cookie('myscript-rights');
var checkRights = allowedStr ? $.Deferred().resolve(allowedStr === 'true') : mw.user.getRights().then(function (rights) {
   var allowed = rights.indexOf('delete') !== -1;
   $.cookie('myscript-rights', String(allowed), { expires: 30, path: '/' });
   return allowed;
});
/*
checkRights.then(function (allowed) {
  console.log('isAllowed:', allowed);
});
*/

My current use case is to allow eliminators to have access to those features of Twinkle that have to do with deleting pages (currently, Twinkle restricts that script by checking the user's right).

The cookie solution is "hacky" but will certainly work. But my question is: even if we have solutions like above (several lines of code, relying on a cookie, etc.) wouldn't it be easier to just have mw.config.get('wgUserRights') to the tool belt?

wouldn't it be easier to just have mw.config.get('wgUserRights') to the tool belt?

Easier to write as developer yes. But in my opinion not an improvement overall, because:

[..] adding it specifically to mw.config poses a performance problem, as it would require this data to be preloaded on all page views, which is not acceptable. I've recently declined T86858 for the same reason. See also T219342, T220926.

If we preload data that is only needed in some cases by some users, we end up preloading all data for all users. This is not sustainable and regresses the user experience for everyone, including users of Twinkle (by needlessly loading data for unrelated gadgets you might not be using).

I'm declining requests like this, so as to maintain the cost and speed for everyone. The long-term vision is to slowly reduce the number of large values exported from mw.config, not to add more to it (see also T206250).

Minimal values to identify the current wiki, page and user will remain. As well as legacy values that are commonly used in gadgets, core, and extensions (such as namespace name/ID mapping).

But for larger data, requesting it from the API is not a "hack". It is the appropriate tool for the given problem. The same solution would also be applied if it were needed client-side in MediaWiki core and extensions. Caching in a cookie works. Another option I would consider if this were needed in MediaWiki itself, would be to explore ways of avoiding the need for the data on regular article views. For example, when viewing an article, perhaps the tool is not visible by default but requires a click. Or perhaps other indicators can be used as proxy (such as availability of Deletion action in the content actions menu).

Fair enough. Thanks for the detailed explanation!