Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
27 / 27
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
1 / 1
TwoFactorModuleSelectAuthenticationRequest
100.00% covered (success)
100.00%
27 / 27
100.00% covered (success)
100.00%
5 / 5
7
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getFieldInfo
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
1
 getMetadata
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 loadFromSubmission
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 __set_state
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2declare( strict_types=1 );
3/**
4 * @license GPL-2.0-or-later
5 *
6 * @file
7 */
8
9namespace MediaWiki\Extension\OATHAuth\Auth;
10
11use MediaWiki\Auth\AuthenticationRequest;
12use MediaWiki\Message\Message;
13
14/**
15 * Represents the module switching UI. Will only be present when there is an alternative module to
16 * switch to.
17 * @author Taavi Väänänen
18 */
19class TwoFactorModuleSelectAuthenticationRequest extends AuthenticationRequest {
20
21    /** The module being rendered in the current UI (as in IModule::getName()). */
22    public string $currentModule;
23
24    /**
25     * The new module selected by the user (as in IModule::getName()). Initially null, returning
26     * a TwoFactorModuleSelectAuthenticationRequest with this field set means the 2FA check will
27     * start again with the new module (other returned requests will be ignored).
28     */
29    public ?string $newModule = null;
30
31    /**
32     * The list of modules the user can switch to, in an internal name => display name format
33     * (as in IModule::getName() / IModule::getDisplayName()). Includes the current module.
34     * @var array<string,Message>
35     */
36    public array $allowedModules;
37
38    /**
39     * @param string $currentModule See {@link ::$currentModule}.
40     * @param array $allowedModules See {@link ::$allowedModules}.
41     */
42    public function __construct( string $currentModule, array $allowedModules ) {
43        $this->currentModule = $currentModule;
44        $this->allowedModules = $allowedModules;
45    }
46
47    /** @inheritDoc */
48    public function getFieldInfo() {
49        $availableModules = array_diff_key( $this->allowedModules, [ $this->currentModule => true ] );
50        $availableModules = [ '' => wfMessage( 'oathauth-auth-switch-module-keep' ) ] + $availableModules;
51
52        return [
53            'newModule' => [
54                'type' => 'select',
55                'options' => $availableModules,
56                'value' => '',
57                'optional' => true,
58                'label' => wfMessage( 'oathauth-auth-switch-module-label' ),
59                'help' => wfMessage( 'oathauth-auth-switch-module-help' ),
60            ],
61        ];
62    }
63
64    /** @inheritDoc */
65    public function getMetadata() {
66        return [
67            'currentModule' => $this->currentModule,
68            'allowedModules' => array_keys( $this->allowedModules ),
69            'moduleDescriptions' => array_map( static fn ( Message $msg ) => $msg->text(), $this->allowedModules ),
70        ];
71    }
72
73    /** @inheritDoc */
74    public function loadFromSubmission( array $data ) {
75        // Be nice to API users and don't require them to submit an empty string when not switching.
76        // The default implementation would result in this object getting discarded when the
77        // newModule field is not present at all, but we still need it to preserve currentModule
78        // (via the session) so we know which 2FA module to call continueAuthentication() one.
79        $data += [ 'newModule' => '' ];
80        $ret = parent::loadFromSubmission( $data );
81        $this->newModule = $this->newModule ?: null;
82        return $ret;
83    }
84
85    /** @inheritDoc */
86    public static function __set_state( $data ) {
87        $ret = new static( '', [] );
88        foreach ( $data as $k => $v ) {
89            $ret->$k = $v;
90        }
91        return $ret;
92    }
93
94}