Compare commits
5 Commits
1aee5b5e71
...
90e1a3a73b
Author | SHA1 | Date | |
---|---|---|---|
|
90e1a3a73b | ||
|
2ad636e887 | ||
|
d74d38a582 | ||
|
8fafc34bcb | ||
|
e8a9e53c35 |
137
app.py
137
app.py
@ -1,5 +1,9 @@
|
|||||||
import glob
|
import glob
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
import re
|
||||||
|
import sshpubkeys
|
||||||
|
|
||||||
from flask import Flask, redirect, url_for, render_template, request
|
from flask import Flask, redirect, url_for, render_template, request
|
||||||
|
|
||||||
# lyadmin
|
# lyadmin
|
||||||
@ -25,6 +29,11 @@ ACCOUNT_DIR = "req/";
|
|||||||
FULL_PATH = str(WORKING_DIR) + str(ACCOUNT_DIR)
|
FULL_PATH = str(WORKING_DIR) + str(ACCOUNT_DIR)
|
||||||
CONF_PATH = str(WORKING_DIR) + "lyadmin.conf.json"
|
CONF_PATH = str(WORKING_DIR) + "lyadmin.conf.json"
|
||||||
|
|
||||||
|
# validation stuff
|
||||||
|
MAX_PUB_KEY_LEN = 5000
|
||||||
|
EMAIL_REGEX = "^[a-z0-9]+[\._]?[a-z0-9]+[@]\w+[.]\w{2,10}$"
|
||||||
|
KEY_REGEX = "^[ -~]+$"
|
||||||
|
|
||||||
# Account requests are given ID numbers
|
# Account requests are given ID numbers
|
||||||
# the first request will have the below
|
# the first request will have the below
|
||||||
# id number
|
# id number
|
||||||
@ -34,6 +43,14 @@ INIT_REQ_ID = "00000"
|
|||||||
with open(CONF_PATH) as c: conf_json_str = c.read()
|
with open(CONF_PATH) as c: conf_json_str = c.read()
|
||||||
conf_obj = json.loads(conf_json_str)
|
conf_obj = json.loads(conf_json_str)
|
||||||
|
|
||||||
|
# A list of all the shell enums
|
||||||
|
conf_obj["shell_tup_list"] = list(map(
|
||||||
|
lambda k : (
|
||||||
|
k, conf_obj["shell"][k]
|
||||||
|
),
|
||||||
|
list(conf_obj["shell"].keys())
|
||||||
|
))
|
||||||
|
|
||||||
# The main home page
|
# The main home page
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
def home():
|
def home():
|
||||||
@ -48,22 +65,23 @@ def home():
|
|||||||
|
|
||||||
return render_template("index.html", u_list=u_list, page_name="home")
|
return render_template("index.html", u_list=u_list, page_name="home")
|
||||||
|
|
||||||
|
# Generates the page with rule. No logic needed.
|
||||||
# The page with rules
|
|
||||||
def rules():
|
def rules():
|
||||||
return render_template("rules.html")
|
return render_template("rules.html")
|
||||||
|
|
||||||
# Generate HTML for a form widget
|
# Generate HTML for a form widget
|
||||||
def widg_fun(widg):
|
def widg_fun(widg):
|
||||||
if(widg.w_type == "input"):
|
if(widg.w_type == "input"):
|
||||||
# Return HTML for a single line input
|
return "input id=id_%s name=%s type=text></input"%(
|
||||||
return "input id=id_%s name=%s type=text></input"%(widg.w_name, widg.w_name)
|
widg.w_name, widg.w_name
|
||||||
|
)
|
||||||
elif(widg.w_type == "textarea"):
|
elif(widg.w_type == "textarea"):
|
||||||
# Return HTML for a big text input box
|
return "textarea cols=40 id=id_%s name=%s rows=10 required=\"\""%(
|
||||||
return "textarea cols=40 id=id_%s name=%s rows=10 required=\"\""%(widg.w_name, widg.w_name)
|
widg.w_name, widg.w_name
|
||||||
|
)
|
||||||
elif(widg.w_type == "check"):
|
elif(widg.w_type == "check"):
|
||||||
# Return HTML for a check box
|
return "input id=id_%s name=%s type=checkbox required=\"\""%(
|
||||||
return "input id=id_%s name=%s type=checkbox required=\"\""%(widg.w_name, widg.w_name)
|
widg.w_name, widg.w_name)
|
||||||
return widg.w_type;
|
return widg.w_type;
|
||||||
|
|
||||||
# Generate HTML for request form
|
# Generate HTML for request form
|
||||||
@ -78,32 +96,57 @@ def req():
|
|||||||
|
|
||||||
# Configuration for our request form
|
# Configuration for our request form
|
||||||
rt = {
|
rt = {
|
||||||
"username": Widg("username", "input", None),
|
"username": Widg(
|
||||||
"email for account lockout / registration confirmation (optional)": Widg("email", "input", None),
|
"username",
|
||||||
"SSH public key": Widg("pub_key", "textarea", None),
|
"input",
|
||||||
"shell of choice": Widg("shell", "choice", map(lambda k : (k, conf_obj["shell"][k]), list(conf_obj["shell"].keys()))),
|
None
|
||||||
"have you read the rules?": Widg("rule_read", "check", None)
|
),
|
||||||
|
"email for account lockout / registration confirmation (optional)": Widg(
|
||||||
|
"email",
|
||||||
|
"input",
|
||||||
|
None
|
||||||
|
),
|
||||||
|
"SSH public key": Widg(
|
||||||
|
"pub_key",
|
||||||
|
"textarea",
|
||||||
|
None
|
||||||
|
),
|
||||||
|
"shell of choice": Widg(
|
||||||
|
"shell",
|
||||||
|
"choice",
|
||||||
|
conf_obj["shell_tup_list"]
|
||||||
|
),
|
||||||
|
"have you read the rules?": Widg(
|
||||||
|
"rule_read", "check", None
|
||||||
|
)
|
||||||
};
|
};
|
||||||
return render_template("req.html", req_tab = rt, widg_fun = widg_fun, page_name="req")
|
return render_template(
|
||||||
|
"req.html",
|
||||||
|
req_tab = rt,
|
||||||
|
widg_fun = widg_fun,
|
||||||
|
page_name="req"
|
||||||
|
)
|
||||||
|
|
||||||
# Process input from the /req page
|
def handle_invalid_data(req):
|
||||||
|
# print(str(e))
|
||||||
|
return render_template("signup.html", is_email_user = False)
|
||||||
|
|
||||||
|
# Process input from user creation POST request
|
||||||
def signup():
|
def signup():
|
||||||
app.route('/req/signup')
|
app.route('/req/signup')
|
||||||
|
|
||||||
# Get all the params from the POST
|
# Get all the params from the POST
|
||||||
# request
|
# request
|
||||||
username = request.form["username"]
|
username = request.form["username"].strip()
|
||||||
email = request.form["email"]
|
email = request.form["email"].strip()
|
||||||
pub_key = request.form["pub_key"]
|
pub_key = request.form["pub_key"].strip()
|
||||||
shell = request.form["shell"]
|
shell = request.form["shell"].strip()
|
||||||
rule_read = request.form["rule_read"]
|
rule_read = request.form["rule_read"].strip()
|
||||||
|
|
||||||
is_email_user = False;
|
is_email_user = False;
|
||||||
|
|
||||||
# If a user didnt read the rules
|
# If a user didnt read the rules
|
||||||
# send them back
|
# send them back
|
||||||
# Browser validations should
|
|
||||||
# prevent this....
|
|
||||||
if(rule_read != "on"):
|
if(rule_read != "on"):
|
||||||
return redirect(url_for('req'))
|
return redirect(url_for('req'))
|
||||||
|
|
||||||
@ -113,18 +156,54 @@ def signup():
|
|||||||
else:
|
else:
|
||||||
email = "NO_EMAIL"
|
email = "NO_EMAIL"
|
||||||
|
|
||||||
|
# Validate shell
|
||||||
|
if(not shell in conf_obj["shell"]):
|
||||||
|
print("failed shell validation")
|
||||||
|
return handle_invalid_data(req)
|
||||||
|
|
||||||
|
# Validate email
|
||||||
|
if( is_email_user and not re.search(EMAIL_REGEX, email)):
|
||||||
|
print("failed email validation")
|
||||||
|
return handle_invalid_data(req)
|
||||||
|
|
||||||
|
# Validate the SSH pub key
|
||||||
|
# Most software only handles up to 4096 bit keys
|
||||||
|
if(len(pub_key) > MAX_PUB_KEY_LEN):
|
||||||
|
print("key failed len check")
|
||||||
|
return handle_invalid_data(req)
|
||||||
|
|
||||||
|
# Only printable ascii characters in
|
||||||
|
# a valid key
|
||||||
|
# if(not re.search("^[ -~]+$", pub_key)):
|
||||||
|
if(not re.search(KEY_REGEX, pub_key)):
|
||||||
|
print("key failed regex")
|
||||||
|
return handle_invalid_data(req)
|
||||||
|
|
||||||
|
# Check the key against a library
|
||||||
|
key = sshpubkeys.SSHKey(
|
||||||
|
pub_key,
|
||||||
|
strict_mode=False,
|
||||||
|
skip_option_parsing=True
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
key.parse()
|
||||||
|
except Exception as e:
|
||||||
|
print("key failed lib validation")
|
||||||
|
return handle_invalid_data(request)
|
||||||
|
|
||||||
# All users requests have a sequential ID
|
# All users requests have a sequential ID
|
||||||
# this checks how many requests we have
|
# The below picks the next ID based on
|
||||||
# and gives us a free ID so we can save
|
# how many requests we already have saved
|
||||||
# our request
|
# to disk
|
||||||
# This sets the ID of the request we're
|
|
||||||
# abou to save to dsik
|
|
||||||
if(len(glob.glob(ACCOUNT_DIR + str("[0-9]*ident*"))) == 0):
|
if(len(glob.glob(ACCOUNT_DIR + str("[0-9]*ident*"))) == 0):
|
||||||
new_id = int(INIT_REQ_ID)
|
new_id = int(INIT_REQ_ID)
|
||||||
new_id_str = INIT_REQ_ID
|
new_id_str = INIT_REQ_ID
|
||||||
else:
|
else:
|
||||||
max_id = max(list(map( lambda path : path.split("/")[-1].split(".")[0] , glob.glob(str(ACCOUNT_DIR) + "[0-9]*ident*"))))
|
max_id = max(
|
||||||
# max_id = max(list(map( lambda path : path.split("/")[-1].split(".")[0] , glob.glob("./test/[0-9]*ident*"))))
|
list(map(
|
||||||
|
lambda path : path.split("/")[-1].split(".")[0],
|
||||||
|
glob.glob(str(ACCOUNT_DIR) + "[0-9]*ident*")))
|
||||||
|
)
|
||||||
zpad = len(max_id)
|
zpad = len(max_id)
|
||||||
new_id = int(max_id)+1
|
new_id = int(max_id)+1
|
||||||
new_id_str = str(new_id).zfill(zpad)
|
new_id_str = str(new_id).zfill(zpad)
|
||||||
|
@ -1 +1,2 @@
|
|||||||
Flask==1.1.2
|
Flask==1.1.2
|
||||||
|
sshpubkeys==3.1.0
|
||||||
|
Loading…
Reference in New Issue
Block a user