class PasswordResetRequestForm(FlaskForm): email = StringField( "Email", validators=[ DataRequired(), Email(message="Invalid email address format"), Regexp( r"" + config.get("PROJECTS", "auth_regex_username"), message=config.get("PROJECTS", "auth_regex_msg"), ), ], )
def projects(): form = TagsSearchForm() entities = Project.get_all() tags = Project.get_top_with("tags", num=10) return render_template( "projects/projects.html", title=config.get("PROJECTS", "title"), grid_header="{} {}".format(config.get("PROJECTS", "title"), "Projects"), tags=list(tags.keys()), objects=entities, form=form, )
def create(): form_class = form_manager.get_form_class("config_form") form = form_class(CombinedMultiDict((request.files, request.form))) if form.validate_on_submit(): f = form.image.data # Make sure the saved image is filename is unique filename = secure_filename(unique_name_encoding(f.filename)) f.save(os.path.join(config.get("PROJECTS", "upload_folder"), filename)) # Remove special fields if form.__contains__("csrf_token"): form._fields.pop("csrf_token") form._fields.pop("image") # Save new instance new_instance = { key: field.data for key, field in form.__dict__.items() if hasattr(field, "data") } new_instance["image"] = filename entity = Project(**new_instance) entity_id = entity.save() # Update user with new instance current_user.projects.append(entity_id) current_user.save() url = url_for("projects.show", object_id=entity_id, _external=True) flash( "Your submission has been received," " your metadata can be found at: " + url, "success", ) return redirect(url) return render_template("projects/create_project.html", form=form)
def update(object_id): entity = Project.get(object_id) if entity is None: flash("That entity dosen't exist", "danger") return redirect(url_for("projects.projects")) if object_id not in current_user.projects: flash("Your trying to update an entity that's not yours", "danger") return redirect(url_for("projects.projects")) form_class = form_manager.get_form_class("config_form") form = form_class(CombinedMultiDict((request.files, request.form))) # Strip image upload validation on upload (Optional) form.image.validators = [ validator for validator in form.image.validators if type(validator) is not FileRequired ] if form.validate_on_submit(): # Only save the image if a new was submitted, else keep the old name f = form.image.data if f and hasattr(f, "filename") and f.filename != "": filename = secure_filename(unique_name_encoding(f.filename)) f.save( os.path.join(config.get("PROJECTS", "upload_folder"), filename)) # Remove old os.remove( os.path.join(config.get("PROJECTS", "upload_folder"), entity.image)) else: filename = entity.image # Update every attribute except _id, _type, and image disabled_updates = ["_id", "_type", "image"] for attr in entity.__dict__: if attr not in disabled_updates: entity.__dict__[attr] = form[attr].data entity.__dict__["image"] = filename entity_id = entity.save() url = url_for("projects.show", object_id=entity_id, _external=True) flash("Update Success, your data can be found at: " + url, "success") return redirect(url) form.image.flags = None return render_template("projects/project.html", object=entity, form=form)
def request_auth(): form = AuthRequestForm(request.form) if form.validate_on_submit(): # Send confirmation token user = User.get_with_first("email", form.email.data) if user is None: data = form.data # Remove csrf_token del data["csrf_token"] subject = "{} requests {} access".format( form.email.data, config.get("PROJECTS", "title")) token = generate_confirmation_token(data=form.data) confirm_url = url_for("projects.approve_auth", token=token, _external=True) html = render_template( "projects/email/activate_user.html", email=form.data, confirm_url=confirm_url, ) msg = Message( subject=subject, html=html, recipients=[app.config["ADMINS_EMAIL"]], sender=app.config["MAIL_USERNAME"], ) try: mail.send(msg) except TimeoutError: return jsonify( data={ "danger": "Timed out before request could be sent" " to an admin for approval" }) return jsonify( data={ "success": "Request successfully submitted" ", awaiting admin approval" }) else: response = jsonify( data={"danger": "That email has already been granted access"}) response.status_code = 400 return response response = jsonify( data={ "danger": ", ".join([ "{} - {}".format(attr, r_msg) for attr, errors in form.errors.items() for r_msg in errors ]) }) response.status_code = 400 return response
def nav_bar(): navbar = list( Navbar( View("{}".format(config.get("PROJECTS", "title")), "projects.projects"), View("Datasets", "projects.projects"), ).items) if current_user.is_authenticated: navbar.extend([ View("My Datasets", "projects.my_projects"), View("Create Dataset", "projects.create"), View("Logout", "projects.logout"), ]) else: navbar.extend([ View("Login", "projects.login"), ]) return Navbar("{}".format(config.get("PROJECTS", "title")), *navbar)
class DefaultProjectForm(FlaskForm): name = StringField("Name", validators=[DataRequired()]) description = TextAreaField("Description") image = FileField( "Project Image", validators=[ FileRequired(), FileAllowed(["jpg", "png"], "Only JPG and PNG images are allowed"), ], ) tags = StringField( "Tags", validators=[ DataRequired(), Regexp( r"" + config.get("PROJECTS", "tags_regex"), message=config.get("PROJECTS", "tags_regex_msg"), ), ], )
def approve_auth(token): data = confirm_token(token) if data is False: flash("Confirmation failed, either it is invalid or expired.", "danger") return redirect(url_for("projects.projects")) if "email" not in data: flash("Confirmation failed, required email is not present", "danger") return redirect(url_for("projects.projects")) user = User.get_with_first("email", data["email"]) if user is not None: flash("That email has already been registered") return redirect(url_for("projects.projects")) else: # Setup user = User( email=data["email"], password=hashpw(os.urandom(24), gensalt()), projects=[], is_active=False, is_authenticated=False, is_anonymous=False, confirmed_on=datetime.datetime.now(), ) user.save() token = generate_confirmation_token(data=data["email"]) reset_url = url_for("projects.reset_password", token=token, _external=True) html = render_template( "projects/email/reset_password.html", email=data["email"], reset_password_url=reset_url, ) msg = Message( subject="{} Projects Account approval".format( config.get("PROJECTS", "title")), html=html, recipients=[data["email"]], sender=app.config["MAIL_USERNAME"], ) mail.send(msg) flash( "The account {} has been approved and created".format( data["email"]), "success", ) return redirect(url_for("projects.projects"))
def delete(object_id): entity = Project.get(object_id) if entity is None: flash("That entity dosen't exist", "danger") return redirect(url_for("projects.projects")) if object_id in current_user.projects: Project.remove(object_id) current_user.projects.remove(object_id) os.remove( os.path.join(config.get("PROJECTS", "upload_folder"), entity.image)) current_user.save() flash("Entity: " + entity.name + " has been deleted", "success") else: flash("Your trying to delete an entity you don't own", "danger") return redirect(url_for("projects.projects"))
def request_password_reset(): form = PasswordResetRequestForm(request.form) if form.validate_on_submit(): user = User.get_with_first("email", form.email.data) if user is None: response = jsonify(data={"danger": "That user does not exist"}) response.status_code = 400 return response else: email = user.email token = generate_confirmation_token(data=email) reset_url = url_for("projects.reset_password", token=token, _external=True) html = render_template( "projects/email/reset_password.html", email=email, reset_password_url=reset_url, ) msg = Message( subject="{} Reset Password".format( config.get("PROJECTS", "title")), html=html, recipients=[email], sender=app.config["MAIL_USERNAME"], ) mail.send(msg) return jsonify( data={ "success": "A password reset link has been sent to {}".format(email) }) response = jsonify( data={ "danger": ", ".join([ "{} - {}".format(attr, r_msg) for attr, errors in form.errors.items() for r_msg in errors ]) }) response.status_code = 400 return response
Bootstrap(app) # Login Manager login_manager = LoginManager() login_manager.init_app(app) login_manager.login_view = "projects.login" # Onetime authentication reset token salt app.config["ONETIME_TOKEN_SALT"] = os.urandom(24) # TODO -> fix hack at some point # Application ADMINS_EMAIL if "ADMINS_EMAIL" in os.environ: app.config["ADMINS_EMAIL"] = os.environ["ADMINS_EMAIL"].split(",") else: app.config["ADMINS_EMAIL"] = config.get("MAIL", "admins") # Email application server if "MAIL_SERVER" in os.environ: app.config["MAIL_SERVER"] = os.environ["MAIL_SERVER"] else: app.config["MAIL_SERVER"] = config.get("MAIL", "server") if "MAIL_PORT" in os.environ: app.config["MAIL_PORT"] = os.environ["MAIL_PORT"] else: app.config["MAIL_PORT"] = config.get("MAIL", "port") if "MAIL_USE_TLS" in os.environ: app.config["MAIL_USE_TLS"] = bool(os.environ["MAIL_USE_TLS"]) else: