51 $this->messageFormat = $params[
'messageformat'] ??
'wikitext';
70 switch ( $this->messageFormat ) {
79 $res[$key] = $message->
setContext( $this->module )->parseAsBlock();
80 $res[$key] = Parser::stripOuterParagraph(
$res[$key] );
85 'key' => $message->
getKey(),
99 $status = AuthManager::singleton()->securitySensitiveOperationStatus( $operation );
101 case AuthManager::SEC_OK:
104 case AuthManager::SEC_REAUTH:
105 $this->module->dieWithError(
'apierror-reauthenticate' );
107 case AuthManager::SEC_FAIL:
108 $this->module->dieWithError(
'apierror-cannotreauthenticate' );
111 throw new UnexpectedValueException(
"Unknown status \"$status\"" );
123 $blacklist = array_flip( $blacklist );
124 $reqs = array_filter( $reqs,
function ( $req ) use ( $blacklist ) {
125 return !isset( $blacklist[get_class( $req )] );
137 $params = $this->module->extractRequestParams();
139 $manager = AuthManager::singleton();
140 $reqs = $manager->getAuthenticationRequests( $action, $this->module->getUser() );
143 $wantedRequests =
null;
144 if ( isset( $params[
'requests'] ) ) {
145 $wantedRequests = array_flip( $params[
'requests'] );
146 } elseif ( isset( $params[
'request'] ) ) {
147 $wantedRequests = [ $params[
'request'] =>
true ];
149 if ( $wantedRequests !==
null ) {
150 $reqs = array_filter( $reqs,
function ( $req ) use ( $wantedRequests ) {
151 return isset( $wantedRequests[$req->getUniqueId()] );
158 foreach ( $reqs as $req ) {
159 $info = (array)$req->getFieldInfo();
161 $sensitive += array_filter( $info,
function ( $opts ) {
162 return !empty( $opts[
'sensitive'] );
168 $data = array_intersect_key( $this->module->getRequest()->getValues(), $fields );
169 $this->module->getMain()->markParamsUsed( array_keys( $data ) );
172 $this->module->getMain()->markParamsSensitive( array_keys( $sensitive ) );
173 $this->module->requirePostedParameters( array_keys( $sensitive ),
'noprefix' );
176 return AuthenticationRequest::loadRequestsFromSubmission( $reqs, $data );
186 'status' =>
$res->status,
189 if (
$res->status === AuthenticationResponse::PASS &&
$res->username !==
null ) {
190 $ret[
'username'] =
$res->username;
193 if (
$res->status === AuthenticationResponse::REDIRECT ) {
194 $ret[
'redirecttarget'] =
$res->redirectTarget;
195 if (
$res->redirectApiData !==
null ) {
196 $ret[
'redirectdata'] =
$res->redirectApiData;
200 if (
$res->status === AuthenticationResponse::REDIRECT ||
201 $res->status === AuthenticationResponse::UI ||
202 $res->status === AuthenticationResponse::RESTART
207 if (
$res->status === AuthenticationResponse::FAIL ||
208 $res->status === AuthenticationResponse::UI ||
209 $res->status === AuthenticationResponse::RESTART
215 if (
$res->status === AuthenticationResponse::FAIL ||
216 $res->status === AuthenticationResponse::RESTART
218 $this->module->getRequest()->getSession()->set(
219 'ApiAuthManagerHelper::createRequest',
222 $ret[
'canpreservestate'] =
$res->createRequest !==
null;
224 $this->module->getRequest()->getSession()->remove(
'ApiAuthManagerHelper::createRequest' );
236 if ( is_string( $result ) ) {
237 $status = Status::newFatal( $result );
238 } elseif ( $result->status === AuthenticationResponse::PASS ) {
239 $status = Status::newGood();
240 } elseif ( $result->status === AuthenticationResponse::FAIL ) {
241 $status = Status::newFatal( $result->message );
247 LoggerFactory::getInstance(
'authevents' )->info(
"$module API attempt", [
259 $ret = $this->module->getRequest()->getSession()->get(
'ApiAuthManagerHelper::createRequest' );
270 $params = $this->module->extractRequestParams();
271 $mergeFields = !empty( $params[
'mergerequestfields'] );
273 $ret = [
'requests' => [] ];
274 foreach ( $reqs as $req ) {
275 $describe = $req->describeCredentials();
277 'id' => $req->getUniqueId(),
280 switch ( $req->required ) {
281 case AuthenticationRequest::OPTIONAL:
282 $reqInfo[
'required'] =
'optional';
284 case AuthenticationRequest::REQUIRED:
285 $reqInfo[
'required'] =
'required';
287 case AuthenticationRequest::PRIMARY_REQUIRED:
288 $reqInfo[
'required'] =
'primary-required';
291 $this->
formatMessage( $reqInfo,
'provider', $describe[
'provider'] );
292 $this->
formatMessage( $reqInfo,
'account', $describe[
'account'] );
293 if ( !$mergeFields ) {
294 $reqInfo[
'fields'] = $this->
formatFields( (array)$req->getFieldInfo() );
296 $ret[
'requests'][] = $reqInfo;
299 if ( $mergeFields ) {
300 $fields = AuthenticationRequest::mergeFieldInfo( $reqs );
324 foreach ( $fields as $name => $field ) {
325 $ret = array_intersect_key( $field, $copy );
327 if ( isset( $field[
'options'] ) ) {
328 $ret[
'options'] = array_map(
function ( $msg ) use (
$module ) {
329 return $msg->setContext(
$module )->plain();
330 }, $field[
'options'] );
335 $ret[
'optional'] = !empty( $field[
'optional'] );
336 $ret[
'sensitive'] = !empty( $field[
'sensitive'] );
338 $retFields[$name] = $ret;
369 'mergerequestfields' => [
388 foreach ( $wantedParams as $name ) {
389 if ( isset( $params[$name] ) ) {
390 $ret[$name] = $params[$name];
Helper class for AuthManager-using API modules.
logAuthenticationResult( $event, $result)
Logs successful or failed authentication.
getPreservedRequest()
Fetch the preserved CreateFromLoginAuthenticationRequest, if any.
static getStandardParams( $action,... $wantedParams)
Fetch the standard parameters this helper recognizes.
formatAuthenticationResponse(AuthenticationResponse $res)
Format an AuthenticationResponse for return.
static newForModule(ApiBase $module)
Static version of the constructor, for chaining.
__construct(ApiBase $module)
ApiBase $module
API module, for context and parameters.
formatRequests(array $reqs)
Format an array of AuthenticationRequests for return.
formatFields(array $fields)
Clean up a field array for output.
formatMessage(array &$res, $key, Message $message)
Format a message for output.
securitySensitiveOperation( $operation)
Call $manager->securitySensitiveOperationStatus()
static blacklistAuthenticationRequests(array $reqs, array $blacklist)
Filter out authentication requests by class name.
loadAuthenticationRequests( $action)
Fetch and load the AuthenticationRequests for an action.
string $messageFormat
Message output format.
This abstract class implements many basic API functions, and is the base of all API classes.
const PARAM_REQUIRED
(boolean) Is the parameter required?
const PARAM_TYPE
(string|string[]) Either an array of allowed value strings, or a string type as described below.
const PARAM_DFLT
(null|boolean|integer|string) Default value of the parameter.
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
getModuleName()
Get the name of the module being executed by this instance.
const PARAM_ISMULTI
(boolean) Accept multiple pipe-separated values for this parameter (e.g.
static create( $msg, $code=null, array $data=null)
Create an IApiMessage for the message.
const META_TYPE
Key for the 'type' metadata item.
static setArrayType(array &$arr, $type, $kvpKeyName=null)
Set the array data type.
static setIndexedTagName(array &$arr, $tag)
Set the tag name for numeric-keyed values in XML format.
The Message class provides methods which fulfil two basic services:
getParams()
Returns the message parameters.
getKey()
Returns the message key.
setContext(IContextSource $context)
Set the language and the title from a context object.