Repurpose plugin as minetest authentication.
parent
03667616c1
commit
015333afe9
|
@ -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 [];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,310 +0,0 @@
|
|||
<?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 Moodle site.
|
||||
*
|
||||
* @ingroup Auth
|
||||
* @since 1.27
|
||||
*/
|
||||
class MoodlePasswordPrimaryAuthenticationProvider extends AbstractPrimaryAuthenticationProvider {
|
||||
|
||||
/** @var string The URL of the Moodle site we authenticate against. */
|
||||
protected $moodleUrl;
|
||||
|
||||
/** @var array */
|
||||
protected $tokens = [];
|
||||
|
||||
/**
|
||||
* @param array $params Settings
|
||||
* - moodleUrl: The URL of the Moodle site we authenticate against.
|
||||
*/
|
||||
public function __construct( $params = [] ) {
|
||||
|
||||
if ( empty( $params['moodleUrl'] ) ) {
|
||||
throw new \InvalidArgumentException( 'The moodleUrl parameter missing in the auth configuration' );
|
||||
}
|
||||
|
||||
$this->moodleUrl = $params['moodleUrl'];
|
||||
}
|
||||
|
||||
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->getMoodleUserToken( $req->username, $req->password );
|
||||
|
||||
if ( $token === false ) {
|
||||
return AuthenticationResponse::newAbstain();
|
||||
|
||||
} else {
|
||||
$this->tokens[$username] = $token;
|
||||
return AuthenticationResponse::newPass( $username );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a curl handler to use for querying the Moodle web services.
|
||||
*
|
||||
* @param string $url
|
||||
* @return resource
|
||||
*/
|
||||
protected function getMoodleCurlClient( $url ) {
|
||||
|
||||
$curl = curl_init( $url );
|
||||
|
||||
curl_setopt_array( $curl, [
|
||||
CURLOPT_USERAGENT => 'MWAuthMoodleBot/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 Moodle and returns the auth token.
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @return string|bool False on error, token otherwise.
|
||||
*/
|
||||
protected function getMoodleUserToken( $username, $password ) {
|
||||
|
||||
$curl = $this->getMoodleCurlClient( $this->moodleUrl.'/login/token.php' );
|
||||
|
||||
$params = http_build_query( [
|
||||
'username' => $username,
|
||||
'password' => $password,
|
||||
'service' => 'moodle_mobile_app',
|
||||
] );
|
||||
|
||||
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 );
|
||||
|
||||
if ( !empty( $error ) ) {
|
||||
$this->logger->error( 'AuthMoodle: cURL error: '.$error );
|
||||
return false;
|
||||
|
||||
} else if ( $info['http_code'] != 200 ) {
|
||||
$this->logger->error( 'AuthMoodle: cURL error: unexpected HTTP response code '.$info['http_code'] );
|
||||
return false;
|
||||
|
||||
} else {
|
||||
$decoded = @json_decode( $ret );
|
||||
if ( empty( $decoded ) ) {
|
||||
$this->logger->error( 'AuthMoodle: Unable to decode the JSON response: '.$ret );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !empty( $decoded->token ) ) {
|
||||
return $decoded->token;
|
||||
|
||||
} else if ( isset( $decoded->exception ) ) {
|
||||
$this->logger->error( 'AuthMoodle: Remote exception: '.$decoded->exception );
|
||||
return false;
|
||||
|
||||
} else if ( isset( $decoded->error ) ) {
|
||||
$this->logger->error( 'AuthMoodle: Remote error: '.$decoded->error );
|
||||
return false;
|
||||
|
||||
} else {
|
||||
$this->logger->error( 'AuthMoodle: Unknown error: '.$ret );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|\User $user
|
||||
* @param AuthenticationResponse $response
|
||||
*/
|
||||
public function postAuthentication( $user, AuthenticationResponse $response ) {
|
||||
if ( $response->status !== AuthenticationResponse::PASS ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( empty( $this->tokens[$user->getName()] ) ) {
|
||||
$this->logger->error( 'AuthMoodle: Moodle token not found' );
|
||||
return;
|
||||
}
|
||||
|
||||
$userinfo = $this->getMoodleUserInfo( $user->getName(), $this->tokens[$user->getName()] );
|
||||
|
||||
if ( empty( $userinfo ) ) {
|
||||
$this->logger->error( 'AuthMoodle: Empty user info, skipping update ');
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $user->getRealName() === '' ) {
|
||||
// Set the user's real name if they are logging in for the first time. Also note MDLSITE-1293.
|
||||
$this->logger->debug( 'AuthMoodle: Setting the user real name' );
|
||||
$mwdbr = wfGetDB( DB_SLAVE );
|
||||
$realname = $userinfo->fullname;
|
||||
$counter = 1;
|
||||
while ( $mwdbr->selectField( 'user', 'user_name', ['user_real_name' => $realname] ) && $counter < 100 ) {
|
||||
$counter++;
|
||||
$realname = $userinfo->fullname.' '.$counter;
|
||||
}
|
||||
$user->setRealName( $realname );
|
||||
}
|
||||
|
||||
$user->setEmail( $userinfo->email );
|
||||
$user->confirmEmail();
|
||||
$user->saveSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the Moodle user's real name and email.
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $token
|
||||
* @return object|bool
|
||||
*/
|
||||
protected function getMoodleUserInfo( $username, $token ) {
|
||||
|
||||
$this->logger->debug( 'AuthMoodle: Attempting to get info about the user: '.$username.' using the token: '.$token );
|
||||
|
||||
// Get the Moodle user id first.
|
||||
|
||||
$params = http_build_query( [
|
||||
'wstoken' => $token,
|
||||
'wsfunction' => 'core_webservice_get_site_info',
|
||||
'moodlewsrestformat' => 'json',
|
||||
] );
|
||||
|
||||
$curl = $this->getMoodleCurlClient( $this->moodleUrl.'/webservice/rest/server.php?'.$params );
|
||||
|
||||
$ret = curl_exec( $curl );
|
||||
curl_close( $curl );
|
||||
|
||||
$decoded = @json_decode( $ret );
|
||||
|
||||
if ( empty( $decoded->userid ) ) {
|
||||
$this->logger->error( 'AuthMoodle: Unable to get Moodle user id' );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( strtolower( $decoded->username ) !== strtolower( $username ) ) {
|
||||
$this->logger->error( 'AuthMoodle: User name mismatch' );
|
||||
return false;
|
||||
}
|
||||
|
||||
$moodleuserid = $decoded->userid;
|
||||
|
||||
// Get the user profile.
|
||||
|
||||
$params = http_build_query( [
|
||||
'wstoken' => $token,
|
||||
'wsfunction' => 'core_user_get_users_by_field',
|
||||
'moodlewsrestformat' => 'json',
|
||||
'field' => 'id',
|
||||
'values' => [$moodleuserid],
|
||||
] );
|
||||
|
||||
$curl = $this->getMoodleCurlClient( $this->moodleUrl.'/webservice/rest/server.php?'.$params );
|
||||
|
||||
$ret = curl_exec( $curl );
|
||||
curl_close( $curl );
|
||||
|
||||
$decoded = @json_decode( $ret );
|
||||
|
||||
if ( empty( $decoded ) ) {
|
||||
$this->logger->error( 'AuthMoodle: Unable to get Moodle user profile' );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( isset( $decoded->exception ) ) {
|
||||
$this->logger->error( 'AuthMoodle: Remote exception: '.$decoded->exception );
|
||||
return false;
|
||||
}
|
||||
|
||||
return (object) [
|
||||
'fullname' => $decoded[0]->fullname,
|
||||
'email' => $decoded[0]->email,
|
||||
];
|
||||
}
|
||||
|
||||
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 Moodle 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 [];
|
||||
}
|
||||
}
|
||||
}
|
34
README.md
34
README.md
|
@ -1,36 +1,52 @@
|
|||
# AuthMoodle
|
||||
# AuthMinetest
|
||||
|
||||
Extension for MediaWiki allowing to authenticate users against Moodle database via mobile app service.
|
||||
Extension for MediaWiki allowing to authenticate users against a Minetest server
|
||||
|
||||
## Requirements:
|
||||
|
||||
* MediaWiki 1.27+
|
||||
* Moodle 3.1+ with mobile app service enabled
|
||||
* Minetest with auth_export mod enabled
|
||||
* minetestauth.py duct-tape http server
|
||||
|
||||
## Installation and setup
|
||||
|
||||
Clone / unzip into your MediaWiki's extension/AuthMoodle/ folder.
|
||||
Clone / unzip into your MediaWiki's extension/AuthMinetest/ folder.
|
||||
|
||||
Configure your MediaWiki authentication manager to use this extension as the
|
||||
primary authentication provider:
|
||||
|
||||
wfLoadExtension( 'AuthMoodle' );
|
||||
wfLoadExtension( 'AuthMinetest' );
|
||||
|
||||
$wgAuthManagerAutoConfig['primaryauth'] = [
|
||||
MediaWiki\Auth\MoodlePasswordPrimaryAuthenticationProvider::class => [
|
||||
'class' => MediaWiki\Auth\MoodlePasswordPrimaryAuthenticationProvider::class,
|
||||
MediaWiki\Auth\MinetestPasswordPrimaryAuthenticationProvider::class => [
|
||||
'class' => MediaWiki\Auth\MinetestPasswordPrimaryAuthenticationProvider::class,
|
||||
'args' => [
|
||||
[
|
||||
'moodleUrl' => 'https://your.moodle.url',
|
||||
'minetestUrl' => 'http://your.minetest.url',
|
||||
]
|
||||
],
|
||||
'sort' => 0,
|
||||
],
|
||||
];
|
||||
];
|
||||
|
||||
Enable the auth\_export mod on your minetest server, and install the
|
||||
minetestauth.py script. You then need to point both the auth\_export
|
||||
mod and this plugin to the minetestauth.py script like this:
|
||||
|
||||
auth_export ←→ minetestauth.py ←→ AuthMinetest
|
||||
|
||||
Keep in mind that stuff is sent in plain text, so you should have all
|
||||
of these listening on localhost or use encrypted tunnels between the
|
||||
hosts, such as ssh or vpn tunnels.
|
||||
|
||||
## Copying
|
||||
|
||||
This extension is based on
|
||||
[AuthMoodle](https://github.com/moodlehq/mediawiki-authmoodle) by
|
||||
David Mudrák.
|
||||
|
||||
Copyright 2017 David Mudrák <david@moodle.org>
|
||||
Copyright 2019 Gabriel Pérez-Cerezo <gabriel@gpcf.eu>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
{
|
||||
"name": "AuthMoodle",
|
||||
"name": "AuthMinetest",
|
||||
"version": "1.0.0",
|
||||
"author": [
|
||||
"David Mudrák"
|
||||
"Gabriel Pérez-Cerezo",
|
||||
"David Mudrák"
|
||||
],
|
||||
"url": "https://github.com/moodlehq/mediawiki-authmoodle",
|
||||
"description": "Extension for MediaWiki allowing to authenticate users against Moodle database via mobile app services",
|
||||
"url": "https://git.bananach.space/MinetestAuth.git",
|
||||
"description": "Extension for MediaWiki allowing to authenticate users against Minetest servers",
|
||||
"license-name": "GPL-3.0+",
|
||||
"type": "auth",
|
||||
"AutoloadClasses": {
|
||||
"MediaWiki\\Auth\\MoodlePasswordPrimaryAuthenticationProvider": "MoodlePasswordPrimaryAuthenticationProvider.php"
|
||||
"MediaWiki\\Auth\\MinetestPasswordPrimaryAuthenticationProvider": "MinetestPasswordPrimaryAuthenticationProvider.php"
|
||||
},
|
||||
"manifest_version": 1
|
||||
}
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
#!/usr/bin/env python3
|
||||
#
|
||||
# Primitive server to interface minetest with mediawiki
|
||||
# Functionality:
|
||||
# - responds to minetest server's requests for authentication
|
||||
# - mediawiki posts request to server on the URL /query
|
||||
# - mediawiki queries user auth status on the URL /status/$USERNAME
|
||||
#
|
||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||
import socketserver
|
||||
import cgi
|
||||
import json
|
||||
queue = []
|
||||
auth_status = {}
|
||||
allowed = ["127.0.0.1"]
|
||||
class S(BaseHTTPRequestHandler):
|
||||
def check_allowed(self) :
|
||||
if not self.client_address[0] in allowed :
|
||||
self.send_response(403)
|
||||
self.end_headers()
|
||||
return False
|
||||
return True
|
||||
def _set_headers(self):
|
||||
|
||||
self.send_response(200)
|
||||
self.send_header('Content-type', 'text/json')
|
||||
self.send_header('Connection', 'keepalive')
|
||||
self.end_headers()
|
||||
return True
|
||||
|
||||
def do_GET(self):
|
||||
if not self.check_allowed() :
|
||||
return
|
||||
self._set_headers()
|
||||
if self.path == "/api/minetest/channel" :
|
||||
if queue :
|
||||
k = queue.pop()
|
||||
self.wfile.write((' { "data" : { "name": %s, "password" : %s }, "type": "auth"} ' % (json.dumps(k[0]),json.dumps(k[1]))).encode())
|
||||
else :
|
||||
self.wfile.write("{}".encode())
|
||||
elif self.path.startswith("/status/"):
|
||||
name = self.path.split("/")[-1]
|
||||
if not name in auth_status :
|
||||
self.wfile.write("Unknown".encode())
|
||||
else :
|
||||
self.wfile.write(str(auth_status[name]).encode())
|
||||
del auth_status[name]
|
||||
def do_POST(self):
|
||||
if not self.check_allowed() :
|
||||
return
|
||||
self._set_headers()
|
||||
if self.path == "/query" :
|
||||
form = cgi.FieldStorage(
|
||||
fp=self.rfile,
|
||||
headers=self.headers,
|
||||
environ={'REQUEST_METHOD': 'POST'}
|
||||
)
|
||||
user = form.getvalue("name")
|
||||
pwd = form.getvalue("password")
|
||||
queue.append((user,pwd))
|
||||
else: # User has been identified
|
||||
js = self.rfile.read().decode()
|
||||
k = json.loads(js)
|
||||
auth_status[k["data"]["name"]] = k["data"]["success"]
|
||||
|
||||
def run(port=8000):
|
||||
server_address = ('127.0.0.1', port)
|
||||
httpd = HTTPServer(server_address, S)
|
||||
httpd.serve_forever()
|
||||
|
||||
if __name__ == "__main__":
|
||||
from sys import argv
|
||||
|
||||
if len(argv) == 2:
|
||||
run(port=int(argv[1]))
|
||||
else:
|
||||
run()
|
Loading…
Reference in New Issue