49
loading...
This website collects cookies to deliver better user experience
The Flask-Mail extension provides a simple interface to set up SMTP with your Flask application and to send messages from your views and scripts.
pip install Flask-Mail
MAIL_SERVER = os.getenv('MAIL_SERVER')
MAIL_PORT = os.getenv('MAIL_PORT')
MAIL_USERNAME = os.getenv('MAIL_USERNAME')
MAIL_PASSWORD = os.getenv('MAIL_PASSWORD')
SUBJECT = os.getenv('SUBJECT')
CONFIRMATION_URI = os.getenv('CONFIRMATION_URI')
os.getenv
is necessary, to get the environment variables.pip install python-dotenv
from flask_mail import Mail
from dotenv import load_dotenv
load_dotenv() # take environment variables from .env.
'MAIL_SERVER' = 'smtp.gmail.com'
'MAIL_PORT' = 465
'MAIL_USE_SSL' = True
'MAIL_USERNAME' = "[email protected]"
'MAIL_PASSWORD' = "password"
# configuration of mail
app.config['MAIL_SERVER'] = MAIL_SERVER
app.config['MAIL_PORT'] = MAIL_PORT
app.config['MAIL_USERNAME'] = MAIL_USERNAME
app.config['MAIL_PASSWORD'] = MAIL_PASSWORD
app.config['MAIL_DEFAULT_SENDER'] = (APP_NAME, MAIL_USERNAME)
app.config['MAIL_USE_TLS'] = False
app.config['MAIL_USE_SSL'] = True
#Initialize Mail extension
mail = Mail()
mail.init_app(app)
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.Text, unique=True, nullable=False)
email = db.Column(db.Text, unique=True, nullable=False)
password = db.Column(db.Text, nullable=False)
roles = db.Column(db.Text)
is_active = db.Column(db.Boolean, default=False, server_default='true')
@property
def rolenames(self):
try:
return self.roles.split(',')
except Exception:
return []
@classmethod
def lookup(cls, username):
return cls.query.filter_by(username=username).one_or_none()
@classmethod
def lookup(cls, email):
return cls.query.filter_by(email=email).one_or_none()
@classmethod
def identify(cls, id):
return cls.query.get(id)
@property
def identity(self):
return self.id
def is_valid(self):
return self.is_active
send_registration_email
from flask-praetorian, on our registration endpoint we need to load the CONFIRMATION_URI which will points to a frontend confirmation uri address with the token sent to the email. In my case it is CONFIRMATION_URI = 'https://patriciadourado.com/jwtlogin-reactjs/#/finalize' with the subject mail as following: SUBJECT = 'Please confirm your registration';subject = SUBJECT
confirmation_sender=(APP_NAME, MAIL_USERNAME)
confirmation_uri = CONFIRMATION_URI
req = flask.request.get_json(force=True)
username = req.get('username', None)
password = req.get('password', None)
email = req.get('email', None)
if db.session.query(User).filter_by(username=username).count() < 1:
if db.session.query(User).filter_by(email=email).count() < 1:
new_user = User(
username=username,
email=email,
password=guard.hash_password(password),
roles='user',
)
db.session.add(new_user)
db.session.commit()
guard.send_registration_email(email, user=new_user, confirmation_sender=confirmation_sender,confirmation_uri=confirmation_uri, subject=subject, override_access_lifespan=None)
ret = {'message': 'successfully sent registration email to user {}'.format(
new_user.username
)}
return (flask.jsonify(ret), 201)
else:
ret = {'message': 'email {} already exists on DB!'.format(email)}
return (flask.jsonify(ret), 303)
else:
ret = {'message':'user {} already exists on DB!'.format(username)}
return (flask.jsonify(ret), 409)
registration_token = guard.read_token_from_header()
user = guard.get_user_from_registration_token(registration_token)
# user activation
user.is_active = True
db.session.commit()
ret = {'access_token': guard.encode_jwt_token(user), 'user': user.username}
print(ret)
return (flask.jsonify(ret), 200)
@app.route('/api/reset', methods=['POST'])
def reset():
"""Reset password email"""
reset_sender=(APP_NAME, MAIL_USERNAME)
reset_uri = RESET_URI
subject_rest = SUBJECT_RESET
req = flask.request.get_json(force=True)
email = req.get('email', None)
if db.session.query(User).filter_by(email=email).count() > 0:
if db.session.query(User).filter(User.email==email, User.is_active==True).scalar():
guard.send_reset_email(email, reset_sender=reset_sender, reset_uri=reset_uri, subject=subject_rest, override_access_lifespan=None)
ret = {'message': 'successfully sent password reset email to {}'.format(email)}
return (flask.jsonify(ret), 200)
else:
ret = {'message': '{} account not activated! active it first!'.format(email)}
return (flask.jsonify(ret), 403)
else:
ret = {'message': 'email {} doest not exists on DB!'.format(email)}
return (flask.jsonify(ret), 404)
@app.route('/api/reset_finalize', methods=['POST'])
def reset_finalize():
"""Reset password on database by token"""
req = flask.request.get_json(force=True)
password = req.get('password', None)
reset_token = guard.read_token_from_header()
try:
user = guard.validate_reset_token(reset_token)
user.password = guard.hash_password(password)
db.session.commit()
ret = {'access_token': guard.encode_jwt_token(user), 'user': user.username}
return (flask.jsonify(ret), 200)
except Exception:
ret = {"Error resetting user password by token:"}
return ret, 500