From 015333afe98d72a42b72b2f4879fa7a1b9aa0460 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20P=C3=A9rez-Cerezo?= Date: Wed, 17 Apr 2019 09:00:02 +0200 Subject: Repurpose plugin as minetest authentication. --- MinetestPasswordPrimaryAuthenticationProvider.php | 201 ++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 MinetestPasswordPrimaryAuthenticationProvider.php (limited to 'MinetestPasswordPrimaryAuthenticationProvider.php') diff --git a/MinetestPasswordPrimaryAuthenticationProvider.php b/MinetestPasswordPrimaryAuthenticationProvider.php new file mode 100644 index 0000000..7d2fb19 --- /dev/null +++ b/MinetestPasswordPrimaryAuthenticationProvider.php @@ -0,0 +1,201 @@ +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 []; + } + } +} -- cgit v1.2.3