diff --git a/selfprivacy_api/repositories/tokens/json_tokens_repository.py b/selfprivacy_api/repositories/tokens/json_tokens_repository.py index e23ed0b..938d419 100644 --- a/selfprivacy_api/repositories/tokens/json_tokens_repository.py +++ b/selfprivacy_api/repositories/tokens/json_tokens_repository.py @@ -75,7 +75,7 @@ class JsonTokensRepository(AbstractTokensRepository): { "token": new_token.token, "name": new_token.device_name, - "date": new_token.created_at, + "date": new_token.created_at.strftime("%Y-%m-%d %H:%M:%S.%f"), } ) return new_token @@ -84,10 +84,11 @@ class JsonTokensRepository(AbstractTokensRepository): """Delete the token""" with WriteUserData(UserDataFiles.TOKENS) as tokens_file: for userdata_token in tokens_file["tokens"]: - if userdata_token["token"] == input_token: - tokens_file["tokens"].remove( - userdata_token - ) # Naiji, i pray it works + if userdata_token["token"] == input_token.token: + tokens_file["tokens"].remove(userdata_token) + return + + raise TokenNotFoundError("Token not found!") def refresh_token(self, input_token: Token) -> Token: """Change the token field of the existing token""" @@ -96,7 +97,7 @@ class JsonTokensRepository(AbstractTokensRepository): with WriteUserData(UserDataFiles.TOKENS) as tokens_file: for userdata_token in tokens_file["tokens"]: - if userdata_token["token"] == input_token.token: + if userdata_token["name"] == input_token.device_name: userdata_token["token"] = new_token.token userdata_token["data"] = new_token.created_at @@ -197,17 +198,17 @@ class JsonTokensRepository(AbstractTokensRepository): with WriteUserData(UserDataFiles.TOKENS) as tokens_file: if "new_device" in tokens_file: del tokens_file["new_device"] + return + + raise TokenNotFoundError("Key not found!") def use_mnemonic_new_device_key( self, mnemonic_phrase: str, device_name: str ) -> Token: """Use the mnemonic new device key""" new_device_key = NewDeviceKey.generate() - - if new_device_key.key is None: - raise TokenNotFoundError("Device key is None!") - token = bytes.fromhex(new_device_key.key) + if not Mnemonic(language="english").check(mnemonic_phrase): raise MnemonicError("Phrase is not mnemonic!") diff --git a/tests/test_graphql/test_repository/test_tokens_repository.py b/tests/test_graphql/test_repository/test_tokens_repository.py index ca8bc24..f664ecb 100644 --- a/tests/test_graphql/test_repository/test_tokens_repository.py +++ b/tests/test_graphql/test_repository/test_tokens_repository.py @@ -2,8 +2,12 @@ # pylint: disable=unused-argument # pylint: disable=missing-function-docstring -import datetime +from datetime import datetime +from typing import Optional +from pydantic import BaseModel import pytest +from selfprivacy_api.models.tokens.new_device_key import NewDeviceKey +from selfprivacy_api.models.tokens.recovery_key import RecoveryKey from tests.common import read_json from selfprivacy_api.repositories.tokens.json_tokens_repository import ( @@ -19,6 +23,83 @@ from selfprivacy_api.repositories.tokens.exceptions import ( ) +class TokenMock(BaseModel): + token: str + device_name: str + created_at: datetime + + @staticmethod + def generate(device_name: str) -> "Token": + return Token( + token="iamtoken", + device_name="imnew", + created_at=datetime(2022, 7, 15, 17, 41, 31, 675698), + ) + + +class NewDeviceKeyMock(BaseModel): + key: str + created_at: datetime + expires_at: datetime + + @staticmethod + def generate() -> "NewDeviceKey": + return NewDeviceKey( + key="imkey", + created_at=datetime(2022, 7, 15, 17, 41, 31, 675698), + expires_at=datetime(2022, 7, 15, 17, 41, 31, 675698), + ) + + +class RecoveryKeyMock(BaseModel): + key: str + created_at: datetime + expires_at: Optional[datetime] + uses_left: Optional[int] + + @staticmethod + def generate( + expiration: Optional[datetime], + uses_left: Optional[int], + ) -> "RecoveryKey": + return RecoveryKey( + key="imnewrecoverykey", + created_at=datetime(2022, 7, 15, 17, 41, 31, 675698), + expires_at=None, + uses_left=1, + ) + + +@pytest.fixture +def mock_new_device_key_generate(mocker): + mock = mocker.patch( + "selfprivacy_api.repositories.tokens.json_tokens_repository.NewDeviceKey", + autospec=True, + return_value=NewDeviceKeyMock, + ) + return mock + + +@pytest.fixture +def mock_token_generate(mocker): + mock = mocker.patch( + "selfprivacy_api.repositories.tokens.json_tokens_repository.Token", + autospec=True, + return_value=TokenMock, + ) + return mock + + +@pytest.fixture +def mock_recovery_key_generate(mocker): + mock = mocker.patch( + "selfprivacy_api.repositories.tokens.json_tokens_repository.RecoveryKey", + autospec=True, + return_value=RecoveryKeyMock, + ) + return mock + + @pytest.fixture def tokens(mocker, datadir): mocker.patch("selfprivacy_api.utils.TOKENS_FILE", new=datadir / "tokens.json") @@ -39,7 +120,7 @@ def test_get_token_by_token_string(tokens): assert repo.get_token_by_token_string(token_string="iamtoken") == Token( token="iamtoken", device_name="primary_token", - created_at=datetime.datetime(2022, 7, 15, 17, 41, 31, 675698), + created_at=datetime(2022, 7, 15, 17, 41, 31, 675698), ) @@ -57,7 +138,7 @@ def test_get_token_by_name(tokens): assert repo.get_token_by_name(token_name="primary_token") == Token( token="iamtoken", device_name="primary_token", - created_at=datetime.datetime(2022, 7, 15, 17, 41, 31, 675698), + created_at=datetime(2022, 7, 15, 17, 41, 31, 675698), ) @@ -76,6 +157,136 @@ def test_get_tokens(tokens): Token( token="iamtoken", device_name="primary_token", - created_at=datetime.datetime(2022, 7, 15, 17, 41, 31, 675698), + created_at=datetime(2022, 7, 15, 17, 41, 31, 675698), ) ] + + +def test_create_token(tokens, mock_token_generate): + repo = JsonTokensRepository() + assert repo.create_token(device_name="imnew") is not None + assert repo.create_token(device_name="imnew") == Token( + token="iamtoken", + device_name="imnew", + created_at=datetime(2022, 7, 15, 17, 41, 31, 675698), + ) + + +def test_delete_token(tokens, datadir): + repo = JsonTokensRepository() + input_token = Token( + token="iamtoken", + device_name="primary_token", + created_at=datetime(2022, 7, 15, 17, 41, 31, 675698), + ) + + assert repo.delete_token(input_token) is None + assert read_json(datadir / "tokens.json")["tokens"] == [] + + +def test_delete_not_found_token(tokens, datadir): + repo = JsonTokensRepository() + input_token = Token( + token="imbadtoken", + device_name="primary_token", + created_at=datetime(2022, 7, 15, 17, 41, 31, 675698), + ) + with pytest.raises(TokenNotFoundError): + assert repo.delete_token(input_token) is None + + +def test_refresh_token(tokens, mock_token_generate): + repo = JsonTokensRepository() + input_token = Token( + token="imtoken", + device_name="primary_token", + created_at=datetime(2022, 7, 15, 17, 41, 31, 675698), + ) + + assert repo.refresh_token(input_token) is not None + assert repo.refresh_token(input_token) == Token( + token="iamtoken", + device_name="imnew", + created_at=datetime(2022, 7, 15, 17, 41, 31, 675698), + ) + + +def test_refresh_not_found_token(tokens, mock_token_generate): + repo = JsonTokensRepository() + input_token = Token( + token="idontknowwhoiam", + device_name="tellmewhoiam?", + created_at=datetime(2022, 7, 15, 17, 41, 31, 675698), + ) + + with pytest.raises(TokenNotFoundError): + assert repo.refresh_token(input_token) is None + + +def test_get_recovery_key(tokens): + repo = JsonTokensRepository() + + assert repo.get_recovery_key() is not None + assert repo.get_recovery_key() == RecoveryKey( + key="iamtoken", + created_at=datetime(2022, 7, 15, 17, 41, 31, 675698), + expires_at=None, + uses_left=None, + ) + + +def test_create_recovery_key(tokens, mock_recovery_key_generate, datadir): + repo = JsonTokensRepository() + + assert repo.create_recovery_key(uses_left=1, expiration=None) is not None + assert read_json(datadir / "tokens.json")["recovery_token"] == RecoveryKey( + key="imnewrecoverykey", + created_at=datetime(2022, 7, 15, 17, 41, 31, 675698), + expires_at=None, + uses_left=1, + ) + + +def test_get_new_device_key(tokens, mock_new_device_key_generate, datadir): + repo = JsonTokensRepository() + + assert repo.get_new_device_key() is not None + # assert read_json(datadir / "tokens.json")["new_device"] == RecoveryKey( + # key="imrecoverykey", + # created_at=datetime(2022, 7, 15, 17, 41, 31, 675698), + # expires_at=None, + # uses_left=1, + # ) + + +# use_mnemonic_recovery_key +# use_mnemonic_new_device_key + + +def test_delete_new_device_key(tokens, datadir): + repo = JsonTokensRepository() + + assert repo.delete_new_device_key() is None + assert "new_device" not in read_json(datadir / "tokens.json") + + +#################################################### + + +def test_use_mnemonic_new_device_key( + tokens, mock_new_device_key_generate, datadir, mock_token_generate +): + repo = JsonTokensRepository() + + assert repo.use_mnemonic_new_device_key( + device_name="imnew", mnemonic_phrase="oh-no" + ) == Token( + token="iamtoken", + device_name="imnew", + created_at=datetime(2022, 7, 15, 17, 41, 31, 675698), + ) + assert read_json(datadir / "tokens.json")["new_device"] == [] + + +def use_mnemonic_recovery_key(): + ... diff --git a/tests/test_graphql/test_repository/test_tokens_repository/tokens.json b/tests/test_graphql/test_repository/test_tokens_repository/tokens.json index b8eaffd..bce68b0 100644 --- a/tests/test_graphql/test_repository/test_tokens_repository/tokens.json +++ b/tests/test_graphql/test_repository/test_tokens_repository/tokens.json @@ -8,7 +8,7 @@ ], "recovery_token": { "token": "iamtoken", - "date": "2022-09-24T17:54:07.607272", + "date": "2022-07-15 17:41:31.675698", "expiration": null, "uses_left": null }, diff --git a/tests/test_graphql/test_users.py b/tests/test_graphql/test_users.py index c36dcb2..7a65736 100644 --- a/tests/test_graphql/test_users.py +++ b/tests/test_graphql/test_users.py @@ -516,7 +516,6 @@ def test_graphql_add_long_username(authorized_client, one_user, mock_subprocess_ }, }, ) - assert response.status_code == 200 assert response.json().get("data") is not None assert response.json()["data"]["createUser"]["message"] is not None