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 []; } } }