mirror of
https://github.com/wassname/flask-security.git
synced 2026-06-27 16:10:11 +08:00
189 lines
6.3 KiB
Python
189 lines
6.3 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
test_emails
|
|
~~~~~~~~~~~
|
|
|
|
Email functionality tests
|
|
"""
|
|
|
|
import pytest
|
|
|
|
from flask_security import Security
|
|
from flask_security.forms import LoginForm, RegisterForm, ConfirmRegisterForm, \
|
|
SendConfirmationForm, PasswordlessLoginForm, ForgotPasswordForm, ResetPasswordForm, \
|
|
ChangePasswordForm, TextField, PasswordField, email_required, email_validator, valid_user_email
|
|
from flask_security.utils import capture_reset_password_requests, md5, string_types
|
|
|
|
from utils import authenticate, init_app_with_options, populate_data
|
|
|
|
|
|
@pytest.mark.recoverable()
|
|
def test_async_email_task(app, client):
|
|
app.mail_sent = False
|
|
|
|
@app.security.send_mail_task
|
|
def send_email(msg):
|
|
app.mail_sent = True
|
|
|
|
client.post('/reset', data=dict(email='matt@lp.com'))
|
|
assert app.mail_sent is True
|
|
|
|
|
|
def test_register_blueprint_flag(app, sqlalchemy_datastore):
|
|
app.security = Security(app, datastore=Security, register_blueprint=False)
|
|
client = app.test_client()
|
|
response = client.get('/login')
|
|
assert response.status_code == 404
|
|
|
|
|
|
@pytest.mark.registerable()
|
|
@pytest.mark.recoverable()
|
|
@pytest.mark.changeable()
|
|
def test_basic_custom_forms(app, sqlalchemy_datastore):
|
|
class MyLoginForm(LoginForm):
|
|
email = TextField('My Login Email Address Field')
|
|
|
|
class MyRegisterForm(RegisterForm):
|
|
email = TextField('My Register Email Address Field')
|
|
|
|
class MyForgotPasswordForm(ForgotPasswordForm):
|
|
email = TextField('My Forgot Email Address Field',
|
|
validators=[email_required, email_validator, valid_user_email])
|
|
|
|
class MyResetPasswordForm(ResetPasswordForm):
|
|
password = TextField('My Reset Password Field')
|
|
|
|
class MyChangePasswordForm(ChangePasswordForm):
|
|
password = PasswordField('My Change Password Field')
|
|
|
|
app.security = Security(app,
|
|
datastore=sqlalchemy_datastore,
|
|
login_form=MyLoginForm,
|
|
register_form=MyRegisterForm,
|
|
forgot_password_form=MyForgotPasswordForm,
|
|
reset_password_form=MyResetPasswordForm,
|
|
change_password_form=MyChangePasswordForm)
|
|
|
|
populate_data(app)
|
|
client = app.test_client()
|
|
|
|
response = client.get('/login')
|
|
assert b'My Login Email Address Field' in response.data
|
|
|
|
response = client.get('/register')
|
|
assert b'My Register Email Address Field' in response.data
|
|
|
|
response = client.get('/reset')
|
|
assert b'My Forgot Email Address Field' in response.data
|
|
|
|
with capture_reset_password_requests() as requests:
|
|
response = client.post('/reset', data=dict(email='matt@lp.com'))
|
|
|
|
token = requests[0]['token']
|
|
response = client.get('/reset/' + token)
|
|
assert b'My Reset Password Field' in response.data
|
|
|
|
authenticate(client)
|
|
|
|
response = client.get('/change')
|
|
assert b'My Change Password Field' in response.data
|
|
|
|
|
|
@pytest.mark.registerable()
|
|
@pytest.mark.confirmable()
|
|
def test_confirmable_custom_form(app, sqlalchemy_datastore):
|
|
app.config['SECURITY_REGISTERABLE'] = True
|
|
app.config['SECURITY_CONFIRMABLE'] = True
|
|
|
|
class MyRegisterForm(ConfirmRegisterForm):
|
|
email = TextField('My Register Email Address Field')
|
|
|
|
class MySendConfirmationForm(SendConfirmationForm):
|
|
email = TextField('My Send Confirmation Email Address Field')
|
|
|
|
app.security = Security(app,
|
|
datastore=sqlalchemy_datastore,
|
|
send_confirmation_form=MySendConfirmationForm,
|
|
confirm_register_form=MyRegisterForm)
|
|
|
|
client = app.test_client()
|
|
|
|
response = client.get('/register')
|
|
assert b'My Register Email Address Field' in response.data
|
|
|
|
response = client.get('/confirm')
|
|
assert b'My Send Confirmation Email Address Field' in response.data
|
|
|
|
|
|
def test_passwordless_custom_form(app, sqlalchemy_datastore):
|
|
app.config['SECURITY_PASSWORDLESS'] = True
|
|
|
|
class MyPasswordlessLoginForm(PasswordlessLoginForm):
|
|
email = TextField('My Passwordless Email Address Field')
|
|
|
|
app.security = Security(app,
|
|
datastore=sqlalchemy_datastore,
|
|
passwordless_login_form=MyPasswordlessLoginForm)
|
|
|
|
client = app.test_client()
|
|
|
|
response = client.get('/login')
|
|
assert b'My Passwordless Email Address Field' in response.data
|
|
|
|
|
|
def test_addition_identity_attributes(app, sqlalchemy_datastore):
|
|
init_app_with_options(app, sqlalchemy_datastore, **{
|
|
'SECURITY_USER_IDENTITY_ATTRIBUTES': ('email', 'username')
|
|
})
|
|
client = app.test_client()
|
|
response = authenticate(client, email='matt', follow_redirects=True)
|
|
assert b'Hello matt@lp.com' in response.data
|
|
|
|
|
|
def test_flash_messages_off(app, sqlalchemy_datastore, get_message):
|
|
init_app_with_options(app, sqlalchemy_datastore, **{
|
|
'SECURITY_FLASH_MESSAGES': False
|
|
})
|
|
client = app.test_client()
|
|
response = client.get('/profile')
|
|
assert get_message('LOGIN') not in response.data
|
|
|
|
|
|
def test_invalid_hash_scheme(app, sqlalchemy_datastore, get_message):
|
|
with pytest.raises(ValueError):
|
|
init_app_with_options(app, sqlalchemy_datastore, **{
|
|
'SECURITY_PASSWORD_HASH': 'bogus'
|
|
})
|
|
|
|
|
|
def test_change_hash_type(app, sqlalchemy_datastore):
|
|
init_app_with_options(app, sqlalchemy_datastore, **{
|
|
'SECURITY_PASSWORD_SCHEMES': ['bcrypt', 'plaintext']
|
|
})
|
|
|
|
app.config['SECURITY_PASSWORD_HASH'] = 'bcrypt'
|
|
app.config['SECURITY_PASSWORD_SALT'] = 'salty'
|
|
|
|
app.security = Security(app, datastore=sqlalchemy_datastore, register_blueprint=False)
|
|
|
|
client = app.test_client()
|
|
|
|
response = client.post('/login', data=dict(email='matt@lp.com', password='password'))
|
|
assert response.status_code == 302
|
|
|
|
|
|
def test_md5():
|
|
data = md5(b'hello')
|
|
assert isinstance(data, string_types)
|
|
data = md5(u'hellö')
|
|
assert isinstance(data, string_types)
|
|
|
|
|
|
@pytest.mark.settings(password_salt=u'öööööööööööööööööööööööööööööööööö',
|
|
password_hash='bcrypt')
|
|
def test_password_unicode_password_salt(client):
|
|
response = authenticate(client)
|
|
assert response.status_code == 302
|
|
response = authenticate(client, follow_redirects=True)
|
|
assert b'Hello matt@lp.com' in response.data
|