restrict access to a small set of netbadge users.

fixing saliva mis-spelling
Drop "Be Safe" use "Prevalance Testing"
This commit is contained in:
Dan 2020-10-02 15:16:28 -04:00
parent 2797083f73
commit d66be8685a
5 changed files with 46 additions and 14 deletions

View File

@ -1,9 +1,10 @@
import logging import logging
import os import os
from functools import wraps
import connexion import connexion
import sentry_sdk import sentry_sdk
from flask import render_template, request, redirect, url_for from flask import render_template, request, redirect, url_for, flash, abort
from flask_assets import Environment from flask_assets import Environment
from flask_cors import CORS from flask_cors import CORS
from flask_mail import Mail from flask_mail import Mail
@ -14,6 +15,7 @@ from flask_sqlalchemy import SQLAlchemy
from sentry_sdk.integrations.flask import FlaskIntegration from sentry_sdk.integrations.flask import FlaskIntegration
from webassets import Bundle from webassets import Bundle
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
# API, fully defined in api.yml # API, fully defined in api.yml
@ -73,15 +75,27 @@ cors = CORS(connexion_app.app, origins=origins_re)
if app.config['SENTRY_ENVIRONMENT']: if app.config['SENTRY_ENVIRONMENT']:
sentry_sdk.init( sentry_sdk.init(
environment=app.config['SENTRY_ENVIRONMENT'], environment=app.config['SENTRY_ENVIRONMENT'],
dsn="https://25342ca4e2d443c6a5c49707d68e9f40@o401361.ingest.sentry.io/5260915", dsn="https://c37225ab38de49749acfbb9c7381f065@o401361.ingest.sentry.io/5449288",
integrations=[FlaskIntegration()] integrations=[FlaskIntegration()]
) )
### HTML Pages ### HTML Pages
BASE_HREF = app.config['APPLICATION_ROOT'].strip('/') BASE_HREF = app.config['APPLICATION_ROOT'].strip('/')
def superuser(f):
@wraps(f)
def decorated_function(*args, **kwargs):
from communicator.services.user_service import UserService
if not UserService().is_valid_user():
flash("You do not have permission to view that page", "warning")
logging.info("Permission Denied to user " + UserService.get_user_info())
abort(404)
return f(*args, **kwargs)
return decorated_function
@app.route('/', methods=['GET']) @app.route('/', methods=['GET'])
@superuser
def index(): def index():
from communicator.models import Sample from communicator.models import Sample
from communicator.tables import SampleTable from communicator.tables import SampleTable
@ -99,6 +113,7 @@ def index():
) )
@app.route('/invitation', methods=['GET', 'POST']) @app.route('/invitation', methods=['GET', 'POST'])
@superuser
def send_invitation(): def send_invitation():
from communicator.models.invitation import Invitation from communicator.models.invitation import Invitation
from communicator.tables import InvitationTable from communicator.tables import InvitationTable
@ -130,6 +145,7 @@ def send_invitation():
) )
@app.route('/imported_files', methods=['GET']) @app.route('/imported_files', methods=['GET'])
@superuser
def list_imported_files_from_ivy(): def list_imported_files_from_ivy():
from communicator.models.ivy_file import IvyFile from communicator.models.ivy_file import IvyFile
from communicator.tables import IvyFileTable from communicator.tables import IvyFileTable
@ -155,6 +171,10 @@ def sso():
response += f"<h1>Current User: {user.display_name} ({user.uid})</h1>" response += f"<h1>Current User: {user.display_name} ({user.uid})</h1>"
return response return response
@app.route('/debug-sentry')
def trigger_error():
division_by_zero = 1 / 0
# Access tokens # Access tokens
@app.cli.command() @app.cli.command()
def globus_token(): def globus_token():
@ -182,3 +202,4 @@ def delete():
from communicator.services.ivy_service import IvyService from communicator.services.ivy_service import IvyService
ivy_service = IvyService() ivy_service = IvyService()
ivy_service.delete_file() ivy_service.delete_file()

View File

@ -1,5 +1,8 @@
import re
from flask import request from flask import request
from communicator import app
from communicator.errors import CommError from communicator.errors import CommError
from communicator.models.user import User from communicator.models.user import User
@ -25,10 +28,19 @@ class UserService(object):
# Connection: Keep-Alive # Connection: Keep-Alive
def get_user_info(self): def get_user_info(self):
uid = request.headers.get("Uid") if app.config['PRODUCTION']:
cn = request.headers.get("Cn") uid = request.headers.get("Uid")
if not uid: cn = request.headers.get("Cn")
uid = request.headers.get("X-Remote-Uid") if not uid:
if not uid: uid = request.headers.get("X-Remote-Uid")
raise CommError(1100, "invalid_sso_credentials", r"'Uid' nor 'X-Remote-Uid' were present in the headers: %s"% str(request.headers)) if not uid:
return User(uid, cn) raise CommError(1100, "invalid_sso_credentials", r"'Uid' nor 'X-Remote-Uid' were present in the headers: %s"% str(request.headers))
return User(uid, cn)
else:
return User('testUser', "Test User")
def is_valid_user(self):
user = self.get_user_info()
valid_ids = [x for x in re.compile('\s*[,|\s+]\s*').split(app.config['ADMINS'])]
return user.uid in valid_ids

View File

@ -13,7 +13,7 @@
spread of the virus. spread of the virus.
</p> </p>
<p style="font-family: sans-serif; font-size: 20px; font-weight: bold; margin: 0; Margin-bottom: 15px;"> <p style="font-family: sans-serif; font-size: 20px; font-weight: bold; margin: 0; Margin-bottom: 15px;">
You have been selected for a salvia screening on {{date}}. You have been selected for a saliva screening on {{date}}.
</p> </p>
<p style="font-family: sans-serif; font-size: 16px; font-weight: normal; margin: 0; Margin-bottom: 15px;"> <p style="font-family: sans-serif; font-size: 16px; font-weight: normal; margin: 0; Margin-bottom: 15px;">

View File

@ -1,6 +1,4 @@
You have a new notification from the University of Virginia BE SAFE System. You have a new notification from UVA Prevalence Testing
Please follow this link, and log in with Netbadge to securely view your notification: Please follow this link, and log in with Netbadge, to securely view your notification:
{{link}} {{link}}
Please note that email is not a secure form of communication and should not be used to discuss any confidential matters, including personal health information, given its confidentiality cannot be assured.

View File

@ -11,6 +11,7 @@ FLASK_PORT = environ.get('PORT0') or environ.get('FLASK_PORT', default="5000")
CORS_ALLOW_ORIGINS = re.split(r',\s*', environ.get('CORS_ALLOW_ORIGINS', default="localhost:4200, localhost:5002")) CORS_ALLOW_ORIGINS = re.split(r',\s*', environ.get('CORS_ALLOW_ORIGINS', default="localhost:4200, localhost:5002"))
TESTING = environ.get('TESTING', default="false") == "true" TESTING = environ.get('TESTING', default="false") == "true"
PRODUCTION = (environ.get('PRODUCTION', default="false") == "true") PRODUCTION = (environ.get('PRODUCTION', default="false") == "true")
ADMINS = environ.get('ADMINS', default="testUser")
# Sentry flag # Sentry flag
ENABLE_SENTRY = environ.get('ENABLE_SENTRY', default="false") == "true" # To be removed soon ENABLE_SENTRY = environ.get('ENABLE_SENTRY', default="false") == "true" # To be removed soon