/** * Move old stale requests to rejected list. Delete old rejected requests. */ public static function runAutoMaintenance() { global $wgRejectedAccountMaxAge, $wgConfirmAccountRejectAge, $wgConfirmAccountFSRepos; $dbw = wfGetDB(DB_MASTER); $repo = new FSRepo($wgConfirmAccountFSRepos['accountreqs']); # Select all items older than time $encCutoff $encCutoff = $dbw->addQuotes($dbw->timestamp(time() - $wgRejectedAccountMaxAge)); $res = $dbw->select('account_requests', array('acr_id', 'acr_storage_key'), array("acr_rejected < {$encCutoff}"), __METHOD__); # Clear out any associated attachments and delete those rows foreach ($res as $row) { $key = $row->acr_storage_key; if ($key) { $path = $repo->getZonePath('public') . '/' . UserAccountRequest::relPathFromKey($key); if ($path && file_exists($path)) { unlink($path); } } $dbw->delete('account_requests', array('acr_id' => $row->acr_id), __METHOD__); } # Select all items older than time $encCutoff $encCutoff = $dbw->addQuotes($dbw->timestamp(time() - $wgConfirmAccountRejectAge)); # Old stale accounts will count as rejected. If the request was held, give it more time. $dbw->update('account_requests', array('acr_rejected' => $dbw->timestamp(), 'acr_user' => 0, 'acr_comment' => wfMsgForContent('confirmaccount-autorej'), 'acr_deleted' => 1), array("acr_rejected IS NULL", "acr_registration < {$encCutoff}", "acr_held < {$encCutoff} OR acr_held IS NULL"), __METHOD__); # Clear cache for notice of how many account requests there are self::clearAccountRequestCountCache(); }
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); }
/** * Show a private file requested by the visitor. * @param $key string */ protected function showFile($key) { global $wgConfirmAccountFSRepos; $out = $this->getOutput(); $request = $this->getRequest(); $out->disable(); # We mustn't allow the output to be Squid cached, otherwise # if an admin previews a private image, and it's cached, then # a user without appropriate permissions can toddle off and # nab the image, and Squid will serve it $request->response()->header('Expires: ' . gmdate('D, d M Y H:i:s', 0) . ' GMT'); $request->response()->header('Cache-Control: no-cache, no-store, max-age=0, must-revalidate'); $request->response()->header('Pragma: no-cache'); $repo = new FSRepo($wgConfirmAccountFSRepos['accountreqs']); $path = $repo->getZonePath('public') . '/' . UserAccountRequest::relPathFromKey($key); $repo->streamFile($path); }