Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
24 / 24
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
1 / 1
CentralIdLookupFactory
100.00% covered (success)
100.00%
24 / 24
100.00% covered (success)
100.00%
5 / 5
8
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 getProviderIds
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDefaultProviderId
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLookup
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
3
 getNonLocalLookup
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2/**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
17 *
18 * @file
19 */
20
21namespace MediaWiki\User\CentralId;
22
23use InvalidArgumentException;
24use MediaWiki\Config\ServiceOptions;
25use MediaWiki\MainConfigNames;
26use MediaWiki\User\UserFactory;
27use MediaWiki\User\UserIdentityLookup;
28use Wikimedia\ObjectFactory\ObjectFactory;
29
30/**
31 * @since 1.37
32 * @package MediaWiki\User\CentralId
33 */
34class CentralIdLookupFactory {
35
36    /**
37     * @internal
38     */
39    public const CONSTRUCTOR_OPTIONS = [
40        MainConfigNames::CentralIdLookupProviders,
41        MainConfigNames::CentralIdLookupProvider,
42    ];
43
44    /** @var array ObjectFactory specs indexed by provider name */
45    private $providers;
46
47    /** @var string */
48    private $defaultProvider;
49
50    private ObjectFactory $objectFactory;
51    private UserIdentityLookup $userIdentityLookup;
52    private UserFactory $userFactory;
53
54    /** @var CentralIdLookup[] */
55    private $instanceCache = [];
56
57    public function __construct(
58        ServiceOptions $options,
59        ObjectFactory $objectFactory,
60        UserIdentityLookup $userIdentityLookup,
61        UserFactory $userFactory
62    ) {
63        $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
64        $this->providers = $options->get( MainConfigNames::CentralIdLookupProviders );
65        $this->defaultProvider = $options->get( MainConfigNames::CentralIdLookupProvider );
66        $this->objectFactory = $objectFactory;
67        $this->userIdentityLookup = $userIdentityLookup;
68        $this->userFactory = $userFactory;
69    }
70
71    /**
72     * Get the IDs of the registered central ID lookup providers.
73     *
74     * @return string[]
75     */
76    public function getProviderIds(): array {
77        return array_keys( $this->providers );
78    }
79
80    /**
81     * Get the ID of the default central ID provider.
82     *
83     * @return string
84     */
85    public function getDefaultProviderId(): string {
86        return $this->defaultProvider;
87    }
88
89    /**
90     * Get an instance of a CentralIdLookup.
91     *
92     * @param string|null $providerId Provider ID from $wgCentralIdLookupProviders or null
93     *   to use the provider configured in $wgCentralIdLookupProvider
94     * @return CentralIdLookup
95     * @throws InvalidArgumentException if $providerId is not properly configured
96     */
97    public function getLookup( ?string $providerId = null ): CentralIdLookup {
98        $providerId ??= $this->defaultProvider;
99
100        if ( !array_key_exists( $providerId, $this->instanceCache ) ) {
101            $providerSpec = $this->providers[$providerId] ?? null;
102            if ( !$providerSpec ) {
103                throw new InvalidArgumentException( "Invalid central ID provider $providerId" );
104            }
105            $provider = $this->objectFactory->createObject(
106                $providerSpec,
107                [ 'assertClass' => CentralIdLookup::class ]
108            );
109            $provider->init( $providerId, $this->userIdentityLookup, $this->userFactory );
110            $this->instanceCache[$providerId] = $provider;
111        }
112        return $this->instanceCache[$providerId];
113    }
114
115    /**
116     * Returns a CentralIdLookup that is guaranteed to be non-local.
117     * If no such guarantee can be made, returns null.
118     *
119     * If this function returns a non-null CentralIdLookup, that lookup is expected to provide IDs
120     * that are shared with some set of other wikis. However, you should still be cautious
121     * when using those IDs, as they will not necessarily work with *all* other wikis, and it can be
122     * hard to tell if another wiki is in the same set as this one or not.
123     *
124     * @param string|null $providerID Provider ID from $wgCentralIdLookupProviders or null
125     *   to use the provider configured in $wgCentralIdLookupProvider
126     * @return ?CentralIdLookup
127     * @throws InvalidArgumentException if $providerId is not properly configured
128     */
129    public function getNonLocalLookup( ?string $providerID = null ): ?CentralIdLookup {
130        $centralIdLookup = $this->getLookup( $providerID );
131        if ( $centralIdLookup instanceof LocalIdLookup ) {
132            /*
133             * A LocalIdLookup (which is the default) may actually be non-local,
134             * if shared user tables are used.
135             * However, we cannot know that here, so play it safe and refuse to return it.
136             * See also T163277 and T170996.
137             */
138            return null;
139        }
140        return $centralIdLookup;
141    }
142}