2021-05-26 19:05:26 +02:00
|
|
|
import pytest
|
2021-10-12 14:36:47 +02:00
|
|
|
import unicodedata
|
2020-01-20 14:36:39 +01:00
|
|
|
from flask import url_for
|
|
|
|
|
2021-10-12 14:36:47 +02:00
|
|
|
from app.db import Session
|
2020-02-28 13:01:54 +01:00
|
|
|
from app.models import User, AccountActivation
|
2020-01-20 14:36:39 +01:00
|
|
|
|
2021-05-27 22:15:46 +02:00
|
|
|
PASSWORD_1 = "Aurélie"
|
2021-06-02 18:48:35 +02:00
|
|
|
PASSWORD_2 = unicodedata.normalize("NFKD", PASSWORD_1)
|
2021-05-27 22:15:46 +02:00
|
|
|
assert PASSWORD_1 != PASSWORD_2
|
|
|
|
|
2020-01-20 14:36:39 +01:00
|
|
|
|
2021-05-26 19:05:26 +02:00
|
|
|
@pytest.mark.parametrize("mfa", (True, False), ids=("MFA", "no MFA"))
|
|
|
|
def test_auth_login_success(flask_client, mfa: bool):
|
2020-01-20 14:36:39 +01:00
|
|
|
User.create(
|
2020-04-27 23:15:30 +02:00
|
|
|
email="abcd@gmail.com",
|
2021-05-27 22:15:46 +02:00
|
|
|
password=PASSWORD_1,
|
2020-01-20 14:36:39 +01:00
|
|
|
name="Test User",
|
|
|
|
activated=True,
|
2021-05-26 19:05:26 +02:00
|
|
|
enable_otp=mfa,
|
2020-01-20 14:36:39 +01:00
|
|
|
)
|
2021-10-12 14:36:47 +02:00
|
|
|
Session.commit()
|
2020-01-20 14:36:39 +01:00
|
|
|
|
|
|
|
r = flask_client.post(
|
2022-02-22 22:12:36 +01:00
|
|
|
"/api/auth/login",
|
2020-04-27 23:15:30 +02:00
|
|
|
json={
|
|
|
|
"email": "abcd@gmail.com",
|
2021-05-27 22:15:46 +02:00
|
|
|
"password": PASSWORD_2,
|
2020-04-27 23:15:30 +02:00
|
|
|
"device": "Test Device",
|
|
|
|
},
|
2020-01-20 14:36:39 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
assert r.status_code == 200
|
|
|
|
assert r.json["name"] == "Test User"
|
2021-05-26 19:05:26 +02:00
|
|
|
assert r.json["email"]
|
|
|
|
|
|
|
|
if mfa:
|
|
|
|
assert r.json["api_key"] is None
|
|
|
|
assert r.json["mfa_enabled"]
|
|
|
|
assert r.json["mfa_key"]
|
|
|
|
else:
|
|
|
|
assert r.json["api_key"]
|
|
|
|
assert not r.json["mfa_enabled"]
|
|
|
|
assert r.json["mfa_key"] is None
|
2020-02-05 12:05:26 +01:00
|
|
|
|
|
|
|
|
|
|
|
def test_auth_login_device_exist(flask_client):
|
2020-04-27 23:15:30 +02:00
|
|
|
User.create(
|
|
|
|
email="abcd@gmail.com", password="password", name="Test User", activated=True
|
|
|
|
)
|
2021-10-12 14:36:47 +02:00
|
|
|
Session.commit()
|
2020-02-05 12:05:26 +01:00
|
|
|
|
|
|
|
r = flask_client.post(
|
|
|
|
url_for("api.auth_login"),
|
2020-04-27 23:15:30 +02:00
|
|
|
json={
|
|
|
|
"email": "abcd@gmail.com",
|
|
|
|
"password": "password",
|
|
|
|
"device": "Test Device",
|
|
|
|
},
|
2020-02-05 12:05:26 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
assert r.status_code == 200
|
|
|
|
api_key = r.json["api_key"]
|
2020-12-06 17:54:54 +01:00
|
|
|
assert not r.json["mfa_enabled"]
|
2020-02-05 12:05:26 +01:00
|
|
|
assert r.json["mfa_key"] is None
|
|
|
|
assert r.json["name"] == "Test User"
|
|
|
|
|
|
|
|
# same device, should return same api_key
|
|
|
|
r = flask_client.post(
|
|
|
|
url_for("api.auth_login"),
|
2020-04-27 23:15:30 +02:00
|
|
|
json={
|
|
|
|
"email": "abcd@gmail.com",
|
|
|
|
"password": "password",
|
|
|
|
"device": "Test Device",
|
|
|
|
},
|
2020-02-05 12:05:26 +01:00
|
|
|
)
|
|
|
|
assert r.json["api_key"] == api_key
|
2020-02-28 13:01:54 +01:00
|
|
|
|
|
|
|
|
|
|
|
def test_auth_register_success(flask_client):
|
2021-08-05 19:44:56 +02:00
|
|
|
assert AccountActivation.first() is None
|
2020-02-28 13:01:54 +01:00
|
|
|
|
|
|
|
r = flask_client.post(
|
2020-04-27 23:15:30 +02:00
|
|
|
url_for("api.auth_register"),
|
|
|
|
json={"email": "abcd@gmail.com", "password": "password"},
|
2020-02-28 13:01:54 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
assert r.status_code == 200
|
|
|
|
assert r.json["msg"]
|
|
|
|
|
|
|
|
# make sure an activation code is created
|
2021-08-05 19:44:56 +02:00
|
|
|
act_code = AccountActivation.first()
|
2020-02-28 13:01:54 +01:00
|
|
|
assert act_code
|
|
|
|
assert len(act_code.code) == 6
|
|
|
|
assert act_code.tries == 3
|
|
|
|
|
|
|
|
|
|
|
|
def test_auth_register_too_short_password(flask_client):
|
|
|
|
r = flask_client.post(
|
2020-04-27 23:15:30 +02:00
|
|
|
url_for("api.auth_register"),
|
|
|
|
json={"email": "abcd@gmail.com", "password": "short"},
|
2020-02-28 13:01:54 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
assert r.status_code == 400
|
|
|
|
assert r.json["error"] == "password too short"
|
|
|
|
|
|
|
|
|
2021-11-16 19:41:05 +01:00
|
|
|
def test_auth_register_too_long_password(flask_client):
|
|
|
|
r = flask_client.post(
|
|
|
|
url_for("api.auth_register"),
|
|
|
|
json={"email": "abcd@gmail.com", "password": "0123456789" * 11},
|
|
|
|
)
|
|
|
|
|
|
|
|
assert r.status_code == 400
|
|
|
|
assert r.json["error"] == "password too long"
|
|
|
|
|
|
|
|
|
2020-02-28 13:01:54 +01:00
|
|
|
def test_auth_activate_success(flask_client):
|
|
|
|
r = flask_client.post(
|
2020-04-27 23:15:30 +02:00
|
|
|
url_for("api.auth_register"),
|
|
|
|
json={"email": "abcd@gmail.com", "password": "password"},
|
2020-02-28 13:01:54 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
assert r.status_code == 200
|
|
|
|
assert r.json["msg"]
|
|
|
|
|
|
|
|
# get the activation code
|
2021-08-05 19:44:56 +02:00
|
|
|
act_code = AccountActivation.first()
|
2020-02-28 13:01:54 +01:00
|
|
|
assert act_code
|
|
|
|
assert len(act_code.code) == 6
|
|
|
|
|
|
|
|
r = flask_client.post(
|
2020-04-27 23:15:30 +02:00
|
|
|
url_for("api.auth_activate"),
|
|
|
|
json={"email": "abcd@gmail.com", "code": act_code.code},
|
2020-02-28 13:01:54 +01:00
|
|
|
)
|
|
|
|
assert r.status_code == 200
|
|
|
|
|
|
|
|
|
|
|
|
def test_auth_activate_wrong_email(flask_client):
|
|
|
|
r = flask_client.post(
|
2020-04-27 23:15:30 +02:00
|
|
|
url_for("api.auth_activate"), json={"email": "abcd@gmail.com", "code": "123456"}
|
2020-02-28 13:01:54 +01:00
|
|
|
)
|
|
|
|
assert r.status_code == 400
|
|
|
|
|
|
|
|
|
|
|
|
def test_auth_activate_user_already_activated(flask_client):
|
2020-04-27 23:15:30 +02:00
|
|
|
User.create(
|
|
|
|
email="abcd@gmail.com", password="password", name="Test User", activated=True
|
|
|
|
)
|
2021-10-12 14:36:47 +02:00
|
|
|
Session.commit()
|
2020-02-28 13:01:54 +01:00
|
|
|
|
|
|
|
r = flask_client.post(
|
2020-04-27 23:15:30 +02:00
|
|
|
url_for("api.auth_activate"), json={"email": "abcd@gmail.com", "code": "123456"}
|
2020-02-28 13:01:54 +01:00
|
|
|
)
|
|
|
|
assert r.status_code == 400
|
|
|
|
|
|
|
|
|
|
|
|
def test_auth_activate_wrong_code(flask_client):
|
|
|
|
r = flask_client.post(
|
2020-04-27 23:15:30 +02:00
|
|
|
url_for("api.auth_register"),
|
|
|
|
json={"email": "abcd@gmail.com", "password": "password"},
|
2020-02-28 13:01:54 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
assert r.status_code == 200
|
|
|
|
assert r.json["msg"]
|
|
|
|
|
|
|
|
# get the activation code
|
2021-08-05 19:44:56 +02:00
|
|
|
act_code = AccountActivation.first()
|
2020-02-28 13:01:54 +01:00
|
|
|
assert act_code
|
|
|
|
assert len(act_code.code) == 6
|
|
|
|
assert act_code.tries == 3
|
|
|
|
|
|
|
|
# make sure to create a wrong code
|
|
|
|
wrong_code = act_code.code + "123"
|
|
|
|
|
|
|
|
r = flask_client.post(
|
2020-04-27 23:15:30 +02:00
|
|
|
url_for("api.auth_activate"),
|
|
|
|
json={"email": "abcd@gmail.com", "code": wrong_code},
|
2020-02-28 13:01:54 +01:00
|
|
|
)
|
|
|
|
assert r.status_code == 400
|
|
|
|
|
|
|
|
# make sure the nb tries decrements
|
2021-08-05 19:44:56 +02:00
|
|
|
act_code = AccountActivation.first()
|
2020-02-28 13:01:54 +01:00
|
|
|
assert act_code.tries == 2
|
|
|
|
|
|
|
|
|
|
|
|
def test_auth_activate_too_many_wrong_code(flask_client):
|
|
|
|
r = flask_client.post(
|
2020-04-27 23:15:30 +02:00
|
|
|
url_for("api.auth_register"),
|
|
|
|
json={"email": "abcd@gmail.com", "password": "password"},
|
2020-02-28 13:01:54 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
assert r.status_code == 200
|
|
|
|
assert r.json["msg"]
|
|
|
|
|
|
|
|
# get the activation code
|
2021-08-05 19:44:56 +02:00
|
|
|
act_code = AccountActivation.first()
|
2020-02-28 13:01:54 +01:00
|
|
|
assert act_code
|
|
|
|
assert len(act_code.code) == 6
|
|
|
|
assert act_code.tries == 3
|
|
|
|
|
|
|
|
# make sure to create a wrong code
|
|
|
|
wrong_code = act_code.code + "123"
|
|
|
|
|
|
|
|
for _ in range(2):
|
|
|
|
r = flask_client.post(
|
2020-04-27 23:15:30 +02:00
|
|
|
url_for("api.auth_activate"),
|
|
|
|
json={"email": "abcd@gmail.com", "code": wrong_code},
|
2020-02-28 13:01:54 +01:00
|
|
|
)
|
|
|
|
assert r.status_code == 400
|
|
|
|
|
|
|
|
# the activation code is deleted
|
|
|
|
r = flask_client.post(
|
2020-04-27 23:15:30 +02:00
|
|
|
url_for("api.auth_activate"),
|
|
|
|
json={"email": "abcd@gmail.com", "code": wrong_code},
|
2020-02-28 13:01:54 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
assert r.status_code == 410
|
|
|
|
|
|
|
|
# make sure the nb tries decrements
|
2021-08-05 19:44:56 +02:00
|
|
|
assert AccountActivation.first() is None
|
2020-02-28 13:01:54 +01:00
|
|
|
|
|
|
|
|
|
|
|
def test_auth_reactivate_success(flask_client):
|
2020-04-27 23:15:30 +02:00
|
|
|
User.create(email="abcd@gmail.com", password="password", name="Test User")
|
2021-10-12 14:36:47 +02:00
|
|
|
Session.commit()
|
2020-02-28 13:01:54 +01:00
|
|
|
|
2020-04-27 23:15:30 +02:00
|
|
|
r = flask_client.post(
|
|
|
|
url_for("api.auth_reactivate"), json={"email": "abcd@gmail.com"}
|
|
|
|
)
|
2020-02-28 13:01:54 +01:00
|
|
|
assert r.status_code == 200
|
|
|
|
|
|
|
|
# make sure an activation code is created
|
2021-08-05 19:44:56 +02:00
|
|
|
act_code = AccountActivation.first()
|
2020-02-28 13:01:54 +01:00
|
|
|
assert act_code
|
|
|
|
assert len(act_code.code) == 6
|
|
|
|
assert act_code.tries == 3
|
2020-03-18 18:43:04 +01:00
|
|
|
|
|
|
|
|
|
|
|
def test_auth_login_forgot_password(flask_client):
|
2020-04-27 23:15:30 +02:00
|
|
|
User.create(
|
|
|
|
email="abcd@gmail.com", password="password", name="Test User", activated=True
|
|
|
|
)
|
2021-10-12 14:36:47 +02:00
|
|
|
Session.commit()
|
2020-03-18 18:43:04 +01:00
|
|
|
|
2020-04-27 23:15:30 +02:00
|
|
|
r = flask_client.post(
|
2020-08-27 10:20:48 +02:00
|
|
|
url_for("api.forgot_password"),
|
|
|
|
json={"email": "abcd@gmail.com"},
|
2020-04-27 23:15:30 +02:00
|
|
|
)
|
2020-03-18 18:43:04 +01:00
|
|
|
|
|
|
|
assert r.status_code == 200
|
|
|
|
|
2020-03-18 21:55:50 +01:00
|
|
|
# No such email, still return 200
|
2020-03-18 18:43:04 +01:00
|
|
|
r = flask_client.post(
|
2020-08-27 10:20:48 +02:00
|
|
|
url_for("api.forgot_password"),
|
|
|
|
json={"email": "not-exist@b.c"},
|
2020-03-18 18:43:04 +01:00
|
|
|
)
|
|
|
|
|
2020-03-18 21:55:50 +01:00
|
|
|
assert r.status_code == 200
|