mirror of
https://github.com/wassname/flask-security.git
synced 2026-06-30 16:40:04 +08:00
76 lines
2.2 KiB
Python
76 lines
2.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
flask.ext.security.passwordless
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Flask-Security passwordless module
|
|
|
|
:copyright: (c) 2012 by Matt Wright.
|
|
:license: MIT, see LICENSE for more details.
|
|
"""
|
|
|
|
from flask import request, current_app as app
|
|
from itsdangerous import SignatureExpired, BadSignature
|
|
from werkzeug.local import LocalProxy
|
|
|
|
from .exceptions import PasswordlessLoginError
|
|
from .signals import login_instructions_sent
|
|
from .utils import send_mail, md5, get_max_age, login_user, get_message, \
|
|
url_for_security, get_url
|
|
|
|
|
|
# Convenient references
|
|
_security = LocalProxy(lambda: app.extensions['security'])
|
|
|
|
_datastore = LocalProxy(lambda: _security.datastore)
|
|
|
|
|
|
def send_login_instructions(user, next):
|
|
"""Sends the login instructions email for the specified user.
|
|
|
|
:param user: The user to send the instructions to
|
|
:param token: The login token
|
|
"""
|
|
token = generate_login_token(user, next)
|
|
|
|
url = url_for_security('token_login', token=token)
|
|
|
|
login_link = request.url_root[:-1] + url
|
|
|
|
ctx = dict(user=user, login_link=login_link)
|
|
|
|
send_mail('Login Instructions', user.email,
|
|
'login_instructions', ctx)
|
|
|
|
login_instructions_sent.send(dict(user=user, login_token=token),
|
|
app=app._get_current_object())
|
|
|
|
|
|
def generate_login_token(user, next):
|
|
next = next or get_url(_security.post_login_view)
|
|
data = [user.id, md5(user.password), next]
|
|
return _security.login_serializer.dumps(data)
|
|
|
|
|
|
def login_by_token(token):
|
|
serializer = _security.login_serializer
|
|
max_age = get_max_age('LOGIN')
|
|
|
|
try:
|
|
user_id, pw, next = serializer.loads(token, max_age=max_age)
|
|
user = _datastore.find_user(id=user_id)
|
|
login_user(user, True)
|
|
return user, next
|
|
|
|
except SignatureExpired:
|
|
sig_okay, data = serializer.loads_unsafe(token)
|
|
user_id, pw, next = data
|
|
user = _datastore.find_user(id=data[0])
|
|
within = _security.login_within
|
|
msg = get_message('LOGIN_EXPIRED', within=within, email=user.email)
|
|
raise PasswordlessLoginError(msg[0], user=user, next=next)
|
|
|
|
except BadSignature:
|
|
msg = get_message('INVALID_LOGIN_TOKEN')
|
|
raise PasswordlessLoginError(msg[0])
|