hey guys, I wrote a Twitter OAuth Provider and included it in the WSOAuth default providers list for myself. It's based on the Facebook example from the docs, and makes use of the smolblog twitter oauth2 plugin provided as a 3rd party integration by the PHP League.
<?php
namespace WSOAuth\AuthenticationProvider;
use Smolblog\OAuth2\Client\Provider\Twitter;
use MediaWiki\User\UserIdentity;
class TwitterAuth extends AuthProvider {
/**
* @var Twitter
*/
private $provider;
/**
* @inheritDoc
*/
public function __construct( string $clientId, string $clientSecret, ?string $authUri, ?string $redirectUri ) {
$this->provider = new Twitter( [
'clientId' => $clientId,
'clientSecret' => $clientSecret,
'redirectUri' => $redirectUri
] );
}
/**
* @inheritDoc
*/
public function login( ?string &$key, ?string &$secret, ?string &$authUrl ): bool {
$authUrl = $this->provider->getAuthorizationUrl( [
'scope' => [ 'users.read', 'offline.access', 'tweet.read' ]
] );
$secret = $this->provider->getState();
// We also need to store the PKCE Verification code so we can send it with
// the authorization code request.
$_SESSION['oauth2verifier'] = $this->provider->getPkceVerifier();
return true;
}
/**
* @inheritDoc
*/
public function logout( UserIdentity &$user ): void {
}
/**
* @inheritDoc
*/
public function getUser( string $key, string $secret, &$errorMessage ) {
if ( !isset( $_GET['code'] ) ) {
unset($_SESSION['oauth2verifier']);
return false;
}
if ( !isset( $_GET['state'] ) || empty( $_GET['state'] ) || ( $_GET['state'] !== $secret ) ) {
return false;
}
try {
$token = $this->provider->getAccessToken('authorization_code', [
'code' => $_GET['code'],
'code_verifier' => $_SESSION['oauth2verifier'],
]);
$user = $this->provider->getResourceOwner( $token );
return [
'name' => $user->getUsername(),
'realname' => $user->getName(),
'email' => $user->getUsername() . '@bonkipedia.dev',
];
} catch ( \Exception $e ) {
return false;
}
}
/**
* @inheritDoc
*/
public function saveExtraAttributes( int $id ): void {
}
}