コード例 #1
0
 public function provideAccountLink()
 {
     $req = $this->getMockForAbstractClass(AuthenticationRequest::class);
     $good = StatusValue::newGood();
     return ['Pre-link test fail in pre' => [StatusValue::newFatal('fail-from-pre'), [], [AuthenticationResponse::newFail($this->message('fail-from-pre'))]], 'Failure in primary' => [$good, $tmp = [AuthenticationResponse::newFail($this->message('fail-from-primary'))], $tmp], 'All primary abstain' => [$good, [AuthenticationResponse::newAbstain()], [AuthenticationResponse::newFail($this->message('authmanager-link-no-primary'))]], 'Primary UI, then redirect, then fail' => [$good, $tmp = [AuthenticationResponse::newUI([$req], $this->message('...')), AuthenticationResponse::newRedirect([$req], '/foo.html', ['foo' => 'bar']), AuthenticationResponse::newFail($this->message('fail-in-primary-continue'))], $tmp], 'Primary redirect, then abstain' => [$good, [$tmp = AuthenticationResponse::newRedirect([$req], '/foo.html', ['foo' => 'bar']), AuthenticationResponse::newAbstain()], [$tmp, new \DomainException('MockPrimaryAuthenticationProvider::continuePrimaryAccountLink() returned ABSTAIN')]], 'Primary UI, then pass' => [$good, [$tmp1 = AuthenticationResponse::newUI([$req], $this->message('...')), AuthenticationResponse::newPass()], [$tmp1, AuthenticationResponse::newPass('')]], 'Primary pass' => [$good, [AuthenticationResponse::newPass('')], [AuthenticationResponse::newPass('')]]];
 }
 /**
  * Continue the link attempt
  * @param User $user
  * @param string $key Session key to look in
  * @param AuthenticationRequest[] $reqs
  * @return AuthenticationResponse
  */
 protected function continueLinkAttempt($user, $key, array $reqs)
 {
     $req = ButtonAuthenticationRequest::getRequestByName($reqs, 'linkOk');
     if ($req) {
         return AuthenticationResponse::newPass();
     }
     $req = AuthenticationRequest::getRequestByClass($reqs, ConfirmLinkAuthenticationRequest::class);
     if (!$req) {
         // WTF? Retry.
         return $this->beginLinkAttempt($user, $key);
     }
     $session = $this->manager->getRequest()->getSession();
     $state = $session->getSecret($key);
     if (!is_array($state)) {
         return AuthenticationResponse::newAbstain();
     }
     $maybeLink = [];
     foreach ($state['maybeLink'] as $linkReq) {
         $maybeLink[$linkReq->getUniqueId()] = $linkReq;
     }
     if (!$maybeLink) {
         return AuthenticationResponse::newAbstain();
     }
     $state['maybeLink'] = [];
     $session->setSecret($key, $state);
     $statuses = [];
     $anyFailed = false;
     foreach ($req->confirmedLinkIDs as $id) {
         if (isset($maybeLink[$id])) {
             $req = $maybeLink[$id];
             $req->username = $user->getName();
             if (!$req->action) {
                 // Make sure the action is set, but don't override it if
                 // the provider filled it in.
                 $req->action = AuthManager::ACTION_CHANGE;
             }
             $status = $this->manager->allowsAuthenticationDataChange($req);
             $statuses[] = [$req, $status];
             if ($status->isGood()) {
                 $this->manager->changeAuthenticationData($req);
             } else {
                 $anyFailed = true;
             }
         }
     }
     if (!$anyFailed) {
         return AuthenticationResponse::newPass();
     }
     $combinedStatus = \Status::newGood();
     foreach ($statuses as $data) {
         list($req, $status) = $data;
         $descriptionInfo = $req->describeCredentials();
         $description = wfMessage('authprovider-confirmlink-option', $descriptionInfo['provider']->text(), $descriptionInfo['account']->text())->text();
         if ($status->isGood()) {
             $combinedStatus->error(wfMessage('authprovider-confirmlink-success-line', $description));
         } else {
             $combinedStatus->error(wfMessage('authprovider-confirmlink-failure-line', $description, $status->getMessage()->text()));
         }
     }
     return AuthenticationResponse::newUI([new ButtonAuthenticationRequest('linkOk', wfMessage('ok'), wfMessage('authprovider-confirmlink-ok-help'))], $combinedStatus->getMessage('authprovider-confirmlink-failed'));
 }
コード例 #3
0
ファイル: AuthManager.php プロジェクト: claudinec/galan-wiki
 /**
  * Start an account creation flow
  * @param User $creator User doing the account creation
  * @param AuthenticationRequest[] $reqs
  * @param string $returnToUrl Url that REDIRECT responses should eventually
  *  return to.
  * @return AuthenticationResponse
  */
 public function beginAccountCreation(User $creator, array $reqs, $returnToUrl)
 {
     $session = $this->request->getSession();
     if (!$this->canCreateAccounts()) {
         // Caller should have called canCreateAccounts()
         $session->remove('AuthManager::accountCreationState');
         throw new \LogicException('Account creation is not possible');
     }
     try {
         $username = AuthenticationRequest::getUsernameFromRequests($reqs);
     } catch (\UnexpectedValueException $ex) {
         $username = null;
     }
     if ($username === null) {
         $this->logger->debug(__METHOD__ . ': No username provided');
         return AuthenticationResponse::newFail(wfMessage('noname'));
     }
     // Permissions check
     $status = $this->checkAccountCreatePermissions($creator);
     if (!$status->isGood()) {
         $this->logger->debug(__METHOD__ . ': {creator} cannot create users: {reason}', ['user' => $username, 'creator' => $creator->getName(), 'reason' => $status->getWikiText(null, null, 'en')]);
         return AuthenticationResponse::newFail($status->getMessage());
     }
     $status = $this->canCreateAccount($username, User::READ_LOCKING);
     if (!$status->isGood()) {
         $this->logger->debug(__METHOD__ . ': {user} cannot be created: {reason}', ['user' => $username, 'creator' => $creator->getName(), 'reason' => $status->getWikiText(null, null, 'en')]);
         return AuthenticationResponse::newFail($status->getMessage());
     }
     $user = User::newFromName($username, 'creatable');
     foreach ($reqs as $req) {
         $req->username = $username;
         $req->returnToUrl = $returnToUrl;
         if ($req instanceof UserDataAuthenticationRequest) {
             $status = $req->populateUser($user);
             if (!$status->isGood()) {
                 $status = Status::wrap($status);
                 $session->remove('AuthManager::accountCreationState');
                 $this->logger->debug(__METHOD__ . ': UserData is invalid: {reason}', ['user' => $user->getName(), 'creator' => $creator->getName(), 'reason' => $status->getWikiText(null, null, 'en')]);
                 return AuthenticationResponse::newFail($status->getMessage());
             }
         }
     }
     $this->removeAuthenticationSessionData(null);
     $state = ['username' => $username, 'userid' => 0, 'creatorid' => $creator->getId(), 'creatorname' => $creator->getName(), 'reqs' => $reqs, 'returnToUrl' => $returnToUrl, 'primary' => null, 'primaryResponse' => null, 'secondary' => [], 'continueRequests' => [], 'maybeLink' => [], 'ranPreTests' => false];
     // Special case: converting a login to an account creation
     $req = AuthenticationRequest::getRequestByClass($reqs, CreateFromLoginAuthenticationRequest::class);
     if ($req) {
         $state['maybeLink'] = $req->maybeLink;
         // If we get here, the user didn't submit a form with any of the
         // usual AuthenticationRequests that are needed for an account
         // creation. So we need to determine if there are any and return a
         // UI response if so.
         if ($req->createRequest) {
             // We have a createRequest from a
             // PrimaryAuthenticationProvider, so don't ask.
             $providers = $this->getPreAuthenticationProviders() + $this->getSecondaryAuthenticationProviders();
         } else {
             // We're only preserving maybeLink, so ask for primary fields
             // too.
             $providers = $this->getPreAuthenticationProviders() + $this->getPrimaryAuthenticationProviders() + $this->getSecondaryAuthenticationProviders();
         }
         $reqs = $this->getAuthenticationRequestsInternal(self::ACTION_CREATE, [], $providers);
         // See if we need any requests to begin
         foreach ((array) $reqs as $r) {
             if (!$r instanceof UsernameAuthenticationRequest && !$r instanceof UserDataAuthenticationRequest && !$r instanceof CreationReasonAuthenticationRequest) {
                 // Needs some reqs, so request them
                 $reqs[] = new CreateFromLoginAuthenticationRequest($req->createRequest, []);
                 $state['continueRequests'] = $reqs;
                 $session->setSecret('AuthManager::accountCreationState', $state);
                 $session->persist();
                 return AuthenticationResponse::newUI($reqs, wfMessage('authmanager-create-from-login'));
             }
         }
         // No reqs needed, so we can just continue.
         $req->createRequest->returnToUrl = $returnToUrl;
         $reqs = [$req->createRequest];
     }
     $session->setSecret('AuthManager::accountCreationState', $state);
     $session->persist();
     return $this->continueAccountCreation($reqs);
 }