| Index: trunk/extensions/CentralAuth/CentralAuthUser.php | ||
| — | — | @@ -60,12 +60,12 @@ |
| 61 | 61 | private function loadState() { |
| 62 | 62 | if( !isset( $this->mGlobalId ) ) { |
| 63 | 63 | global $wgDBname; |
| 64 | ||
| 64 | + $dbr = self::getCentralSlaveDB(); | |
| 65 | 65 | $globaluser = self::tableName( 'globaluser' ); |
| 66 | 66 | $localuser = self::tableName( 'localuser' ); |
| 67 | 67 | |
| 68 | 68 | $sql = |
| 69 | ||
| 69 | + "SELECT gu_id, lu_dbname, gu_salt, gu_password,gu_authtoken,gu_locked,gu_hidden,gu_registration | |
| 70 | 70 | FROM $globaluser |
| 71 | 71 | LEFT OUTER JOIN $localuser |
| 72 | 72 | ON gu_name=lu_name |
| — | — | @@ -78,6 +78,12 @@ |
| 79 | 79 | if( $row ) { |
| 80 | 80 | $this->mGlobalId = intval( $row->gu_id ); |
| 81 | 81 | $this->mIsAttached = ($row->lu_dbname !== null); |
| 82 | + $this->mSalt = $row->gu_salt; | |
| 83 | + $this->mPassword = $row->gu_password; | |
| 84 | + $this->mAuthToken = $row->gu_authtoken; | |
| 85 | + $this->mLocked = $row->gu_locked; | |
| 86 | + $this->mHidden = $row->gu_hidden; | |
| 87 | + $this->mRegistration = $row->gu_registration; | |
| 82 | 88 | } else { |
| 83 | 89 | $this->mGlobalId = 0; |
| 84 | 90 | $this->mIsAttached = false; |
| — | — | @@ -100,6 +106,27 @@ |
| 101 | 107 | $this->loadState(); |
| 102 | 108 | return $this->mIsAttached; |
| 103 | 109 | } |
| 110 | + | |
| 111 | + /** | |
| 112 | + * Return the password hash and salt. | |
| 113 | + * @return array( salt, hash ) | |
| 114 | + */ | |
| 115 | + public function getPasswordHash() { | |
| 116 | + $this->loadState(); | |
| 117 | + return array( $this->mSalt, $this->mPassword ); | |
| 118 | + } | |
| 119 | + | |
| 120 | + /** | |
| 121 | + * Return the global-login token for this account. | |
| 122 | + */ | |
| 123 | + public function getAuthToken() { | |
| 124 | + $this->loadState(); | |
| 125 | + | |
| 126 | + if (!$this->mAuthToken) { | |
| 127 | + $this->resetAuthToken(); | |
| 128 | + } | |
| 129 | + return $this->mAuthToken; | |
| 130 | + } | |
| 104 | 131 | |
| 105 | 132 | /** |
| 106 | 133 | * Check whether a global user account for this name exists yet. |
| — | — | @@ -116,41 +143,27 @@ |
| 117 | 144 | } |
| 118 | 145 | |
| 119 | 146 | /** |
| 120 | ||
| 121 | ||
| 122 | ||
| 123 | ||
| 124 | ||
| 125 | ||
| 126 | ||
| 127 | ||
| 128 | ||
| 129 | ||
| 130 | ||
| 131 | ||
| 132 | ||
| 133 | ||
| 134 | 147 | * @return bool |
| 135 | 148 | */ |
| 136 | 149 | public function isLocked() { |
| 137 | ||
| 138 | ||
| 150 | + $this->loadState(); | |
| 151 | + return (bool)$this->mLocked; | |
| 139 | 152 | } |
| 140 | 153 | |
| 141 | 154 | /** |
| 142 | ||
| 155 | + * @return bool | |
| 143 | 156 | */ |
| 144 | 157 | public function isHidden() { |
| 145 | ||
| 146 | ||
| 158 | + $this->loadState(); | |
| 159 | + return (bool)$this->mHidden; | |
| 147 | 160 | } |
| 148 | 161 | |
| 149 | 162 | /** |
| 150 | 163 | * @return string timestamp |
| 151 | 164 | */ |
| 152 | 165 | public function getRegistration() { |
| 153 | ||
| 154 | ||
| 166 | + $this->loadState(); | |
| 167 | + return wfTimestamp( TS_MW, $this->mRegistration ); | |
| 155 | 168 | } |
| 156 | 169 | |
| 157 | 170 | private function lazyMigrate() { |
| — | — | @@ -677,38 +690,46 @@ |
| 678 | 691 | $this->resetState(); |
| 679 | 692 | } |
| 680 | 693 | } |
| 681 | ||
| 694 | + | |
| 682 | 695 | /** |
| 683 | ||
| 684 | ||
| 685 | ||
| 686 | ||
| 696 | + * If the user provides the correct password, would we let them log in? | |
| 697 | + * This encompasses checks on missing and locked accounts, at present. | |
| 698 | + * @return string status, one of: "no user", "locked" | |
| 687 | 699 | */ |
| 688 | ||
| 700 | + public function canAuthenticate() { | |
| 689 | 701 | $this->lazyMigrate(); |
| 690 | 702 | |
| 691 | ||
| 692 | ||
| 693 | ||
| 694 | ||
| 695 | ||
| 696 | ||
| 697 | ||
| 703 | + if( !$this->getId() ) { | |
| 698 | 704 | wfDebugLog( 'CentralAuth', |
| 699 | 705 | "authentication for '$this->mName' failed due to missing account" ); |
| 700 | 706 | return "no user"; |
| 701 | 707 | } |
| 702 | 708 | |
| 703 | ||
| 704 | ||
| 705 | ||
| 709 | + list($salt,$crypt) = $this->getPasswordHash(); | |
| 710 | + $locked = $this->isLocked(); | |
| 706 | 711 | |
| 707 | 712 | if( $locked ) { |
| 708 | 713 | wfDebugLog( 'CentralAuth', |
| 709 | 714 | "authentication for '$this->mName' failed due to lock" ); |
| 710 | 715 | return "locked"; |
| 711 | 716 | } |
| 717 | + | |
| 718 | + return true; | |
| 719 | + } | |
| 712 | 720 | |
| 721 | + /** | |
| 722 | + * Attempt to authenticate the global user account with the given password | |
| 723 | + * @param string $password | |
| 724 | + * @return string status, one of: "ok", "no user", "locked", or "bad password". | |
| 725 | + * @todo Currently only the "ok" result is used (i.e. either use, or return a bool). | |
| 726 | + */ | |
| 727 | + public function authenticate( $password ) { | |
| 728 | + if (($ret = $this->canAuthenticate()) !== true) { | |
| 729 | + return $ret; | |
| 730 | + } | |
| 731 | + | |
| 732 | + list( $salt, $crypt ) = $this->getPasswordHash(); | |
| 733 | + | |
| 713 | 734 | if( $this->matchHash( $password, $salt, $crypt ) ) { |
| 714 | 735 | wfDebugLog( 'CentralAuth', |
| 715 | 736 | "authentication for '$this->mName' succeeded" ); |
| — | — | @@ -719,6 +740,23 @@ |
| 720 | 741 | return "bad password"; |
| 721 | 742 | } |
| 722 | 743 | } |
| 744 | + | |
| 745 | + /** | |
| 746 | + * Attempt to authenticate the global user account with the given global authtoken | |
| 747 | + * @param string $token | |
| 748 | + * @return string status, one of: "ok", "no user", "locked", or "bad token" | |
| 749 | + */ | |
| 750 | + public function authenticateWithToken( $token ) { | |
| 751 | + if (($ret = $this->canAuthenticate()) !== true) { | |
| 752 | + return $ret; | |
| 753 | + } | |
| 754 | + | |
| 755 | + if ($this->validateAuthToken( $token ) ) { | |
| 756 | + return "ok"; | |
| 757 | + } else { | |
| 758 | + return "bad token"; | |
| 759 | + } | |
| 760 | + } | |
| 723 | 761 | |
| 724 | 762 | /** |
| 725 | 763 | * @param $plaintext User-provided password plaintext. |
| — | — | @@ -1095,7 +1133,78 @@ |
| 1096 | 1134 | |
| 1097 | 1135 | wfDebugLog( 'CentralAuth', |
| 1098 | 1136 | "Set global password for '$this->mName'" ); |
| 1137 | + | |
| 1138 | + // Reset the auth token. | |
| 1139 | + $this->resetAuthToken(); | |
| 1140 | + $this->setGlobalCookies(); | |
| 1099 | 1141 | return true; |
| 1100 | 1142 | } |
| 1101 | 1143 | |
| 1144 | + /** | |
| 1145 | + * Set a global cookie that auto-authenticates the user on other wikis | |
| 1146 | + * Called on login. | |
| 1147 | + */ | |
| 1148 | + function setGlobalCookies($localUser) { | |
| 1149 | + global $wgCentralAuthCookiePrefix,$wgCentralAuthCookieDomain,$wgCookieSecure,$wgCookieExpiration; | |
| 1150 | + | |
| 1151 | + $exp = time() + $wgCookieExpiration; | |
| 1152 | + | |
| 1153 | + $global_session = array(); | |
| 1154 | + | |
| 1155 | + $global_session['user'] = $this->mName; | |
| 1156 | + setcookie( $wgCentralAuthCookiePrefix.'User', $this->mName, $exp, '/', $wgCentralAuthCookieDomain, $wgCookieSecure ); | |
| 1157 | + $global_session['token'] = $this->getAuthToken(); | |
| 1158 | + $global_session['expiry'] = time() + 86400; | |
| 1159 | + | |
| 1160 | + if ($localUser->getOption('rememberpassword') == 1) { | |
| 1161 | + setcookie( $wgCentralAuthCookiePrefix.'Token', $this->getAuthToken(), $exp, '/', $wgCentralAuthCookieDomain, $wgCookieSecure ); | |
| 1162 | + } else { | |
| 1163 | + setcookie( $wgCentralAuthCookiePrefix.'Token', '', time() - 86400 ); | |
| 1164 | + } | |
| 1165 | + | |
| 1166 | + // Make up a session id. | |
| 1167 | + $session_id = md5( $exp . mt_rand( 0, 0x7fffffff ) . $this->getId() ); | |
| 1168 | + // Store the session in memcached | |
| 1169 | + global $wgMemc; | |
| 1170 | + $wgMemc->set( 'centralauth_session_'.$session_id, serialize($global_session), 86400 ); | |
| 1171 | + | |
| 1172 | + setcookie( $wgCentralAuthCookiePrefix.'Session', $session_id, time() + 86400, '/', $wgCentralAuthCookieDomain, $wgCookieSecure ); | |
| 1173 | + } | |
| 1174 | + | |
| 1175 | + /** | |
| 1176 | + * Delete global cookies which auto-authenticate the user on other wikis. | |
| 1177 | + * Called on logout. | |
| 1178 | + */ | |
| 1179 | + function deleteGlobalCookies() { | |
| 1180 | + global $wgCentralAuthCookiePrefix,$wgCentralAuthCookieDomain,$wgCookieSecure; | |
| 1181 | + | |
| 1182 | + $exp = time() - 86400; | |
| 1183 | + | |
| 1184 | + setcookie( $wgCentralAuthCookiePrefix.'User', '', $exp, '/', $wgCentralAuthCookieDomain, $wgCookieSecure ); | |
| 1185 | + setcookie( $wgCentralAuthCookiePrefix.'Token', '', $exp, '/', $wgCentralAuthCookieDomain, $wgCookieSecure ); | |
| 1186 | + setcookie( $wgCentralAuthCookiePrefix.'Session', '', $exp, '/', $wgCentralAuthCookieDomain, $wgCookieSecure ); | |
| 1187 | + | |
| 1188 | + $this->resetAuthToken(); | |
| 1189 | + } | |
| 1190 | + | |
| 1191 | + /** | |
| 1192 | + * Check a global auth token against the one we know of in the database. | |
| 1193 | + */ | |
| 1194 | + function validateAuthToken( $token ) { | |
| 1195 | + return ($token == $this->getAuthToken()); | |
| 1196 | + } | |
| 1197 | + | |
| 1198 | + /** | |
| 1199 | + * Generate a new random auth token, and store it in the database. | |
| 1200 | + * Should be called as often as possible, to the extent that it will | |
| 1201 | + * not randomly log users out (so on logout, as is done currently, is a good time). | |
| 1202 | + */ | |
| 1203 | + function resetAuthToken() { | |
| 1204 | + // Generate a random token. | |
| 1205 | + $this->mAuthToken = md5( mt_rand( 0, 0x7fffffff ) . $this->getId() ); | |
| 1206 | + | |
| 1207 | + // Save it. | |
| 1208 | + $dbw = self::getCentralDB(); | |
| 1209 | + $dbw->update( self::tableName( 'globaluser' ), array( 'gu_authtoken' => $this->mAuthToken ), array( 'gu_id' => $this->getId() ), __METHOD__ ); | |
| 1210 | + } | |
| 1102 | 1211 | } |
| Index: trunk/extensions/CentralAuth/CentralAuth.php | ||
| — | — | @@ -38,6 +38,27 @@ |
| 39 | 39 | */ |
| 40 | 40 | $wgCentralAuthDryRun = false; |
| 41 | 41 | |
| 42 | +/** | |
| 43 | + * Domain to set global cookies for. | |
| 44 | + */ | |
| 45 | +$wgCentralAuthCookieDomains = $wgServer; | |
| 46 | + | |
| 47 | +/** | |
| 48 | + * Prefix for CentralAuth cookies. | |
| 49 | + */ | |
| 50 | +$wgCentralAuthCookiePrefix = 'centralauth_'; | |
| 51 | + | |
| 52 | +/** | |
| 53 | + * Wikis to automatically log into when this one is logged into. | |
| 54 | + * Done by loading a 1x1 image from Special:AutoLogin on that wiki. | |
| 55 | + */ | |
| 56 | +$wgCentralAuthAutoLoginWikis = array(); | |
| 57 | + | |
| 58 | +/** | |
| 59 | + * Prefix for CentralAuth global auto-authentication cookies | |
| 60 | + */ | |
| 61 | + $wgCentralAuthCookiePrefix = 'centralauth'; | |
| 62 | + | |
| 42 | 63 | $wgExtensionCredits['specialpage'][] = array( |
| 43 | 64 | 'name' => 'Central Auth', |
| 44 | 65 | 'url' => 'http://www.mediawiki.org/wiki/Extension:CentralAuth', |
| — | — | @@ -57,12 +78,17 @@ |
| 58 | 79 | $wgAutoloadClasses['CentralAuthPlugin'] = "$caBase/CentralAuthPlugin.php"; |
| 59 | 80 | $wgAutoloadClasses['WikiMap'] = "$caBase/WikiMap.php"; |
| 60 | 81 | $wgAutoloadClasses['WikiReference'] = "$caBase/WikiMap.php"; |
| 82 | +$wgAutoloadClasses['SpecialAutoLogin'] = "$caBase/SpecialAutoLogin.php"; | |
| 61 | 83 | $wgExtensionMessagesFiles['SpecialCentralAuth'] = "$caBase/CentralAuth.i18n.php"; |
| 62 | 84 | |
| 63 | 85 | $wgHooks['AuthPluginSetup'][] = 'wfSetupCentralAuthPlugin'; |
| 64 | 86 | $wgHooks['AddNewAccount'][] = 'wfCentralAuthAddNewAccount'; |
| 65 | 87 | $wgHooks['PreferencesUserInformationPanel'][] = 'wfCentralAuthInformationPanel'; |
| 66 | 88 | $wgHooks['AbortNewAccount'][] = 'wfCentralAuthAbortNewAccount'; |
| 89 | +$wgHooks['UserLoginComplete'][] = 'wfCentralAuthUserLoginComplete'; | |
| 90 | +$wgHooks['AutoAuthenticate'][] = 'wfCentralAuthAutoAuthenticate'; | |
| 91 | +$wgHooks['UserLogout'][] = 'wfCentralAuthLogout'; | |
| 92 | +$wgHooks['UserLogoutComplete'][] = 'wfCentralAuthLogoutComplete'; | |
| 67 | 93 | |
| 68 | 94 | // For interaction with the Special:Renameuser extension |
| 69 | 95 | $wgHooks['RenameUserAbort'][] = 'wfCentralAuthRenameUserAbort'; |
| — | — | @@ -72,6 +98,7 @@ |
| 73 | 99 | $wgGroupPermissions['*']['centralauth-merge'] = true; |
| 74 | 100 | |
| 75 | 101 | $wgSpecialPages['CentralAuth'] = 'SpecialCentralAuth'; |
| 102 | +$wgSpecialPages['AutoLogin'] = 'SpecialAutoLogin'; | |
| 76 | 103 | $wgSpecialPages['MergeAccount'] = 'SpecialMergeAccount'; |
| 77 | 104 | |
| 78 | 105 | function wfSetupCentralAuthPlugin( &$auth ) { |
| — | — | @@ -199,3 +226,107 @@ |
| 200 | 227 | return true; |
| 201 | 228 | } |
| 202 | 229 | |
| 230 | +function wfCentralAuthUserLoginComplete( &$user, &$inject_html ) { | |
| 231 | + $centralUser = new CentralAuthUser( $user->getName() ); | |
| 232 | + | |
| 233 | + if ($centralUser->exists()) { | |
| 234 | + $centralUser->setGlobalCookies($user); | |
| 235 | + } else { | |
| 236 | + return; | |
| 237 | + } | |
| 238 | + | |
| 239 | + // On other wikis | |
| 240 | + global $wgCentralAuthAutoLoginWikis; | |
| 241 | + | |
| 242 | + $inject_html .= Xml::openElement( 'p' ); | |
| 243 | + | |
| 244 | + foreach( $wgCentralAuthAutoLoginWikis as $dbname ) { | |
| 245 | + $wiki = WikiMap::byDatabase( $dbname ); | |
| 246 | + $url = $wiki->getUrl( 'Special:AutoLogin' ); | |
| 247 | + | |
| 248 | + $querystring = 'user=' . urlencode( $user->getName() ); | |
| 249 | + $querystring .= '&token=' . $centralUser->getAuthToken(); | |
| 250 | + $querystring .= '&remember=' . $user->getOption( 'rememberpassword' ); | |
| 251 | + | |
| 252 | + if (strpos($url, '?') > 0) { | |
| 253 | + $url .= "&$querystring"; | |
| 254 | + } else { | |
| 255 | + $url .= "?$querystring"; | |
| 256 | + } | |
| 257 | + | |
| 258 | + $inject_html .= Xml::element( 'img', array( 'src' => $url ) ); | |
| 259 | + } | |
| 260 | + | |
| 261 | + $inject_html .= Xml::closeElement( 'p' ); | |
| 262 | + | |
| 263 | + return true; | |
| 264 | +} | |
| 265 | + | |
| 266 | +function wfCentralAuthAutoAuthenticate( &$user ) { | |
| 267 | + global $wgCentralAuthCookiePrefix; | |
| 268 | + $prefix = $wgCentralAuthCookiePrefix; | |
| 269 | + | |
| 270 | + if (isset($_COOKIE["{$prefix}User"]) && isset($_COOKIE["{$prefix}Token"])) { | |
| 271 | + list ($username, $token) = array( $_COOKIE["{$prefix}User"], $_COOKIE["{$prefix}Token"] ); | |
| 272 | + $centralUser = new CentralAuthUser( $username ); | |
| 273 | + | |
| 274 | + if ($centralUser->authenticateWithToken( $token ) == 'ok' && $centralUser->isAttached()) { | |
| 275 | + // Auth OK. | |
| 276 | + $user = User::newFromName( $username ); | |
| 277 | + } | |
| 278 | + } elseif (isset($_COOKIE["{$prefix}Session"])) { | |
| 279 | + $session_id = $_COOKIE["{$prefix}Session"]; | |
| 280 | + | |
| 281 | + global $wgMemc; | |
| 282 | + $global_session = unserialize($wgMemc->get( "centralauth_session_$session_id" )); | |
| 283 | + | |
| 284 | + $token = $global_session['token']; | |
| 285 | + $username = $global_session['user']; | |
| 286 | + | |
| 287 | + if ($global_session['expiry'] < time()) { | |
| 288 | + return true; // Session has expired. Don't let it be logged-in with. | |
| 289 | + } | |
| 290 | + | |
| 291 | + $centralUser = new CentralAuthUser( $username ); | |
| 292 | + | |
| 293 | + if ($centralUser->authenticateWithToken( $token ) == 'ok' && $centralUser->isAttached()) { | |
| 294 | + // Auth OK. | |
| 295 | + $user = User::newFromName( $username ); | |
| 296 | + } | |
| 297 | + } | |
| 298 | + | |
| 299 | + return true; | |
| 300 | +} | |
| 301 | + | |
| 302 | +function wfCentralAuthLogout( &$user ) { | |
| 303 | + $centralUser = new CentralAuthUser( $user->getName() ); | |
| 304 | + | |
| 305 | + if ($centralUser->exists()) { | |
| 306 | + $centralUser->deleteGlobalCookies(); | |
| 307 | + } | |
| 308 | + | |
| 309 | + return true; | |
| 310 | +} | |
| 311 | + | |
| 312 | +function wfCentralAuthLogoutComplete( &$user, &$inject_html ) { | |
| 313 | + // Generate the images | |
| 314 | + global $wgCentralAuthAutoLoginWikis; | |
| 315 | + | |
| 316 | + $inject_html .= Xml::openElement( 'p' ); | |
| 317 | + | |
| 318 | + foreach( $wgCentralAuthAutoLoginWikis as $dbname ) { | |
| 319 | + $wiki = WikiMap::byDatabase( $dbname ); | |
| 320 | + $url = $wiki->getUrl( 'Special:AutoLogin' ); | |
| 321 | + | |
| 322 | + if (strpos($url, '?') > 0) { | |
| 323 | + $url .= '&logout=1'; | |
| 324 | + } else { | |
| 325 | + $url .= '?logout=1'; | |
| 326 | + } | |
| 327 | + | |
| 328 | + $inject_html .= Xml::element( 'img', array( 'src' => $url, alt => '' ) ); | |
| 329 | + } | |
| 330 | + | |
| 331 | + $inject_html .= Xml::closeElement( 'p' ); | |
| 332 | + return true; | |
| 333 | +} | |
| \ No newline at end of file | ||
| Index: trunk/extensions/CentralAuth/central-auth.sql | ||
| — | — | @@ -80,6 +80,9 @@ |
| 81 | 81 | -- Random key for password resets |
| 82 | 82 | gu_password_reset_key tinyblob, |
| 83 | 83 | gu_password_reset_expiration varchar(14) binary, |
| 84 | + | |
| 85 | + -- Random key for crosswiki authentication tokens | |
| 86 | + gu_auth_token varchar(32) binary, | |
| 84 | 87 | |
| 85 | 88 | primary key (gu_id), |
| 86 | 89 | unique key (gu_name), |
| Index: trunk/extensions/CentralAuth/SpecialAutoLogin.php | ||
| — | — | @@ -0,0 +1,59 @@ |
| 2 | +<? | |
| 3 | +if (!defined('MEDIAWIKI')) { | |
| 4 | + die('CentralAuth'); | |
| 5 | +} | |
| 6 | + | |
| 7 | +/** | |
| 8 | + * Unlisted Special page to set requisite cookies for being logged into this wiki. | |
| 9 | + * | |
| 10 | + * @addtogroup Extensions | |
| 11 | + */ | |
| 12 | + | |
| 13 | + global $IP; | |
| 14 | + | |
| 15 | +require_once( "$IP/includes/StreamFile.php" ); | |
| 16 | + | |
| 17 | +class SpecialAutoLogin extends UnlistedSpecialPage | |
| 18 | +{ | |
| 19 | + function SpecialAutoLogin() { | |
| 20 | + SpecialPage::SpecialPage('AutoLogin'); | |
| 21 | + } | |
| 22 | + | |
| 23 | + function execute() { | |
| 24 | + global $wgRequest,$wgOut,$wgUser; | |
| 25 | + | |
| 26 | + $username = $wgRequest->getVal( 'user' ); | |
| 27 | + $token = $wgRequest->getVal('token'); | |
| 28 | + $remember = $wgRequest->getBool( 'remember' ); | |
| 29 | + $logout = $wgRequest->getBool( 'logout' ); | |
| 30 | + | |
| 31 | + if ((strlen($username) == 0 || strlen($token) == 0) && !$logout) { | |
| 32 | + $wgOut->addWikitext( 'AutoLogin' ); | |
| 33 | + return; | |
| 34 | + } | |
| 35 | + | |
| 36 | + if ($logout == true) { | |
| 37 | + $centralUser = new CentralAuthUser( $wgUser->getName() ); | |
| 38 | + | |
| 39 | + if ($centralUser->getId) { | |
| 40 | + $centralUser->deleteGlobalCookies(); | |
| 41 | + } | |
| 42 | + } else { | |
| 43 | + $centralUser = new CentralAuthUser( $username ); | |
| 44 | + | |
| 45 | + $login_result = $centralUser->authenticateWithToken( $token ); | |
| 46 | + | |
| 47 | + if ($login_result == 'ok' && $centralUser->isAttached()) { | |
| 48 | + // Auth OK. | |
| 49 | + $user = User::newFromName( $username ); | |
| 50 | + $user->setOption( 'rememberpassword', $remember ); | |
| 51 | + | |
| 52 | + $centralUser->setGlobalCookies($user); | |
| 53 | + } | |
| 54 | + } | |
| 55 | + | |
| 56 | + wfStreamFile( dirname(__FILE__).'/1x1.png' ); | |
| 57 | + | |
| 58 | + $wgOut->disable(); | |
| 59 | + } | |
| 60 | +} | |
| \ No newline at end of file | ||
| Property changes on: trunk/extensions/CentralAuth/SpecialAutoLogin.php | ||
| ___________________________________________________________________ | ||
| Added: svn:eol-style | ||
| 1 | 61 | + native |
| Index: trunk/extensions/CentralAuth/1x1.png | ||
| Cannot display: file marked as a binary type. | ||
| svn:mime-type = image/png | ||
| Property changes on: trunk/extensions/CentralAuth/1x1.png | ||
| ___________________________________________________________________ | ||
| Added: svn:mime-type | ||
| 2 | 62 | + image/png |
US