def send_email_with_retry(msg, times_retried=0): """Send email with retry on exception""" try: mail.send(msg) except smtplib.SMTPException as err: # Wait a little bit time.sleep(10) # Retry twice if times_retried < 2: retry = times_retried + 1 AddUser.send_email_with_retry(msg, retry)
def send_hotp_email(user): """Send one time code via email.""" # Only send if the hotp has not been issued or if it's been more than 15 minutes since # a hotp email was last sent if not user.hotp_issue_time or ( user.hotp_issue_time and (dds_web.utils.current_time() - user.hotp_issue_time > datetime.timedelta(minutes=15))): # Generate the one time code from the users specific hotp secret hotp_value = user.generate_HOTP_token() # Create and send email msg = dds_web.utils.create_one_time_password_email( user=user, hotp_value=hotp_value) mail.send(msg) return True return False
def send_project_access_reset_email(email_row, email, token): """Generate password reset email.""" msg = flask_mail.Message( "WARNING! A Unit Admin has lost access", recipients=[email_row.email], ) # Need to attach the image to be able to use it msg.attach( "scilifelab_logo.png", "image/png", open(os.path.join(flask.current_app.static_folder, "img/scilifelab_logo.png"), "rb").read(), "inline", headers=[ ["Content-ID", "<Logo>"], ], ) msg.body = flask.render_template("mail/project_access_reset.txt", email=email) msg.html = flask.render_template("mail/project_access_reset.html", email=email) mail.send(msg)
def send_reset_email(email_row, token): """Generate password reset email.""" msg = flask_mail.Message( "WARNING! Password Reset Request for SciLifeLab Data Delivery System", recipients=[email_row.email], ) # Need to attach the image to be able to use it msg.attach( "scilifelab_logo.png", "image/png", open(os.path.join(flask.current_app.static_folder, "img/scilifelab_logo.png"), "rb").read(), "inline", headers=[ ["Content-ID", "<Logo>"], ], ) link = flask.url_for("auth_blueprint.reset_password", token=token, _external=True) msg.body = flask.render_template("mail/password_reset.txt", link=link) msg.html = flask.render_template("mail/password_reset.html", link=link) mail.send(msg)
def delete(self): """Request deletion of own account.""" current_user = auth.current_user() email_str = current_user.primary_email username = current_user.username proj_ids = None if current_user.role != "Super Admin": proj_ids = [proj.public_id for proj in current_user.projects] if current_user.role == "Unit Admin": num_admins = models.UnitUser.query.filter_by( unit_id=current_user.unit.id, is_admin=True).count() if num_admins <= 3: raise ddserr.AccessDeniedError(message=( f"Your unit only has {num_admins} Unit Admins. " "You cannot delete your account. " "Invite a new Unit Admin first if you wish to proceed.")) # Create URL safe token for invitation link s = itsdangerous.URLSafeTimedSerializer( flask.current_app.config["SECRET_KEY"]) token = s.dumps(email_str, salt="email-delete") # Create deletion request in database unless it already exists try: if not dds_web.utils.delrequest_exists(email_str): new_delrequest = models.DeletionRequest( **{ "requester": current_user, "email": email_str, "issued": dds_web.utils.current_time(), }) db.session.add(new_delrequest) db.session.commit() else: return { "message": ("The confirmation link has already " f"been sent to your address {email_str}!"), "status": http.HTTPStatus.OK, } except (sqlalchemy.exc.SQLAlchemyError, sqlalchemy.exc.OperationalError) as sqlerr: db.session.rollback() raise ddserr.DatabaseError( message=str(sqlerr), alt_message=f"Creation of self-deletion request failed" + (": Database malfunction." if isinstance( sqlerr, sqlalchemy.exc.OperationalError) else "."), ) from sqlerr # Create link for deletion request email link = flask.url_for("auth_blueprint.confirm_self_deletion", token=token, _external=True) subject = f"Confirm deletion of your user account {username} in the SciLifeLab Data Delivery System" msg = flask_mail.Message( subject, recipients=[email_str], ) # Need to attach the image to be able to use it msg.attach( "scilifelab_logo.png", "image/png", open( os.path.join(flask.current_app.static_folder, "img/scilifelab_logo.png"), "rb").read(), "inline", headers=[ ["Content-ID", "<Logo>"], ], ) msg.body = flask.render_template( "mail/deletion_request.txt", link=link, sender_name=current_user.name, projects=proj_ids, ) msg.html = flask.render_template( "mail/deletion_request.html", link=link, sender_name=current_user.name, projects=proj_ids, ) mail.send(msg) flask.current_app.logger.info( f"The user account {username} / {email_str} ({current_user.role}) " "has requested self-deletion.") return { "message": ("Requested account deletion initiated. An e-mail with a " f"confirmation link has been sent to your address {email_str}!"), }