/** * Adds an user to the database * @param String $sUsername user name * @param String $sPassword password * @param String $sRePassword password confirmation * @param String $sEmail user's e-mail address * @param String $sRealname user's real name * @param Array $aGroups user name * @return string json encoded response */ public static function editUser($sUsername, $sPassword, $sRePassword, $sEmail, $sRealname, $aGroups = array()) { $res = $resDelGroups = $resInsGroups = $resERealUser = false; if (wfReadOnly()) { global $wgReadOnly; return FormatJson::encode(array('success' => false, 'message' => array(wfMessage('bs-readonly', $wgReadOnly)->plain()))); } if (BsCore::checkAccessAdmission('wikiadmin') === false) { return true; } $aAnswer = array('success' => true, 'errors' => array(), 'message' => array()); $oUser = User::newFromName($sUsername); if ($oUser->getId() === 0) { $aAnswer['success'] = false; $aAnswer['message'][] = wfMessage('bs-usermanager-idnotexist')->plain(); // id_noexist = 'This user ID does not exist' } if (!empty($sPassword) && !$oUser->isValidPassword($sPassword)) { $aAnswer['success'] = false; $aAnswer['errors'][] = array('id' => 'pass', 'message' => wfMessage('bs-usermanager-invalid-pwd')->plain()); } if ($sPassword !== $sRePassword) { $aAnswer['success'] = false; $aAnswer['errors'][] = array('id' => 'newpass', 'message' => wfMessage('badretype')->plain()); } if (strpos($sRealname, '\\')) { $aAnswer['success'] = false; $aAnswer['errors'][] = array('id' => 'realname', 'message' => wfMessage('bs-usermanager-invalid-realname')->plain()); } if ($sEmail != '' && Sanitizer::validateEmail($sEmail) === false) { $aAnswer['success'] = false; $aAnswer['errors'][] = array('id' => 'email', 'message' => wfMessage('bs-usermanager-invalid-email-gen')->plain()); } global $wgUser; if ($wgUser->getId() == $oUser->getId() && in_array('sysop', $wgUser->getEffectiveGroups()) && !in_array('sysop', $aGroups)) { $aAnswer['success'] = false; $aAnswer['errors'][] = array('id' => 'groups', 'message' => wfMessage('bs-usermanager-no-self-desysop')->plain()); } $dbw = wfGetDB(DB_MASTER); if ($aAnswer['success']) { if (!empty($sPassword)) { $res = $dbw->update('user', array('user_password' => User::crypt($sPassword)), array('user_id' => $oUser->getId())); } else { $res = true; } $resDelGroups = $dbw->delete('user_groups', array('ug_user' => $oUser->getId())); $resInsGroups = true; if (is_array($aGroups)) { foreach ($aGroups as $sGroup) { if (in_array($sGroup, self::$excludegroups)) { continue; } $resInsGroups = $dbw->insert('user_groups', array('ug_user' => $oUser->getId(), 'ug_group' => addslashes($sGroup))); } } $resERealUser = $dbw->update('user', array('user_real_name' => $sRealname, 'user_email' => $sEmail), array('user_id' => $oUser->getId())); $oUser->invalidateCache(); } if ($res === false || $resDelGroups === false || !$resInsGroups || $resERealUser === false) { $aAnswer['success'] = false; $aAnswer['message'][] = wfMessage('bs-usermanager-db-error')->plain(); } if ($aAnswer['success']) { $aAnswer['message'][] = wfMessage('bs-usermanager-save-successful')->plain(); } return FormatJson::encode($aAnswer); }
protected function acceptRequest(IContextSource $context) { global $wgAuth, $wgAccountRequestTypes, $wgConfirmAccountSaveInfo; global $wgAllowAccountRequestFiles, $wgConfirmAccountFSRepos; $accReq = $this->accountReq; // convenience # Now create user and check if the name is valid $user = User::newFromName($this->userName, 'creatable'); if (!$user) { return array('accountconf_invalid_name', wfMsgHtml('noname')); } # Check if account name is already in use if (0 != $user->idForName() || $wgAuth->userExists($user->getName())) { return array('accountconf_user_exists', wfMsgHtml('userexists')); } $dbw = wfGetDB(DB_MASTER); $dbw->begin(); # Make a random password $p = User::randomPassword(); # Insert the new user into the DB... $tokenExpires = $accReq->getEmailTokenExpires(); $authenticated = $accReq->getEmailAuthTimestamp(); $params = array('real_name' => $accReq->getRealName(), 'newpassword' => User::crypt($p), 'email' => $accReq->getEmail(), 'email_authenticated' => $dbw->timestampOrNull($authenticated), 'email_token_expires' => $dbw->timestamp($tokenExpires), 'email_token' => $accReq->getEmailToken()); $user = User::createNew($user->getName(), $params); # Grant any necessary rights (exclude blank or dummy groups) $group = self::getGroupFromType($this->type); if ($group != '' && $group != 'user' && $group != '*') { $user->addGroup($group); } $acd_id = null; // used for rollback cleanup # Save account request data to credentials system if ($wgConfirmAccountSaveInfo) { $key = $accReq->getFileStorageKey(); # Copy any attached files to new storage group if ($wgAllowAccountRequestFiles && $key) { $repoOld = new FSRepo($wgConfirmAccountFSRepos['accountreqs']); $repoNew = new FSRepo($wgConfirmAccountFSRepos['accountcreds']); $pathRel = UserAccountRequest::relPathFromKey($key); $oldPath = $repoOld->getZonePath('public') . '/' . $pathRel; $triplet = array($oldPath, 'public', $pathRel); $status = $repoNew->storeBatch(array($triplet)); // copy! if (!$status->isOK()) { $dbw->rollback(); # DELETE new rows in case there was a COMMIT somewhere $this->acceptRequest_rollback($dbw, $user->getId(), $acd_id); return array('accountconf_copyfailed', $context->getOutput()->parse($status->getWikiText())); } } $acd_id = $dbw->nextSequenceValue('account_credentials_acd_id_seq'); # Move request data into a separate table $dbw->insert('account_credentials', array('acd_user_id' => $user->getID(), 'acd_real_name' => $accReq->getRealName(), 'acd_email' => $accReq->getEmail(), 'acd_email_authenticated' => $dbw->timestampOrNull($authenticated), 'acd_bio' => $accReq->getBio(), 'acd_notes' => $accReq->getNotes(), 'acd_urls' => $accReq->getUrls(), 'acd_ip' => $accReq->getIP(), 'acd_filename' => $accReq->getFileName(), 'acd_storage_key' => $accReq->getFileStorageKey(), 'acd_areas' => $accReq->getAreas('flat'), 'acd_registration' => $dbw->timestamp($accReq->getRegistration()), 'acd_accepted' => $dbw->timestamp(), 'acd_user' => $this->admin->getID(), 'acd_comment' => $this->reason, 'acd_id' => $acd_id), __METHOD__); if (is_null($acd_id)) { $acd_id = $dbw->insertId(); // set $acd_id to ID inserted } } # Add to global user login system (if there is one) if (!$wgAuth->addUser($user, $p, $accReq->getEmail(), $accReq->getRealName())) { $dbw->rollback(); # DELETE new rows in case there was a COMMIT somewhere $this->acceptRequest_rollback($dbw, $user->getId(), $acd_id); return array('accountconf_externaldberror', wfMsgHtml('externaldberror')); } # OK, now remove the request from the queue $accReq->remove(); # Commit this if we make past the CentralAuth system # and the groups are added. Next step is sending out an # email, which we cannot take back... $dbw->commit(); # Prepare a temporary password email... if ($this->reason != '') { $msg = "confirmaccount-email-body2-pos{$this->type}"; # If the user is in a group and there is a welcome for that group, use it if ($group && !wfEmptyMsg($msg)) { $ebody = wfMsgExt($msg, array('parsemag', 'content'), $user->getName(), $p, $this->reason); # Use standard if none found... } else { $ebody = wfMsgExt('confirmaccount-email-body2', array('parsemag', 'content'), $user->getName(), $p, $this->reason); } } else { $msg = "confirmaccount-email-body-pos{$this->type}"; # If the user is in a group and there is a welcome for that group, use it if ($group && !wfEmptyMsg($msg)) { $ebody = wfMsgExt($msg, array('parsemag', 'content'), $user->getName(), $p, $this->reason); # Use standard if none found... } else { $ebody = wfMsgExt('confirmaccount-email-body', array('parsemag', 'content'), $user->getName(), $p, $this->reason); } } # Actually send out the email (@TODO: rollback on failure including $wgAuth) $result = $user->sendMail(wfMsgForContent('confirmaccount-email-subj'), $ebody); /* if ( !$result->isOk() ) { # DELETE new rows in case there was a COMMIT somewhere $this->acceptRequest_rollback( $dbw, $user->getId(), $acd_id ); return array( 'accountconf_mailerror', wfMsg( 'mailerror', $context->getOutput()->parse( $result->getWikiText() ) ) ); } */ # Update user count $ssUpdate = new SiteStatsUpdate(0, 0, 0, 0, 1); $ssUpdate->doUpdate(); # Safe to hook/log now... wfRunHooks('AddNewAccount', array($user, false)); $user->addNewUserLogEntry(); # Clear cache for notice of how many account requests there are ConfirmAccount::clearAccountRequestCountCache(); # Delete any attached file and don't stop the whole process if this fails if ($wgAllowAccountRequestFiles) { $key = $accReq->getFileStorageKey(); if ($key) { $repoOld = new FSRepo($wgConfirmAccountFSRepos['accountreqs']); $pathRel = UserAccountRequest::relPathFromKey($key); $oldPath = $repoOld->getZonePath('public') . '/' . $pathRel; if (file_exists($oldPath)) { unlink($oldPath); // delete! } } } # Start up the user's userpages if set to do so. # Will not append, so previous content will be blanked. $this->createUserPage($user); # Greet the new user if set to do so. $this->createUserTalkPage($user); return array(true, null); }
/** * Salt and hash a new plaintext password. * @param string $password plaintext * @return array of strings, salt and hash */ protected function saltedPassword($password) { return array('', User::crypt($password)); }