Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • rc/account-app
  • louistw/account-app
  • krish94/self-reg-form
  • dwheel7/self-reg-form
  • dwheel7/feature-reanme-self-reg-app-to-account-app
  • atlurie/account-app
  • dwheel7/account-app
7 results
Show changes
docs/images/rabbitmq-agents-flowchart.png

84 KiB

docs/images/rabbitmq-agents-messages.png

58.5 KiB

docs/images/rc-network .png

106 KiB

docs/images/security_rules.png

311 KiB

docs/images/site_example.png

478 KiB

This diff is collapsed.
welcome_message = "The information below will be used to create your account. Please fill in the reason for requesting your account as this helps us understand our user base.<br>Contact <a href='mailto:support@listserv.uab.edu'>Research Computing</a> if you have any questions."
cancel_message = "Close current tab to end session.<br>Contact <a href="'mailto:support@listserv.uab.edu'">Research Computing</a> if you have any questions."
error_message = "An error occurred while creating your account. Research Computing team has been notified and is working on fixing it.<br>Contact <a href='mailto:support@listserv.uab.edu'>Research Computing</a> if you have any questions."
unauthorized_message = "Your UAB Research Computing account is currently on hold.<br>Accounts are put on hold if there are changes with your UAB affiliation or if there is an issue on one of the platforms.<br>Please contact <a href="'mailto:support@listserv.uab.edu'">Research Computing</a> or attend the weekly office hours to resolve any issues."
account_hold_message = "Your UAB Research Computing account is currently on hold.<br>Please contact <a href="'mailto:support@listserv.uab.edu'">Research Computing</a> or attend the weekly office hours to resolve any issues."
pre_certification_message = "Welcome back to the UAB Research Computing services page.<br>Annual account certification is required for continued access to Research Computing services. <br> To continue with the self certification process click on continue below"
certification_message = "Welcome back to the UAB Research Computing services page.<br>The usage of this resource is governed by UAB IT's <a href=' https://secure2.compliancebridge.com/uab/public/index.php?fuseaction=print.preview&docID=786' target='_blank'>Acceptable Use Policy </a> and <a href='https://www.uab.edu/it/home/policies/data-classification/classification-overview' target='_blank'>Data Classification Policy</a><br>To read and understand all UAB IT policies click <a href=' https://www.uab.edu/it/home/policies' target='_blank'>here</a><br>Verify your information in the form below and hit the Certify Account button when you are done."
good_standing_message= "Your account is in good standing. Click <a href=https://rc.uab.edu>here</a> to proceed to dashboard"
"""
Messages used in account management app
"""
welcome_message = (
"The information below will be used to create your account. Please fill in"
" the reason for requesting your account as this helps us understand our"
" user base. Please be aware that the use of this resource is governed by"
" <a href='https://www.uab.edu/it/home/policies' target='_blank'>UAB"
" Information Technology Security Policies.</a><br><br>Contact <a"
" href='mailto:support@listserv.uab.edu'>Research Computing</a> if you"
" have any questions.<br>"
)
cancel_message = (
"Close current tab to end session.<br>Contact <a href="
"mailto:support@listserv.uab.edu"
">Research Computing</a> if you have any questions.<br>"
)
error_message = (
"An error occurred while creating your account. Research Computing team"
" has been notified and is working on fixing it.<br>Contact <a"
" href='mailto:support@listserv.uab.edu'>Research Computing</a> if you"
" have any questions.<br>"
)
unauthorized_message = (
"Your UAB login is not authorized to use UAB Research Computing Systems."
" Contact <a href='mailto:support@listserv.uab.edu'>Research Computing</a>"
" to resolve this issue.<br>"
)
account_hold_message = (
"Your UAB Research Computing account is currently on hold.<br>Please"
" contact <a href=mailto:support@listserv.uab.edu>Research Computing</a>"
" or attend the weekly <a href='https://uabrc.github.io/#contact-us'"
" target='_blank'>office hours</a> to resolve this issue.<br>"
)
pre_certification_message = (
"Annual account certification is required for continued access to Research"
" Computing Systems.<br>To continue with the self certification process"
" click on continue below.<br><br>"
)
certification_message = (
"This resource is governed by <a"
" href='https://www.uab.edu/it/home/policies' target='_blank'>UAB"
" Information Technology Security Policies.</a><br><br>Please verify your"
" information in the form below and press the Certify Account to complete"
" the certification process.<br>"
)
good_standing_message = (
"Your account is in good standing. Click <a"
" href=https://rc.uab.edu>here</a> to proceed to dashboard.<br>"
)
......@@ -3,6 +3,7 @@ line-length = 79
target-version = ['py36']
preview = true
[tool.pylint.main]
disable = ["import-error", "unused-argument", "broad-except"]
disable = ["invalid-name", "import-error", "unused-argument", "broad-except"]
ignore = ["config.py", "tests.py"]
[tool.pylint.format]
max-line-length = 79
"""
This python script conatins functions that talk with Flask frontend over
socketio.
It has functions to join a unique room, creating an account and
certifying an account.
"""
# run.py
# standard imports
import os
import time
import tasks
import vars
# third-party imports
from flask import session
from flask_socketio import SocketIO, join_room
from app import create_app
from gevent import monkey
# local imports
# pylint: disable=wrong-import-order
import tasks
import app_vars
# pylint: enable=wrong-import-order
from app import create_app
monkey.patch_all(subprocess=True)
config_name = os.getenv('FLASK_CONFIG')
config_name = os.getenv("FLASK_CONFIG")
app = create_app(config_name)
app.config['SECRET_KEY'] = vars.key
socketio = SocketIO(app, cors_allowed_origins=vars.cors_allowed_origins, message_queue=vars.message_queue)
app.config["SECRET_KEY"] = app_vars.key
socketio = SocketIO(
app,
cors_allowed_origins=app_vars.cors_allowed_origins,
message_queue=app_vars.message_queue,
)
@socketio.on('join_room')
@socketio.on("join_room")
def on_room(json):
room = str(session['uid'])
referrer = json['referrer']
"""
This function creates a unique room/flask session id, and joins it
Input:
json: conatins config information for the flask session
Output:
Join the unique room.
"""
room = str(session["uid"])
referrer = json["referrer"]
join_room(room)
print('\t\t\t|-----Room ID: ' + room)
print('\t\t\t|-----Referrer: ' + referrer)
@socketio.on('request account')
def request_account(json, methods=['GET', 'POST']):
print (time.strftime("%m-%d-%Y_%H:%M:%S") + '\tQueue request received: ' + str(json))
room = str(session['uid'])
print("Room: {}".format(room))
print("\t\t\t|-----Room ID: " + room)
print("\t\t\t|-----Referrer: " + referrer)
@socketio.on("request account")
def request_account(json):
"""
This function is called by the Flask frontend on an account request.
Input:
json: This contains information needed for the user that needs to be
created from the frontend.
methods: Defaults to ["GET", "POST"].
Output:
Send the json to Celery tasks file for account creation.
"""
print(
time.strftime("%m-%d-%Y_%H:%M:%S")
+ "\tQueue request received: "
+ str(json)
)
room = str(session["uid"])
print(f"Room: {room}")
try:
tasks.celery_create_account.delay(json, 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)
print(
time.strftime("%m-%d-%Y_%H:%M:%S")
+ "\tError in account creation: ",
e,
)
socketio.emit("Account creation failed", room)
@socketio.on('request certification')
def certify_account(json, methods=['GET', 'POST']):
print (time.strftime("%m-%d-%Y_%H:%M:%S") + '\tQueue request received: ' + str(json))
room = str(session['uid'])
print("CERTIFY Room: {}".format(room))
@socketio.on("request certification")
def certify_account(json):
"""
This function is called by the Flask frontend from self certification page.
Inputs:
json: Conatins information about the user that needs to be certified
from the frontend.
methods: Defaults to ["GET", "POST"].
Outputs:
Send the json to Celery tasks file for user certification.
"""
print(
time.strftime("%m-%d-%Y_%H:%M:%S")
+ "\tQueue request received: "
+ str(json)
)
room = str(session["uid"])
print(f"CERTIFY Room: {room}")
try:
tasks.celery_certify_account(json, session=room )
tasks.celery_certify_account(json, session=room)
except Exception as e:
print(time.strftime("%m-%d-%Y_%H:%M:%S") + "\tError in account certification: ", e)
print(
time.strftime("%m-%d-%Y_%H:%M:%S")
+ "\tError in account certification: ",
e,
)
socketio.emit("Account certification failed", room)
if __name__ == '__main__':
socketio.run(app, host='0.0.0.0')
if __name__ == "__main__":
socketio.run(app, host="0.0.0.0")
import vars
import sys
"""
This python module defines celery tasks for following fucntions:
* Account creation
* Account certification
"""
# standard imports
import json
import sys
import time
import signal
# third-party imports
from celery import Celery
from flask_socketio import SocketIO
sys.path.append(vars.rabbitmq_agents_loc)
import rc_util
# local imports
import app_vars
sys.path.append(app_vars.rabbitmq_agents_loc)
# pylint: disable=wrong-import-position
import rc_util # noqa: E402
broker_url = vars.broker_url
celery = Celery(vars.celery_app, broker=broker_url)
# pylint: enable=wrong-import-position
socketio = SocketIO(message_queue=vars.message_queue)
broker_url = app_vars.broker_url
celery = Celery(app_vars.celery_app, broker=broker_url)
socketio = SocketIO(message_queue=app_vars.message_queue)
timeout = 30
def gen_f(room):
"""
This function defines the callback function for creating account process.
Inputs:
room: Room/session ID for the flask session, so that communications
are going to the right session.
Output:
RabbitMQ callback function.
"""
def callback(channel, method, properties, body):
"""
This function defines the RabbitMQ callback function executed after
account creation process.
Inputs:
channel: channel over which the RabbitMQ communication is
happening.
method: Defines meta information regarding the message delivery.
properties: user-defined properties on the message
body: Message that is passed throughout account creation process
across multiple agents.
Output:
Send appropriate message to the frontend, for account creation
success or failure. And delete the queue.
"""
msg = json.loads(body)
username = msg['username']
queuename = msg['queuename']
username = msg["username"]
queuename = msg["queuename"]
if msg['success']:
print(f'Account for {username} has been created.')
send_msg('account ready', room)
if msg["success"]:
print(f"Account for {username} has been created.")
send_msg("account ready", room)
else:
print(f"There's some issue while creating account for {username}")
errmsg = msg.get('errmsg', [])
errmsg = msg.get("errmsg", [])
for err in errmsg:
print(err)
socketio.emit('account error', errmsg, room= room)
socketio.emit("account error", errmsg, room=room)
rc_util.rc_rmq.stop_consume()
rc_util.rc_rmq.delete_queue(queuename)
return callback
def certify_gen_f(room):
"""
This function defines the callback function for certifying account process.
Inputs:
room: Room/session ID for the flask session, so that communications are
going to the right session.
Output:
RabbitMQ callback function.
"""
def callback(channel, method, properties, body):
"""
This function defines the RabbitMQ callback function executed after
account certification process.
Inputs:
channel: channel over which the RabbitMQ communication is happening
method: Defines meta information regarding the message delivery.
properties: user-defined properties on the message
body: Message that is passed throughout account creation process
across multiple agents.
Output:
Send appropriate message to the frontend, for account certification
success or failure. And delete the queue.
"""
msg = json.loads(body)
username = msg['username']
queuename = msg['queuename']
username = msg["username"]
queuename = msg["queuename"]
if msg['success']:
print(f'Account for {username} has been certified.')
send_msg('certified', room)
if msg["success"]:
print(f"Account for {username} has been certified.")
send_msg("certified", room)
else:
print(f"There's some issue while certifying account for {username}")
errmsg = msg.get('errmsg', [])
print(
f"There's some issue while certifying account for {username}"
)
errmsg = msg.get("errmsg", [])
for err in errmsg:
print(err)
socketio.emit('certify error', errmsg, room= room)
socketio.emit("certify error", errmsg, room=room)
rc_util.rc_rmq.stop_consume()
rc_util.rc_rmq.delete_queue(queuename)
return callback
def send_msg(event, room):
"""
This function is used to send messages via socketio
Input:
string event, room:
Output:
string: emit event to room
"""
socketio.emit(event, room=room)
def timeout_handler(signum, frame):
print("Process timeout, there's might some issue with agents")
socketio.emit('account error', errmsg, room= room)
rc_util.rc_rmq.stop_consume()
rc_util.rc_rmq.delete_queue()
# def timeout_handler(signum, frame):
# print("Process timeout, there's might some issue with agents")
# socketio.emit("account error", errmsg, room=room)
# rc_util.rc_rmq.stop_consume()
# rc_util.rc_rmq.delete_queue()
@celery.task
def celery_create_account(json, session):
def celery_create_account(msg, session):
"""
This function is used to create account for new users
Input:
msg: json object of all user attributes and session/room
Output:
gen_f(room): callback to check for success or failure
"""
room = session
username= json['username']
email= json['email']
fullname= json['fullname']
reason= json['reason']
queuename= rc_util.encode_name(username)
updated_by= f'{username}'
host= vars.app_host
print(time.strftime("%m-%d-%Y_%H:%M:%S") + '\tUser ' + username + ' added to queue')
send_msg('creating account', room)
username = msg["username"]
email = msg["email"]
fullname = msg["fullname"]
reason = msg["reason"]
# aup= msg['aup']
queuename = rc_util.encode_name(username)
updated_by = f"{username}"
host = app_vars.app_host
print(
time.strftime("%m-%d-%Y_%H:%M:%S")
+ "\tUser "
+ username
+ " added to queue"
)
send_msg("creating account", room)
print(username)
rc_util.add_account(username, queuename, email, fullname, reason, updated_by, host)
print('sent account info')
print('Waiting for completion...')
rc_util.consume(queuename, routing_key=f'complete.{queuename}', callback=gen_f(room))
rc_util.add_account(
username, queuename, email, fullname, reason, updated_by, host
)
print("sent account info")
print("Waiting for completion...")
rc_util.consume(
queuename, routing_key=f"complete.{queuename}", callback=gen_f(room)
)
@celery.task
def celery_certify_account(json, session):
def celery_certify_account(msg, session):
"""
This function is used to certify account for existing users
Input:
msg: json object of all user attributes and session/room
Output:
gen_f(room): callback to check for success or failure
"""
room = session
username= json['username']
email= json['email']
fullname= json['fullname']
queuename= rc_util.encode_name(username)
updated_by= f'{username}'
host= vars.app_host
print("CERTIFY : "+time.strftime("%m-%d-%Y_%H:%M:%S") + '\tUser ' + username + ' added to queue')
send_msg('certifying account', room)
username = msg["username"]
queuename = rc_util.encode_name(username)
updated_by = f"{username}"
host = app_vars.app_host
print(
"CERTIFY : "
+ time.strftime("%m-%d-%Y_%H:%M:%S")
+ "\tUser "
+ username
+ " added to queue"
)
send_msg("certifying account", room)
print(username)
rc_util.certify_account(username, queuename, 'ok', 'all', updated_by, host)
print('sent account info')
print('Waiting for certification...')
rc_util.consume(queuename, routing_key=f'certified.{queuename}', callback=certify_gen_f(room))
rc_util.certify_account(username, queuename, "ok", "all", updated_by, host)
print("sent account info")
print("Waiting for certification...")
rc_util.consume(
queuename,
routing_key=f"certified.{queuename}",
callback=certify_gen_f(room),
)
......@@ -3,23 +3,22 @@
import unittest
import flask
from flask import abort, url_for, g
from flask import abort, url_for
from flask_testing import TestCase
from app import create_app
class TestBase(TestCase):
def create_app(self):
app = create_app('testing')
app = create_app("testing")
return app
def setUp(self):
"""
Will be called before every test
"""
app = create_app('testing')
app = create_app("testing")
return app
def tearDown(self):
......@@ -41,7 +40,7 @@ class TestViews(TestBase):
Test that homepage is accessible.
"""
response = self.client.get(url_for('index'))
response = self.client.get(url_for("index"))
self.assertEqual(response.status_code, 200)
# with self.app.test_client() as c:
......@@ -52,10 +51,10 @@ class TestViews(TestBase):
"""
Test that all resources load are found.
"""
with self.app.test_request_context('/?redir=test'):
assert flask.request.path == '/'
c = flask.app.request.args['redir']
assert c == 'test'
with self.app.test_request_context("/?redir=test"):
assert flask.request.path == "/"
c = flask.app.request.args["redir"]
assert c == "test"
# def test_logout_view(self):
# """
......@@ -70,32 +69,31 @@ class TestViews(TestBase):
class TestErrorPages(TestBase):
def test_403_forbidden(self):
# create route to abort the request with the 403 Error
@self.app.route('/403')
@self.app.route("/403")
def forbidden_error():
abort(403)
response = self.client.get('/403')
response = self.client.get("/403")
self.assertEqual(response.status_code, 403)
self.assertTrue("403 Error" in response.data)
def test_404_not_found(self):
response = self.client.get('/nothinghere')
response = self.client.get("/nothinghere")
self.assertEqual(response.status_code, 404)
self.assertTrue("404 Error" in response.data)
def test_500_internal_server_error(self):
# create route to abort the request with the 500 Error
@self.app.route('/500')
@self.app.route("/500")
def internal_server_error():
abort(500)
response = self.client.get('/500')
response = self.client.get("/500")
self.assertEqual(response.status_code, 500)
self.assertTrue("500 Error" in response.data)
if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()