diff --git a/app/__init__.py b/app/__init__.py index c30a7f15fe768cea4c82808aeb8b10d79d782177..28010cd589a0f39467a585361dbec9e7a987243b 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -9,26 +9,48 @@ import uuid from flask import Flask, redirect, url_for, request, render_template, flash, session from flask_bootstrap import Bootstrap import random - +import os +import json def create_app(config_name): app = Flask(__name__) # initialization of the flask app Bootstrap(app) # allowing app to use bootstrap + def get_authorized_user(): + username_key = list(filter(lambda key: (request.headers.get(key) is not None), vars.username_key)) + fullname_key = list(filter(lambda key: (request.headers.get(key) is not None), vars.fullname_key)) + email_key = list(filter(lambda key: (request.headers.get(key) is not None), vars.email_key)) + + user = { + "username": (request.headers.get(username_key[0]) if len(username_key) > 0 else None), + "fullname": (request.headers.get(fullname_key[0]) if len(fullname_key) > 0 else None), + "email": (request.headers.get(email_key[0]) if len(email_key) > 0 else None), + } + + return user + @app.route('/', methods=['GET', 'POST']) # initial route to display the reg page def index(): if 'uid' not in session: session['uid']=str(uuid.uuid4()) + if 'user' not in session: + session["user"] = get_authorized_user() + if "redir" in request.args and 'return_url' not in session: # check for redir arg in url session['return_url'] = request.args.get("redir") + elif "redir" not in request.args and 'return_url' not in session: session['return_url'] = vars.default_referrer else: session['return_url'] = request.referrer - return render_template('auth/SignUp.html', room_id=session['uid'], referrer=session['return_url']) + return render_template('auth/SignUp.html', room_id=session['uid'], + username=session['user'].get('username'), + fullname=session['user'].get('fullname'), email=session['user'].get('email'), + referrer=session['return_url'], cancel_url=vars.default_referrer) + # misc page error catching @app.errorhandler(403) diff --git a/app/static/scripts/function.js b/app/static/scripts/function.js index 694ff191aaa2e9a4221412f1489f31ee84878ac1..d3ee135e7438bd7c523f04e2fdb838a3407fa65a 100644 --- a/app/static/scripts/function.js +++ b/app/static/scripts/function.js @@ -5,11 +5,33 @@ function displayloading() { function request_account() { socket.emit('request account', { fullname: document.getElementById("fullname").value, + email: document.getElementById("email").value, reason: document.getElementById("reason").value, - username: document.getElementById("bid").value + username: document.getElementById("username").value }) } function refresh() { document.location.reload(true); } + +function autofill_form(username, fullname, email) { + let username_input = document.getElementById("username"); + let fullname_input = document.getElementById("fullname"); + let email_input = document.getElementById("email"); + + if ((username.localeCompare("None")) !== 0) { + username_input.value = username; + username_input.disabled = "true"; + } + + if ((fullname.localeCompare("None")) !== 0) { + fullname_input.value = fullname; + fullname_input.disabled = "true"; + } + + if ((email.localeCompare("None")) !== 0) { + email_input.value = email; + email_input.disabled = "true"; + } +} diff --git a/app/templates/auth/SignUp.html b/app/templates/auth/SignUp.html index 891a09a663e1b0ed49f4d0bd2a13840cd8371f2c..1ada7d2c0ba488ffb98a271c0ce35009d2dd5a9d 100644 --- a/app/templates/auth/SignUp.html +++ b/app/templates/auth/SignUp.html @@ -11,6 +11,7 @@ var socket = io.connect('http://' + document.domain + ':' + location.port); socket.on( 'connect', function() { + autofill_form("{{ username }}", "{{ fullname }}", "{{ email }}"); socket.emit( 'join_room', { referrer: '{{ referrer }}' }); @@ -22,7 +23,6 @@ socket.on( 'account ready', function( msg ) { $('#myModal').modal('hide'); - alert("Account has been created!"); window.location.replace('{{ referrer }}'); }); @@ -87,22 +87,32 @@ <!-- <h2>Hello, <span id="username">{{ user }}</span>!</h2> --> <h2>Hi, </h2> - <div id="test"> - <form action="." method="post" onsubmit=""> - <div class="signUpContainer"> - <label><b><label for="username">Blazer Id: </label><br></b></label> - <input class="form-control" id="bid" name="bid" placeholder="Enter BlazerId" required="" type="text"> - <label><b><label for="fullname">Full Name: </label><br></b></label> - <input class="form-control" id="fullname" name="fullname" placeholder="Enter Full Name" required="" type="text"> - <label><b><label for="reason">Reason for Requesting Account: </label><br></b></label> - <textarea class="form-control" id="reason" name="reason" placeholder="Enter Reason for Account Request" required=""></textarea> - <input class="btn btn-primary btn-block" id="submit" name="submit" type="button" value="Submit" onclick="request_account()"> - - <div> + <div id="user-input"> + + <form id="signup" data-toggle="validator" role="form" action="." method="post" onsubmit=""> + <div class="form-group"> + <label for="username" class="control-label">Blazer Id:</label>	<input id="username" class="form-control" + placeholder="Enter Username" required><br> + </div> + <div class="form-group"> + <label for="fullname" class="control-label">Full Name:</label>	<input id="fullname" class="form-control" + placeholder="Enter Full Name" required><br> + </div> + <div class="form-group"> + <label for="email" class="control-label">Email:</label>	<input id="email" class="form-control" + placeholder="Enter Email" required><br> + </div> + <div class="form-group"> + <label for="reason" class="control-label">Reason for Requesting Account:</label><br> + <textarea class="form-control" id="reason" name="reason" placeholder="Enter Reason for Account Request" required></textarea> + </div> + + <input class="btn btn-primary btn-block" id="submit" name="submit" type="button" value="Submit" onclick="request_account()"> + + <div> <strong id="error" style="color: #be051b; text-align: center;"></strong> </div> - </div> </form> </div> </div> diff --git a/rabbit_config.py b/rabbit_config.py new file mode 100644 index 0000000000000000000000000000000000000000..70081fc0f4bb46c6d90e10a300cf126fadb0877b --- /dev/null +++ b/rabbit_config.py @@ -0,0 +1,6 @@ +Exchange = 'RegUsr' +User = 'reggie' +Password = 'reggie' +VHost = '/' +Server = 'ohpc' +Port = 5672 diff --git a/rc_rmq.py b/rc_rmq.py new file mode 100644 index 0000000000000000000000000000000000000000..37afa3f44f872454a3b96fccf2d5a6a538fe01cf --- /dev/null +++ b/rc_rmq.py @@ -0,0 +1,116 @@ +import json +import pika +import socket +import rabbit_config as rcfg + +class RCRMQ(object): + + USER = 'guest' + PASSWORD = 'guest' + HOST = 'localhost' + PORT = 5672 + VHOST = '/' + EXCHANGE = '' + EXCHANGE_TYPE = 'direct' + QUEUE = None + DURABLE = True + ROUTING_KEY = None + DEBUG = False + + def __init__(self, config=None, debug=False): + if config: + if 'exchange' in config: + self.EXCHANGE = config['exchange'] + if 'exchange_type' in config: + self.EXCHANGE_TYPE = config['exchange_type'] + + hostname = socket.gethostname().split(".", 1)[0] + + self.HOST = rcfg.Server if hostname != rcfg.Server else "localhost" + self.USER = rcfg.User + self.PASSWORD = rcfg.Password + self.VHOST = rcfg.VHost + self.PORT = rcfg.Port + self.DEBUG = debug + + if self.DEBUG: + print(""" + Created RabbitMQ instance with: + Exchange name: {}, + Exchange type: {}, + Host: {}, + User: {}, + VHost: {}, + Port: {} + """.format(self.EXCHANGE, self.EXCHANGE_TYPE, self.HOST, self.USER, self.VHOST, self.PORT)) + + self._consumer_tag = None + self._connection = None + self._consuming = False + self._channel = None + self._parameters = pika.ConnectionParameters( + self.HOST, + self.PORT, + self.VHOST, + pika.PlainCredentials(self.USER, self.PASSWORD)) + + def connect(self): + if self.DEBUG: + print("Connecting...\n" + "Exchange: " + self.EXCHANGE + " Exchange type: " + self.EXCHANGE_TYPE) + + self._connection = pika.BlockingConnection(self._parameters) + self._channel = self._connection.channel() + self._channel.exchange_declare( + exchange=self.EXCHANGE, + exchange_type=self.EXCHANGE_TYPE, + durable=True) + + def bind_queue(self): + self._channel.queue_declare(queue=self.QUEUE, durable=self.DURABLE) + self._channel.queue_bind(exchange=self.EXCHANGE, + queue=self.QUEUE, + routing_key=self.ROUTING_KEY) + + def disconnect(self): + self._channel.close() + self._connection.close() + self._connection = None + + def delete_queue(self): + self._channel.queue_delete(self.QUEUE) + + def publish_msg(self, obj): + if 'routing_key' in obj: + self.ROUTING_KEY = obj['routing_key'] + + if self._connection is None: + self.connect() + + self._channel.basic_publish(exchange=self.EXCHANGE, + routing_key=self.ROUTING_KEY, + body=json.dumps(obj['msg'])) + + def start_consume(self, obj): + if 'queue' in obj: + self.QUEUE = obj['queue'] + self.ROUTING_KEY = obj['routing_key'] if 'routing_key' in obj else self.QUEUE + if 'durable' in obj: + self.DURABLE = obj['durable'] + + if self.DEBUG: + print("Queue: " + self.QUEUE + "\nRouting_key: " + self.ROUTING_KEY) + + if self._connection is None: + self.connect() + + self.bind_queue() + + self._consumer_tag = self._channel.basic_consume(self.QUEUE,obj['cb']) + self._consuming = True + try: + self._channel.start_consuming() + except KeyboardInterrupt: + self._channel.stop_consuming() + + def stop_consume(self): + self._channel.basic_cancel(self._consumer_tag) diff --git a/rc_util.py b/rc_util.py new file mode 100644 index 0000000000000000000000000000000000000000..0e7c4c1e6ec7d0cba4cc7370cf35370efa7f7354 --- /dev/null +++ b/rc_util.py @@ -0,0 +1,72 @@ +import logging +import argparse +from rc_rmq import RCRMQ +import json + +rc_rmq = RCRMQ({'exchange': 'RegUsr', 'exchange_type': 'topic'}) +tasks = {'ohpc_account': None, 'ood_account': None, 'slurm_account': None} +logger_fmt = '%(asctime)s [%(module)s] - %(message)s' + +def add_account(username, email, full='', reason=''): + rc_rmq.publish_msg({ + 'routing_key': 'request.' + username, + 'msg': { + "username": username, + "email": email, + "fullname": full, + "reason": reason + } + }) + rc_rmq.disconnect() + +def worker(ch, method, properties, body): + msg = json.loads(body) + task = msg['task'] + tasks[task] = msg['success'] + print("Got msg: {}({})".format(msg['task'], msg['success'])) + + # Check if all tasks are done + done = True + for key, status in tasks.items(): + if not status: + print("{} is not done yet.".format(key)) + done = False + if done: + rc_rmq.stop_consume() + rc_rmq.delete_queue() + +def consume(username, callback=worker, debug=False): + if debug: + sleep(5) + else: + rc_rmq.start_consume({ + 'queue': username, + 'routing_key': 'confirm.' + username, + 'cb': callback + }) + rc_rmq.disconnect() + + return { 'success' : True } + +def get_args(): + # Parse arguments + parser = argparse.ArgumentParser() + parser.add_argument('-v', '--verbose', action='store_true', help='verbose output') + parser.add_argument('-n', '--dry-run', action='store_true', help='enable dry run mode') + return parser.parse_args() + +def get_logger(args=None): + if args is None: + args = get_args() + + logger_lvl = logging.WARNING + + if args.verbose: + logger_lvl = logging.DEBUG + + if args.dry_run: + logger_lvl = logging.INFO + + logging.basicConfig(format=logger_fmt, level=logger_lvl) + return logging.getLogger(__name__) + diff --git a/run.py b/run.py index ff6b02509478326d87d84364bab4c9601b0025b2..1232ae6e5f0e6e41f340e6951e754a5b886294a4 100644 --- a/run.py +++ b/run.py @@ -36,7 +36,7 @@ def request_account(json, methods=['GET', 'POST']): room = str(session['uid']) print("Room: {}".format(room)) try: - tasks.celery_create_account.delay(json['username'], json['fullname'], json['reason'], session=room) + tasks.celery_create_account.delay(json, session=room ) except Exception as e: print(time.strftime("%m-%d-%Y_%H:%M:%S") + "\tError in account creation: ", e) socketio.emit("Account creation failed", room) diff --git a/tasks.py b/tasks.py index 6e6aad59ac1bba861f77d29b7928e0c39f7629c5..fe371fbd81bd360986b07afd99987e535a542ce7 100644 --- a/tasks.py +++ b/tasks.py @@ -3,6 +3,7 @@ import time from flask_socketio import SocketIO import subprocess import vars +import rc_util from gevent import monkey monkey.patch_all(subprocess=True) @@ -19,11 +20,17 @@ def send_msg(event, room): @celery.task -def celery_create_account(username, fullname, reason, session): +def celery_create_account(json, session): room = session + username= json['username'] + email= json['email'] + fullname= json['fullname'] + reason= json['reason'] + print(time.strftime("%m-%d-%Y_%H:%M:%S") + '\tUser ' + username + ' added to queue') send_msg('creating account', room) print(username) - subprocess.call(["/opt/rabbitmq_agents/create_account.py", username, '', fullname, reason]) + rc_util.add_account(username, email, fullname, reason) + rc_util.consume(username) print(time.strftime("%m-%d-%Y_%H:%M:%S") + '\tAccount successfully created for ' + username) send_msg('account ready', room) diff --git a/vars.py b/vars.py index 8314f9d955c4c3029bf374de2dee84fd74298817..41249880a3d18ee7e7b813060e1c511fea23dadd 100644 --- a/vars.py +++ b/vars.py @@ -3,4 +3,7 @@ password = '' key = '' broker_url = 'amqp://' + id + ':' + password + '@ohpc:5672/' message_queue = broker_url + 'socketio' -default_referrer = "https://docs.uabgrid.uab.edu/wiki/Cheaha_Quick_Start" +default_referrer = "/pun/sys/dashboard" +username_key = ["REMOTE_USER"] +fullname_key = ["HTTP_DISPLAYNAME"] +email_key = ["HTTP_MAIL"]