23use UnexpectedValueException;
35 private string $messageFormat;
47 private readonly
ApiBase $module,
51 $params = $module->extractRequestParams();
52 $this->messageFormat = $params[
'messageformat'] ??
'wikitext';
65 return new self( $module, $authManager );
74 private function formatMessage( array &$res, $key,
Message $message ) {
75 switch ( $this->messageFormat ) {
80 $res[$key] = $message->
setContext( $this->module )->text();
84 $res[$key] = $message->
setContext( $this->module )->parseAsBlock();
85 $res[$key] = Parser::stripOuterParagraph( $res[$key] );
91 'key' => $message->
getKey(),
105 $status = $this->authManager->securitySensitiveOperationStatus( $operation );
107 case AuthManager::SEC_OK:
110 case AuthManager::SEC_REAUTH:
111 $this->module->dieWithError( [
'apierror-reauthenticate', $operation ],
112 null, [
'operation' => $operation ] );
115 case AuthManager::SEC_FAIL:
116 $this->module->dieWithError(
'apierror-cannotreauthenticate' );
120 throw new UnexpectedValueException(
"Unknown status \"$status\"" );
132 $remove = array_fill_keys( $remove,
true );
133 $reqs = array_filter( $reqs,
static function ( $req ) use ( $remove ) {
134 return !isset( $remove[get_class( $req )] );
147 $params = $this->module->extractRequestParams();
149 $reqs = $this->authManager->getAuthenticationRequests( $action, $this->module->getUser(), $options );
152 $wantedRequests =
null;
153 if ( isset( $params[
'requests'] ) ) {
154 $wantedRequests = array_fill_keys( $params[
'requests'],
true );
155 } elseif ( isset( $params[
'request'] ) ) {
156 $wantedRequests = [ $params[
'request'] => true ];
158 if ( $wantedRequests !==
null ) {
159 $reqs = array_filter(
162 return isset( $wantedRequests[$req->
getUniqueId()] );
170 foreach ( $reqs as $req ) {
171 $info = (array)$req->getFieldInfo();
173 $sensitive += array_filter( $info,
static function ( $opts ) {
174 return !empty( $opts[
'sensitive'] );
180 $data = array_intersect_key( $this->module->getRequest()->getValues(), $fields );
181 $this->module->getMain()->markParamsUsed( array_keys( $data ) );
184 $this->module->getMain()->markParamsSensitive( array_keys( $sensitive ) );
185 $this->module->requirePostedParameters( array_keys( $sensitive ),
'noprefix' );
188 return AuthenticationRequest::loadRequestsFromSubmission( $reqs, $data );
198 'status' => $res->status,
201 if ( $res->status === AuthenticationResponse::PASS && $res->username !==
null ) {
202 $ret[
'username'] = $res->username;
205 if ( $res->status === AuthenticationResponse::REDIRECT ) {
206 $ret[
'redirecttarget'] = $res->redirectTarget;
207 if ( $res->redirectApiData !==
null ) {
208 $ret[
'redirectdata'] = $res->redirectApiData;
212 if ( $res->status === AuthenticationResponse::REDIRECT ||
213 $res->status === AuthenticationResponse::UI ||
214 $res->status === AuthenticationResponse::RESTART
219 if ( $res->status === AuthenticationResponse::FAIL ||
220 $res->status === AuthenticationResponse::UI ||
221 $res->status === AuthenticationResponse::RESTART
224 $this->formatMessage( $ret,
'message', $res->message );
228 if ( $res->status === AuthenticationResponse::FAIL ||
229 $res->status === AuthenticationResponse::RESTART
231 $this->module->getRequest()->getSession()->set(
232 'ApiAuthManagerHelper::createRequest',
235 $ret[
'canpreservestate'] = $res->createRequest !==
null;
237 $this->module->getRequest()->getSession()->remove(
'ApiAuthManagerHelper::createRequest' );
250 if ( !in_array( $result->status, [ AuthenticationResponse::PASS, AuthenticationResponse::FAIL ] ) ) {
253 $accountType = $this->identityUtils->getShortUserTypeInternal( $performer );
255 $module = $this->module->getModuleName();
256 LoggerFactory::getInstance(
'authevents' )->info(
"$module API attempt", [
258 'successful' => $result->status === AuthenticationResponse::PASS,
259 'status' => $result->message ? $result->message->getKey() :
'-',
260 'accountType' => $accountType,
270 $ret = $this->module->getRequest()->getSession()->get(
'ApiAuthManagerHelper::createRequest' );
281 $params = $this->module->extractRequestParams();
282 $mergeFields = !empty( $params[
'mergerequestfields'] );
284 $ret = [
'requests' => [] ];
285 foreach ( $reqs as $req ) {
286 $describe = $req->describeCredentials();
288 'id' => $req->getUniqueId(),
291 switch ( $req->required ) {
292 case AuthenticationRequest::OPTIONAL:
293 $reqInfo[
'required'] =
'optional';
295 case AuthenticationRequest::REQUIRED:
296 $reqInfo[
'required'] =
'required';
298 case AuthenticationRequest::PRIMARY_REQUIRED:
299 $reqInfo[
'required'] =
'primary-required';
302 $this->formatMessage( $reqInfo,
'provider', $describe[
'provider'] );
303 $this->formatMessage( $reqInfo,
'account', $describe[
'account'] );
304 if ( !$mergeFields ) {
305 $reqInfo[
'fields'] = $this->formatFields( (array)$req->getFieldInfo() );
307 $ret[
'requests'][] = $reqInfo;
310 if ( $mergeFields ) {
311 $fields = AuthenticationRequest::mergeFieldInfo( $reqs );
312 $ret[
'fields'] = $this->formatFields( $fields );
325 private function formatFields( array $fields ) {
331 $module = $this->module;
334 foreach ( $fields as $name => $field ) {
335 $ret = array_intersect_key( $field, $copy );
337 if ( isset( $field[
'options'] ) ) {
338 $ret[
'options'] = array_map(
static function ( $msg ) use ( $module ) {
339 return $msg->setContext( $module )->plain();
340 }, $field[
'options'] );
343 $this->formatMessage( $ret,
'label', $field[
'label'] ??
new RawMessage(
'' ) );
344 $this->formatMessage( $ret,
'help', $field[
'help'] );
345 $ret[
'optional'] = !empty( $field[
'optional'] );
346 $ret[
'sensitive'] = !empty( $field[
'sensitive'] );
348 $retFields[$name] = $ret;
365 ParamValidator::PARAM_TYPE =>
'string',
366 ParamValidator::PARAM_ISMULTI =>
true,
370 ParamValidator::PARAM_TYPE =>
'string',
371 ParamValidator::PARAM_REQUIRED =>
true,
375 ParamValidator::PARAM_DEFAULT =>
'wikitext',
376 ParamValidator::PARAM_TYPE => [
'html',
'wikitext',
'raw',
'none' ],
379 'mergerequestfields' => [
380 ParamValidator::PARAM_DEFAULT =>
false,
384 ParamValidator::PARAM_DEFAULT =>
false,
388 ParamValidator::PARAM_TYPE =>
'string',
392 ParamValidator::PARAM_DEFAULT =>
false,
398 foreach ( $wantedParams as $name ) {
399 if ( isset( $params[$name] ) ) {
400 $ret[$name] = $params[$name];
408class_alias( ApiAuthManagerHelper::class,
'ApiAuthManagerHelper' );