summaryrefslogtreecommitdiff
blob: 3eee770ac4f1d97f5cb188b890c504c22bf45992 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
<?php

class PluggableAuthHooks {

	/**
	 * Implements extension registration callback.
	 * See https://www.mediawiki.org/wiki/Manual:Extension_registration#Customizing_registration
	 * Removes password providers if local login is not enabled.
	 *
	 * @since 2.0
	 *
	 */
	public static function onRegistration() {
		if ( $GLOBALS['wgPluggableAuth_EnableLocalLogin'] ) {
			return;
		}
		$passwordProviders = [
			'MediaWiki\Auth\LocalPasswordPrimaryAuthenticationProvider',
			'MediaWiki\Auth\TemporaryPasswordPrimaryAuthenticationProvider'
		];
		$providers = $GLOBALS['wgAuthManagerAutoConfig'];
		if ( isset( $providers['primaryauth'] ) ) {
			$primaries = $providers['primaryauth'];
			foreach ( $primaries as $key => $provider ) {
				if ( in_array( $provider['class'], $passwordProviders ) ) {
					unset( $GLOBALS['wgAuthManagerAutoConfig']['primaryauth'][$key] );
				}
			}
		}
	}

	/**
	 * Implements TitleReadWhitelist hook.
	 * See https://www.mediawiki.org/wiki/Manual:Hooks/TitleReadWhitelist
	 * Adds PluggableAuth login special pages to whitelist.
	 *
	 * @since 2.0
	 * @param Title $title being checked
	 * @param User $user Current user
	 * @param bool &$whitelisted whether this title is whitelisted
	 */
	public static function onTitleReadWhitelist(
		Title $title, User $user, &$whitelisted
	) {
		$loginSpecialPages = ExtensionRegistry::getInstance()->getAttribute(
			'PluggableAuthLoginSpecialPages' );
		foreach ( $loginSpecialPages as $page ) {
			if ( $title->isSpecial( $page ) ) {
				$whitelisted = true;
				return;
			}
		}
	}

	/**
	 * Implements AuthChangeFormFields hook.
	 * See https://www.mediawiki.org/wiki/Manual:Hooks/AuthChangeFormFields
	 * Moves login button to bottom of form.
	 *
	 * @since 2.0
	 * @param array $requests AuthenticationRequests the fields are created from
	 * @param array $fieldInfo union of AuthenticationRequest::getFieldInfo()
	 * @param HTMLForm &$formDescriptor The special key weight can be set to
	 *        change the order of the fields.
	 * @param int $action one of the AuthManager::ACTION_* constants.
	 */
	public static function onAuthChangeFormFields(
		array $requests, array $fieldInfo, array &$formDescriptor, $action
	) {
		if ( isset( $formDescriptor['pluggableauthlogin'] ) ) {
			$formDescriptor['pluggableauthlogin']['weight'] = 101;
		}
	}

	/**
	 * Implements UserLogoutComplete hook.
	 * See https://www.mediawiki.org/wiki/Manual:Hooks/UserLogoutComplete
	 * Calls deauthenticate hook in authentication plugin.
	 *
	 * @since 2.0
	 * @param User $user User after logout (won't have name, ID, etc.)
	 * @param string $inject_html Any HTML to inject after the logout message.
	 * @param string $old_name The text of the username that just logged out.
	 */
	public static function deauthenticate(
		User $user, $inject_html, $old_name
	) {
		$old_user = User::newFromName( $old_name );
		if ( $old_user === false ) {
			return;
		}
		wfDebugLog( 'PluggableAuth', 'Deauthenticating ' . $old_name );
		$pluggableauth = PluggableAuth::singleton();
		if ( $pluggableauth ) {
			$pluggableauth->deauthenticate( $old_user );
		}
		wfDebugLog( 'PluggableAuth', 'Deauthenticated ' . $old_name );
	}

	/**
	 * Grab the page request early
	 * See https://www.mediawiki.org/wiki/Manual:Hooks/BeforeInitialize
	 * Redirects ASAP to login
	 * @param Title &$title being used for request
	 * @param null $article unused
	 * @param OutputPage $out object
	 * @param User $user current user
	 * @param WebRequest $request why we're here
	 * @param MediaWiki $mw object
	 *
	 * Note that $title has to be passed by ref so we can replace it.
	 */
	public static function doBeforeInitialize(
		Title &$title, $article, OutputPage $out, User $user,
		WebRequest $request, MediaWiki $mw
	) {
		if ( !$GLOBALS['wgPluggableAuth_EnableAutoLogin'] ) {
			return;
		}
		if ( !$out->getUser()->isAnon() ) {
			return;
		}

		if ( class_exists( 'MediaWiki\Permissions\PermissionManager' ) ) {
			// MW 1.33+
			$pm = \MediaWiki\MediaWikiServices::getInstance()->getPermissionManager();
			if ( !$pm->isEveryoneAllowed( 'read' ) &&
				$pm->userCan( 'read', $user, $title )
			) {
				return;
			}
		} else {
			if ( !User::isEveryoneAllowed( 'read' ) && $title->userCan( 'read' ) ) {
				return;
			}
		}

		$loginSpecialPages = ExtensionRegistry::getInstance()->getAttribute(
			'PluggableAuthLoginSpecialPages'
		);
		foreach ( $loginSpecialPages as $page ) {
			if ( $title->isSpecial( $page ) ) {
				return;
			}
		}

		$oldTitle = $title;
		$title = SpecialPage::getTitleFor( 'Userlogin' );
		$url = $title->getFullURL( [
			'returnto' => $oldTitle,
			'returntoquery' => $request->getRawQueryString()
		] );
		if ( $url ) {
			header( 'Location: ' . $url );
		} else {
			throw new MWException( "Could not determine URL for Special:Userlogin" );
		}
		exit;
	}

	/**
	 * Implements PersonalUrls hook.
	 * See https://www.mediawiki.org/wiki/Manual:Hooks/PersonalUrls
	 * Removes logout link from skin if auto login is enabled.
	 *
	 * @since 1.0
	 *
	 * @param array &$personal_urls urls sto modify
	 * @param Title|null $title current title
	 * @param SkinTemplate|null $skin template for vars
	 */
	public static function modifyLoginURLs(
		array &$personal_urls, Title $title = null, SkinTemplate $skin = null
	) {
		if ( $GLOBALS['wgPluggableAuth_EnableAutoLogin'] ) {
			unset( $personal_urls['logout'] );
		}
	}

	/**
	 * Implements LocalUserCreated hook.
	 * See https://www.mediawiki.org/wiki/Manual:Hooks/LocalUserCreated
	 * Populate groups after the local user is created
	 * Called immediately after a local user has been created and saved to the database.
	 *
	 * @since 5.5
	 *
	 * @param User $user current user
	 * @param bool $autocreated whether the user was autocreated
	 */
	public static function onLocalUserCreated( User $user, $autocreated ) {
		if ( $autocreated ) {
			Hooks::run( 'PluggableAuthPopulateGroups', [ $user ] );
		}
	}
}