use MediaWiki\Auth\AuthenticationRequest;
use MediaWiki\Auth\AuthenticationResponse;
use MediaWiki\Auth\CreateFromLoginAuthenticationRequest;
+use MediaWiki\Logger\LoggerFactory;
/**
* Helper class for AuthManager-using API modules. Intended for use via
// Collect the fields for all the requests
$fields = [];
+ $sensitive = [];
foreach ( $reqs as $req ) {
- $fields += (array)$req->getFieldInfo();
+ $info = (array)$req->getFieldInfo();
+ $fields += $info;
+ $sensitive += array_filter( $info, function ( $opts ) {
+ return !empty( $opts['sensitive'] );
+ } );
}
// Extract the request data for the fields and mark those request
$data = array_intersect_key( $this->module->getRequest()->getValues(), $fields );
$this->module->getMain()->markParamsUsed( array_keys( $data ) );
+ if ( $sensitive ) {
+ try {
+ $this->module->requirePostedParameters( array_keys( $sensitive ), 'noprefix' );
+ } catch ( UsageException $ex ) {
+ // Make this a warning for now, upgrade to an error in 1.29.
+ $this->module->setWarning( $ex->getMessage() );
+ $this->module->logFeatureUsage( $this->module->getModuleName() . '-params-in-query-string' );
+ }
+ }
+
return AuthenticationRequest::loadRequestsFromSubmission( $reqs, $data );
}
return $ret;
}
+ /**
+ * Logs successful or failed authentication.
+ * @param string|AuthenticationResponse $result Response or error message
+ * @param string $event Event type (e.g. 'accountcreation')
+ */
+ public function logAuthenticationResult( $event, $result ) {
+ if ( is_string( $result ) ) {
+ $status = Status::newFatal( $result );
+ } elseif ( $result->status === AuthenticationResponse::PASS ) {
+ $status = Status::newGood();
+ } elseif ( $result->status === AuthenticationResponse::FAIL ) {
+ $status = Status::newFatal( $result->message );
+ } else {
+ return;
+ }
+
+ $module = $this->module->getModuleName();
+ LoggerFactory::getInstance( 'authevents' )->info( "$module API attempt", [
+ 'event' => $event,
+ 'status' => $status,
+ 'module' => $module,
+ ] );
+ }
+
/**
* Fetch the preserved CreateFromLoginAuthenticationRequest, if any
* @return CreateFromLoginAuthenticationRequest|null
$describe = $req->describeCredentials();
$reqInfo = [
'id' => $req->getUniqueId(),
- 'metadata' => $req->getMetadata(),
+ 'metadata' => $req->getMetadata() + [ ApiResult::META_TYPE => 'assoc' ],
];
switch ( $req->required ) {
case AuthenticationRequest::OPTIONAL:
private function formatFields( array $fields ) {
static $copy = [
'type' => true,
- 'image' => true,
'value' => true,
];
$this->formatMessage( $ret, 'label', $field['label'] );
$this->formatMessage( $ret, 'help', $field['help'] );
$ret['optional'] = !empty( $field['optional'] );
+ $ret['sensitive'] = !empty( $field['sensitive'] );
$retFields[$name] = $ret;
}