diff options
Diffstat (limited to 'MinetestPasswordPrimaryAuthenticationProvider.php')
-rw-r--r-- | MinetestPasswordPrimaryAuthenticationProvider.php | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/MinetestPasswordPrimaryAuthenticationProvider.php b/MinetestPasswordPrimaryAuthenticationProvider.php new file mode 100644 index 0000000..7d2fb19 --- /dev/null +++ b/MinetestPasswordPrimaryAuthenticationProvider.php @@ -0,0 +1,201 @@ +<?php +/** + * This program is a free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + * @ingroup Auth + */ + +namespace MediaWiki\Auth; + +use User; + +/** + * A primary authentication provider that authenticates the user against a remote Minetest site. + * + * @ingroup Auth + * @since 1.27 + */ +class MinetestPasswordPrimaryAuthenticationProvider extends AbstractPrimaryAuthenticationProvider { + + /** @var string The URL of the Minetest site we authenticate against. */ + protected $minetestUrl; + + /** @var array */ + /* protected $tokens = [];*/ + + /** + * @param array $params Settings + * - minetestUrl: The URL of the Minetest site we authenticate against. + */ + public function __construct( $params = [] ) { + + if ( empty( $params['minetestUrl'] ) ) { + throw new \InvalidArgumentException( 'The minetestUrl parameter missing in the auth configuration' ); + } + + $this->minetestUrl = $params['minetestUrl']; + } + + public function beginPrimaryAuthentication( array $reqs ) { + $req = AuthenticationRequest::getRequestByClass( $reqs, PasswordAuthenticationRequest::class ); + if ( !$req ) { + return AuthenticationResponse::newAbstain(); + } + + if ( $req->username === null || $req->password === null ) { + return AuthenticationResponse::newAbstain(); + } + + $username = User::getCanonicalName( $req->username, 'usable' ); + if ( $username === false ) { + return AuthenticationResponse::newAbstain(); + } + + $token = $this->getMinetestUserToken( $req->username, $req->password ); + + if ( $token === false ) { + return AuthenticationResponse::newAbstain(); + + } else { + return AuthenticationResponse::newPass( $username ); + } + } + + /** + * Prepares a curl handler to use for querying the Minetest web services. + * + * @param string $url + * @return resource + */ + protected function getMinetestCurlClient( $url ) { + + $curl = curl_init( $url ); + + curl_setopt_array( $curl, [ + CURLOPT_USERAGENT => 'MWAuthMinetestBot/1.0', + CURLOPT_NOBODY => false, + CURLOPT_HEADER => false, + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_MAXREDIRS => 10, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_SSL_VERIFYPEER => 1, + CURLOPT_SSL_VERIFYHOST => 2, + ]); + + return $curl; + } + + /** + * Attempts to authenticate the user against Minetest. Checks if user is authenticated. + * + * @param string $username + * @param string $password + * @return bool False on error, true otherwise + */ + protected function getMinetestUserToken( $username, $password ) { + + $curl = $this->getMinetestCurlClient( $this->minetestUrl.'/query' ); + + $params = http_build_query( [ + 'name' => $username, + 'password' => $password, + ] ); + + curl_setopt_array( $curl, [ + CURLOPT_POST => true, + CURLOPT_POSTFIELDS => $params, + ]); + + $ret = curl_exec( $curl ); + $info = curl_getinfo( $curl ); + $error = curl_error( $curl ); + curl_close( $curl ); + + sleep(2); + + $query2 = $this->getMinetestCurlClient( $this->minetestUrl.'/status/'.$username ); + $ret = curl_exec ( $query2 ); + + + if ( !empty( $error ) ) { + $this->logger->error( 'AuthMinetest: cURL error: '.$error ); + return false; + + } else if ( $info['http_code'] != 200 ) { + $this->logger->error( 'AuthMinetest: cURL error: unexpected HTTP response code '.$info['http_code'] ); + return false; + + } + if ( $ret == "True" ) { + return true; + + } else { + return false; + } + + } + + /** + * @param null|\User $user + * @param AuthenticationResponse $response + */ + public function postAuthentication( $user, AuthenticationResponse $response ) { + if ( $response->status !== AuthenticationResponse::PASS ) { + return; + } + return; + } + + + public function testUserCanAuthenticate( $username ) { + return $this->testUserExists( $username ); + } + + public function testUserExists( $username, $flags = User::READ_NORMAL ) { + // TODO - there is no easy way to do this without additional web services on the Minetest side. + return false; + } + + public function providerAllowsPropertyChange( $property ) { + return false; + } + + public function providerAllowsAuthenticationDataChange( AuthenticationRequest $req, $checkData = true) { + return \StatusValue::newGood( 'ignored' ); + } + + public function providerChangeAuthenticationData( AuthenticationRequest $req ) { + return; + } + + public function accountCreationType() { + return self::TYPE_CREATE; + } + + public function beginPrimaryAccountCreation( $user, $creator, array $reqs ) { + throw new \BadMethodCallException( 'This should not get called' ); + } + + public function getAuthenticationRequests( $action, array $options ) { + switch ( $action ) { + case AuthManager::ACTION_LOGIN: + return [ new PasswordAuthenticationRequest() ]; + default: + return []; + } + } +} |