AuthMinetest/minetestauth.py

78 lines
2.5 KiB
Python

#!/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()