~ubuntu-branches/ubuntu/saucy/mediawiki-extensions/saucy

« back to all changes in this revision

Viewing changes to include/SpecialOpenIDFinish.body.php

  • Committer: Bazaar Package Importer
  • Author(s): Romain Beauxis
  • Date: 2010-05-04 15:13:35 UTC
  • mfrom: (0.1.1 experimental)
  • Revision ID: james.westby@ubuntu.com-20100504151335-54qeucg3ec108q28
Tags: 2.2
* Added Replaces:/Conflicts: to allow a proper upgrade.
Closes: #580066
* Fixed package descriptions.
Closes: #579667
* Patched mediawiki-extensions-fckeditor to make it work with
  php 5.3. The fix may not be perfect but at least it work.
  Not closing the bug (#579822) for now..

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<?php
2
 
/**
3
 
 * SpecialOpenIDFinish.body.php -- Finish logging into an OpenID site
4
 
 * Copyright 2006,2007 Internet Brands (http://www.internetbrands.com/)
5
 
 * Copyright 2007,2008 Evan Prodromou <evan@prodromou.name>
6
 
 *
7
 
 *  This program is free software; you can redistribute it and/or modify
8
 
 *  it under the terms of the GNU General Public License as published by
9
 
 *  the Free Software Foundation; either version 2 of the License, or
10
 
 *  (at your option) any later version.
11
 
 *
12
 
 * This program is distributed in the hope that it will be useful,
13
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
 *  GNU General Public License for more details.
16
 
 *
17
 
 *  You should have received a copy of the GNU General Public License
18
 
 *  along with this program; if not, write to the Free Software
19
 
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 
 *
21
 
 * @author Evan Prodromou <evan@prodromou.name>
22
 
 * @addtogroup Extensions
23
 
 */
24
 
 
25
 
if (!defined('MEDIAWIKI'))
26
 
  exit(1);
27
 
 
28
 
require_once("Auth/OpenID/Consumer.php");
29
 
require_once("Auth/OpenID/SReg.php");
30
 
require_once("Auth/Yadis/XRI.php");
31
 
 
32
 
class SpecialOpenIDFinish extends SpecialOpenID {
33
 
 
34
 
        function SpecialOpenIDFinish() {
35
 
                SpecialPage::SpecialPage("OpenIDFinish", '', false);
36
 
        }
37
 
 
38
 
        function execute( $par) {
39
 
 
40
 
                global $wgUser, $wgOut, $wgRequest;
41
 
 
42
 
                wfLoadExtensionMessages( 'OpenID' );
43
 
 
44
 
                $this->setHeaders();
45
 
 
46
 
                # Shouldn't work if you're already logged in.
47
 
 
48
 
                if ( $wgUser->getID() != 0 ) {
49
 
                        $this->alreadyLoggedIn();
50
 
                        return;
51
 
                }
52
 
 
53
 
                $consumer = $this->getConsumer();
54
 
 
55
 
                switch ( $par ) {
56
 
                 case 'ChooseName':
57
 
                        list( $openid, $sreg) = $this->fetchValues();
58
 
                        if ( !isset( $openid ) ) {
59
 
                                wfDebug( "OpenID: aborting in ChooseName because identity_url is missing\n" );
60
 
                                $this->clearValues();
61
 
                                # No messing around, here
62
 
                                $wgOut->showErrorPage( 'openiderror', 'openiderrortext' );
63
 
                                return;
64
 
                        }
65
 
 
66
 
                        if ( $wgRequest->getCheck( 'wpCancel' ) ) {
67
 
                                $this->clearValues();
68
 
                                $wgOut->showErrorPage( 'openidcancel', 'openidcanceltext' );
69
 
                                return;
70
 
                        }
71
 
 
72
 
                        $choice = $wgRequest->getText( 'wpNameChoice' );
73
 
                        $nameValue = $wgRequest->getText( 'wpNameValue' );
74
 
 
75
 
                        if ($choice == 'existing') {
76
 
                                $user = $this->attachUser( $openid, $sreg,
77
 
                                        $wgRequest->getText( 'wpExistingName' ),
78
 
                                        $wgRequest->getText( 'wpExistingPassword' )
79
 
                                );
80
 
 
81
 
                                if ( !$user ) {
82
 
                                        $this->chooseNameForm( $openid, $sreg, 'wrongpassword' );
83
 
                                        return;
84
 
                                }
85
 
 
86
 
                                if ($wgRequest->getText( 'wpUpdateUserInfo' ))
87
 
                                {
88
 
                                        $this->updateUser( $user, $sreg );
89
 
                                }
90
 
                        } else {
91
 
                                $name = $this->getUserName( $openid, $sreg, $choice, $nameValue);
92
 
 
93
 
                                if ( !$name || !$this->userNameOK( $name ) ) {
94
 
                                        wfDebug( "OpenID: Name not OK: '$name'\n" );
95
 
                                        $this->chooseNameForm( $openid, $sreg );
96
 
                                        return;
97
 
                                }
98
 
                                
99
 
                                $user = $this->createUser( $openid, $sreg, $name );
100
 
                        }
101
 
 
102
 
                        if ( !isset( $user ) ) {
103
 
                                wfDebug( "OpenID: aborting in ChooseName because we could not create user object\n" );
104
 
                                $this->clearValues();
105
 
                                $wgOut->showErrorPage( 'openiderror', 'openiderrortext' );
106
 
                                return;
107
 
                        }
108
 
 
109
 
                        $wgUser = $user;
110
 
 
111
 
                        $this->clearValues();
112
 
 
113
 
                        $this->finishLogin( $response->identity_url );
114
 
                        break;
115
 
 
116
 
                 default: # No parameter, returning from a server
117
 
 
118
 
                        $response = $consumer->complete( $this->scriptUrl( 'OpenIDFinish' ) );
119
 
 
120
 
                        if ( !isset( $response ) ) {
121
 
                                wfDebug( "OpenID: aborting in auth because no response was recieved\n" );
122
 
                                $wgOut->showErrorPage( 'openiderror', 'openiderrortext' );
123
 
                                return;
124
 
                        }
125
 
 
126
 
                        switch ( $response->status ) {
127
 
                         case Auth_OpenID_CANCEL:
128
 
                                // This means the authentication was cancelled.
129
 
                                $wgOut->showErrorPage( 'openidcancel', 'openidcanceltext' );
130
 
                                break;
131
 
                         case Auth_OpenID_FAILURE:
132
 
                                wfDebug( "OpenID: error message '" . $response->message . "'\n" );
133
 
                                $wgOut->showErrorPage( 'openidfailure', 'openidfailuretext',
134
 
                                                                  array( ( $response->message ) ? $response->message : '' ) );
135
 
                                break;
136
 
                         case Auth_OpenID_SUCCESS:
137
 
                                // This means the authentication succeeded.
138
 
                                $openid = $response->getDisplayIdentifier();
139
 
                                $sreg_resp = Auth_OpenID_SRegResponse::fromSuccessResponse( $response );
140
 
                                $sreg = $sreg_resp->contents();
141
 
 
142
 
                                if (!isset($openid)) {
143
 
                                        wfDebug( "OpenID: aborting in auth success because display identifier is missing\n" );
144
 
                                        $wgOut->showErrorPage( 'openiderror', 'openiderrortext' );
145
 
                                        return;
146
 
                                }
147
 
 
148
 
                                $user = $this->getUser( $openid );
149
 
 
150
 
                                if ( isset( $user ) )
151
 
                                {
152
 
                                        if ($user->getOption('openid-update-userinfo-on-login'))
153
 
                                        {
154
 
                                                $this->updateUser( $user, $sreg); # update from server
155
 
                                        }
156
 
                                } else {
157
 
                                        # For easy names
158
 
                                        $name = $this->createName( $openid, $sreg );
159
 
                                        if ( $name ) {
160
 
                                                $user = $this->createUser( $openid, $sreg, $name );
161
 
                                        } else {
162
 
                                        # For hard names
163
 
                                                $this->saveValues( $openid, $sreg );
164
 
                                                $this->chooseNameForm( $openid, $sreg );
165
 
                                                return;
166
 
                                        }
167
 
                                }
168
 
 
169
 
                                if ( !isset( $user ) ) {
170
 
                                        wfDebug( "OpenID: aborting in auth success because we could not create user object\n" );
171
 
                                        $wgOut->showErrorPage( 'openiderror', 'openiderrortext' );
172
 
                                } else {
173
 
                                        $wgUser = $user;
174
 
                                        $this->finishLogin( $openid );
175
 
                                }
176
 
                        }
177
 
                }
178
 
        }
179
 
 
180
 
        function finishLogin( $openid ) {
181
 
                global $wgUser, $wgOut;
182
 
 
183
 
                $wgUser->SetupSession();
184
 
                $wgUser->SetCookies();
185
 
 
186
 
                # Run any hooks; ignore results
187
 
                $inject_html = '';
188
 
                wfRunHooks( 'UserLoginComplete', array( &$wgUser, &$inject_html ) );
189
 
 
190
 
                # Set a cookie for later check-immediate use
191
 
 
192
 
                $this->loginSetCookie($openid);
193
 
 
194
 
                $wgOut->setPageTitle( wfMsg( 'openidsuccess' ) );
195
 
                $wgOut->setRobotPolicy( 'noindex,nofollow' );
196
 
                $wgOut->setArticleRelated( false );
197
 
                $wgOut->addWikiText( wfMsg( 'openidsuccess', $wgUser->getName(), $openid ) );
198
 
                $wgOut->addHtml( $inject_html );
199
 
                $wgOut->returnToMain( false, $this->returnTo() );
200
 
        }
201
 
 
202
 
        function loginSetCookie( $openid ) {
203
 
                global $wgCookiePath, $wgCookieDomain, $wgCookieSecure, $wgCookiePrefix;
204
 
                global $wgOpenIDCookieExpiration;
205
 
 
206
 
                $exp = time() + $wgOpenIDCookieExpiration;
207
 
 
208
 
                setcookie( $wgCookiePrefix.'OpenID', $openid, $exp, $wgCookiePath, $wgCookieDomain, $wgCookieSecure );
209
 
        }
210
 
 
211
 
        function chooseNameForm( $openid, $sreg, $messagekey = NULL ) {
212
 
 
213
 
                global $wgOut, $wgUser, $wgOpenIDOnly;
214
 
                
215
 
                $sk = $wgUser->getSkin();
216
 
                if ($messagekey) {
217
 
                        $message = wfMsg( $messagekey );
218
 
                } else if ( array_key_exists( 'nickname', $sreg ) ) {
219
 
                        $message = wfMsg( 'openidnotavailable', $sreg['nickname'] );
220
 
                } else {
221
 
                        $message = wfMsg( 'openidnotprovided' );
222
 
                }
223
 
                $instructions = wfMsg( 'openidchooseinstructions' );
224
 
                $wgOut->addHTML( "<p>{$message}</p>" .
225
 
                                                 "<p>{$instructions}</p>" .
226
 
                                                 '<form action="' . $sk->makeSpecialUrl( 'OpenIDFinish/ChooseName' ) . '" method="POST">' );
227
 
                $def = false;
228
 
 
229
 
                if ( !$wgOpenIDOnly ) {
230
 
                        # Let them attach it to an existing user
231
 
                        
232
 
                        # Grab the UserName in the cookie if it exists
233
 
                        
234
 
                        global $wgCookiePrefix;
235
 
                        $name = '';
236
 
                        if ( isset( $_COOKIE["{$wgCookiePrefix}UserName"] ) ) {
237
 
                                $name = trim( $_COOKIE["{$wgCookiePrefix}UserName"] );
238
 
                        }
239
 
 
240
 
                        # show OpenID Attributes
241
 
                        $oidAttributesToAccept = array('fullname', 'nickname', 'email', 'language');
242
 
                        $oidAttributes = array();
243
 
 
244
 
                        foreach ($oidAttributesToAccept as $oidAttr)
245
 
                        {
246
 
                                if ($oidAttr == 'fullname' && !$wgAllowRealName)
247
 
                                {
248
 
                                        next;
249
 
                                }
250
 
 
251
 
                                if ( array_key_exists( $oidAttr, $sreg )) {
252
 
                                        $oidAttributes[] = '<div>'.wfMsg( "openid$oidAttr" ).': <i>'.$sreg[$oidAttr].'</i></div>';
253
 
                                }
254
 
                        }
255
 
 
256
 
                        $oidAttributesUpdate = '';
257
 
                        if (count($oidAttributes) > 0)
258
 
                        {
259
 
                                $oidAttributesUpdate = '<div style="margin-left: 25px">'.
260
 
                                        '<input type="checkbox" name="wpUpdateUserInfo" id="wpUpdateUserInfo">' .
261
 
                                        '<label for="wpUpdateUserInfo">' . wfMsg( "openidupdateuserinfo" ) .
262
 
                                        '<div style="margin-left: 25px">'.implode('', $oidAttributes).'</div>'.
263
 
                                        '</label></div>';
264
 
                        }
265
 
                        
266
 
                        $wgOut->addHTML("<div><input type='radio' name='wpNameChoice' id='wpNameChoiceExisting' value='existing' />" .
267
 
                                "<label for='wpNameChoiceExisting'>" . wfMsg( "openidchooseexisting" ) . "</label> " .
268
 
                                "<input type='text' name='wpExistingName' id='wpExistingName' size='16' value='{$name}'> " .
269
 
                                "<label for='wpExistingPassword'>" . wfMsg( "openidchoosepassword" ) . "</label> " .
270
 
                                "<input type='password' name='wpExistingPassword' size='8' /> " .
271
 
                                $oidAttributesUpdate . "</div>\n" );
272
 
                }
273
 
                
274
 
                # These options won't exist if we can't get them.
275
 
 
276
 
                if ( array_key_exists( 'fullname', $sreg ) && $this->userNameOK( $sreg['fullname'] ) ) {
277
 
                        $wgOut->addHTML( "<div><input type='radio' name='wpNameChoice' id='wpNameChoiceFull' value='full' " .
278
 
                                                        ( ( !$def ) ? "checked = 'checked'" : "" ) . " />" .
279
 
                                                        "<label for='wpNameChoiceFull'>" . wfMsg( "openidchoosefull", $sreg['fullname'] ) . "</label></div>\n" );
280
 
                        $def = true;
281
 
                }
282
 
 
283
 
                $idname = $this->toUserName( $openid );
284
 
 
285
 
                if ( $idname && $this->userNameOK( $idname ) ) {
286
 
                        $wgOut->addHTML( "<div><input type='radio' name='wpNameChoice' id='wpNameChoiceUrl' value='url' " .
287
 
                                                        ( ( !$def ) ? "checked = 'checked'" : "" ) . " />" .
288
 
                                                        "<label for='wpNameChoiceUrl'>" . wfMsg( "openidchooseurl", $idname ) . "</label></div>\n" );
289
 
                        $def = true;
290
 
                }
291
 
 
292
 
                # These are always available
293
 
 
294
 
                $wgOut->addHTML( "<div><input type='radio' name='wpNameChoice' id='wpNameChoiceAuto' value='auto' " .
295
 
                                                        ( ( !$def ) ? "checked = 'checked'" : "" ) . " />" .
296
 
                                                        "<label for='wpNameChoiceAuto'>" . wfMsg( "openidchooseauto", $this->automaticName( $sreg ) ) . "</label></div>\n");
297
 
 
298
 
                $def = true;
299
 
 
300
 
                $wgOut->addHTML("<div><input type='radio' name='wpNameChoice' id='wpNameChoiceManual' value='manual' " .
301
 
                                                " checked='off' />" .
302
 
                                                "<label for='wpNameChoiceManual'>" . wfMsg( "openidchoosemanual" ) . "</label> " .
303
 
                                                "<input type='text' name='wpNameValue' id='wpNameValue' size='16' /></div>\n");
304
 
 
305
 
                $ok = wfMsg( 'login' );
306
 
                $cancel = wfMsg( 'cancel' );
307
 
 
308
 
                $wgOut->addHTML( "<input type='submit' name='wpOK' value='{$ok}' /> <input type='submit' name='wpCancel' value='{$cancel}' />" );
309
 
                $wgOut->addHTML( "</form>" );
310
 
        }
311
 
 
312
 
        function canLogin( $openid_url ) {
313
 
                global $wgOpenIDConsumerDenyByDefault, $wgOpenIDConsumerAllow, $wgOpenIDConsumerDeny;
314
 
 
315
 
                if ( $this->isLocalUrl( $openid_url ) ) {
316
 
                        return false;
317
 
                }
318
 
 
319
 
                if ( $wgOpenIDConsumerDenyByDefault ) {
320
 
                        $canLogin = false;
321
 
                        foreach ( $wgOpenIDConsumerAllow as $allow ) {
322
 
                                if ( preg_match( $allow, $openid_url ) ) {
323
 
                                        wfDebug( "OpenID: $openid_url matched allow pattern $allow.\n" );
324
 
                                        $canLogin = true;
325
 
                                        foreach ( $wgOpenIDConsumerDeny as $deny ) {
326
 
                                                if ( preg_match( $deny, $openid_url ) ) {
327
 
                                                        wfDebug( "OpenID: $openid_url matched deny pattern $deny.\n" );
328
 
                                                        $canLogin = false;
329
 
                                                        break;
330
 
                                                }
331
 
                                        }
332
 
                                        break;
333
 
                                }
334
 
                        }
335
 
                } else {
336
 
                        $canLogin = true;
337
 
                        foreach ( $wgOpenIDConsumerDeny as $deny ) {
338
 
                                if ( preg_match( $deny, $openid_url ) ) {
339
 
                                        wfDebug( "OpenID: $openid_url matched deny pattern $deny.\n" );
340
 
                                        $canLogin = false;
341
 
                                        foreach ( $wgOpenIDConsumerAllow as $allow ) {
342
 
                                                if ( preg_match( $allow, $openid_url ) ) {
343
 
                                                        wfDebug( "OpenID: $openid_url matched allow pattern $allow.\n" );
344
 
                                                        $canLogin = true;
345
 
                                                        break;
346
 
                                                }
347
 
                                        }
348
 
                                        break;
349
 
                                }
350
 
                        }
351
 
                }
352
 
                return $canLogin;
353
 
        }
354
 
 
355
 
        function isLocalUrl( $url ) {
356
 
                global $wgServer, $wgArticlePath;
357
 
 
358
 
                $pattern = $wgServer . $wgArticlePath;
359
 
                $pattern = str_replace( '$1', '(.*)', $pattern );
360
 
                $pattern = str_replace( '?', '\?', $pattern );
361
 
 
362
 
                return preg_match( '|^' . $pattern . '$|', $url );
363
 
        }
364
 
 
365
 
        # Find the user with the given openid, if any
366
 
 
367
 
        function getUser( $openid ) {
368
 
                global $wgSharedDB, $wgDBprefix;
369
 
 
370
 
                if ( isset( $wgSharedDB ) ) {
371
 
                        $tableName = "`$wgSharedDB`.${wgDBprefix}user_openid";
372
 
                } else {
373
 
                        $tableName = 'user_openid';
374
 
                }
375
 
 
376
 
                $dbr = wfGetDB( DB_SLAVE );
377
 
                $id = $dbr->selectField(
378
 
                        $tableName,
379
 
                        'uoi_user',
380
 
                        array( 'uoi_openid' => $openid ),
381
 
                        __METHOD__
382
 
                );
383
 
                if ( $id ) {
384
 
                        return User::newFromID( $id );
385
 
                } else {
386
 
                        return NULL;
387
 
                }
388
 
        }
389
 
 
390
 
        function updateUser( $user, $sreg ) {
391
 
                global $wgAllowRealName;
392
 
 
393
 
                # FIXME: only update if there's been a change
394
 
                $user->setOption('nickname', array_key_exists( 'nickname', $sreg )
395
 
                        ? $sreg['nickname'] : '');
396
 
 
397
 
                $user->setEmail( array_key_exists( 'email', $sreg ) ? $sreg['email'] : '' );
398
 
 
399
 
                $user->setRealName( (array_key_exists( 'fullname', $sreg ) && $wgAllowRealName)
400
 
                        ? $sreg['fullname'] : '');
401
 
 
402
 
                if ( array_key_exists( 'language', $sreg ) ) {
403
 
                        # FIXME: check and make sure the language exists
404
 
                        $user->setOption( 'language', $sreg['language'] );
405
 
                } else {
406
 
                        $user->setOption( 'language', NULL );
407
 
                }
408
 
 
409
 
                if (array_key_exists( 'timezone', $sreg ) ) {
410
 
                        # FIXME: do something with it.
411
 
                        # $offset = OpenIDTimezoneToTzoffset($sreg['timezone']);
412
 
                        # $user->setOption('timecorrection', $offset);
413
 
                } else {
414
 
                        # $user->setOption('timecorrection', NULL);
415
 
                }
416
 
 
417
 
                $user->saveSettings();
418
 
        }
419
 
 
420
 
        function createUser($openid, $sreg, $name) {
421
 
 
422
 
                global $wgAuth, $wgAllowRealName;
423
 
 
424
 
                $user = User::newFromName($name);
425
 
 
426
 
                if (!$user) {
427
 
                        wfDebug("OpenID: Error adding new user.\n");
428
 
                        return NULL;
429
 
                }
430
 
                
431
 
                $user->addToDatabase();
432
 
 
433
 
                if (!$user->getId()) {
434
 
                        wfDebug("OpenID: Error adding new user.\n");
435
 
                } else {
436
 
 
437
 
                        $this->insertUserUrl($user, $openid);
438
 
 
439
 
                        if (array_key_exists('nickname', $sreg)) {
440
 
                                $user->setOption('nickname', $sreg['nickname']);
441
 
                        }
442
 
                        if (array_key_exists('email', $sreg)) {
443
 
                                $user->setEmail( $sreg['email'] );
444
 
                        }
445
 
                        if ($wgAllowRealName && array_key_exists('fullname', $sreg)) {
446
 
                                $user->setRealName($sreg['fullname']);
447
 
                        }
448
 
                        if (array_key_exists('language', $sreg)) {
449
 
                                # FIXME: check and make sure the language exists
450
 
                                $user->setOption('language', $sreg['language']);
451
 
                        }
452
 
                        if (array_key_exists('timezone', $sreg)) {
453
 
                                # FIXME: do something with it.
454
 
                                # $offset = OpenIDTimezoneToTzoffset($sreg['timezone']);
455
 
                                # $user->setOption('timecorrection', $offset);
456
 
                        }
457
 
                        $user->saveSettings();
458
 
                        return $user;
459
 
                }
460
 
        }
461
 
 
462
 
        function createName($openid, $sreg) {
463
 
 
464
 
                if (array_key_exists('nickname', $sreg) && # try nickname
465
 
                        $this->userNameOK($sreg['nickname']))
466
 
                {
467
 
                        return $sreg['nickname'];
468
 
                }
469
 
        }
470
 
 
471
 
        function toUserName($openid) {
472
 
        if (Auth_Yadis_identifierScheme($openid) == 'XRI') {
473
 
                        return $this->toUserNameXri($openid);
474
 
                } else {
475
 
                        return $this->toUserNameUrl($openid);
476
 
                }
477
 
        }
478
 
 
479
 
        # We try to use an OpenID URL as a legal MediaWiki user name in this order
480
 
        # 1. Plain hostname, like http://evanp.myopenid.com/
481
 
        # 2. One element in path, like http://profile.typekey.com/EvanProdromou/
482
 
        #    or http://getopenid.com/evanprodromou
483
 
 
484
 
    function toUserNameUrl($openid) {
485
 
                static $bad = array('query', 'user', 'password', 'port', 'fragment');
486
 
 
487
 
            $parts = parse_url($openid);
488
 
 
489
 
                # If any of these parts exist, this won't work
490
 
 
491
 
                foreach ($bad as $badpart) {
492
 
                        if (array_key_exists($badpart, $parts)) {
493
 
                                return NULL;
494
 
                        }
495
 
                }
496
 
 
497
 
                # We just have host and/or path
498
 
 
499
 
                # If it's just a host...
500
 
                if (array_key_exists('host', $parts) &&
501
 
                        (!array_key_exists('path', $parts) || strcmp($parts['path'], '/') == 0))
502
 
                {
503
 
                        $hostparts = explode('.', $parts['host']);
504
 
 
505
 
                        # Try to catch common idiom of nickname.service.tld
506
 
 
507
 
                        if ((count($hostparts) > 2) &&
508
 
                                (strlen($hostparts[count($hostparts) - 2]) > 3) && # try to skip .co.uk, .com.au
509
 
                                (strcmp($hostparts[0], 'www') != 0))
510
 
                        {
511
 
                                return $hostparts[0];
512
 
                        } else {
513
 
                                # Do the whole hostname
514
 
                                return $parts['host'];
515
 
                        }
516
 
                } else {
517
 
                        if (array_key_exists('path', $parts)) {
518
 
                                # Strip starting, ending slashes
519
 
                                $path = preg_replace('@/$@', '', $parts['path']);
520
 
                                $path = preg_replace('@^/@', '', $path);
521
 
                                if (strpos($path, '/') === false) {
522
 
                                        return $path;
523
 
                                }
524
 
                        }
525
 
                }
526
 
 
527
 
                return NULL;
528
 
        }
529
 
 
530
 
        function toUserNameXri($xri) {
531
 
                $base = $this->xriBase($xri);
532
 
 
533
 
                if (!$base) {
534
 
                        return NULL;
535
 
                } else {
536
 
                        # =evan.prodromou
537
 
                        # or @gratis*evan.prodromou
538
 
                        $parts = explode('*', substr($base, 1));
539
 
                        return array_pop($parts);
540
 
                }
541
 
        }
542
 
 
543
 
        # Is this name OK to use as a user name?
544
 
 
545
 
        function userNameOK($name) {
546
 
                global $wgReservedUsernames;
547
 
                return (0 == User::idFromName($name) &&
548
 
                                !in_array( $name, $wgReservedUsernames ));
549
 
        }
550
 
 
551
 
        # Get an auto-incremented name
552
 
 
553
 
        function firstAvailable($prefix) {
554
 
                for ($i = 2; ; $i++) { # FIXME: this is the DUMB WAY to do this
555
 
                        $name = "$prefix$i";
556
 
                        if ($this->userNameOK($name)) {
557
 
                                return $name;
558
 
                        }
559
 
                }
560
 
        }
561
 
 
562
 
        function alreadyLoggedIn() {
563
 
 
564
 
                global $wgUser, $wgOut;
565
 
 
566
 
                $wgOut->setPageTitle( wfMsg( 'openiderror' ) );
567
 
                $wgOut->setRobotPolicy( 'noindex,nofollow' );
568
 
                $wgOut->setArticleRelated( false );
569
 
                $wgOut->addWikiText( wfMsg( 'openidalreadyloggedin', $wgUser->getName() ) );
570
 
                $wgOut->returnToMain( false, $this->returnTo() );
571
 
        }
572
 
 
573
 
        static function getUserUrl( $user ) {
574
 
                $openid_url = null;
575
 
 
576
 
                if ( isset( $user ) && $user->getId() != 0 ) {
577
 
                        global $wgSharedDB, $wgDBprefix;
578
 
                        if ( isset( $wgSharedDB ) ) {
579
 
                                $tableName = "`${wgSharedDB}`.${wgDBprefix}user_openid";
580
 
                        } else {
581
 
                                $tableName = 'user_openid';
582
 
                        }
583
 
 
584
 
                        $dbr = wfGetDB( DB_SLAVE );
585
 
                        $res = $dbr->select(
586
 
                                array( $tableName ),
587
 
                                array( 'uoi_openid' ),
588
 
                                array( 'uoi_user' => $user->getId() ),
589
 
                                __METHOD__
590
 
                        );
591
 
 
592
 
                        # This should return 0 or 1 result, since user is unique
593
 
                        # in the table.
594
 
 
595
 
                        while ( $row = $res->fetchObject() ) {
596
 
                                $openid_url = $row->uoi_openid;
597
 
                        }
598
 
                        $res->free();
599
 
                }
600
 
                return $openid_url;
601
 
        }
602
 
 
603
 
        function saveValues($openid, $sreg) {
604
 
                global $wgSessionStarted, $wgUser;
605
 
 
606
 
                if (!$wgSessionStarted) {
607
 
                        $wgUser->SetupSession();
608
 
                }
609
 
 
610
 
                $_SESSION['openid_consumer_identity'] = $openid;
611
 
                $_SESSION['openid_consumer_sreg'] = $sreg;
612
 
 
613
 
                return true;
614
 
        }
615
 
 
616
 
        function clearValues() {
617
 
                unset( $_SESSION['openid_consumer_identity'] );
618
 
                unset( $_SESSION['openid_consumer_sreg'] );
619
 
                return true;
620
 
        }
621
 
 
622
 
        function fetchValues() {
623
 
                return array( $_SESSION['openid_consumer_identity'], $_SESSION['openid_consumer_sreg'] );
624
 
        }
625
 
 
626
 
        function returnTo() {
627
 
                return $_SESSION['openid_consumer_returnto'];
628
 
        }
629
 
 
630
 
        function setReturnTo($returnto) {
631
 
                $_SESSION['openid_consumer_returnto'] = $returnto;
632
 
        }
633
 
 
634
 
        function getUserName($openid, $sreg, $choice, $nameValue) {
635
 
                switch ( $choice ) {
636
 
                 case 'full':
637
 
                        return ( ( array_key_exists( 'fullname', $sreg ) ) ? $sreg['fullname'] : null );
638
 
                        break;
639
 
                 case 'url':
640
 
                        return $this->toUserName( $openid );
641
 
                        break;
642
 
                 case 'auto':
643
 
                        return $this->automaticName( $sreg );
644
 
                        break;
645
 
                 case 'manual':
646
 
                        return $nameValue;
647
 
                 default:
648
 
                        return null;
649
 
                }
650
 
        }
651
 
 
652
 
        function automaticName( $sreg ) {
653
 
                if ( array_key_exists( 'nickname', $sreg ) && # try auto-generated from nickname
654
 
                        strlen( $sreg['nickname']) > 0 ) {
655
 
                        return $this->firstAvailable( $sreg['nickname'] );
656
 
                } else { # try auto-generated
657
 
                        return $this->firstAvailable( wfMsg( 'openidusernameprefix' ) );
658
 
                }
659
 
        }
660
 
        
661
 
        function attachUser( $openid, $sreg, $name, $password ) {
662
 
 
663
 
                $user = User::newFromName( $name );
664
 
 
665
 
                if ( !$user ) {
666
 
                        return NULL;
667
 
                }
668
 
                
669
 
                if ( !$user->checkPassword( $password ) ) {
670
 
                        return NULL;
671
 
                }
672
 
                
673
 
                $this->setUserUrl( $user, $openid );
674
 
                
675
 
                return $user;
676
 
        }
677
 
}