X-Git-Url: https://scripts.mit.edu/gitweb/autoinstallsdev/mediawiki.git/blobdiff_plain/19e297c21b10b1b8a3acad5e73fc71dcb35db44a..6932310fd58ebef145fa01eb76edf7150284d8ea:/includes/auth/ResetPasswordSecondaryAuthenticationProvider.php diff --git a/includes/auth/ResetPasswordSecondaryAuthenticationProvider.php b/includes/auth/ResetPasswordSecondaryAuthenticationProvider.php new file mode 100644 index 00000000..45ac3aa0 --- /dev/null +++ b/includes/auth/ResetPasswordSecondaryAuthenticationProvider.php @@ -0,0 +1,133 @@ +manager->setAuthenticationSessionData() + * + * The authentication data key is 'reset-pass'; the data is an object with the + * following properties: + * - msg: Message object to display to the user + * - hard: Boolean, if true the reset cannot be skipped. + * - req: Optional PasswordAuthenticationRequest to use to actually reset the + * password. Won't be displayed to the user. + * + * @ingroup Auth + * @since 1.27 + */ +class ResetPasswordSecondaryAuthenticationProvider extends AbstractSecondaryAuthenticationProvider { + + public function getAuthenticationRequests( $action, array $options ) { + return []; + } + + public function beginSecondaryAuthentication( $user, array $reqs ) { + return $this->tryReset( $user, $reqs ); + } + + public function continueSecondaryAuthentication( $user, array $reqs ) { + return $this->tryReset( $user, $reqs ); + } + + public function beginSecondaryAccountCreation( $user, $creator, array $reqs ) { + return $this->tryReset( $user, $reqs ); + } + + public function continueSecondaryAccountCreation( $user, $creator, array $reqs ) { + return $this->tryReset( $user, $reqs ); + } + + /** + * Try to reset the password + * @param \User $user + * @param AuthenticationRequest[] $reqs + * @return AuthenticationResponse + */ + protected function tryReset( \User $user, array $reqs ) { + $data = $this->manager->getAuthenticationSessionData( 'reset-pass' ); + if ( !$data ) { + return AuthenticationResponse::newAbstain(); + } + + if ( is_array( $data ) ) { + $data = (object)$data; + } + if ( !is_object( $data ) ) { + throw new \UnexpectedValueException( 'reset-pass is not valid' ); + } + + if ( !isset( $data->msg ) ) { + throw new \UnexpectedValueException( 'reset-pass msg is missing' ); + } elseif ( !$data->msg instanceof \Message ) { + throw new \UnexpectedValueException( 'reset-pass msg is not valid' ); + } elseif ( !isset( $data->hard ) ) { + throw new \UnexpectedValueException( 'reset-pass hard is missing' ); + } elseif ( isset( $data->req ) && ( + !$data->req instanceof PasswordAuthenticationRequest || + !array_key_exists( 'retype', $data->req->getFieldInfo() ) + ) ) { + throw new \UnexpectedValueException( 'reset-pass req is not valid' ); + } + + if ( !$data->hard ) { + $req = ButtonAuthenticationRequest::getRequestByName( $reqs, 'skipReset' ); + if ( $req ) { + $this->manager->removeAuthenticationSessionData( 'reset-pass' ); + return AuthenticationResponse::newPass(); + } + } + + $needReq = isset( $data->req ) ? $data->req : new PasswordAuthenticationRequest(); + if ( !$needReq->action ) { + $needReq->action = AuthManager::ACTION_CHANGE; + } + $needReq->required = $data->hard ? AuthenticationRequest::REQUIRED + : AuthenticationRequest::OPTIONAL; + $needReqs = [ $needReq ]; + if ( !$data->hard ) { + $needReqs[] = new ButtonAuthenticationRequest( + 'skipReset', + wfMessage( 'authprovider-resetpass-skip-label' ), + wfMessage( 'authprovider-resetpass-skip-help' ) + ); + } + + $req = AuthenticationRequest::getRequestByClass( $reqs, get_class( $needReq ) ); + if ( !$req || !array_key_exists( 'retype', $req->getFieldInfo() ) ) { + return AuthenticationResponse::newUI( $needReqs, $data->msg, 'warning' ); + } + + if ( $req->password !== $req->retype ) { + return AuthenticationResponse::newUI( $needReqs, new \Message( 'badretype' ), 'error' ); + } + + $req->username = $user->getName(); + $status = $this->manager->allowsAuthenticationDataChange( $req ); + if ( !$status->isGood() ) { + return AuthenticationResponse::newUI( $needReqs, $status->getMessage(), 'error' ); + } + $this->manager->changeAuthenticationData( $req ); + + $this->manager->removeAuthenticationSessionData( 'reset-pass' ); + return AuthenticationResponse::newPass(); + } +}