-
Notifications
You must be signed in to change notification settings - Fork 0
/
OpauthLogin.hooks.php
executable file
·206 lines (154 loc) · 6.04 KB
/
OpauthLogin.hooks.php
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
197
198
199
200
201
202
203
204
205
206
<?php
/**
* Hooks class declaration for mediawiki extension OpauthLogin
*
* @file OpauthLogin.hooks.php
* @ingroup OpauthLogin
*/
class OpauthLoginHooks {
public static function onOpauthUserAuthorized( $provider, $uid, $info, $raw )
{
global $wgOpauthLoginRequestUsername;
if( OpauthLogin::isUidLinked( $uid, $provider ) ) {
// Login existing user into system
$user = OpauthLogin::getUidUser( $uid, $provider );
wfRunHooks('OpauthLoginUserAuthorized', array( $user, $provider, $uid, $info ) );
self::loginUser( $user );
}else{
// Based on $wgOpauthLoginRequestUsername option we should either ask user to provide username
// or just proceed with user creation process
if( $wgOpauthLoginRequestUsername ) {
self::requestUsername( $provider, $uid, $info, $raw );
}else{
self::authenticateCreateUser( $provider, $uid, $info, $raw );
}
}
return true;
}
public static function authenticateCreateUser( $provider, $uid, $info, $raw ) {
// Called when user was successfully authenticated from Opauth
// This function should compare UID with internal storage and decide to create new account for this user
// or load existing user from database
// Create new user from external data, $info refers to https://github.com/opauth/opauth/wiki/Auth-response
// Lets try to prepare username for wiki
// try to convert given input into canonical name without any validation
$canonicalName = User::getCanonicalName( $info['name'], 'valid' );
// Lets try to create with original username first and
// iterate until we will find available name
if( $canonicalName && User::isCreatableName( $canonicalName ) ) {
// First check if this name can be used at all
// Then check if there are users with same name exists
$testUser = User::newFromName( $canonicalName );
$suffix = 0;
while( $testUser->getId() !== 0 ) {
$suffix++;
// We're free to add suffix since base part of the name was already checked for validity
$testUser = User::newFromName( $canonicalName.' '.$suffix );
}
// Use found available name
$user = $testUser;
}else{
/**
* We set UID based string as user name in mediawiki to avoid
* user nicknames override and collisions problems. We store external user name into
* "real name" field of user object. This should be supported in skin.
*/
$user = User::newFromName( md5( $provider.$uid ) . '_' . $uid, false );
}
$user->setRealName( $info['name'] );
if( array_key_exists('email', $info) ) {
if( !OpauthLogin::isEmailCollate( $info['email'] ) ) {
$user->setEmail( $info['email'] );
}
}
$user->setPassword( md5( $info['name'] . time() ) );
$user->setToken();
$user->confirmEmail(); // Mark email address as confirmed by default
$user->addToDatabase(); // Commit changes to database
OpauthLogin::addUidLink( $uid, $provider, $user->getId() );
// Update site stats
$ssUpdate = new SiteStatsUpdate(0, 0, 0, 0, 1);
$ssUpdate->doUpdate();
// Run AddNewAccount hook for proper handling
wfRunHooks( 'AddNewAccount', array( $user, false, 'opauth' ) );
wfRunHooks('OpauthLoginUserCreated', array( $user, $provider, $info, $uid ) );
self::loginUser( $user, true );
}
/**
* Logins the user and runs necessary hooks
*
* @param User $user
* @param bool $wasCreated
*/
public static function loginUser( $user, $wasCreated = false ) {
global $wgOut, $wgUser;
// Replace current user with new one
$wgUser = $user;
$wgUser->setCookies( null, null, true );
$redirectTarget = Title::newMainPage()->getFullURL();
if( array_key_exists('opauth_returnto', $_SESSION) && isset($_SESSION['opauth_returnto']) ) {
$returnToTitle = Title::newFromText( $_SESSION['opauth_returnto'] );
unset($_SESSION['opauth_returnto']);
$redirectTarget = $returnToTitle->getFullURL();
}
// Allow extensions to modify final redirect
// $redirectTarget - URL to redirect user
// $user - authenticated User object
// $wasCreated - flag indicates if user was created or just authenticated during the session
wfRunHooks('OpauthLoginFinalRedirect', array( &$redirectTarget, $user, $wasCreated ) );
$wgOut->redirect( $redirectTarget );
}
/**
* Initiates additional information request
* called after successful authorization via provider
*
* @param string $provider
* @param int $uid
* @param array $info
* @param array $raw
*/
public static function requestUsername( $provider, $uid, $info, $raw ) {
global $wgOut;
// Pack necessary information into session storage
if( session_id() == '' ) {
wfSetupSession();
}
$_SESSION['opauth_login_provider'] = $provider;
$_SESSION['opauth_login_uid'] = $uid;
$_SESSION['opauth_login_info'] = $info;
// Redirect user to the special page
$wgOut->redirect( SpecialPage::getTitleFor('OpauthLoginInfo')->getFullURL() );
}
public static function onUserLoadFromSession( $user, &$result ) {
// Called when user was loaded (or not) from session
return true;
}
/**
* @param DatabaseUpdater $updater
*/
public static function onLoadExtensionSchemaUpdates( $updater ) {
global $wgOpauthLoginDir;
$updater->addExtensionTable(
'opauth_login',
$wgOpauthLoginDir .'/schema/opauth_login.sql'
);
}
/**
* @param UsercreateTemplate $template
*/
public static function onUserCreateForm( &$template ) {
global $wgOpauthLoginEnableButtons;
if( $wgOpauthLoginEnableButtons ) {
$template->set( 'header', OpauthLogin::getButtonsMarkup() );
}
}
/**
* @param UserloginTemplate $template
*/
public static function onUserLoginForm( &$template ) {
global $wgOpauthLoginEnableButtons;
if( $wgOpauthLoginEnableButtons ) {
$template->set( 'header', OpauthLogin::getButtonsMarkup() );
}
}
}