feat: OAuth

wiki
Pyjacpp 2026-03-23 22:20:33 +01:00
parent cafa89b7e7
commit 55767e5690
No known key found for this signature in database
GPG Key ID: ED479A5A26930939
6 changed files with 186 additions and 6 deletions

View File

@ -0,0 +1,14 @@
# NoteKfetAuth
Extension pour médiawiki pour ajouter le support de l'autentification par Note
via l'extension WSOAuth.
## Installation
Il faut enregistrer l'extension comme provider
```
$wgOAuthCustomAuthProviders = [
'note' => WSOAuthNoteKfetAuth\NoteKfetAuth::class
];
```

View File

@ -0,0 +1,25 @@
{
"name": "WSONoteKfetAuth",
"author": [
"Pyjacpp"
],
"url": "https://gitlab.crans.org/nounou/WSONoteKfet",
"description": "Implementation of the NoteKfet OAuth2 for the WSOAuth extension",
"type": "other",
"requires": {
"MediaWiki": ">= 1.35.0",
"extensions": {
"WSOAuth": ">= 9.0"
}
},
"AutoloadNamespaces": {
"WSONoteKfetAuth\\": "src/"
},
"config": {
"NoteKfetUrl": {
"description": "The url of the NoteKfet.",
"value": "https://note.crans.org/"
}
},
"manifest_version": 2
}

View File

@ -0,0 +1,137 @@
<?php
/**
* Copyright 2020 Marijn van Wezel
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
* Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
* LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
namespace WSOAuth\AuthenticationProvider;
use MediaWiki\User\UserIdentity;
class NoteKfetAuth extends AuthProvider {
/**
* @var string
*/
private $clientId;
/**
* @var string
*/
private $clientSecret;
/**
* @inheritDoc
*/
public function __construct(
string $clientId,
string $clientSecret,
?string $authUri,
?string $redirectUri,
array $extensionData = []
) {
$this->clientId = $clientId;
$this->clientSecret = $clientSecret;
}
/**
* @inheritDoc
*/
public function login( ?string &$key, ?string &$secret, ?string &$authUrl ): bool {
$state = random_int(PHP_INT_MIN, PHP_INT_MAX);
$secret = "$state";
$authUrl = $GLOBALS['wgNoteKfetUrl'] . "o/authorize/?" . http_build_query(
'client_id' => $this->clientId,
'response_type' => 'code',
'scope' => '1_1',
'state' => $secret,
);
return true;
}
/**
* @inheritDoc
*/
public function logout( UserIdentity &$user ): void {
}
/**
* @inheritDoc
*/
public function getUser( string $key, string $secret, &$errorMessage ) {
if ( !isset( $_GET['code'] ) ) {
return false;
}
if ( !isset( $_GET['state'] ) || empty( $_GET['state'] ) || ( $_GET['state'] !== $secret ) ) {
return false;
}
try {
$token = $this->getAccessTokens( $_GET['code'] );
$userInfos = $this->getUserInfos( $token );
return [
'name' => $userInfos->normalized_name,
'realname' => $userInfos->username,
'email' => $userInfos->email,
];
} catch ( \Exception $e ) {
return false;
}
}
private function getAccessTokens( string $code ) {
$data = [
'grant_type' => 'authorization_code',
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
'code' => $code,
];
$options = [
'http' => [
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => http_build_query($data),
],
];
$context = stream_context_create($options);
$response = file_get_contents($GLOBALS['wgNoteKfetUrl'] . 'o/oauth/token/', false, $context);
$tokens = json_decode($response);
return $tokens->access_token;
}
private function getUserInfos( string $token ) {
$options = [
'http' => [
'method' => 'GET',
'header' => "Authorization: Bearer $token",
],
];
$context = stream_context_create($options);
$response = file_get_contents($GLOBALS['wgNoteKfetUrl'] . 'api/me/', false, $context);
return json_decode($response);
}
/**
* @inheritDoc
*/
public function saveExtraAttributes( int $id ): void {
}
}

View File

@ -106,6 +106,9 @@ in
$wgPluggableAuth_EnableLocalLogin = true; $wgPluggableAuth_EnableLocalLogin = true;
$LDAPAuthentication2AllowLocalLogin = true; $LDAPAuthentication2AllowLocalLogin = true;
$LDAPProviderDomainConfigs = "${config.age.secrets.mediawiki-ldap.path}"; $LDAPProviderDomainConfigs = "${config.age.secrets.mediawiki-ldap.path}";
$wgOAuthCustomAuthProviders = [
'note' => WSOAuthNoteKfetAuth\NoteKfetAuth::class
];
$wgPluggableAuth_Config = [ $wgPluggableAuth_Config = [
"Compte Crans" => [ "Compte Crans" => [
'plugin' => 'LDAPAuthentication2', 'plugin' => 'LDAPAuthentication2',
@ -114,8 +117,8 @@ in
] ]
], ],
"Note BDE" => [ "Note BDE" => [
'plugin' => 'OpenIDConnect', 'plugin' => 'WSOAuth',
'data' => require('${config.age.secrets.mediawiki-openid.path}'), 'data' => require('${config.age.secrets.mediawiki-oauth.path}'),
] ]
]; ];
@ -257,15 +260,16 @@ in
# Pas de meilleure solution à ma connaissance pour suivre les releases. # Pas de meilleure solution à ma connaissance pour suivre les releases.
sha256 = "sha256-oi5rliHb4KnLbvQxO7MGuLp/FEucoGR/Z0NP1gmbgMc="; sha256 = "sha256-oi5rliHb4KnLbvQxO7MGuLp/FEucoGR/Z0NP1gmbgMc=";
}; };
OpenIDConnect = pkgs.fetchFromGitHub { WSOAuth = pkgs.fetchFromGitHub {
name = "OpenIDConnect"; name = "WSOAuth";
owner = "wikimedia"; owner = "wikimedia";
repo = "mediawiki-extensions-OpenIDConnect"; repo = "mediawiki-extensions-WSOAuth";
rev = "REL" + major + "_" + minor; rev = "REL" + major + "_" + minor;
# Le SHA doit être changé à chaque nouveau commit de traduction. # Le SHA doit être changé à chaque nouveau commit de traduction.
# Pas de meilleure solution à ma connaissance pour suivre les releases. # Pas de meilleure solution à ma connaissance pour suivre les releases.
sha256 = "sha256-KoBULn53xnY+ydodeTGN7YEoqgLr9qhhuR5mNibbh5s="; sha256 = "sha256-1jv4nmkxky1dx7833sacsbqww54yb9glrnl1360b13h2z5fhwdxp";
}; };
WSONoteKfetAuth = ./WSONoteKfetAuth;
}; };
}; };
} }

Binary file not shown.