Extension:WSOAuth/For developers

From mediawiki.org

This page explains how to develop and add a new OAuth provider to WSOAuth and how to develop WSOAuth extensions. Please consider creating a pull request that adds your authentication provider to WSOAuth or consider publishing it as a standalone extension.

Creating an OAuth provider for WSOAuth[edit]

Authentication plugins must extend the WSOAuth\SRC\AuthenticationProvider\AuthProvider abstract class provided by WSOAuth and must implement at least the following methods:

abstract public function __construct( string $clientId, string $clientSecret, ?string $authUri, ?string $redirectUri );

  • This is the constructor of the auth provider.
  • $clientId corresponds directly to the "clientId" passed through the data array by PluggableAuth.
  • $clientSecret corresponds directly to the "clientSecret" passed through the data array by PluggableAuth.
  • $authUri corresponds directly to the "uri" passed through the data array by PluggableAuth. May be null.
  • $redirectUri corresponds directly to the "redirectUri" passed through the data array by PluggableAuth. May be null.


abstract public function login( ?string &$key, ?string &$secret, ?string &$authUrl ): bool;

  • This function is called to initiate the OAuth conversion (i.e. the user has not been authenticated yet and visits the login page for the first time). This is the first leg of the 3-legged OAuth login.
  • $key may be set to the consumer key returned by the OAuth provider.
  • $secret may be set to the consumer secret returned by the OAuth provider.
  • $authUrl must be set to the authorization URL to which the user will be redirected.
  • Must return true if the authorization grant has been successfully received, false otherwise.

An example implementation of this function:

try {
    list($authUrl, $token) = $this->client->initiate();

    $key = $token->key;
    $secret = $token->secret;

    return true;
} catch (\MediaWiki\OAuthClient\Exception $e) {
    return false;
}

abstract public function logout( UserIdentity &$user ): void;

  • Called when the user logs out to notify the OAuth provider, if necessary, that clean up such as removing the user's session can be performed.
  • This function shadows PluggableAuth's function deauthenticate(User $user).

abstract public function getUser( string $key, string $secret, &$errorMessage );

  • This function is called after login() has been executed and the user has been redirected back from the OAuth provider.
  • The purpose of this function is to retrieve the user info from the session variables set during login().
  • This function must return an array with the following format if the user info could be retrieved from the session variables set during the login() step of the authentication:
return [
    'name' => 'John', // required
    'realname' => 'John Doe', // optional
    'email' => 'john@doe.com' // optional
];
  • If the request failed, or the user is not authorised to log in, the function must return false.
  • $key is equal to $key set during login().
  • $secret is equal to $secret set during login().
  • $errorMessage can be edited to give a custom error message when the login has failed.

An example implementation of this function:

if (!isset($_GET['oauth_verifier']) {
    return false; // oauth_verifier is set by the OAuth extension. If it is not available, this means login() has not been performed.
}

try {
    $request_token = new Token($key, $secret); // From \MediaWik\OAuthClient
    $access_token = $this->client->complete($request_token, $_GET['oauth_verifier']);

    $access_token = new Token($access_token->key, $access_token->secret);
    $identity = $this->client->identify($access_token);

    return [
        "name" => $identity->username
    ];
} catch (\Exception $e) {
    return false;
}

abstract public function saveExtraAttributes( int $id ): void;

  • Called after a new user has been authenticated and added to the database to add any additional information to the database required by the OAuth provider.
  • This function shadows PluggableAuth's function saveExtraAttributes.

Adding a new OAuth provider to WSOAuth[edit]

You can add the OAuth provider you have developed to WSOAuth by placing the class you have written inside of extensions/WSOAuth/src/AuthenticationProvider. The class must live in the WSOAuth\AuthenticationProvider namespace. You must then update $wgOAuthCustomAuthProviders:

$wgOAuthCustomAuthProviders = [
    'google' => GoogleAuth::class // OAuth provider "google" uses class "GoogleAuth".
];

You can also use the hook WSOAuthGetAuthProviders to dynamically add new authentication providers. This can be handy for extension makers that do not want the site administrator to have to manually add a new authentication provider.

Writing extensions[edit]

Extensions can be written to extend WSOAuth's functionality. These are different from OAuth providers, as they do not directly authenticate a user. Instead, WSOAuth extensions should alter the authentication flow by using the provided hooks:

More about how to write extensions can be found on Manual:Extensions.