MWX/Invite/notes: Difference between revisions

From Woozle Writes Code
< MWX‎ | Invite
Jump to navigation Jump to search
No edit summary
m (Woozle moved page Special-Invite/notes to MWX/Invite/notes: reorganizing MW extensions)
 
(6 intermediate revisions by the same user not shown)
Line 1: Line 1:
==Notes==
==MediaWiki API issues==
===MW API: selectively enabling account request===
===related discussions===
* '''2020-09-06''' posted a [https://toot.cat/@woozle/104819648051582653 call for help] on Mastodon
* [[mw:Anonymous editor acquisition/Signup invites]]
* '''2020-09-07''' and then in desperation, [https://www.mediawiki.org/wiki/Topic:Vtk1jmnjcfz71wq1 submitted a help-desk request]
===selectively enabling account creation===
====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 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.


Line 10: Line 9:
The ''actual'' class for handling account requests appears to be [https://doc.wikimedia.org/mediawiki-core/master/php/classSpecialCreateAccount.html SpecialCreateAccount] ...which descends from LoginSignupSpecialPage. (Honestly, guys, I think that class is still in use.)
The ''actual'' class for handling account requests appears to be [https://doc.wikimedia.org/mediawiki-core/master/php/classSpecialCreateAccount.html 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 [https://phabricator.wikimedia.org/source/mediawiki/browse/master/includes/auth/AuthManager.php$46 the AuthManager source code]:
Posts:
* If you are looking at this because you are working on an extension that creates its own
* '''2020-09-06''' posted a [https://toot.cat/@woozle/104819648051582653 call for help] on Mastodon
* login or signup page, then 1) you really shouldn't do that, 2) if you feel you absolutely
* '''2020-09-07''' and then in desperation, [https://www.mediawiki.org/wiki/Topic:Vtk1jmnjcfz71wq1 submitted a help-desk request]
* 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.
 
{{l/mw|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 [https://phabricator.wikimedia.org/source/mediawiki/browse/master/includes/auth/AuthManager.php?grep=AuthManagerSpecialPage 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 [[mw:Manual:Hooks/userCan|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:<blockquote>You do not have permission to do that, for the following reason:<br>You are not allowed to execute the action you have requested.</blockquote>So now it's a matter of tracing back through the code to find out why it thinks this.
Attempts:
* [[/take 1]]: descending from SpecialCreateAccount was a dead end
* [[/take 2]]: hook interception works and is simpler (but don't forget to declare all hooks)


I traced the error message to several possible places where it could be occurring; the one which was actually being tripped was this:
===checking for admin permission===
<blockquote style="font-size: 10pt;"><poem>
This bit (where you check whether the user can access the admin interface) was easier, but I did find several ways to do it. There's an obvious best way; the others may be useful in future.
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}
</poem></blockquote>
===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:
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:
Line 65: Line 38:
$canMakeUsers = $mwoUser->isAllowed('createaccount');
$canMakeUsers = $mwoUser->isAllowed('createaccount');
</source>
</source>
===related discussions===
* [[mw:Anonymous editor acquisition/Signup invites]]

Latest revision as of 00:31, 17 April 2022

MediaWiki API issues

related discussions

selectively enabling account creation

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.)

Posts:

Attempts:

  • /take 1: descending from SpecialCreateAccount was a dead end
  • /take 2: hook interception works and is simpler (but don't forget to declare all hooks)

checking for admin permission

This bit (where you check whether the user can access the admin interface) was easier, but I did find several ways to do it. There's an obvious best way; 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');