Zdalne-systemy-z-kit-uVPN/app.py

246 lines
7.6 KiB
Python
Raw Normal View History

2023-04-14 09:24:32 +00:00
import datetime
2023-04-24 06:27:35 +00:00
from functools import wraps
2023-04-14 08:41:07 +00:00
from time import sleep
from flask import Flask, make_response, redirect, send_file, jsonify, request, render_template, url_for
2023-04-07 11:25:24 +00:00
import db
import os
from werkzeug.utils import secure_filename
2023-04-12 13:49:11 +00:00
import subprocess
2023-04-13 11:12:08 +00:00
import utils
import shutil
2023-04-14 10:37:37 +00:00
import config
import machines
2023-04-12 13:46:10 +00:00
2023-04-06 12:07:13 +00:00
app = Flask(__name__)
2023-04-13 11:38:36 +00:00
app.config['UPLOAD_FOLDER'] = "squash"
2023-04-24 08:22:17 +00:00
app.config['STYLE_FOLDER'] = "style"
app.config['MAX_CONTENT_LENGTH'] = 1024 * 1024 * 512 # 512MB
2023-04-07 11:25:24 +00:00
2023-04-14 10:37:37 +00:00
utils.init_threads()
2023-04-14 08:41:07 +00:00
2023-04-24 06:27:35 +00:00
def login_required(f):
@wraps(f)
def login_function(*args, **kwargs):
auth_token = request.cookies.get('auth_token')
if auth_token != "" or auth_token is not None:
if db.get_user_bytoken(auth_token) is None:
return redirect("/login")
return f(*args, **kwargs)
return login_function
2023-04-24 06:33:51 +00:00
def is_logged(auth_token):
if auth_token != "" or auth_token is not None:
if db.get_user_bytoken(auth_token) is not None:
return True
return False
2023-04-13 09:52:51 +00:00
@app.route('/')
2023-04-24 06:27:35 +00:00
@login_required
2023-04-13 09:52:51 +00:00
def main():
machines_all = db.get_machines()
2023-04-21 09:02:06 +00:00
return render_template('index.html', ssh_port=config.webssh_port, machines=machines_all.machines)
2023-04-13 09:52:51 +00:00
2023-04-13 10:13:54 +00:00
@app.route('/login')
2023-04-13 10:13:24 +00:00
def login():
2023-04-24 06:33:51 +00:00
if is_logged(request.cookies.get('auth_token')) is True:
machines_all = db.get_machines()
return render_template('index.html', ssh_port=config.webssh_port, machines=machines_all.machines)
return render_template('login.html')
2023-04-13 10:09:15 +00:00
2023-04-21 08:40:09 +00:00
2023-04-19 10:27:09 +00:00
@app.route('/logout')
def logout():
2023-04-24 06:33:51 +00:00
if is_logged(request.cookies.get('auth_token')) is True:
db.del_auth_token(request.cookies.get('auth_token'))
response = make_response(redirect('/'))
response.delete_cookie('auth_token')
return response
2023-04-19 10:27:09 +00:00
return render_template('login.html')
2023-04-21 08:40:09 +00:00
2023-04-19 12:10:31 +00:00
@app.route('/images')
2023-04-24 06:27:35 +00:00
@login_required
2023-04-19 12:10:31 +00:00
def list_images():
images_all = db.get_images()
2023-04-19 12:11:18 +00:00
return render_template("images.html", images=images_all.images)
2023-04-19 12:10:31 +00:00
2023-04-21 08:40:09 +00:00
2023-04-19 12:10:31 +00:00
@app.route('/create')
2023-04-24 06:27:35 +00:00
@login_required
2023-04-13 10:55:06 +00:00
def create_conf():
return render_template("create.html")
2023-04-13 10:55:06 +00:00
@app.route('/api/createconf', methods=['POST'])
2023-04-24 06:27:35 +00:00
@login_required
2023-04-13 10:55:06 +00:00
def create_conf_post():
2023-04-21 08:40:09 +00:00
try:
config_name = request.form['config_name']
token_name = request.form['token_name']
key_length = request.form['key_length']
ip = request.form['ip']
password = request.form['pass']
except:
return jsonify(message="400")
2023-04-19 13:31:25 +00:00
if db.get_conf_id_name(config_name+".squashfs") is not None:
return jsonify(message="400")
if db.get_conf_id(token_name) is not None:
2023-04-21 08:40:09 +00:00
return jsonify(message="400")
2023-04-13 11:14:21 +00:00
folder = utils.generate_random_string(5)
2023-04-13 10:55:06 +00:00
try:
os.mkdir(os.path.join(os.getcwd(), 'configs', folder))
2023-04-13 10:55:06 +00:00
authorized_keys_config = request.form['authorized_keys_config']
authorized_keys_file = open(folder+"/authorized_keys", "w")
2023-04-13 11:12:08 +00:00
authorized_keys_file.write(authorized_keys_config)
authorized_keys_file.close()
2023-04-13 10:55:06 +00:00
except:
shutil.copy('./configs/authorized_keys',
'./configs/' + folder+"/authorized_keys")
2023-04-13 11:20:37 +00:00
script_path = os.path.join(os.getcwd(), 'configs', "create.sh")
ini_path = os.path.join(os.getcwd(), 'configs', "uVPN.ini")
conf_path = os.path.join(os.getcwd(), 'configs', "uVPN.conf")
pub_path = os.path.join(os.getcwd(), 'configs', "server.pub")
authorized_keys_path = os.path.join(
os.getcwd(), 'configs', folder, "authorized_keys")
2023-04-13 11:20:37 +00:00
sshd_config_path = os.path.join(os.getcwd(), 'configs', "sshd_config")
sendmail_path = os.path.join(os.getcwd(), 'configs', "sendmail.sh")
msmtp_conf = os.path.join(os.getcwd(), 'configs', "msmtprc")
2023-04-25 08:07:43 +00:00
subprocess.run([script_path, "-i "+ini_path, "-c "+conf_path,
"-k "+pub_path, "-l "+key_length, "-n"+config_name,
"-p "+ip, "-a "+authorized_keys_path, "-d "+sshd_config_path,
"-m "+sendmail_path, "-o "+msmtp_conf," > /dev/null 2>&1 "])
2023-04-13 11:12:08 +00:00
if os.path.exists(folder):
2023-04-13 11:23:54 +00:00
shutil.rmtree(folder)
2023-04-21 14:39:25 +00:00
output = subprocess.run(
['openssl', 'passwd', '-6', password], capture_output=True, text=True)
2023-04-21 08:40:09 +00:00
db.add_conf_image(config_name+".squashfs", token_name, ip, output.stdout)
2023-04-13 11:12:08 +00:00
return send_file(os.path.join(app.config['UPLOAD_FOLDER'], config_name+".pub"))
2023-04-13 10:55:06 +00:00
2023-04-13 09:52:51 +00:00
@app.route('/api/login', methods=['POST'])
2023-04-13 10:13:24 +00:00
def login_api():
2023-04-13 09:52:51 +00:00
username = request.form['username']
password = request.form['password']
# register
# db.add_user(username, password)
# register
2023-04-13 09:59:55 +00:00
auth_token = db.login(username, password)
2023-04-13 09:52:51 +00:00
if auth_token is None:
2023-04-13 10:25:01 +00:00
return render_template('login.html', incorrect="Incorrect username or password!")
2023-04-13 10:32:13 +00:00
response = make_response(redirect('/'))
2023-04-13 09:52:51 +00:00
response.set_cookie('auth_token', auth_token)
return response
2023-04-21 08:40:09 +00:00
2023-04-19 13:31:25 +00:00
@app.route('/delete/<int:image_id>', methods=['POST'])
2023-04-24 06:27:35 +00:00
@login_required
2023-04-19 13:31:25 +00:00
def delete(image_id):
2023-04-21 06:00:29 +00:00
if db.get_image_allocation(image_id) is not None:
return jsonify(message="409")
2023-04-19 13:31:25 +00:00
filename = db.get_conf_image_id(image_id)
squashfs = os.path.join(app.config['UPLOAD_FOLDER'], filename)
2023-04-21 08:40:09 +00:00
pubkey = os.path.join(
app.config['UPLOAD_FOLDER'], filename.split(".")[0]+".pub")
2023-04-19 13:31:25 +00:00
if os.path.exists(squashfs):
os.remove(squashfs)
if os.path.exists(pubkey):
os.remove(pubkey)
db.del_image(image_id)
2023-04-13 09:52:51 +00:00
2023-04-21 08:40:09 +00:00
return redirect(url_for('list_images'))
2023-04-06 12:07:13 +00:00
2023-04-25 07:21:53 +00:00
@app.route('/download_key/<int:image_id>', methods=['POST'])
@login_required
def download_key(image_id):
filename = db.get_conf_image_id(image_id)
return send_file(os.path.join(
app.config['UPLOAD_FOLDER'], filename.split(".")[0]+".pub"))
2023-04-13 09:52:51 +00:00
@app.route("/api/getconf")
2023-04-07 11:25:24 +00:00
def get_image():
2023-04-14 09:24:32 +00:00
try:
filename = db.get_conf_image(request.headers['token'])
except:
pass
try:
date = db.get_image_allocation_time(request.headers['token'])
if date is not None:
delta = datetime.datetime.now() - date
if delta.total_seconds() > 30:
2023-04-14 09:24:32 +00:00
db.del_image_allocation_token(request.headers['token'])
else:
filename = None
2023-04-14 09:26:34 +00:00
else:
db.set_image_allocation(
request.headers['token'], request.remote_addr)
2023-04-14 09:24:32 +00:00
except:
pass
2023-04-07 11:25:24 +00:00
if filename is None or filename == "":
2023-04-14 10:37:37 +00:00
filename = config.default_file
2023-04-12 13:50:21 +00:00
return send_file(os.path.join(app.config['UPLOAD_FOLDER'], filename))
2023-04-14 10:37:37 +00:00
2023-04-21 08:40:09 +00:00
@app.route("/api/getpass")
def get_pass():
try:
password = db.get_conf_password(request.headers['token'])
return password
except:
return ""
2023-04-14 12:02:01 +00:00
@app.route("/api/release_allocation", methods=['POST'])
def release_allocation():
try:
2023-04-19 09:45:08 +00:00
id_allocation = db.get_conf_id_name(
request.headers['name']+".squashfs")
2023-04-14 12:16:03 +00:00
if id_allocation is None or id_allocation == "":
2023-04-14 12:02:01 +00:00
return jsonify(message="400")
except:
2023-04-19 09:45:08 +00:00
return jsonify(message="400")
2023-04-14 12:02:01 +00:00
if id_allocation is not None:
2023-04-14 13:49:19 +00:00
db.del_image_allocation_id_image(id_allocation)
2023-04-14 12:02:01 +00:00
else:
2023-04-14 12:13:12 +00:00
return jsonify(message="404")
2023-04-14 12:02:01 +00:00
return jsonify(message="200")
2023-04-14 13:42:41 +00:00
@app.route("/api/addip", methods=['POST'])
def add_ip():
try:
token = request.headers['token']
2023-04-14 13:51:54 +00:00
ip = request.form['ip']
if utils.is_valid_ip_address(ip) is False:
return jsonify(message="400")
2023-04-14 13:42:41 +00:00
except:
2023-04-19 08:25:14 +00:00
return jsonify(message="400")
2023-04-19 10:01:53 +00:00
if db.update_image_allocation_ip_vpn(token, ip) is not None:
2023-04-19 08:25:14 +00:00
return jsonify(message="200")
else:
return jsonify(message="400")
2023-04-24 08:22:17 +00:00
@app.route("/style/<string:name>")
def get_style(name):
try:
return send_file(os.path.join(app.config['STYLE_FOLDER'], name))
except:
return "", 404
2023-04-14 10:37:37 +00:00
if __name__ == '__main__':
app.run(host="0.0.0.0")