Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
68.18% covered (warning)
68.18%
15 / 22
40.00% covered (danger)
40.00%
2 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
CentralAuthApiSessionProvider
68.18% covered (warning)
68.18%
15 / 22
40.00% covered (danger)
40.00%
2 / 5
10.06
0.00% covered (danger)
0.00%
0 / 1
 getTokenFromRequest
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
2.15
 makeBogusSessionInfo
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 provideSessionInfo
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
2.15
 consumeToken
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 onApiCheckCanExecute
37.50% covered (danger)
37.50%
3 / 8
0.00% covered (danger)
0.00%
0 / 1
2.98
1<?php
2
3use MediaWiki\Api\Hook\ApiCheckCanExecuteHook;
4use MediaWiki\Request\WebRequest;
5use MediaWiki\Session\SessionInfo;
6use MediaWiki\User\User;
7
8/**
9 * Session provider for CentralAuth API centralauthtoken
10 *
11 * This session provider looks for the 'centralauthtoken' request parameter,
12 * and checks that it corresponds to an existing token set up by
13 * ApiCentralAuthToken. If the parameter is present but invalid, it returns a
14 * bogus SessionInfo and hooks ApiBeforeMain to throw an appropriate exception
15 * later when MediaWiki is ready to handle it.
16 *
17 * @see \MediaWiki\Extension\CentralAuth\Api\ApiCentralAuthToken
18 */
19class CentralAuthApiSessionProvider
20    extends CentralAuthTokenSessionProvider
21    implements ApiCheckCanExecuteHook
22    {
23
24    /**
25     * @param WebRequest $request
26     *
27     * @return string|null
28     */
29    protected function getTokenFromRequest( WebRequest $request ) {
30        // Only relevant in the API
31        if ( !defined( 'MW_API' ) ) {
32            return null;
33        }
34
35        return $request->getVal( 'centralauthtoken' );
36    }
37
38    /**
39     * Throw an exception, later
40     *
41     * @param string $code Error code
42     * @param string|array $error Error message key, or key+parameters
43     * @return SessionInfo
44     */
45    protected function makeBogusSessionInfo( $code, $error ) {
46        // Schedule the throwing of the exception for later when the API
47        // is ready to catch it.
48        $exception = \ApiUsageException::newWithMessage( null, $error, $code );
49        /** @return never */
50        $excepClosure = static function () use ( $exception ) {
51            throw $exception;
52        };
53        $this->getHookContainer()->register( 'ApiBeforeMain', $excepClosure );
54
55        return parent::makeBogusSessionInfo( $code, $error );
56    }
57
58    /** @inheritDoc */
59    public function provideSessionInfo( WebRequest $request ) {
60        // Only relevant in the API
61        if ( !defined( 'MW_API' ) ) {
62            return null;
63        }
64
65        return parent::provideSessionInfo( $request );
66    }
67
68    /**
69     * Overridden to defer actual consumption of the token until the ApiCheckCanExecute
70     * hook is called.
71     *
72     * @param string $token
73     *
74     * @return bool
75     */
76    protected function consumeToken( $token ) {
77        // Delete the token once it's actually used
78        $this->getHookContainer()->register( 'ApiCheckCanExecute', $this );
79        return true;
80    }
81
82    /**
83     * Consume the centralauthtoken
84     * @param ApiBase $module
85     * @param User $user
86     * @param array &$message Error message key and params
87     * @return bool
88     */
89    public function onApiCheckCanExecute( $module, $user, &$message ) {
90        // Mark used
91        $token = $module->getMain()->getVal( 'centralauthtoken' );
92
93        // NOTE: Call parent, because we override consumeToken() in this class
94        //       to operate indirectly via this hook.
95        if ( !parent::consumeToken( $token ) ) {
96            // Raced out trying to mark the token as expired
97            $message = ApiMessage::create(
98                'apierror-centralauth-badtoken',
99                'badtoken'
100            );
101
102            return false;
103        }
104
105        return true;
106    }
107
108}