diff --git a/app/api/views/auth_login.py b/app/api/views/auth_login.py index c4bce079..55ba87b0 100644 --- a/app/api/views/auth_login.py +++ b/app/api/views/auth_login.py @@ -56,8 +56,11 @@ def auth_login(): ret["mfa_key"] = s.sign(str(user.id)) ret["api_key"] = None else: - api_key = ApiKey.create(user.id, device) - db.session.commit() + api_key = ApiKey.get_by(user_id=user.id, name=device) + if not api_key: + LOG.d("create new api key for %s and %s", user, device) + api_key = ApiKey.create(user.id, device) + db.session.commit() ret["mfa_key"] = None ret["api_key"] = api_key.code diff --git a/app/api/views/auth_mfa.py b/app/api/views/auth_mfa.py index 6271e853..08dae060 100644 --- a/app/api/views/auth_mfa.py +++ b/app/api/views/auth_mfa.py @@ -6,6 +6,7 @@ from itsdangerous import Signer, BadSignature from app.api.base import api_bp from app.config import FLASK_SECRET from app.extensions import db +from app.log import LOG from app.models import User, ApiKey @@ -58,8 +59,12 @@ def auth_mfa(): "name": user.name, } - api_key = ApiKey.create(user.id, device) - db.session.commit() + api_key = ApiKey.get_by(user_id=user.id, name=device) + if not api_key: + LOG.d("create new api key for %s and %s", user, device) + api_key = ApiKey.create(user.id, device) + db.session.commit() + ret["api_key"] = api_key.code return jsonify(**ret), 200 diff --git a/tests/api/test_auth_login.py b/tests/api/test_auth_login.py index 59f89024..96241333 100644 --- a/tests/api/test_auth_login.py +++ b/tests/api/test_auth_login.py @@ -40,3 +40,26 @@ def test_auth_login_success_mfa_enabled(flask_client): assert r.json["mfa_enabled"] == True assert r.json["mfa_key"] assert r.json["name"] == "Test User" + + +def test_auth_login_device_exist(flask_client): + User.create(email="a@b.c", password="password", name="Test User", activated=True) + db.session.commit() + + r = flask_client.post( + url_for("api.auth_login"), + json={"email": "a@b.c", "password": "password", "device": "Test Device"}, + ) + + assert r.status_code == 200 + api_key = r.json["api_key"] + assert r.json["mfa_enabled"] == False + 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"), + json={"email": "a@b.c", "password": "password", "device": "Test Device"}, + ) + assert r.json["api_key"] == api_key