/** * @param ValueObject $other * * @return bool */ public function sameValueAs(Password $other) { if (!$other instanceof self) { return false; } return $this->toString() === $other->toString(); }
/** * Add this existing user object to the database. If the user already * exists, a fatal status object is returned, and the user object is * initialised with the data from the database. * * Previously, this function generated a DB error due to a key conflict * if the user already existed. Many extension callers use this function * in code along the lines of: * * $user = User::newFromName( $name ); * if ( !$user->isLoggedIn() ) { * $user->addToDatabase(); * } * // do something with $user... * * However, this was vulnerable to a race condition (bug 16020). By * initialising the user object if the user exists, we aim to support this * calling sequence as far as possible. * * Note that if the user exists, this function will acquire a write lock, * so it is still advisable to make the call conditional on isLoggedIn(), * and to commit the transaction after calling. * * @throws MWException * @return Status */ public function addToDatabase() { $this->load(); $this->loadPasswords(); if (!$this->mToken) { $this->setToken(); // init token } $this->mTouched = $this->newTouchedTimestamp(); $dbw = wfGetDB(DB_MASTER); $inWrite = $dbw->writesOrCallbacksPending(); $seqVal = $dbw->nextSequenceValue('user_user_id_seq'); $dbw->insert('user', array('user_id' => $seqVal, 'user_name' => $this->mName, 'user_password' => $this->mPassword->toString(), 'user_newpassword' => $this->mNewpassword->toString(), 'user_newpass_time' => $dbw->timestampOrNull($this->mNewpassTime), 'user_email' => $this->mEmail, 'user_email_authenticated' => $dbw->timestampOrNull($this->mEmailAuthenticated), 'user_real_name' => $this->mRealName, 'user_token' => strval($this->mToken), 'user_registration' => $dbw->timestamp($this->mRegistration), 'user_editcount' => 0, 'user_touched' => $dbw->timestamp($this->mTouched)), __METHOD__, array('IGNORE')); if (!$dbw->affectedRows()) { // The queries below cannot happen in the same REPEATABLE-READ snapshot. // Handle this by COMMIT, if possible, or by LOCK IN SHARE MODE otherwise. if ($inWrite) { // Can't commit due to pending writes that may need atomicity. // This may cause some lock contention unlike the case below. $options = array('LOCK IN SHARE MODE'); $flags = self::READ_LOCKING; } else { // Often, this case happens early in views before any writes when // using CentralAuth. It's should be OK to commit and break the snapshot. $dbw->commit(__METHOD__, 'flush'); $options = array(); $flags = self::READ_LATEST; } $this->mId = $dbw->selectField('user', 'user_id', array('user_name' => $this->mName), __METHOD__, $options); $loaded = false; if ($this->mId) { if ($this->loadFromDatabase($flags)) { $loaded = true; } } if (!$loaded) { throw new MWException(__METHOD__ . ": hit a key conflict attempting " . "to insert user '{$this->mName}' row, but it was not present in select!"); } return Status::newFatal('userexists'); } $this->mId = $dbw->insertId(); // Clear instance cache other than user table data, which is already accurate $this->clearInstanceCache(); $this->saveOptions(); return Status::newGood(); }
/** * @param Password $other * * @return bool */ public function sameValueAs(Password $other) { return $this->toString() === $other->toString(); }
/** * Save the BotPassword to the database * @param string $operation 'update' or 'insert' * @param Password|null $password Password to set. * @return bool Success */ public function save($operation, Password $password = null) { $conds = array('bp_user' => $this->centralId, 'bp_app_id' => $this->appId); $fields = array('bp_token' => MWCryptRand::generateHex(User::TOKEN_LENGTH), 'bp_restrictions' => $this->restrictions->toJson(), 'bp_grants' => FormatJson::encode($this->grants)); if ($password !== null) { $fields['bp_password'] = $password->toString(); } elseif ($operation === 'insert') { $fields['bp_password'] = PasswordFactory::newInvalidPassword()->toString(); } $dbw = self::getDB(DB_MASTER); switch ($operation) { case 'insert': $dbw->insert('bot_passwords', $fields + $conds, __METHOD__, array('IGNORE')); break; case 'update': $dbw->update('bot_passwords', $fields, $conds, __METHOD__); break; default: return false; } $ok = (bool) $dbw->affectedRows(); if ($ok) { $this->token = $dbw->selectField('bot_passwords', 'bp_token', $conds, __METHOD__); $this->isSaved = true; } return $ok; }
/** @test */ public function should_return_as_string() { $password = new Password('qwertyuiop'); $this->assertEquals('qwertyuiop', $password->toString()); }