def get_studies(): # Cases: invalid access creds access_key = request.values["access_key"] access_secret = request.values["secret_key"] admin = Admin(access_key_id=access_key) if not admin: return abort(403) # access key DNE if not admin.validate_access_credentials(access_secret): return abort(403) # incorrect secret key return json.dumps({ str(study._id): study.name for study in Studies(admins=str(admin._id)) })
def get_and_validate_admin(study_obj): """ Finds admin based on the secret key provided, returns 403 if admin doesn't exist, is not credentialled on the study, or if the secret key does not match. """ access_key = request.values["access_key"] access_secret = request.values["secret_key"] admin = Admin(access_key_id=access_key) if not admin: return abort(403) # access key DNE if admin._id not in study_obj['admins']: return abort(403) # admin is not credentialed for this study if not admin.validate_access_credentials(access_secret): return abort(403) # incorrect secret key return admin
def reset_admin_password(): username = session['admin_username'] current_password = request.values['current_password'] new_password = request.values['new_password'] confirm_new_password = request.values['confirm_new_password'] if not Admin.check_password(username, current_password): flash("The Current Password you have entered is invalid", 'danger') return redirect('/manage_credentials') if not check_password_requirements(new_password, flash_message=True): return redirect("/manage_credentials") if new_password != confirm_new_password: flash("New Password does not match Confirm New Password", 'danger') return redirect('/manage_credentials') Admin(username).set_password(new_password) flash("Your password has been reset!", 'success') return redirect('/manage_credentials')
def reset_download_api_credentials(): admin = Admin(session['admin_username']) access_key, secret_key = admin.reset_access_credentials() msg = """<h3>Your Data-Download API access credentials have been reset!</h3> <p>Your new <b>Access Key</b> is: <div class="container-fluid"> <textarea rows="1" cols="85" readonly="readonly" onclick="this.focus();this.select()">%s</textarea></p> </div> <p>Your new <b>Secret Key</b> is: <div class="container-fluid"> <textarea rows="1" cols="85" readonly="readonly" onclick="this.focus();this.select()">%s</textarea></p> </div> <p>Please record these somewhere; they will not be shown again!</p>""" \ % (access_key, secret_key) flash(Markup(msg), 'warning') return redirect("/manage_credentials")
def authenticate_and_call(*args, **kwargs): if not is_logged_in(): #check for regular login requirement return redirect("/") admin_name = session["admin_username"] admin = Admin(admin_name) #check proper syntax usage. if "survey_id" not in kwargs and "study_id" not in kwargs: raise ArgumentMissingException() #We want the survey_id check to execute first if both args are supplied. if "survey_id" in kwargs: #turn the survey_id into a bson ObjectId. survey_id = ObjectId(kwargs["survey_id"]) kwargs['survey_id'] = survey_id #MongoDB checks both equality and contains when you pass it a value. study = Study(surveys=survey_id) if not study: #study does not exist. return abort(404) #check admin is allowed, allow system admins. if not admin.system_admin: if admin['_id'] not in study.admins: return abort(403) if "study_id" in kwargs: study_id = ObjectId(kwargs['study_id']) kwargs['study_id'] = study_id study = Study(study_id) if not study: return abort(404) if not admin.system_admin: if admin['_id'] not in study.admins: return abort(403) return some_function(*args, **kwargs)
def login(): """ Authenticates administrator login, redirects to login page if authentication fails. """ if request.method == 'POST': username = request.values["username"] password = request.values["password"] if Admin.check_password(username, password): admin_authentication.log_in_admin(username) return redirect("/choose_study") flash("Incorrect username & password combination; try again.", 'danger') return redirect("/")
def edit_admin(admin_id): admin = Admin(admin_id) admin_is_current_user = (admin._id == session['admin_username']) current_studies = sorted(Studies(admins=admin._id), key=lambda x: x.name.lower()) return render_template('edit_admin.html', admin=admin, current_studies=current_studies, all_studies=Studies.get_all_studies(), allowed_studies=get_admins_allowed_studies(), admin_is_current_user=admin_is_current_user, system_admin=admin_is_system_admin())
def create_new_researcher(): if request.method == 'GET': return render_template('create_new_researcher.html', allowed_studies=get_admins_allowed_studies(), system_admin=admin_is_system_admin()) admin_id = ''.join(e for e in request.form.get('admin_id') if e.isalnum()) password = request.form.get('password') if Admins(_id=admin_id): flash("There is already a researcher with username " + admin_id, 'danger') return redirect('/create_new_researcher') else: admin = Admin.create(admin_id, password) return redirect('/edit_admin/' + admin._id)
def data_api_web_form_page(): # TODO: Josh, provide access to this route via a link in the top navbar admin = Admin(session['admin_username']) warn_admin_if_hasnt_yet_generated_access_key(admin) allowed_studies = get_admins_allowed_studies() # dict of {study ids : list of user ids} users_by_study = { str(study["_id"]): [user["_id"] for user in Users(study_id=study['_id'])] for study in allowed_studies } return render_template("data_api_web_form.html", allowed_studies=allowed_studies, users_by_study=users_by_study, ALL_DATA_STREAMS=ALL_DATA_STREAMS, system_admin=admin_is_system_admin())
def authenticate_and_call(*args, **kwargs): if not is_logged_in(): #check for regular login requirement return redirect("/") admin = Admin(session['admin_username']) if not admin["system_admin"]: # TODO: Low Priority. Josh. redirect to a URL, not a template file return abort(403) if 'study_id' in kwargs: study_id = kwargs['study_id'] if not isinstance(study_id, ObjectId): # make an extra check in case study_id = ObjectId( study_id) # authenticate_admin_study_access kwargs['study_id'] = study_id # has already converted the id. if not Studies(_id=study_id): return redirect("/") return some_function(*args, **kwargs)
def remove_admin(username): Admin(username).remove()
def create_admin(username, password): Admin.create(username, password)
def get_admins_allowed_studies(): """ Return a list of studies which the currently logged-in admin is autho- rized to view and edit """ admin = Admin(session['admin_username']) return sorted(Studies(admins=admin._id), key=lambda x: x.name.lower())
def admin_is_system_admin(): # TODO: Low Priority. Josh. find a more efficient way of checking this and # "allowed_studies" than passing it to every render_template. admin = Admin(session['admin_username']) return admin.system_admin