From 539cd6f0f44dfcdc0345367c4cf7f859ec9eb36d Mon Sep 17 00:00:00 2001 From: Jordan Rodgers Date: Tue, 12 Dec 2017 15:48:37 -0500 Subject: [PATCH] add oidc auth to all routes and yapf everything --- app.py | 93 ++++++++++++++++++++++++++++++++++-------------- config.sample.py | 18 +++++++++- db.py | 1 + starrs.py | 23 ++++++------ 4 files changed, 97 insertions(+), 38 deletions(-) diff --git a/app.py b/app.py index e2ec590..db9d010 100644 --- a/app.py +++ b/app.py @@ -17,10 +17,11 @@ app.config.from_pyfile(config) app.config["GIT_REVISION"] = subprocess.check_output( ['git', 'rev-parse', '--short', 'HEAD']).decode('utf-8').rstrip() +auth = OIDCAuthentication( + app, + issuer=app.config['OIDC_ISSUER'], + client_registration_info=app.config['OIDC_CLIENT_CONFIG']) -auth = OIDCAuthentication(app, - issuer=app.config['OIDC_ISSUER'], - client_registration_info=app.config['OIDC_CLIENT_CONFIG']) @app.route("/") @auth.oidc_auth @@ -39,6 +40,7 @@ def list_vms(): @app.route("/isos") +@auth.oidc_auth def isos(): proxmox = connect_proxmox(app.config['PROXMOX_HOST'], app.config['PROXMOX_USER'], @@ -48,6 +50,7 @@ def isos(): @app.route("/hostname/") +@auth.oidc_auth def hostname(name): starrs = connect_starrs( app.config['STARRS_DB_NAME'], app.config['STARRS_DB_USER'], @@ -62,6 +65,7 @@ def hostname(name): @app.route("/vm/") +@auth.oidc_auth def vm_details(vmid): user = session['userinfo']['preferred_username'] rtp = 'rtp' in session['userinfo']['groups'] @@ -71,34 +75,50 @@ def vm_details(vmid): starrs = connect_starrs( app.config['STARRS_DB_NAME'], app.config['STARRS_DB_USER'], app.config['STARRS_DB_HOST'], app.config['STARRS_DB_PASS']) - if int(vmid) in get_user_allowed_vms(proxmox, user) or 'rtp' in session['userinfo']['groups']: + if int(vmid) in get_user_allowed_vms( + proxmox, user) or 'rtp' in session['userinfo']['groups']: vm = get_vm(proxmox, vmid) vm['vmid'] = vmid vm['config'] = get_vm_config(proxmox, vmid) vm['disks'] = get_vm_disks(proxmox, vmid, config=vm['config']) vm['iso'] = get_vm_iso(proxmox, vmid, config=vm['config']) vm['interfaces'] = [] - for interface in get_vm_interfaces(proxmox, vm['vmid'], config=vm['config']): - vm['interfaces'].append([interface[0], get_ip_for_mac(starrs, interface[1])]) - vm['expire'] = get_vm_expire(vmid, app.config['VM_EXPIRE_MONTHS']).strftime('%m/%d/%Y') + for interface in get_vm_interfaces( + proxmox, vm['vmid'], config=vm['config']): + vm['interfaces'].append( + [interface[0], + get_ip_for_mac(starrs, interface[1])]) + vm['expire'] = get_vm_expire( + vmid, app.config['VM_EXPIRE_MONTHS']).strftime('%m/%d/%Y') usage = get_user_usage(proxmox, 'proxstar') limits = get_user_usage_limits(user) - usage_check = check_user_usage(proxmox, user, vm['config']['cores'], vm['config']['memory'], 0) - return render_template('vm_details.html', username=user, rtp=rtp, vm=vm, usage=usage, limits=limits, usage_check=usage_check) + usage_check = check_user_usage(proxmox, user, vm['config']['cores'], + vm['config']['memory'], 0) + return render_template( + 'vm_details.html', + username=user, + rtp=rtp, + vm=vm, + usage=usage, + limits=limits, + usage_check=usage_check) else: return '', 403 @app.route("/vm//power/", methods=['POST']) +@auth.oidc_auth def vm_power(vmid, action): user = session['userinfo']['preferred_username'] proxmox = connect_proxmox(app.config['PROXMOX_HOST'], app.config['PROXMOX_USER'], app.config['PROXMOX_PASS']) - if int(vmid) in get_user_allowed_vms(proxmox, user) or 'rtp' in session['userinfo']['groups']: + if int(vmid) in get_user_allowed_vms( + proxmox, user) or 'rtp' in session['userinfo']['groups']: if action == 'start': config = get_vm_config(proxmox, vmid) - usage_check = check_user_usage(proxmox, user, config['cores'], config['memory'], 0) + usage_check = check_user_usage(proxmox, user, config['cores'], + config['memory'], 0) if usage_check: return usage_check change_vm_power(proxmox, vmid, action) @@ -108,17 +128,20 @@ def vm_power(vmid, action): @app.route("/vm//cpu/", methods=['POST']) +@auth.oidc_auth def vm_cpu(vmid, cores): user = session['userinfo']['preferred_username'] proxmox = connect_proxmox(app.config['PROXMOX_HOST'], app.config['PROXMOX_USER'], app.config['PROXMOX_PASS']) - if int(vmid) in get_user_allowed_vms(proxmox, user) or 'rtp' in session['userinfo']['groups']: + if int(vmid) in get_user_allowed_vms( + proxmox, user) or 'rtp' in session['userinfo']['groups']: cur_cores = get_vm_config(proxmox, vmid)['cores'] if cores >= cur_cores: status = get_vm(proxmox, vmid)['qmpstatus'] if status == 'running' or status == 'paused': - usage_check = check_user_usage(proxmox, user, cores - cur_cores, 0, 0) + usage_check = check_user_usage(proxmox, user, + cores - cur_cores, 0, 0) else: usage_check = check_user_usage(proxmox, user, cores, 0, 0) if usage_check: @@ -130,17 +153,20 @@ def vm_cpu(vmid, cores): @app.route("/vm//mem/", methods=['POST']) +@auth.oidc_auth def vm_mem(vmid, mem): user = session['userinfo']['preferred_username'] proxmox = connect_proxmox(app.config['PROXMOX_HOST'], app.config['PROXMOX_USER'], app.config['PROXMOX_PASS']) - if int(vmid) in get_user_allowed_vms(proxmox, user) or 'rtp' in session['userinfo']['groups']: + if int(vmid) in get_user_allowed_vms( + proxmox, user) or 'rtp' in session['userinfo']['groups']: cur_mem = get_vm_config(proxmox, vmid)['memory'] // 1024 if mem >= cur_mem: status = get_vm(proxmox, vmid)['qmpstatus'] if status == 'running' or status == 'paused': - usage_check = check_user_usage(proxmox, user, 0, mem - cur_mem, 0) + usage_check = check_user_usage(proxmox, user, 0, mem - cur_mem, + 0) else: usage_check = check_user_usage(proxmox, user, 0, mem, 0) if usage_check: @@ -152,6 +178,7 @@ def vm_mem(vmid, mem): @app.route("/vm//renew", methods=['POST']) +@auth.oidc_auth def vm_renew(vmid): user = session['userinfo']['preferred_username'] proxmox = connect_proxmox(app.config['PROXMOX_HOST'], @@ -160,7 +187,8 @@ def vm_renew(vmid): starrs = connect_starrs( app.config['STARRS_DB_NAME'], app.config['STARRS_DB_USER'], app.config['STARRS_DB_HOST'], app.config['STARRS_DB_PASS']) - if int(vmid) in get_user_allowed_vms(proxmox, user) or 'rtp' in session['userinfo']['groups']: + if int(vmid) in get_user_allowed_vms( + proxmox, user) or 'rtp' in session['userinfo']['groups']: renew_vm_expire(vmid, app.config['VM_EXPIRE_MONTHS']) for interface in get_vm_interfaces(proxmox, vmid): renew_ip(starrs, get_ip_for_mac(starrs, interface[1])) @@ -170,12 +198,14 @@ def vm_renew(vmid): @app.route("/vm//eject", methods=['POST']) +@auth.oidc_auth def iso_eject(vmid): user = session['userinfo']['preferred_username'] proxmox = connect_proxmox(app.config['PROXMOX_HOST'], app.config['PROXMOX_USER'], app.config['PROXMOX_PASS']) - if int(vmid) in get_user_allowed_vms(proxmox, user) or 'rtp' in session['userinfo']['groups']: + if int(vmid) in get_user_allowed_vms( + proxmox, user) or 'rtp' in session['userinfo']['groups']: eject_vm_iso(proxmox, vmid) return '', 200 else: @@ -183,12 +213,14 @@ def iso_eject(vmid): @app.route("/vm//mount/", methods=['POST']) +@auth.oidc_auth def iso_mount(vmid, iso): user = session['userinfo']['preferred_username'] proxmox = connect_proxmox(app.config['PROXMOX_HOST'], app.config['PROXMOX_USER'], app.config['PROXMOX_PASS']) - if int(vmid) in get_user_allowed_vms(proxmox, user) or 'rtp' in session['userinfo']['groups']: + if int(vmid) in get_user_allowed_vms( + proxmox, user) or 'rtp' in session['userinfo']['groups']: iso = "{}:iso/{}".format(app.config['PROXMOX_ISO_STORAGE'], iso) mount_vm_iso(proxmox, vmid, iso) return '', 200 @@ -197,6 +229,7 @@ def iso_mount(vmid, iso): @app.route("/vm//delete", methods=['POST']) +@auth.oidc_auth def delete(vmid): user = session['userinfo']['preferred_username'] proxmox = connect_proxmox(app.config['PROXMOX_HOST'], @@ -205,7 +238,8 @@ def delete(vmid): starrs = connect_starrs( app.config['STARRS_DB_NAME'], app.config['STARRS_DB_USER'], app.config['STARRS_DB_HOST'], app.config['STARRS_DB_PASS']) - if int(vmid) in get_user_allowed_vms(proxmox, user) or 'rtp' in session['userinfo']['groups']: + if int(vmid) in get_user_allowed_vms( + proxmox, user) or 'rtp' in session['userinfo']['groups']: vmname = get_vm_config(proxmox, vmid)['name'] delete_vm(proxmox, starrs, vmid) delete_starrs(starrs, vmname) @@ -216,6 +250,7 @@ def delete(vmid): @app.route("/vm/create", methods=['GET', 'POST']) +@auth.oidc_auth def create(): user = session['userinfo']['preferred_username'] rtp = 'rtp' in session['userinfo']['groups'] @@ -252,16 +287,17 @@ def create(): else: valid, available = check_hostname(starrs, name) if valid and available: - vmid, mac = create_vm(proxmox, starrs, user, name, cores, memory, - disk, iso) - register_starrs(starrs, name, app.config['STARRS_USER'], mac, - get_next_ip(starrs, - app.config['STARRS_IP_RANGE'])[0][0]) + vmid, mac = create_vm(proxmox, starrs, user, name, cores, + memory, disk, iso) + register_starrs( + starrs, name, app.config['STARRS_USER'], mac, + get_next_ip(starrs, app.config['STARRS_IP_RANGE'])[0][0]) get_vm_expire(vmid, app.config['VM_EXPIRE_MONTHS']) return vmid @app.route('/limits/', methods=['POST']) +@auth.oidc_auth def set_limits(user): if 'rtp' in session['userinfo']['groups']: cpu = request.form['cpu'] @@ -274,6 +310,7 @@ def set_limits(user): @app.route('/limits//reset', methods=['POST']) +@auth.oidc_auth def reset_limits(user): if 'rtp' in session['userinfo']['groups']: delete_user_usage_limits(user) @@ -283,6 +320,7 @@ def reset_limits(user): @app.route('/limits') +@auth.oidc_auth def limits(): if 'rtp' in session['userinfo']['groups']: user = session['userinfo']['preferred_username'] @@ -296,13 +334,16 @@ def limits(): for pool in pools: if pool not in app.config['IGNORED_POOLS']: limits = get_user_usage_limits(pool) - user_limits.append([pool, limits['cpu'], limits['mem'], limits['disk']]) - return render_template('limits.html', username=user, rtp=rtp, user_limits=user_limits) + user_limits.append( + [pool, limits['cpu'], limits['mem'], limits['disk']]) + return render_template( + 'limits.html', username=user, rtp=rtp, user_limits=user_limits) else: return '', 403 @app.route('/novnc/') +@auth.oidc_auth def send_novnc(path): return send_from_directory('static/novnc-pve/novnc', path) diff --git a/config.sample.py b/config.sample.py index 1c82236..248fd5d 100644 --- a/config.sample.py +++ b/config.sample.py @@ -1,15 +1,31 @@ # Proxstar VM_EXPIRE_MONTHS = 3 +IGNORED_POOLS = [] + +# Flask +IP = '127.0.0.1' +PORT = '5000' +SERVER_NAME = 'proxstar.csh.rit.edu' +SECRET_KEY = '' + +# OIDC +OIDC_ISSUER = 'https://sso.csh.rit.edu/realms/csh' +OIDC_CLIENT_CONFIG = { + 'client_id': 'proxstar', + 'client_secret': '', + 'post_logout_redirect_uris': ['https://proxstar.csh.rit.edu/logout'] +} # Proxmox PROXMOX_HOST = '' PROXMOX_USER = '' PROXMOX_PASS = '' -PROXMOX_ISO_STORAGE = '' +PROXMOX_ISO_STORAGE = 'nfs-iso' # STARRS STARRS_DB_HOST = '' STARRS_DB_NAME = '' STARRS_DB_USER = '' STARRS_DB_PASS = '' +STARRS_USER = 'proxstar' STARRS_IP_RANGE = '' diff --git a/db.py b/db.py index 1457a22..cfe178e 100644 --- a/db.py +++ b/db.py @@ -55,6 +55,7 @@ def get_expired_vms(): expired.append(vm.id) return expired + def get_user_usage_limits(user): limits = dict() if session.query(exists().where(Usage_Limit.id == user)).scalar(): diff --git a/starrs.py b/starrs.py index d8385c6..8d41b3e 100644 --- a/starrs.py +++ b/starrs.py @@ -1,5 +1,6 @@ import psycopg2 + def connect_starrs(db, user, host, password): try: starrs = psycopg2.connect( @@ -15,7 +16,7 @@ def get_next_ip(starrs, range_name): c = starrs.cursor() try: c.execute("BEGIN") - c.callproc("api.initialize", ('root',)) + c.callproc("api.initialize", ('root', )) c.callproc("api.get_address_from_range", (range_name, )) results = c.fetchall() c.execute("COMMIT") @@ -28,8 +29,8 @@ def get_ip_for_mac(starrs, mac): c = starrs.cursor() try: c.execute("BEGIN") - c.callproc("api.initialize", ('root',)) - c.callproc("api.get_system_interface_addresses", (mac.lower(),)) + c.callproc("api.initialize", ('root', )) + c.callproc("api.get_system_interface_addresses", (mac.lower(), )) results = c.fetchall() c.execute("COMMIT") finally: @@ -43,8 +44,8 @@ def renew_ip(starrs, addr): c = starrs.cursor() try: c.execute("BEGIN") - c.callproc("api.initialize", ('root',)) - c.callproc("api.renew_interface_address", (addr,)) + c.callproc("api.initialize", ('root', )) + c.callproc("api.renew_interface_address", (addr, )) results = c.fetchall() c.execute("COMMIT") finally: @@ -56,20 +57,20 @@ def check_hostname(starrs, hostname): c = starrs.cursor() try: c.execute("BEGIN") - c.callproc("api.initialize", ('root',)) - c.callproc("api.validate_name", (hostname,)) + c.callproc("api.initialize", ('root', )) + c.callproc("api.validate_name", (hostname, )) valid = False if hostname == c.fetchall()[0][0]: valid = True c.execute("COMMIT") c.execute("BEGIN") - c.callproc("api.initialize", ('root',)) + c.callproc("api.initialize", ('root', )) c.callproc("api.check_dns_hostname", (hostname, 'csh.rit.edu')) available = False if not c.fetchall()[0][0]: available = True c.execute("COMMIT") - except(psycopg2.InternalError): + except (psycopg2.InternalError): valid = False available = False finally: @@ -81,7 +82,7 @@ def register_starrs(starrs, name, owner, mac, addr): c = starrs.cursor() try: c.execute("BEGIN") - c.callproc("api.initialize", ('root',)) + c.callproc("api.initialize", ('root', )) c.callproc( "api.create_system_quick", (name, owner, 'members', mac, addr, 'csh.rit.edu', 'dhcp', True)) @@ -96,7 +97,7 @@ def delete_starrs(starrs, name): c = starrs.cursor() try: c.execute("BEGIN") - c.callproc("api.initialize", ('root',)) + c.callproc("api.initialize", ('root', )) c.callproc("api.remove_system", (name, )) results = c.fetchall() c.execute("COMMIT")