Last modified: 2011-11-14 08:42:27 UTC

Wikimedia Bugzilla is closed!

Wikimedia migrated from Bugzilla to Phabricator. Bug reports are handled in Wikimedia Phabricator.
This static website is read-only and for historical purposes. It is not possible to log in and except for displaying bug reports and their history, links might be broken. See T33613, the corresponding Phabricator task for complete and up-to-date bug report information.
Bug 31613 - API UsageException when saving a collection to a page
API UsageException when saving a collection to a page
Status: RESOLVED FIXED
Product: MediaWiki extensions
Classification: Unclassified
Collection (Other open bugs)
unspecified
Macintosh Mac OS X 10.7
: Highest blocker with 1 vote (vote)
: ---
Assigned To: Nobody - You can work on this!
:
: 31953 32313 (view as bug list)
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2011-10-11 19:05 UTC by Mark A. Hershberger
Modified: 2011-11-14 08:42 UTC (History)
10 users (show)

See Also:
Web browser: Google Chrome
Mobile Platform: ---
Assignee Huggle Beta Tester: ---


Attachments

Description Mark A. Hershberger 2011-10-11 19:05:17 UTC
From [[WP:VPT]]: http://en.wikipedia.org/w/index.php?diff=455038876


Unexpected non-MediaWiki exception encountered, of type "UsageException"
badtoken: Invalid token

#0 /usr/local/apache/common-local/php-1.18/includes/api/ApiBase.php(1205): ApiBase->dieUsage('Invalid token', 'badtoken')
#1 /usr/local/apache/common-local/php-1.18/includes/api/ApiMain.php(590): ApiBase->dieUsageMsg('sessionfailure')
#2 /usr/local/apache/common-local/php-1.18/includes/api/ApiMain.php(678): ApiMain->setupModule()
#3 /usr/local/apache/common-local/php-1.18/includes/api/ApiMain.php(340): ApiMain->executeAction()
#4 /usr/local/apache/common-local/php-1.18/extensions/Collection/Collection.body.php(867): ApiMain->execute()
#5 /usr/local/apache/common-local/php-1.18/extensions/Collection/Collection.body.php(225): SpecialCollection->saveCollection(Object(Title), false)
#6 /usr/local/apache/common-local/php-1.18/includes/SpecialPageFactory.php(460): SpecialCollection->execute(NULL)
#7 /usr/local/apache/common-local/php-1.18/includes/Wiki.php(224): SpecialPageFactory::executePath(Object(Title), Object(RequestContext))
#8 /usr/local/apache/common-local/php-1.18/includes/Wiki.php(624): MediaWiki->performRequest()
#9 /usr/local/apache/common-local/php-1.18/includes/Wiki.php(531): MediaWiki->main()
#10 /usr/local/apache/common-local/php-1.18/index.php(57): MediaWiki->run()
#11 /usr/local/apache/common-local/live-1.5/index.php(3): require('/usr/local/apac...')
#12 {main}
Comment 1 Tim Starling 2011-10-11 19:57:27 UTC
Diff seems unrelated. Try <http://en.wikipedia.org/w/index.php?title=Wikipedia:Village_pump_%28technical%29&oldid=455088498#Error_when_attempting_to_create_new_book>

Relevant code:

$req = new FauxRequest( array(
	'action' => 'edit',
	'title' => $title->getPrefixedText(),
	'text' => $articleText,
	'token' => $wgUser->editToken(),
), true );
$api = new ApiMain( $req, true );
Comment 2 James Michael DuPont 2011-10-26 04:57:34 UTC
This affects me as well.
Comment 3 Christoph Kepper 2011-10-26 10:40:34 UTC
*** Bug 31953 has been marked as a duplicate of this bug. ***
Comment 4 Christoph Kepper 2011-10-26 12:56:12 UTC
As far as I can see, there is a logical problem in $wgUser->matchEditToken(). (includes/User.php L3228)

public function matchEditToken( $val, $salt = '', $request = null ) {
    $sessionToken = $this->editToken( $salt, $request );
        if ( $val != $sessionToken ) {
            wfDebug( "User::matchEditToken: broken session data\n" \
        );
    }
    return $val == $sessionToken;
}

The token ($val) has to be inserted in the request, but $sessionToken is hashed with the request. Therefore, the token inserted in the request can NEVER match the original $wgUser->editToken().
Comment 5 Roan Kattouw 2011-10-26 17:58:07 UTC
It's not hashed with the entire request. $request is just passed through so that getEditToken() can do 			$token = $request->getSessionData( 'wsEditToken' );  (line 3194)

It's very unlikely that there is a logic error in matchEditToken(), or there'd be a heck of a lot more things breaking.
Comment 6 Mark A. Hershberger 2011-10-26 17:59:55 UTC
Bumping priority since it was seen in Bug 31821
Comment 7 Christoph Kepper 2011-10-26 19:21:30 UTC
You are right Roan. This is not the problem. 

After digging a little deeper I found that the $request parameter that is handed to matchEditToken() is the FauxRequest. This FauxRequest does not contain 'wsEditToken' and so getEditToken() generates a new token with every call.

I don't know what would be the right way to fix this. It works if I set $request = null in matchEditToken() but this seems like short-circuiting the check.
Comment 8 Christoph Kepper 2011-10-27 07:01:08 UTC
I cannot commit files from the includes directory, but this patch might fix the problem:

Index: includes/User.php
===================================================================
--- includes/User.php	(revision 100951)
+++ includes/User.php	(working copy)
@@ -3184,7 +3184,7 @@
 	 * @return String The new edit token
 	 */
 	public function getEditToken( $salt = '', $request = null ) {
-		if ( $request == null ) {
+		if ( $request == null || get_class($request) == 'FauxRequest') {
 			$request = $this->getRequest();
 		}
Comment 9 Roan Kattouw 2011-10-27 11:03:05 UTC
What exactly is passing a FauxRequest to editToken()?
Comment 10 Christoph Kepper 2011-10-27 12:04:52 UTC
The FauxRequest is created in /extensions/Collection/Collection.body.php(867).

The FauxRequest is passed on from ApiMain->setupModule() (in ApiMain.php:591):
if ( !$this->getUser()->matchEditToken( $moduleParams['token'], $salt, $this->getRequest() ) ) {

The problem is that $this->getRequest() does retrieve the FauxRequest not $wgRequest.
Comment 11 Roan Kattouw 2011-10-28 08:24:05 UTC
Hmph, this kind of sucks. I guess we could either change ApiMain to obtain the session data from $wgRequest instead of the provided request, or require that the caller provide the session data in the FauxRequest. The latter is something you can easily do in Collection by using

new FauxRequest( array( your parameters here ), true, $_SESSION )
Comment 12 Daniel Friesen 2011-10-28 08:42:37 UTC
ApiMain is extracting query and session data from the request data it's provided in it's context and using that to secure the edit action. Collection is providing faux request data and saying there's no session data.

Looks to me like the correct way to do this is definitely for Collection to provide the session data to the api, or to use a proper internal api for editing instead of using the web use intended api.
Comment 13 Christoph Kepper 2011-10-28 09:40:13 UTC
Integrating $_SESSION as Roan suggested is no problem. 

@Daniel: The collection extension currently implements the API as described in http://www.mediawiki.org/wiki/API:Calling_internally 
If there is a new/better way to create new pages from an extension, the documentation should be updated.
Comment 14 Daniel Friesen 2011-10-28 09:58:20 UTC
(In reply to comment #13)
> Integrating $_SESSION as Roan suggested is no problem. 
> 
> @Daniel: The collection extension currently implements the API as described in
> http://www.mediawiki.org/wiki/API:Calling_internally 
> If there is a new/better way to create new pages from an extension, the
> documentation should be updated.

That's just a documentation page on how to call the api internally if you choose to. Namely if you want to use things like the query api internally. It doesn't even mention editing besides how to handle edit tokens.

The 'other' or rather usual way extensions end up trying to make edits is using WikiPage::doEdit or the EditPage class itself.

Not sure how good the state of that all is though to be honest. There are extra checks that EditPage goes and hacks into itself that might actually belong in doEdit.

That said, it's not like Collection is bothering to check for things like if a page is actually saved at all.

Also side note, it's making a bad use of Article. All it's doing is checking for existence, if that's all you want you should be using Title.
It'll break less when we kill off Article in our ideal world.
Comment 15 Christoph Kepper 2011-10-28 16:45:19 UTC
I applied the patch from Roan in r101149 and fixed the immediate problem. 

Patches for further improvements as suggested by Daniel are welcome.
Comment 16 konjahman 2011-10-30 11:37:27 UTC
Although this bug has been given the status of "resolved fixed" I got the below error today:

Unexpected non-MediaWiki exception encountered, of type "UsageException"
badtoken: Invalid token

#0 /usr/local/apache/common-local/php-1.18/includes/api/ApiBase.php(1205): ApiBase->dieUsage('Invalid token', 'badtoken')
#1 /usr/local/apache/common-local/php-1.18/includes/api/ApiMain.php(590): ApiBase->dieUsageMsg('sessionfailure')
#2 /usr/local/apache/common-local/php-1.18/includes/api/ApiMain.php(678): ApiMain->setupModule()
#3 /usr/local/apache/common-local/php-1.18/includes/api/ApiMain.php(340): ApiMain->executeAction()
#4 /usr/local/apache/common-local/php-1.18/extensions/Collection/Collection.body.php(867): ApiMain->execute()
#5 /usr/local/apache/common-local/php-1.18/extensions/Collection/Collection.body.php(225): SpecialCollection->saveCollection(Object(Title), false)
#6 /usr/local/apache/common-local/php-1.18/includes/SpecialPageFactory.php(460): SpecialCollection->execute(NULL)
#7 /usr/local/apache/common-local/php-1.18/includes/Wiki.php(224): SpecialPageFactory::executePath(Object(Title), Object(RequestContext))
#8 /usr/local/apache/common-local/php-1.18/includes/Wiki.php(624): MediaWiki->performRequest()
#9 /usr/local/apache/common-local/php-1.18/includes/Wiki.php(531): MediaWiki->main()
#10 /usr/local/apache/common-local/php-1.18/index.php(57): MediaWiki->run()
#11 /usr/local/apache/common-local/live-1.5/index.php(3): require('/usr/local/apac...')
#12 {main}
Comment 17 Roan Kattouw 2011-10-30 21:00:30 UTC
(In reply to comment #16)
> Although this bug has been given the status of "resolved fixed" I got the below
> error today:
> 
> Unexpected non-MediaWiki exception encountered, of type "UsageException"
> badtoken: Invalid token
> 
> #0 /usr/local/apache/common-local/php-1.18/includes/api/ApiBase.php(1205):
> ApiBase->dieUsage('Invalid token', 'badtoken')
> #1 /usr/local/apache/common-local/php-1.18/includes/api/ApiMain.php(590):
> ApiBase->dieUsageMsg('sessionfailure')
> #2 /usr/local/apache/common-local/php-1.18/includes/api/ApiMain.php(678):
> ApiMain->setupModule()
> #3 /usr/local/apache/common-local/php-1.18/includes/api/ApiMain.php(340):
> ApiMain->executeAction()
> #4
> /usr/local/apache/common-local/php-1.18/extensions/Collection/Collection.body.php(867):
> ApiMain->execute()
> #5
> /usr/local/apache/common-local/php-1.18/extensions/Collection/Collection.body.php(225):
> SpecialCollection->saveCollection(Object(Title), false)
> #6
> /usr/local/apache/common-local/php-1.18/includes/SpecialPageFactory.php(460):
> SpecialCollection->execute(NULL)
> #7 /usr/local/apache/common-local/php-1.18/includes/Wiki.php(224):
> SpecialPageFactory::executePath(Object(Title), Object(RequestContext))
> #8 /usr/local/apache/common-local/php-1.18/includes/Wiki.php(624):
> MediaWiki->performRequest()
> #9 /usr/local/apache/common-local/php-1.18/includes/Wiki.php(531):
> MediaWiki->main()
> #10 /usr/local/apache/common-local/php-1.18/index.php(57): MediaWiki->run()
> #11 /usr/local/apache/common-local/live-1.5/index.php(3):
> require('/usr/local/apac...')
> #12 {main}
It was fixed in SVN but the fix has not been deployed yet. It is customary to mark bugs as FIXED as soon as the fix is checked in, though.
Comment 18 kai.marc.heide 2011-11-02 15:51:54 UTC
When can the deployment of this fix be expected? Are the deployment cycles big?
Comment 19 Mark A. Hershberger 2011-11-03 01:30:11 UTC
Fixes like this one will probably be deployed in a few days time.
I'll try to ping someone tomorrow.
Comment 20 Christoph Kepper 2011-11-10 22:40:53 UTC
*** Bug 32313 has been marked as a duplicate of this bug. ***
Comment 21 Roan Kattouw 2011-11-14 08:42:19 UTC
(In reply to comment #19)
> Fixes like this one will probably be deployed in a few days time.
> I'll try to ping someone tomorrow.
Deployed.

Note You need to log in before you can comment on or make changes to this bug.


Navigation
Links