added the server component.

This commit is contained in:
iou1name 2019-06-02 18:20:55 -04:00
parent 82638d56d1
commit 68e25bcdcc
3 changed files with 99 additions and 1 deletions

View File

@ -6,7 +6,7 @@ Python 3.6+
#### Master #### Master
Python packages: `requests bs4` Python packages: `requests bs4`
#### Server #### Server
Python packages: `flask` Python packages: `flask passlib argon2_cffi`
#### Slave #### Slave
Python packages: ` ` Python packages: ` `

12
config_server.py.template Normal file
View File

@ -0,0 +1,12 @@
#!/usr/bin/env python3
"""
Configuration settings for overwrought_server.py.
`modpack_name` is used for vanity purposes when naming the modpack.
`pw_hash` is the argon2-hashed version of the modpack owner's password.
`mods_dir` is the directory to place the mod files in for download. Your
web server/reverse proxy eg. Nginx should allow access to this directory.
"""
modpack_name = "motherlode1"
pw_hash = "PW_HASH"
mods_dir = "/var/www/overwrought/mods"
"""

86
overwrought_server.py Normal file
View File

@ -0,0 +1,86 @@
#!/usr/bin/env python3
"""
The overwrought server, for exchanging mods from master to slave recipients.
"""
import json
import sqlite3
import threading
from passlib.hash import argon2
from flask import Flask, send_file, request, abort
import config_server
app = Flask(__name__)
app.config['db_lock'] = threading.Lock()
@app.route('/')
def index():
"""
Main index page. Displays the mod summary page.
"""
return send_file(config_server.modpack_name + '.html')
@app.route('/get')
def get():
"""
Returns all mod file entries contained in the database as JSON.
Determing which files to update is left as an exercise up to the
client.
"""
app.config.get('db_lock').acquire()
con = sqlite3.connect('modpack.db')
cur = sqlite3.cursor()
mods = cur.execute('SELECT filename FROM mod').fetchall()
app.config.get('db_lock').release()
mods = [mod[0] for mod in mods]
return json.dumps(mods)
@app.route('/post', methods=['POST'])
def post():
"""
Allows the modpack owner to upload new mods and a new database to the
server. Owner must be validated.
"""
password = request.form.get('password')
if not argon2.verify(password, config_server.pw_hash):
abort(401)
db = request.files.get('database')
app.config.get('db_lock').acquire()
db.save('modpack.db')
app.config.get('db_lock').release()
for fname, file in request.files.items():
if fname == 'modpack.db':
continue
file.save(os.path.join(config_server.mods_dir, fname))
def generate_hash(password):
"""
A utility for generating an argon2 password hash.
"""
pw_hash = argon2.hash(password)
return pw_hash
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(
description="The overwrought server. Use gunicorn to start."
)
parse.add_argument(
'action',
choices=['hash'],
help="What action to perform.",
)
parse.add_argument(
'target',
help="The target to perform the action on."
)
args.parse_args()
if args.action == "hash":
pw_hash = generate_hash(args.target)
print(pw_hash)