Show users tree

This commit is contained in:
Andy Teijelo Pérez 2015-11-04 12:46:20 -05:00
parent ba036d26b7
commit 2a1a8d9e94
6 changed files with 111 additions and 75 deletions

130
main.py
View file

@ -3,14 +3,11 @@
from flask import Flask, request, abort, make_response, \
render_template, redirect, url_for, \
json, jsonify, session, flash
from werkzeug import secure_filename
from multiprocessing import Process
from urllib.parse import unquote
import hashlib
import random
import shutil
import time
import sys
import re
import os
@ -38,10 +35,12 @@ def delete_user(deluser):
f.close()
reload_freeradius()
def create_user(username, password):
nthash = hashlib.new('md4',password.encode('utf-16le')).hexdigest().upper()
def nthash(password):
return hashlib.new('md4',password.encode('utf-16le')).hexdigest().upper()
def create_user(username, password, creator):
f = open(users_file,"a")
f.write('{} NT-Password := "{}"\n'.format(username, nthash))
f.write('{} NT-Password := "{}" # created by {} \n'.format(username, nthash(password), creator))
f.close()
reload_freeradius()
@ -58,6 +57,22 @@ def index():
return render_template("index.html", guestpass=guestpass)
def load_users():
users = []
with open(users_file) as f:
for l in f:
if l.strip().startswith("#"):
continue
m = re.match("(^\S+).*-Password\s+:=\s+\"(\S+)\"(?:\s+#.*created.by\s+(\S+))?", l)
if m:
users.append(m.groups())
return users
def check_login(username, password):
for u,p,c in load_users():
if u == username and p == nthash(password):
return True
raise ValueError("Invalid username or password")
@app.route("/login",methods=['GET','POST'])
def login():
@ -68,18 +83,20 @@ def login():
if request.method == 'POST':
username = request.form.get("username",None)
password = request.form.get("password",None)
if username is None or password is None:
return render_template("login.html",error=True,errormsg="invalid username or password")
try:
check_call(["radtest",username,password,"localhost","0","testing123"])
except:
if username is None or password is None:
return render_template("login.html",error=True,errormsg="invalid username or password")
if username == 'guest':
return render_template("login.html",error=True,errormsg="guest user has no admin privileges")
try:
check_login(username, password)
except Exception as e:
return render_template("login.html",error=True,errormsg=str(e))
session['logged_in'] = True
session['username'] = username
return redirect(url_for('admin'))
@app.route("/admin",methods=['GET','POST'])
@ -97,6 +114,7 @@ def admin():
username = request.form.get('username',None)
pass1 = request.form.get('password1',None)
pass2 = request.form.get('password2',None)
creator = session['username']
if username is not None:
if username == 'guest':
return render_template("admin.html", create_error=True, errormsg="Cannot create guest user")
@ -104,67 +122,53 @@ def admin():
pass2 is None or \
pass1 != pass2:
return render_template("admin.html", create_error=True, errormsg="Password do not match")
create_user(username,pass1)
create_user(username,pass1,creator)
flash("User created successfully")
return render_template("admin.html")
def render_users_tree(tree):
lines = []
def _render(user, edges, is_last):
lines.append((edges + (" └─" if is_last else " ├─"), user))
n = len(tree[user])
for i,u in enumerate(tree[user]):
_render(u, edges + (" " if is_last else ""), i == n - 1)
return lines
# root = tree(""); n = len(root)
# for i,u in enumerate(root):
_render("", "", True)
return lines
@app.route("/users")
def list_users():
if not session.get('logged_in', False):
return redirect(url_for('login'))
users = load_users()
users_set = set(x[0] for x in users)
tree = { "": [] }
for user,passwd,creator in users:
if user == "guest":
continue
tree[user] = []
if creator is None:
tree[""].append(user)
else:
if creator not in users_set:
creator += " (invalid username)"
tree[""].append(creator)
tree[creator] = tree.get(creator,[]) + [user]
lines = render_users_tree(tree)
return render_template("users.html", users=lines)
@app.route("/logout")
def logout():
session.pop("logged_in",None)
return redirect(url_for("index"))
#@app.route("/upload",methods=['GET','POST'])
#def upload():
# if request.method == 'POST':
# f = request.files['circuit']
# if len(f.filename) == 0:
# return render_template("emptyupload.html")
# if f and len(f.filename) > 0:
# sid = new_id()
# session_dir = os.path.join('sessions',sid)
# shutil.copytree('skel',session_dir)
# old_dir = os.getcwd()
# os.chdir(session_dir)
# try:
# skipcookie = unquote(request.cookies.get('skip_tests',''))
# skip = set(int(n) for n in skipcookie.split(','))
# except:
# skip = set()
# options = {'skip_tests': skip}
# try:
# filename = secure_filename(f.filename)
# f.save(filename)
# p = Process(target=Verifier, args=(filename, ), kwargs={'options': options})
# p.start()
# except:
# os.chdir(old_dir)
# raise
# os.chdir(old_dir)
# return redirect(url_for('tests',sid=sid))
# return "Ocurrió algún error haciendo upload"
#@app.route("/details")
#def details():
# sid = request.args.get('sid','')
# filename = request.args.get('file','')
# if len(sid) == 0:
# return ''
# if len(filename) == 0:
# return ''
# filename = secure_filename(filename)
# session_dir = os.path.join('sessions',sid)
# try:
# f = open(os.path.join(session_dir,filename), encoding="utf8")
# s = f.read()
# f.close()
# except FileNotFoundError:
# s = ""
# resp = make_response(s)
# resp.mimetype = 'text/plain'
# return resp
if __name__ == '__main__':
if "debug" in sys.argv:
users_file = "users.dpto2"
app.debug = True
app.run(host="0.0.0.0")

View file

@ -17,3 +17,12 @@
#selected-tests span {
margin-left: 0.5em;
}
div.users-tree {
line-height: initial;
}
.edges {
font-family: monospace;
line-height: initial;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

View file

@ -6,7 +6,7 @@
{% endblock %}
{% block content %}
<center><h1>Usuarios de <code>dpto2</code></h1></center>
<center><h2>Usuarios de <code>dpto2</code></h2></center>
{% with messages = get_flashed_messages() %}
{% if messages %}
@ -18,7 +18,6 @@
{% endif %}
{% endwith %}
<div class="container" style="width: 601px;">
<div class="row"><h3>Crear usuario nuevo:</h3></div>
<div class="row">
@ -76,7 +75,7 @@
</div>
</form>
</div>
<div class="row"><a href="{{ url_for('list_users') }}">Lista de usuarios</a></div>
<div class="row"><a href="{{ url_for('logout') }}">Cerrar sesión</a></div>
</div>
{% endblock %}

View file

@ -10,7 +10,7 @@
<link href="{{ static('css/bootstrap.min.css') }}" rel="stylesheet">
<link href="{{ static('css/font-awesome.min.css') }}" rel="stylesheet">
<link href="{{ static('css/isabel.css') }}" rel="stylesheet">
<!-- <link href="{{ static('img/icon.png') }}" rel="icon"/> -->
<link href="{{ static('img/icon.png') }}" rel="icon"/>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="{{ static('js/cookies.js')}}"></script>
@ -28,14 +28,10 @@
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="container" style="width: 600px;">
{% block content %}
{% endblock %}
</div>
</div>
</div>
{% block body_scripts %}
<!-- Include all compiled plugins (below), or include individual files as needed -->

28
templates/users.html Normal file
View file

@ -0,0 +1,28 @@
{% extends "base.html" %}
{% block title %}Usuarios{% endblock %}
{% block head %}
{{ super() }}
{% endblock %}
{% block content %}
<div class="row"><h3>Usuarios de <code>dpto2</code>:</h3></div>
<div class="well well-lg">
<div class="users-tree">
{% for edges, username in users %}
<span>
{% if username == "" %}
&nbsp;&nbsp;<i>Ilúvatar</i>
{% else %}
<span class="edges">{{ edges|replace(" ","&nbsp;")|safe }}</span>
{{ username }}
{% endif %}
</span><br>
{% endfor %}
</div>
</div>
<div class="row"><a href="{{ url_for('admin') }}">Administrar usuarios</a></div>
<div class="row"><a href="{{ url_for('logout') }}">Cerrar sesión</a></div>
{% endblock %}