def index(): # Log user-agent for browser use analysis app.logger.info({"user-agent": request.headers.get("User-Agent")}) args = request.args if "code" in args: oauth_code = args["code"] response = exchange_code_for_session_user(oauth_code) if response.status_code != 200: app.logger.error({"error": "OAuth failed", "response": response}) return redirect("/403") return redirect("/admin" if has_admin_role() else "/") if "details" in session: upload_rights = has_upload_rights() is_admin_role = has_admin_role() return render_template_custom( "welcome.html", user=session["user"], email=session["email"], upload_rights=upload_rights, is_admin_role=is_admin_role, ) else: login_url = ( f"https://{app.config['cognito_domain']}/oauth2/authorize?" f"client_id={app.config['client_id']}&" "response_type=code&" f"redirect_uri={app.config['redirect_host']}&" "scope=profile+email+phone+openid+aws.cognito.signin.user.admin") return render_template_custom("login.html", hide_logout=True, login_url=login_url)
def admin_user(app): done = "None" email = "" if len(request.args) != 0: email = request.args.get("email", "") # Remove url encoding for special characters email = unquote(email) done = request.args.get("done", "None") if len(request.form) != 0: email = request.form.get("email", "") done = request.form.get("done", "None") if email != "": clear_session(app) elif "admin_user_email" in session: email = session["admin_user_email"] if email != "": user = User(email).get_details() if user != {}: session["admin_user_email"] = user["email"] session["admin_user_object"] = user user_group = return_users_group(user) return render_template_custom("admin/user.html", user=user, user_group=user_group, done=done) return redirect("/admin/user/not-found")
def admin_confirm_user(app): """ Render the /admin/user/confirm flask route This route posts back to the same page and performs the user create/updates against cognito. """ # Get the edited user content from the session # or initialise as an empty dictionary admin_user_object = session.get("admin_user_object", {}) task = "" new_user = False # Redirect to admin home if post data missing args = request.form if len(args) == 0: clear_session(app) return redirect("/admin") elif "task" in args: task = args["task"] # Sanitise the email address if user edited if task in ["new", "continue-new"]: new_user = True if "email" in args: user = User(args["email"]) if user.email_address_is_valid(): admin_user_object["email"] = user.email_address else: return redirect(url_for("admin_edit_user")) # Handle Cognito create and update user logic if task in ["confirm-new", "confirm-existing"]: is_task_complete = perform_cognito_task(task, admin_user_object) target = "/admin/user/error" state = "created" if task == "confirm-new" else "updated" if is_task_complete: target = "/admin/user?done={}&email={}".format( state, quote(admin_user_object["email"])) # If this fails an error message should have been added to the session # by the user.create or user.update methods. clear_session(app) return redirect(target) admin_user_object = parse_edit_form_fields(args, admin_user_object, app) session["admin_user_email"] = admin_user_object["email"] session["admin_user_object"] = admin_user_object return render_template_custom( app, "admin/confirm-user.html", user=admin_user_object, new_user=new_user, user_group=admin_user_object["group"], )
def server_error_403(): error_message = session.get("error_message", "Access denied") app.logger.error(f"Server error: {error_message}") del session["error_message"] return ( render_template_custom( app, "error.html", hide_logout=True, error=error_message ), 403, )
def admin_user_error(app): error_message = session.get("error_message", "Something went wrong") app.logger.error(f"Server error: {error_message}") del session["error_message"] return ( render_template_custom("error.html", hide_logout=True, error=error_message), 403, )
def admin_edit_user(app): args = request.values new_user = False user_custom_paths = [] task = "" if "task" in args: task = args["task"] if task == "new": clear_session(app) session["admin_user_email"] = "" session["admin_user_object"] = {} # only admin-full can create a new user if not user_has_a_valid_role(["admin-full"]): return redirect("/403") admin_user_email = session["admin_user_email"] admin_user_object = session["admin_user_object"] # If the user doesn't exist, allow editing of email/username # and don't pre-set user account type options. if admin_user_email == "" or User(admin_user_email).get_details() == {}: new_user = True is_local_authority_user = False is_other_user = False else: # If you are editing an existing user: # - check that all the granted paths are valid for the user's type. # - and remove any paths where the account type doesn't match if "custom:paths" not in admin_user_object: admin_user_object["custom:paths"] = "" is_local_authority_user = admin_user_object["custom:is_la"] == "1" is_other_user = not is_local_authority_user admin_user_object = remove_invalid_user_paths(admin_user_object) user_custom_paths = admin_user_object["custom:paths"].split(";") return render_template_custom( app, "admin/edit-user.html", user=admin_user_object, new_user=new_user, user_custom_paths=user_custom_paths, local_authority=value_paths_by_type("local_authority"), is_la=is_local_authority_user, other=value_paths_by_type("other"), is_other=is_other_user, allowed_domains=(User(admin_user_email).allowed_domains() if new_user else []), available_groups=user_groups(), )
def files(): files = get_files(app.config["bucket_name"], session) # TODO sorting return render_template_custom( "files.html", user=session["user"], email=session["email"], files=collect_files_by_date(files), is_la=return_attribute(session, "custom:is_la"), )
def upload(): user_upload_paths = user_custom_paths(is_upload=True, session=session) preupload = True file_path_to_upload = "" presigned_object = "" upload_history = [] file_extensions = {"csv": {"ext": "csv", "display": "CSV"}} if request.method == "POST": form_fields = request.form task = form_fields.get("task", None) if task == "preupload": preupload = False validated_form = upload_form_validate(form_fields, user_upload_paths, file_extensions) if validated_form["valid"]: file_path_to_upload = generate_upload_file_path( validated_form["fields"]) # generate a S3 presigned_object PutObjct based # on s3 key in file_path_to_upload presigned_object = create_presigned_post(file_path_to_upload) if presigned_object is None: return redirect("/upload?error=True") else: return redirect("/upload?error=True") else: upload_history = get_upload_history(config.get("bucket_name"), session) app.logger.debug({"uploads": upload_history}) return render_template_custom( "upload.html", user=session["user"], email=session["email"], is_la=return_attribute(session, "custom:is_la"), presigned_object=presigned_object, preupload=preupload, filepathtoupload=file_path_to_upload, file_extensions=list(file_extensions.values()) if preupload else {}, upload_keys=user_upload_paths if preupload else [], upload_history=collect_files_by_date(upload_history), )
def admin_delete_user(app): args = request.values task = "" if "task" in args: task = args["task"] admin_user_object = session["admin_user_object"] if task == "do-delete-user": email = admin_user_object["email"] clear_session(app) User(email).delete() return redirect("/admin?done=deleted") return render_template_custom( "admin/confirm-delete.html", email=quote(admin_user_object["email"]), user_email=admin_user_object["email"], )
def admin_reinvite_user(app): args = request.values task = "" if "task" in args: task = args["task"] admin_user_object = session["admin_user_object"] if task == "do-reinvite-user": email = admin_user_object["email"] User(email).reinvite() clear_session(app) session["admin_user_email"] = email return redirect("/admin/user?done=reinvited") return render_template_custom( app, "admin/confirm-reinvite.html", email=quote(admin_user_object["email"]), user_email=admin_user_object["email"], )
def server_error_400(error): app.logger.error(f"Server error: {request.url}") return render_template_custom(app, "error.html", hide_logout=True, error=error), 400
def admin_list_users(app): return render_template_custom(app, "admin/list-user.html")
def admin_user_not_found(app): return render_template_custom(app, "error.html", error="User not found")
def admin_main(app): clear_session(app) return render_template_custom(app, "admin/index.html", can_create_users=user_has_a_valid_role( ["admin-full"]))