http://www.mediawiki.org/wiki/Special:Code/MediaWiki/90784
Revision: 90784
Author: reedy
Date: 2011-06-25 19:17:04 +0000 (Sat, 25 Jun 2011)
Log Message:
-----------
Commit SignupApi extension by Akshay Agarwal for GSoC 2011 project
(Doing on his behalf due to key issues with svn. Allows people to easily start
doing some level of codereview)
Commiting with a few very minor tweaks
Added Paths:
-----------
trunk/extensions/SignupAPI/
trunk/extensions/SignupAPI/SignupAPI.php
trunk/extensions/SignupAPI/includes/
trunk/extensions/SignupAPI/includes/APISignup.php
trunk/extensions/SignupAPI/includes/SpecialUserSignup.php
Added: trunk/extensions/SignupAPI/SignupAPI.php
===================================================================
--- trunk/extensions/SignupAPI/SignupAPI.php (rev 0)
+++ trunk/extensions/SignupAPI/SignupAPI.php 2011-06-25 19:17:04 UTC (rev
90784)
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Setup for SignupAPI extension, a special page that cleans up
SpecialUserLogin
+ * from signup related stuff & adds an API for signup
+ *
+ * @file
+ * @ingroup Extensions
+ * @author Akshay Agarwal, akshayagarwal.in
+ * @copyright \xA9 2011 Akshay Agarwal
+ * @licence GNU General Public Licence 2.0 or later
+ */
+
+if( !defined( 'MEDIAWIKI' ) ) {
+ echo( "This file is an extension to the MediaWiki software and cannot
be used standalone.\n" );
+ die( 1 );
+}
+
+$wgExtensionCredits['specialpage'][] = array(
+ 'path' => __FILE__,
+ 'name' => 'SignupAPI',
+ 'version' => 1.0,
+ 'author' => 'Akshay Agarwal',
+ 'url' => 'http://www.mediawiki.org/wiki/Extension:SignupAPI',
+ 'description' => 'Cleans up SpecialUserLogin from signup related stuff
& adds an API for signup',
+// 'descriptionmsg' => 'signupapiextension-desc',
+);
+
+$wgMyExtensionIncludes = dirname(__FILE__) . '/includes';
+
+## Special page class
+$wgAutoloadClasses['SignupForm']
+ = $wgMyExtensionIncludes . '/SpecialUserSignup.php';
+
+$wgAutoloadClasses['ApiSignup']
+ = $wgMyExtensionIncludes . '/APISignup.php';
+$wgSpecialPages['UserSignup'] = 'SignupForm';
+
+$wgAPIModules['signup'] = 'ApiSignup';
Property changes on: trunk/extensions/SignupAPI/SignupAPI.php
___________________________________________________________________
Added: svn:eol-style
+ native
Added: trunk/extensions/SignupAPI/includes/APISignup.php
===================================================================
--- trunk/extensions/SignupAPI/includes/APISignup.php
(rev 0)
+++ trunk/extensions/SignupAPI/includes/APISignup.php 2011-06-25 19:17:04 UTC
(rev 90784)
@@ -0,0 +1,221 @@
+<?php
+
+if ( !defined( 'MEDIAWIKI' ) ) {
+ // Eclipse helper - will be ignored in production
+ require_once( 'ApiBase.php' );
+}
+
+/**
+ * Unit to create accounts in the current wiki
+ *
+ * @ingroup API
+ */
+class ApiSignup extends ApiBase {
+
+ public function __construct( $main, $action ) {
+ parent::__construct( $main, $action);
+ }
+
+ public function execute() {
+ $params = $this->extractRequestParams();
+
+ $result = array();
+
+ $req = new FauxRequest( array(
+ 'wpName' => $params['name'],
+ 'wpPassword' => $params['password'],
+ 'wpRetype' => $params['retype'],
+ 'wpEmail' => $params['email'],
+ 'wpDomain' => $params['domain'],
+ 'wpRemember' => ''
+ ) );
+
+ // Init session if necessary
+ if ( session_id() == '' ) {
+ wfSetupSession();
+ }
+
+ $signupForm = new SignupForm( $req );
+
+ global $wgCookiePrefix, $wgUser, $wgAccountCreationThrottle;
+
+ $signupRes = $signupForm->addNewAccountInternal();
+ switch( $signupRes ) {
+ case SignupForm::SUCCESS:
+ $signupForm->initUser();
+
+ wfRunHooks( 'AddNewAccount', array( $wgUser,
false ) );
+ # Run any hooks; display injected HTML
+ $injected_html = '';
+ $welcome_creation_msg = 'welcomecreation';
+
+ wfRunHooks( 'UserLoginComplete', array(
&$wgUser, &$injected_html ) );
+
+ //let any extensions change what message is
shown
+ wfRunHooks( 'BeforeWelcomeCreation', array(
&$welcome_creation_msg, &$injected_html ) );
+
+ $result['result'] = 'Success';
+ $result['lguserid'] = intval( $wgUser->getId()
);
+ $result['lgusername'] = $wgUser->getName();
+ $result['lgtoken'] = $wgUser->getToken();
+ $result['cookieprefix'] = $wgCookiePrefix;
+ $result['sessionid'] = session_id();
+ break;
+
+ case SignupForm::INVALID_DOMAIN:
+ $result['result'] = 'WrongPassword';
+ $result['domain']= $signupForm->mDomain;
+ break;
+
+ case SignupForm::READ_ONLY_PAGE:
+ $result['result'] = 'ReadOnlyPage';
+ break;
+
+ case SignupForm::NO_COOKIES:
+ $result['result'] = 'NoCookies';
+ break;
+
+ case SignupForm::NEED_TOKEN:
+ $result['result'] = 'NeedToken';
+ $result['token'] =
$signupForm->getCreateaccountToken();
+ $result['cookieprefix'] = $wgCookiePrefix;
+ $result['sessionid'] = session_id();
+ break;
+
+ case SignupForm::WRONG_TOKEN:
+ $result['result'] = 'WrongToken';
+ break;
+
+ case SignupForm::INSUFFICIENT_PERMISSION:
+ $result['result'] = 'InsufficientPermission';
+ break;
+
+ case SignupForm::CREATE_BLOCKED:
+ $result['result'] = 'CreateBlocked';
+ break;
+
+ case SignupForm::IP_BLOCKED:
+ $result['result'] = 'IPBlocked';
+ break:
+
+ case SignupForm::NO_NAME:
+ $result['result'] = 'NoName';
+ break;
+
+ case SignupForm::USER_EXISTS:
+ $result['result'] = 'UserExists';
+ break;
+
+ case SignupForm::WRONG_RETYPE:
+ $result['result'] = 'WrongRetype';
+ break;
+
+ case SignupForm::INVALID_PASS:
+ $result['result'] = 'InvalidPass';
+ break;
+
+ case SignupForm::NO_EMAIL:
+ $result['result'] = 'NoEmail';
+ break;
+
+ case SignupForm::INVALID_EMAIL:
+ $result['result'] = 'InvalidEmail';
+ break;
+
+ case SignupForm::BLOCKED_BY_HOOK:
+ $result['result'] = 'BlockedByHook';
+ break;
+
+ case SignupForm::EXTR_DB_ERROR:
+ $result['result'] = 'ExternalDBError';
+ break;
+
+ case SignupForm::THROTLLED:
+ $result['result'] = 'Throttled';
+ break;
+
+ default:
+ ApiBase::dieDebug( __METHOD__, "Unhandled case
value: {$signupRes}" );
+ }
+
+ $this->getResult()->addValue( null, 'signup', $result );
+ }
+
+ public function mustBePosted() {
+ return true;
+ }
+
+ public function isReadMode() {
+ return false;
+ }
+
+ public function getAllowedParams() {
+ return array(
+ 'name' => null,
+ 'password' => null,
+ 'retype' => null,
+ 'email' => null,
+ 'domain' => null,
+ );
+ }
+
+ public function getParamDescription() {
+ return array(
+ 'name' => 'Desired Username',
+ 'password' => 'Password',
+ 'retype' => 'Re-typed Password',
+ 'email' => 'Email ID(optional)',
+ 'domain' => 'Domain (optional)',
+ );
+ }
+
+
+
+ public function getDescription() {
+ return array(
+ 'This module validates the parameters posted by the
signup form.',
+ 'If validated, a new account is created for the user.',
+ 'If validation of any of the fields fails, the cause
of',
+ 'the error will be output. If the user chooses to
provide',
+ 'his email then a confirmation mail will be sent to
him.',
+ 'On successful account creation, this module will call
APILogin',
+ 'alongwith the newly created username & password'
+ );
+ }
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'code' => 'WrongPassword', 'info' => 'Incorrect
password entered. Please try again.' ),
+ array( 'code' => 'ReadOnlyPage', 'info' => 'Accounts
cannot be created with read-only permissions' ),
+ array( 'code' => 'NoCookies', 'info' => 'The user
account was not created, as we could not confirm its source.
+ Ensure you
have cookies enabled, reload this page and try again.' ),
+ array( 'code' => 'NeedToken', 'info' => 'You need to
resubmit your signup with the specified token' ),
+ array( 'code' => 'WrongToken', 'info' => 'You specified
an invalid token' ),
+ array( 'code' => 'InsufficientPermission', 'info' =>
'You do not have sufficient permissions to create account' ),
+ array( 'code' => 'CreateBlocked', 'info' => 'You have
been blocked from creating accounts' ),
+ array( 'code' => 'IPBlocked', 'info' => 'Your IP is
blocked from creating accounts' ),
+ array( 'code' => 'NoName', 'info' => 'You have not set
a valid name for the username parameter' ),
+ array( 'code' => 'UserExists', 'info' => 'Username
entered already in use. Please choose a different name.' ),
+ array( 'code' => 'WrongRetype', 'info' => 'The
passwords you entered do not match.' ),
+ array( 'code' => 'InvalidPass', 'info' => 'You
specified an invalid password' ),
+ array( 'code' => 'NoEmail', 'info' => 'No e-mail
address specified' ),
+ array( 'code' => 'InvalidEmail', 'info' => 'You
specified an invalid email address' ),
+ array( 'code' => 'BlockedByHook', 'info' => 'A hook
blocked account creation' ),
+ array( 'code' => 'ExternalDBError', 'info' => 'There
was either an authentication database error or you are not allowed to update
your external account.' ),
+ array( 'code' => 'Throttled', 'info' => 'You have tried
creating accounts too many times in a short period' ),
+ ) );
+ }
+
+ protected function getExamples() {
+ return array(
+
'api.php?action=signup&username=username&password=password&retype=passretype'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+
+}
+
+
\ No newline at end of file
Property changes on: trunk/extensions/SignupAPI/includes/APISignup.php
___________________________________________________________________
Added: svn:keywords
+ Id
Added: svn:eol-style
+ native
Added: trunk/extensions/SignupAPI/includes/SpecialUserSignup.php
===================================================================
--- trunk/extensions/SignupAPI/includes/SpecialUserSignup.php
(rev 0)
+++ trunk/extensions/SignupAPI/includes/SpecialUserSignup.php 2011-06-25
19:17:04 UTC (rev 90784)
@@ -0,0 +1,870 @@
+<?php
+/**
+ * Implements Special:UserSignup
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup SpecialPage
+ */
+
+/**
+ * Implements Special:UserSignup
+ *
+ * @ingroup SpecialPage
+ */
+class SignupForm extends SpecialPage {
+
+ const SUCCESS = 0;
+ const NO_NAME = 1;
+ const CREATE_BLOCKED = 2;
+ const NEED_TOKEN = 3;
+ const WRONG_TOKEN = 4;
+ const IP_BLOCKED = 5;
+ const USER_EXISTS = 6;
+ const WRONG_RETYPE = 7;
+ const INVALID_DOMAIN = 8;
+ const READ_ONLY_PAGE = 9;
+ const NO_COOKIES = 10;
+ const INSUFFICIENT_PERMISSION = 11;
+ const INVALID_PASS = 12;
+ const NO_EMAIL = 13;
+ const INVALID_EMAIL = 14;
+ const BLOCKED_BY_HOOK = 15;
+ const EXTR_DB_ERROR = 16;
+ const THROTLLED = 17;
+
+
+ //Initialise all variables to be used
+ var $mUsername, $mPassword, $mRetype, $mReturnTo, $mCookieCheck,
$mPosted;
+ var $mAction, $mCreateaccount, $mCreateaccountMail;
+ var $mRemember, $mEmail, $mDomain, $mLanguage;
+ var $mSkipCookieCheck, $mReturnToQuery, $mToken, $mStickHTTPS;
+ var $mType, $mReason, $mRealName;
+ var $abortError = '';
+ var $mUser;
+
+ /**
+ * @var ExternalUser
+ */
+ private $mExtUser = null;
+
+ /**
+ * @param WebRequest $request
+ */
+ public function __construct( $request = null ) {
+ parent::__construct( 'UserSignup' );
+
+ if ( $request === null ) {
+ global $wgRequest;
+ $this->load( $wgRequest );
+ } else {
+ $this->load( $request );
+ }
+ }
+
+ /**
+ * Loader
+ *
+ * @param $request WebRequest object
+ */
+ function load( $request ) {
+ global $wgAuth, $wgHiddenPrefs, $wgEnableEmail,
$wgRedirectOnLogin;
+
+ $this->mType = $request->getText( 'type' );
+ $this->mUsername = $request->getText( 'wpName' );
+ $this->mPassword = $request->getText( 'wpPassword' );
+ $this->mRetype = $request->getText( 'wpRetype' );
+ $this->mDomain = $request->getText( 'wpDomain' );
+ $this->mReason = $request->getText( 'wpReason' );
+ $this->mReturnTo = $request->getVal( 'returnto' );
+ $this->mReturnToQuery = $request->getVal( 'returntoquery' );
+ $this->mCookieCheck = $request->getVal( 'wpCookieCheck' );
+ $this->mPosted = $request->wasPosted();
+ $this->mCreateaccount = $request->getCheck( 'wpCreateaccount' );
+ $this->mCreateaccountMail = $request->getCheck(
'wpCreateaccountMail' )
+ &&
$wgEnableEmail;
+ $this->mAction = $request->getVal( 'action' );
+ $this->mRemember = $request->getCheck( 'wpRemember' );
+ $this->mStickHTTPS = $request->getCheck( 'wpStickHTTPS' );
+ $this->mLanguage = $request->getText( 'uselang' );
+ $this->mSkipCookieCheck = $request->getCheck(
'wpSkipCookieCheck' );
+
+ //Decide whether login or signup request
+
+ $this->mToken = $request->getVal( 'wpCreateaccountToken' );
+
+ if( $wgEnableEmail ) {
+ $this->mEmail = $request->getText( 'wpEmail' );
+ } else {
+ $this->mEmail = '';
+ }
+
+ if( !in_array( 'realname', $wgHiddenPrefs ) ) {
+ $this->mRealName = $request->getText( 'wpRealName' );
+ } else {
+ $this->mRealName = '';
+ }
+
+ if( !$wgAuth->validDomain( $this->mDomain ) ) {
+ $this->mDomain = 'invaliddomain';
+ }
+ $wgAuth->setDomain( $this->mDomain );
+ }
+
+ public function execute( $par ) {
+ if ( session_id() == '' ) {
+ wfSetupSession();
+ }
+
+ if ( $par == 'signup' ) { # Check for
[[Special:Userlogin/signup]]
+ $this->mType = 'signup';
+ }
+
+ if ( !is_null( $this->mCookieCheck ) ) {
+ $this->onCookieRedirectCheck( $this->mCookieCheck );
+ return;
+ } elseif( $this->mPosted ) {
+ if( $this->mCreateaccount ) {
+ return $this->processSignup();
+ } elseif ( $this->mCreateaccountMail ) {
+ return $this->addNewAccountMailPassword();
+ }
+ }
+ $this->mainSignupForm( '' );
+ }
+
+ /**
+ * @private
+ */
+ //Used for mailing password reset request
+ function addNewAccountMailPassword() {
+ global $wgOut;
+
+ //check if no email id was provided
+ if ( $this->mEmail == '' ) {
+ $this->mainSignupForm( wfMsgExt( 'noemail', array(
'parsemag', 'escape' ), $this->mUsername ) );
+ return;
+ }
+
+
+ $mUser = $this->addNewaccountInternal();
+
+ if ( $mUser == null ) {
+ return;
+ }
+
+ // Wipe the initial password and mail a temporary one
+ $mUser->setPassword( null );
+ $mUser->saveSettings();
+ $result = $this->mailPasswordInternal( $mUser, false,
'createaccount-title', 'createaccount-text' );
+
+ wfRunHooks( 'AddNewAccount', array( $mUser, true ) );
+ $mUser->addNewUserLogEntry( true, $this->mReason );
+
+ $wgOut->setPageTitle( wfMsg( 'accmailtitle' ) );
+
+ if( !$result->isGood() ) {
+ $this->mainSignupForm( wfMsg( 'mailerror',
$result->getWikiText() ) );
+ } else {
+ $wgOut->addWikiMsg( 'accmailtext', $mUser->getName(),
$mUser->getEmail() );
+ $wgOut->returnToMain( false );
+ }
+ }
+
+ /**
+ * @private
+ */
+ function addNewAccount($mUser) {
+ global $wgUser, $wgEmailAuthentication, $wgOut;
+
+ # Create the account and abort if there's a problem doing so
+ //$mUser = $this->addNewAccountInternal();
+ if( $mUser == null ) {
+ return;
+ }
+
+ # If we showed up language selection links, and one was in use,
be
+ # smart (and sensible) and save that language as the user's
preference
+ global $wgLoginLanguageSelector;
+ if( $wgLoginLanguageSelector && $this->mLanguage ) {
+ $mUser->setOption( 'language', $this->mLanguage );
+ }
+
+ # Send out an email authentication message if needed
+ if( $wgEmailAuthentication && User::isValidEmailAddr(
$mUser->getEmail() ) ) {
+ $status = $mUser->sendConfirmationMail();
+ if( $status==1 ) {
+ $wgOut->addWikiMsg( 'confirmemail_oncreate' );
+ } else {
+ $wgOut->addWikiText( $status->getWikiText(
'confirmemail_sendfailed' ) );
+ }
+ }
+
+ # Save settings (including confirmation token)
+ $mUser->saveSettings();
+
+ # If not logged in, assume the new account as the current one
and set
+ # session cookies then show a "welcome" message or a "need
cookies"
+ # message as needed
+ if( $wgUser->isAnon() ) {
+ $wgUser = $mUser;
+ $wgUser->setCookies();
+ wfRunHooks( 'AddNewAccount', array( $wgUser, false ) );
+ $wgUser->addNewUserLogEntry();
+ if( $this->hasSessionCookie() ) {
+ return $this->successfulCreation();
+ } else {
+ return $this->cookieRedirectCheck( 'new' );
+ }
+ } else {
+ # Confirm that the account was created
+ $self = SpecialPage::getTitleFor( 'Userlogin' );
+ $wgOut->setPageTitle( wfMsgHtml( 'accountcreated' ) );
+ $wgOut->addWikiMsg( 'accountcreatedtext',
$mUser->getName() );
+ $wgOut->returnToMain( false, $self );
+ wfRunHooks( 'AddNewAccount', array( $mUser, false ) );
+ $mUser->addNewUserLogEntry( false, $this->mReason );
+ return true;
+ }
+ }
+
+ /**
+ * @private
+ */
+ function addNewAccountInternal() {
+ global $wgUser, $wgOut;
+ global $wgMemc, $wgAccountCreationThrottle;
+ global $wgAuth, $wgMinimalPasswordLength;
+ global $wgEmailConfirmToEdit;
+
+ // If the user passes an invalid domain, something is fishy
+ if( !$wgAuth->validDomain( $this->mDomain ) ) {
+ return self::INVALID_DOMAIN;
+ }
+
+ // If we are not allowing users to login locally, we should be
checking
+ // to see if the user is actually able to authenticate to the
authenti-
+ // cation server before they create an account (otherwise, they
can
+ // create a local account and login as any domain user). We
only need
+ // to check this for domains that aren't local.
+ if( 'local' != $this->mDomain && $this->mDomain != '' ) {
+ if( !$wgAuth->canCreateAccounts() && (
!$wgAuth->userExists( $this->mUsername )
+ || !$wgAuth->authenticate( $this->mUsername,
$this->mPassword ) ) ) {
+ return self::INVALID_DOMAIN;
+ }
+ }
+
+ if ( wfReadOnly() ) {
+
+ return self::READ_ONLY_PAGE;
+ }
+
+ # Request forgery checks.
+ if ( !self::getCreateaccountToken() ) {
+ self::setCreateaccountToken();
+ return self::NO_COOKIES;
+ }
+
+ # The user didn't pass a createaccount token
+ if ( !$this->mToken ) {
+ return self::NEED_TOKEN;
+ }
+
+ # Validate the createaccount token
+ if ( $this->mToken !== self::getCreateaccountToken() ) {
+ return self::WRONG_TOKEN;
+ }
+
+ # Check permissions
+ if ( !$wgUser->isAllowed( 'createaccount' ) ) {
+ return self::INSUFFICIENT_PERMISSION;
+ } elseif ( $wgUser->isBlockedFromCreateAccount() ) {
+ return self::CREATE_BLOCKED;
+ }
+
+ $ip = wfGetIP();
+ if ( $wgUser->isDnsBlacklisted( $ip, true /* check
$wgProxyWhitelist */ ) ) {
+ return self::IP_BLOCKED;
+ }
+
+ # Now create a dummy user ($mUser) and check if it is valid
+ $name = trim( $this->mUsername );
+ $mUser = User::newFromName( $name, 'creatable' );
+ if ( !is_object( $mUser ) ) {
+ return self::NO_NAME;
+ }
+
+ if ( 0 != $mUser->idForName() ) {
+ return self::USER_EXISTS;
+ }
+
+ if ( 0 != strcmp( $this->mPassword, $this->mRetype ) ) {
+ return self::WRONG_RETYPE;
+ }
+
+ # check for minimal password length
+ $valid = $mUser->getPasswordValidity( $this->mPassword );
+ if ( $valid !== true ) {
+ if ( !$this->mCreateaccountMail ) {
+ return self::INVALID_PASS;
+ } else {
+ # do not force a password for account creation
by email
+ # set invalid password, it will be replaced
later by a random generated password
+ $this->mPassword = null;
+ }
+ }
+
+ # if you need a confirmed email address to edit, then obviously
you
+ # need an email address.
+ if ( $wgEmailConfirmToEdit && empty( $this->mEmail ) ) {
+ return self::NO_EMAIL;
+ }
+
+ # if email is provided then validate it
+ if( !empty( $this->mEmail ) && !User::isValidEmailAddr(
$this->mEmail ) ) {
+ return self::INVALID_EMAIL;
+ }
+
+ # Set some additional data so the AbortNewAccount hook can be
used for
+ # more than just username validation
+ $mUser->setEmail( $this->mEmail );
+ $mUser->setRealName( $this->mRealName );
+
+ if( !wfRunHooks( 'AbortNewAccount', array( $mUser, &$abortError
) ) ) {
+ // Hook point to add extra creation throttles and blocks
+ return self::BLOCKED_BY_HOOK;
+ }
+
+ if ( $wgAccountCreationThrottle && $wgUser->isPingLimitable() )
{
+ $key = wfMemcKey( 'acctcreate', 'ip', $ip );
+ $value = $wgMemc->get( $key );
+ if ( !$value ) {
+ $wgMemc->set( $key, 0, 86400 );
+ }
+ if ( $value >= $wgAccountCreationThrottle ) {
+ return self::THROTLLED;
+ }
+ $wgMemc->incr( $key );
+ }
+
+ if( !$wgAuth->addUser( $mUser, $this->mPassword, $this->mEmail,
$this->mRealName ) ) {
+ return self::EXTR_DB_ERROR;
+ }
+
+ self::clearCreateaccountToken();
+ $mUser = $this->initUser( $mUser, false );
+ $this->addNewAccount($mUser);
+ return self::SUCCESS;
+ }
+
+ /**
+ * Actually add a user to the database.
+ * Give it a User object that has been initialised with a name.
+ *
+ * @param $mUser User object.
+ * @param $autocreate boolean -- true if this is an autocreation via
auth plugin
+ * @return User object.
+ * @private
+ */
+ function initUser( $mUser, $autocreate ) {
+ global $wgAuth;
+
+ $mUser->addToDatabase();
+
+ if ( $wgAuth->allowPasswordChange() ) {
+ $mUser->setPassword( $this->mPassword );
+ }
+
+ $mUser->setEmail( $this->mEmail );
+ $mUser->setRealName( $this->mRealName );
+ $mUser->setToken();
+
+ $wgAuth->initUser( $mUser, $autocreate );
+
+ if ( $this->mExtUser ) {
+ $this->mExtUser->linkToLocal( $mUser->getId() );
+ $email = $this->mExtUser->getPref( 'emailaddress' );
+ if ( $email && !$this->mEmail ) {
+ $mUser->setEmail( $email );
+ }
+ }
+
+ $mUser->setOption( 'rememberpassword', $this->mRemember ? 1 : 0
);
+ $mUser->saveSettings();
+
+ # Update user count
+ $ssUpdate = new SiteStatsUpdate( 0, 0, 0, 0, 1 );
+ $ssUpdate->doUpdate();
+
+ return $mUser;
+ }
+
+
+ function processSignup() {
+ global $wgUser;
+
+ switch ( $this->addNewAccountInternal() ) {
+ case self::SUCCESS:
+ //$this->initUser( $mUser, false );
+ //$this->addNewAccount($mUser);
+ break;
+ case self::INVALID_DOMAIN:
+ $this->mainSignupForm( wfMsg( 'wrongpassword' )
);
+ break;
+ case self::READ_ONLY_PAGE:
+ $wgOut->readOnlyPage();
+ break;
+ case self::NO_COOKIES:
+ $this->mainSignupForm( wfMsgExt(
'nocookiesfornew', array( 'parseinline' ) ) );
+ break;
+ case self::NEED_TOKEN:
+ $this->mainSignupForm( wfMsg( 'sessionfailure'
) );
+ break;
+ case self::WRONG_TOKEN:
+ $this->mainSignupForm( wfMsg( 'sessionfailure'
) );
+ break;
+ case self::INSUFFICIENT_PERMISSION:
+ $wgOut->permissionRequired( 'createaccount' );
+ break;
+ case self::CREATE_BLOCKED:
+ $this->userBlockedMessage(
$wgUser->isBlockedFromCreateAccount() );
+ break;
+ case self::IP_BLOCKED:
+ $this->mainSignupForm( wfMsg(
'sorbs_create_account_reason' ) . ' (' . htmlspecialchars( $ip ) . ')' );
+ break;
+ case self::NO_NAME:
+ $this->mainSignupForm( wfMsg( 'noname' ) );
+ break;
+ case self::USER_EXISTS:
+ $this->mainSignupForm( wfMsg( 'userexists' ) );
+ break;
+ case self::WRONG_RETYPE:
+ $this->mainSignupForm( wfMsg( 'badretype' ) );
+ break;
+ case self::INVALID_PASS:
+ if ( is_array( $valid ) ) {
+ $message = array_shift( $valid );
+ $params = $valid;
+ } else {
+ $message = $valid;
+ $params = array( $wgMinimalPasswordLength );
+ }
+ $this->mainSignupForm( wfMsgExt( $message,
array( 'parsemag' ), $params ) );
+ break;
+ case self::NO_EMAIL:
+ $this->mainSignupForm( wfMsg( 'noemailtitle' )
);
+ break;
+ case self::INVALID_EMAIL:
+ $this->mainSignupForm( wfMsg(
'invalidemailaddress' ) );
+ break;
+ case self::BLOCKED_BY_HOOK:
+ wfDebug( "LoginForm::addNewAccountInternal: a
hook blocked creation\n" );
+ $this->mainSignupForm( $abortError );
+ break;
+ case self::EXTR_DB_ERROR:
+ $this->mainSignupForm( wfMsg( 'externaldberror'
) );
+ break;
+ case self::THROTLLED;
+ $this->mainSignupForm( wfMsgExt(
'acct_creation_throttle_hit', array( 'parseinline' ),
$wgAccountCreationThrottle ) );
+ break;
+ default:
+ throw new MWException( 'Unhandled case value' );
+ }
+ }
+
+
+
+ /**
+ * @param $mUser User object
+ * @param $throttle Boolean
+ * @param $emailTitle String: message name of email title
+ * @param $emailText String: message name of email text
+ * @return Status object
+ * @private
+ */
+ function mailPasswordInternal( $mUser, $throttle = true, $emailTitle =
'passwordremindertitle', $emailText = 'passwordremindertext' ) {
+ global $wgServer, $wgScript, $wgUser, $wgNewPasswordExpiry;
+
+ if ( $mUser->getEmail() == '' ) {
+ return Status::newFatal( 'noemail', $mUser->getName() );
+ }
+ $ip = wfGetIP();
+ if( !$ip ) {
+ return Status::newFatal( 'badipaddress' );
+ }
+
+ wfRunHooks( 'User::mailPasswordInternal', array( &$wgUser,
&$ip, &$mUser ) );
+
+ $np = $mUser->randomPassword();
+ $mUser->setNewpassword( $np, $throttle );
+ $mUser->saveSettings();
+ $mUserserLanguage = $mUser->getOption( 'language' );
+ $m = wfMsgExt( $emailText, array( 'parsemag', 'language' =>
$mUserserLanguage ), $ip, $mUser->getName(), $np,
+ $wgServer . $wgScript, round(
$wgNewPasswordExpiry / 86400 ) );
+ $result = $mUser->sendMail( wfMsgExt( $emailTitle, array(
'parsemag', 'language' => $mUserserLanguage ) ), $m );
+
+ return $result;
+ }
+
+
+
+ /**
+ * Run any hooks registered for logins, then display a message welcoming
+ * the user.
+ *
+ * @private
+ */
+ function successfulCreation() {
+ global $wgUser;
+ # Run any hooks; display injected HTML
+ $injected_html = '';
+ $welcome_creation_msg = 'welcomecreation';
+
+ wfRunHooks( 'UserLoginComplete', array( &$wgUser,
&$injected_html ) );
+
+ //let any extensions change what message is shown
+ wfRunHooks( 'BeforeWelcomeCreation', array(
&$welcome_creation_msg, &$injected_html ) );
+
+ $this->displaySuccessfulCreation( $welcome_creation_msg,
$injected_html );
+ }
+
+ /**
+ * Output a message that informs the user that they cannot create an
account because
+ * there is a block on them or their IP which prevents account
creation. Note that
+ * User::isBlockedFromCreateAccount(), which gets this block, ignores
the 'hardblock'
+ * setting on blocks (bug 13611).
+ * @param $block Block the block causing this error
+ */
+ function userBlockedMessage( Block $block ) {
+ global $wgOut;
+
+ # Let's be nice about this, it's likely that this feature will
be used
+ # for blocking large numbers of innocent people, e.g. range
blocks on
+ # schools. Don't blame it on the user. There's a small chance
that it
+ # really is the user's fault, i.e. the username is blocked and
they
+ # haven't bothered to log out before trying to create an
account to
+ # evade it, but we'll leave that to their guilty conscience to
figure
+ # out.
+
+ $wgOut->setPageTitle( wfMsg( 'cantcreateaccounttitle' ) );
+
+ $block_reason = $block->mReason;
+ if ( strval( $block_reason ) === '' ) {
+ $block_reason = wfMsg( 'blockednoreason' );
+ }
+
+ $wgOut->addWikiMsg(
+ 'cantcreateaccount-text',
+ $block->getTarget(),
+ $block_reason,
+ $block->getBlocker()->getName()
+ );
+
+ $wgOut->returnToMain( false );
+ }
+
+ /**
+ * @private
+ */
+ function mainSignupForm( $msg, $msgtype = 'error' ) {
+ global $wgUser, $wgOut, $wgHiddenPrefs;
+ global $wgEnableEmail, $wgEnableUserEmail;
+ global $wgRequest, $wgLoginLanguageSelector;
+ global $wgAuth, $wgEmailConfirmToEdit, $wgCookieExpiration;
+ global $wgSecureLogin, $wgPasswordResetRoutes;
+
+ $titleObj = SpecialPage::getTitleFor( 'Usersignup' );
+
+
+ // Block signup here if in readonly. Keeps user from
+ // going through the process (filling out data, etc)
+ // and being informed later.
+ if ( wfReadOnly() ) {
+ $wgOut->readOnlyPage();
+ return;
+ } elseif ( $wgUser->isBlockedFromCreateAccount() ) {
+ $this->userBlockedMessage(
$wgUser->isBlockedFromCreateAccount() );
+ return;
+ } elseif ( count( $permErrors =
$titleObj->getUserPermissionsErrors( 'createaccount', $wgUser, true ) )>0 ) {
+ $wgOut->showPermissionsErrorPage( $permErrors,
'createaccount' );
+ return;
+ }
+
+
+ if ( $this->mUsername == '' ) {
+ if ( $wgUser->isLoggedIn() ) {
+ $this->mUsername = $wgUser->getName();
+ } else {
+ //$this->mUsername = $wgRequest->getCookie(
'UserName' );
+ }
+ }
+
+
+ $template = new UsercreateTemplate();
+ $q = 'action=submitlogin&type=signup';
+ $linkq = 'type=login';
+ $linkmsg = 'gotaccount';
+
+
+ if ( !empty( $this->mReturnTo ) ) {
+ $returnto = '&returnto=' . wfUrlencode(
$this->mReturnTo );
+ if ( !empty( $this->mReturnToQuery ) ) {
+ $returnto .= '&returntoquery=' .
+ wfUrlencode( $this->mReturnToQuery );
+ }
+ $q .= $returnto;
+ $linkq .= $returnto;
+ }
+
+ # Pass any language selection on to the mode switch link
+ if( $wgLoginLanguageSelector && $this->mLanguage ) {
+ $linkq .= '&uselang=' . $this->mLanguage;
+ }
+
+ $link = '<a href="' . htmlspecialchars (
$titleObj->getLocalURL( $linkq ) ) . '">';
+ $link .= wfMsgHtml( $linkmsg . 'link' ); # Calling either
'gotaccountlink' or 'nologinlink'
+ $link .= '</a>';
+
+ # Don't show a "create account" link if the user can't
+ if( $this->showCreateOrLoginLink( $wgUser ) ) {
+ $template->set( 'link', wfMsgExt( $linkmsg, array(
'parseinline', 'replaceafter' ), $link ) );
+ } else {
+ $template->set( 'link', '' );
+ }
+
+ $resetLink = $this->mType == 'signup'
+ ? null
+ : is_array( $wgPasswordResetRoutes ) && in_array( true,
array_values( $wgPasswordResetRoutes ) );
+
+ $template->set( 'header', '' );
+ $template->set( 'name', $this->mUsername );
+ $template->set( 'password', $this->mPassword );
+ $template->set( 'retype', $this->mRetype );
+ $template->set( 'email', $this->mEmail );
+ $template->set( 'realname', $this->mRealName );
+ $template->set( 'domain', $this->mDomain );
+ $template->set( 'reason', $this->mReason );
+
+ $template->set( 'action', $titleObj->getLocalURL( $q ) );
+ $template->set( 'message', $msg );
+ $template->set( 'messagetype', $msgtype );
+ $template->set( 'createemail', $wgEnableEmail &&
$wgUser->isLoggedIn() );
+ $template->set( 'userealname', !in_array( 'realname',
$wgHiddenPrefs ) );
+ $template->set( 'useemail', $wgEnableEmail );
+ $template->set( 'emailrequired', $wgEmailConfirmToEdit );
+ $template->set( 'emailothers', $wgEnableUserEmail );
+ $template->set( 'canreset', $wgAuth->allowPasswordChange() );
+ $template->set( 'resetlink', $resetLink );
+ $template->set( 'canremember', ( $wgCookieExpiration > 0 ) );
+ $template->set( 'usereason', $wgUser->isLoggedIn() );
+ $template->set( 'remember', $wgUser->getOption(
'rememberpassword' ) || $this->mRemember );
+ $template->set( 'cansecurelogin', ( $wgSecureLogin === true ) );
+ $template->set( 'stickHTTPS', $this->mStickHTTPS );
+
+
+ if ( !self::getCreateaccountToken() ) {
+ self::setCreateaccountToken();
+ }
+ $template->set( 'token', self::getCreateaccountToken() );
+
+
+ # Prepare language selection links as needed
+ if( $wgLoginLanguageSelector ) {
+ $template->set( 'languages',
$this->makeLanguageSelector() );
+ if( $this->mLanguage )
+ $template->set( 'uselang', $this->mLanguage );
+ }
+
+ // Give authentication and captcha plugins a chance to modify
the form
+ $wgAuth->modifyUITemplate( $template, $this->mType );
+
+ wfRunHooks( 'UserCreateForm', array( &$template ) );
+
+
+ // Changes the title depending on permissions for creating
account
+ if ( $wgUser->isAllowed( 'createaccount' ) ) {
+ $wgOut->setPageTitle( wfMsg( 'userlogin' ) );
+ } else {
+ $wgOut->setPageTitle( wfMsg( 'userloginnocreate' ) );
+ }
+
+ $wgOut->disallowUserJs(); // just in case...
+ $wgOut->addTemplate( $template );
+ }
+
+ /**
+ * @private
+ *
+ * @param $mUserser User
+ *
+ * @return Boolean
+ */
+ function showCreateOrLoginLink( &$mUserser ) {
+ if( $this->mType == 'signup' ) {
+ return true;
+ } elseif( $mUserser->isAllowed( 'createaccount' ) ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Check if a session cookie is present.
+ *
+ * This will not pick up a cookie set during _this_ request, but is
meant
+ * to ensure that the client is returning the cookie which was set on a
+ * previous pass through the system.
+ *
+ * @private
+ */
+ function hasSessionCookie() {
+ global $wgDisableCookieCheck, $wgRequest;
+ return $wgDisableCookieCheck ? true :
$wgRequest->checkSessionCookie();
+ }
+
+ /**
+ * Get the createaccount token from the current session
+ */
+ public static function getCreateaccountToken() {
+ global $wgRequest;
+ return $wgRequest->getSessionData( 'wsCreateaccountToken' );
+ }
+
+ /**
+ * Randomly generate a new createaccount token and attach it to the
current session
+ */
+ public static function setCreateaccountToken() {
+ global $wgRequest;
+ $wgRequest->setSessionData( 'wsCreateaccountToken',
User::generateToken() );
+ }
+
+ /**
+ * Remove any createaccount token attached to the current session
+ */
+ public static function clearCreateaccountToken() {
+ global $wgRequest;
+ $wgRequest->setSessionData( 'wsCreateaccountToken', null );
+ }
+
+ /**
+ * @private
+ */
+ function cookieRedirectCheck( $type ) {
+ global $wgOut;
+
+ $titleObj = SpecialPage::getTitleFor( 'Userlogin' );
+ $query = array( 'wpCookieCheck' => $type );
+ if ( $this->mReturnTo ) {
+ $query['returnto'] = $this->mReturnTo;
+ }
+ $check = $titleObj->getFullURL( $query );
+
+ return $wgOut->redirect( $check );
+ }
+
+ /**
+ * @private
+ */
+ function onCookieRedirectCheck( $type ) {
+ if ( !$this->hasSessionCookie() ) {
+ if ( $type == 'new' ) {
+ return $this->mainSignupForm( wfMsgExt(
'nocookiesnew', array( 'parseinline' ) ) );
+ } elseif ( $type == 'login' ) {
+ return $this->mainSignupForm( wfMsgExt(
'nocookieslogin', array( 'parseinline' ) ) );
+ } else {
+ # shouldn't happen
+ return $this->mainSignupForm( wfMsg( 'error' )
);
+ }
+ } else {
+ return $this->successfulLogin();
+ }
+ }
+
+ /**
+ * Produce a bar of links which allow the user to select another
language
+ * during login/registration but retain "returnto"
+ *
+ * @return string
+ */
+
+ function makeLanguageSelector() {
+ global $wgLang;
+
+ $msg = wfMessage( 'loginlanguagelinks' )->inContentLanguage();
+ if( !$msg->isBlank() ) {
+ $langs = explode( "\n", $msg->text() );
+ $links = array();
+ foreach( $langs as $lang ) {
+ $lang = trim( $lang, '* ' );
+ $parts = explode( '|', $lang );
+ if ( count( $parts ) >= 2 ) {
+ $links[] =
$this->makeLanguageSelectorLink( $parts[0], $parts[1] );
+ }
+ }
+ return count( $links ) > 0 ? wfMsgHtml(
'loginlanguagelabel', $wgLang->pipeList( $links ) ) : '';
+ } else {
+ return '';
+ }
+ }
+
+ /**
+ * Create a language selector link for a particular language
+ * Links back to this page preserving type and returnto
+ *
+ * @param $text Link text
+ * @param $lang Language code
+ */
+ function makeLanguageSelectorLink( $text, $lang ) {
+ global $wgUser;
+ $self = SpecialPage::getTitleFor( 'Userlogin' );
+ $attr = array( 'uselang' => $lang );
+ if( $this->mType == 'signup' ) {
+ $attr['type'] = 'signup';
+ }
+ if( $this->mReturnTo ) {
+ $attr['returnto'] = $this->mReturnTo;
+ }
+ $skin = $wgUser->getSkin();
+ return $skin->linkKnown(
+ $self,
+ htmlspecialchars( $text ),
+ array(),
+ $attr
+ );
+ }
+
+ /**
+ * Display a "login successful" page.
+ */
+ private function displaySuccessfulCreation( $msgname, $injected_html ) {
+ global $wgOut, $wgUser;
+
+ $wgOut->setPageTitle( wfMsg( 'loginsuccesstitle' ) );
+ if( $msgname ){
+ $wgOut->addWikiMsg( $msgname, $wgUser->getName() );
+ }
+
+ $wgOut->addHTML( $injected_html );
+
+ if ( !empty( $this->mReturnTo ) ) {
+ $wgOut->returnToMain( null, $this->mReturnTo,
$this->mReturnToQuery );
+ } else {
+ $wgOut->returnToMain( null );
+ }
+ }
+}
Property changes on: trunk/extensions/SignupAPI/includes/SpecialUserSignup.php
___________________________________________________________________
Added: svn:eol-style
+ native
_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs