MWX/Invite/notes
Notes
MW API: selectively enabling account request
- 2020-09-06 posted a call for help on Mastodon
- 2020-09-07 and then in desperation, submitted a help-desk request
dead end
The tricky part of this is the interface with MediaWiki to selectively allow a visitor (i.e. one who has a valid invite code) to request an account when visitors are not generally allowed to access that page.
The class for creating pages based on the "Create account" page is apparently LoginSignupSpecialPage... except the documentation says "This feature was removed completely in version 1.33." (...and yet the file is still present in 1.34.2)
The actual class for handling account requests appears to be SpecialCreateAccount ...which descends from LoginSignupSpecialPage. (Honestly, guys, I think that class is still in use.)
I tried descending my page from that, and overriding its methods when a valid invite has not been received, but got caught up in a tangle of internal security checks which never seemed to be satisfiable. I then came across a note in the AuthManager source code:
* If you are looking at this because you are working on an extension that creates its own * login or signup page, then 1) you really shouldn't do that, 2) if you feel you absolutely * have to, subclass AuthManagerSpecialPage or build it on the client side using the clientlogin * or the createaccount API. Trying to call this class directly will very likely end up in * security vulnerabilities or broken UX in edge cases.
...where "security vulnerability" plus "broken UX" sounds kinda like what I was running into, subclassing SpecialCreateAccount (and having already tried subclassing from its parent, LoginSignupSpecialPage).
So I figured maybe this wasn't the right way to go... and there certainly didn't seem to be any instructions on how to make it work right.
AuthManager, however, seems to be strictly for handling logins and creating accounts; I don't need to modify any of that behavior, just grant access to existing functionality. So that doesn't seem like the right path either.
That said, I haven't yet tried subclassing AuthManagerSpecialPage (which doesn't seem to exist??) -- but when all the functionality I want is in SpecialCreateAccount, it doesn't seem right to subclass anything else (because I'd have to replicate that functionality, increasing technical debt).
hook interception
What seems like it should work, but hasn't, is to intercept the userCan hook, ignore anything that isn't the SpecialCreateAccount, and authorize everything as long as a valid invite code is passed.
The problem is that authorizing access doesn't seem to authorize access; I still get this same message:
You do not have permission to do that, for the following reason:
You are not allowed to execute the action you have requested.
So now it's a matter of tracing back through the code to find out why it thinks this.
The second line corresponds to the error message badaccess-group0
. I searched the code and found several possible places where it could be occurring; the one which was actually being tripped was this:
Original exception: [e851e4d8ff408613bd96ef03] /w/Special:CreateAccount Exception from line 587 of /home/psycrit/site/mediawiki-1.34.2/includes/Permissions/PermissionManager.php: 2020-09-10 What is triggering this error? action=deletedhistory
Backtrace:
- #0 /home/psycrit/site/mediawiki-1.34.2/includes/Permissions/PermissionManager.php(789): MediaWiki\Permissions\PermissionManager->missingPermissionError(string, boolean)
- #1 /home/psycrit/site/mediawiki-1.34.2/includes/Permissions/PermissionManager.php(395): MediaWiki\Permissions\PermissionManager->checkQuickPermissions(string, User, array, string, boolean, Title)
- #2 /home/psycrit/site/mediawiki-1.34.2/includes/Permissions/PermissionManager.php(229): MediaWiki\Permissions\PermissionManager->getPermissionErrorsInternal(string, User, Title, string, boolean)
- #3 /home/psycrit/site/mediawiki-1.34.2/includes/Permissions/PermissionManager.php(248): MediaWiki\Permissions\PermissionManager->userCan(string, User, Title, string)
- #4 /home/psycrit/site/mediawiki-1.34.2/includes/skins/Skin.php(733): MediaWiki\Permissions\PermissionManager->quickUserCan(string, User, Title)
- #5 /home/psycrit/site/mediawiki-1.34.2/includes/skins/SkinTemplate.php(284): Skin->getUndeleteLink()
- #6 /home/psycrit/site/mediawiki-1.34.2/includes/skins/SkinTemplate.php(215): SkinTemplate->prepareQuickTemplate()
- #7 /home/psycrit/site/mediawiki-1.34.2/includes/OutputPage.php(2574): SkinTemplate->outputPage()
- #8 /home/psycrit/site/mediawiki-1.34.2/includes/MediaWiki.php(537): OutputPage->output()
- #9 /home/psycrit/site/mediawiki-1.34.2/index.php(44): MediaWiki->run()
- #10 {main}
MW API: checking for permission
This bit was easier, but I did find several ways to do it. There's an obvious best way, but the others may be useful in future.
First you get the object for the current User. SpecialPages have a built-in function so you don't have to use the $wgUser global:
$mwoUser = $this->getUser();
The obvious best way to find out if the user has permission to create other accounts:
$mwoUser->isAllowedToCreateAccount();
Other ways:
// 1. get groups for user, then get perms for those groups
$arGroups = $mwoUser->getEffectiveGroups();
$arPerms = \User::getGroupPermissions($arGroups);
// 2. get perms for user
$arPerms = $mwoUser->getRights();
// 3. get flag for whether the user has the "create account" permission
$canMakeUsers = $mwoUser->isAllowed('createaccount');