mirror of https://gitlab.crans.org/nounous/nixos
feat: OAuth
parent
cafa89b7e7
commit
55767e5690
|
|
@ -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
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
@ -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 {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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.
Binary file not shown.
Loading…
Reference in New Issue