From 1674fb23003964cac8fff731568e98fc987edfaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Andr=C3=A9s=20Marino=20Rojas?= <47573394+Marinovsky@users.noreply.github.com> Date: Wed, 4 Sep 2024 16:24:31 -0500 Subject: [PATCH] Draft of the solution --- lean/commands/decrypt.py | 5 +- lean/components/util/encryption_helper.py | 4 +- tests/commands/test_encrypt.py | 69 ++++++++++++++++++++++- 3 files changed, 72 insertions(+), 6 deletions(-) diff --git a/lean/commands/decrypt.py b/lean/commands/decrypt.py index e479b041..0ea4c2ea 100644 --- a/lean/commands/decrypt.py +++ b/lean/commands/decrypt.py @@ -43,17 +43,16 @@ def decrypt(project: Path, decryption_key = get_and_validate_user_input_encryption_key(key, decryption_key) organization_id = container.organization_manager.try_get_working_organization_id() - source_files = project_manager.get_source_files(project) try: from lean.components.util.encryption_helper import get_decrypted_file_content_for_local_project - decrypted_data = get_decrypted_file_content_for_local_project(project, + decrypted_data = get_decrypted_file_content_for_local_project(project, source_files, decryption_key, project_config_manager, organization_id) except Exception as e: raise RuntimeError(f"Could not decrypt project {project}: {e}") for file, decrypted in zip(source_files, decrypted_data): - with open(file, 'w') as f: + with open(file, 'w', encoding="utf-8") as f: f.write(decrypted) # Mark the project as decrypted diff --git a/lean/components/util/encryption_helper.py b/lean/components/util/encryption_helper.py index 09f8db74..c7cec0d4 100644 --- a/lean/components/util/encryption_helper.py +++ b/lean/components/util/encryption_helper.py @@ -103,7 +103,7 @@ def get_decrypted_file_content_for_local_project(project: Path, source_files: Li for file in source_files: try: # lets read and decrypt the file - with open(file, 'r') as f: + with open(file, 'r', encoding="utf-8") as f: encrypted = f.read() if not areProjectFilesAlreadyEncrypted: decrypted = encrypted @@ -131,7 +131,7 @@ def get_encrypted_file_content_for_local_project(project: Path, source_files: Li for file in source_files: try: # lets read and decrypt the file - with open(file, 'r') as f: + with open(file, 'r', encoding= "utf-8") as f: plain_text = f.read() if areProjectFilesAlreadyEncrypted: encrypted = plain_text diff --git a/tests/commands/test_encrypt.py b/tests/commands/test_encrypt.py index 2af2c668..6a818fe6 100644 --- a/tests/commands/test_encrypt.py +++ b/tests/commands/test_encrypt.py @@ -43,6 +43,30 @@ def test_encrypt_encrypts_file_in_case_project_not_in_encrypt_state() -> None: assert project_config.get("encrypted", False) == True assert project_config.get("encryption-key-path", None) == str(encryption_file_path) +def test_encrypt_encrypts_file_with_chinese_characters() -> None: + create_fake_lean_cli_directory() + + project_path = Path.cwd() / "Python Project" + + encryption_file_path = project_path / "encryption_x.txt" + encryption_file_path.write_text("是一的", encoding="utf-8") + + project_config = container.project_config_manager.get_project_config(project_path) + assert project_config.get("encrypted", False) == False + assert project_config.get("encryption-key-path", None) == None + + result = CliRunner().invoke(lean, ["encrypt", "Python Project", "--key", encryption_file_path]) + + assert result.exit_code == 0 + + source_files = container.project_manager.get_source_files(project_path) + expected_encrypted_files = _get_expected_encrypted_files_content() + for file in source_files: + assert expected_encrypted_files["chinese_" + file.name].strip() == file.read_text().strip() + project_config = container.project_config_manager.get_project_config(project_path) + assert project_config.get("encrypted", False) == True + assert project_config.get("encryption-key-path", None) == str(encryption_file_path) + def test_encrypt_does_not_change_file_in_case_project_already_in_encrypt_state() -> None: create_fake_lean_cli_directory() @@ -167,6 +191,23 @@ def _get_expected_encrypted_files_content() -> dict: 4T/vRU2aSdisuNMdXyuF4OH7ZgBdUYaNtfxmuJlmS4tYsom5xJfxrEEGG203gq0ME5eZCmu4JlLbEo1w L4u74Hsr4mWkJKbMJMcwW8ByRuy/VJiWW8JKIcoB0yHlwLJ/YoqMDF0BPG5i2EF0DXu1USNC/vE=""" , + "chinese_main.py": + """/hBXLMAwLMr3D0WTwS5lbHxJquOwtubD1rwNFPyrPkaFfn4oJF/MlHR0+ibh0S/HmOfZy3bSaNUNyVlv +GwUc6BkTVduHfl0m0doinxtovFkLMi33PWYwTrdr7tXWoklzq+J+AyjmaYiJsN9GxJvUzM3fsvRR7+5h +6j16o+zI/PHntLsldC2+66e3E1yP+b6uYrOaqubIs6ORGV3G9oViLfKCADiHTRLH+7885cJxN1Is1wOE +5zIIe4DOBnq92XpazPM/1Lk3ECcu/bno2capvjRtqXZiINv7QGGtcHyZ5C4vanfE9KkUbXTaDBtxrxSH +jmI/kNo+2DFM9BQ9YWK8bBYBUEt6cBDnyM6yBC33QCoYVOm37p3lj5mZkeePPSMdLmXfi7tZ7iySuT49 +/iWJ88rddbKVKU2qMtGjem5loKTOtKWoqd2R/fpOLAr+rH2D/Zz/hwomD+TdQ3DyWSYES3B9mMhk2Mpk +jtWkTiMMRdOalmC6GyihFbvYVUU19MZr3nTk6aEjRs1lSOZ+HiNV3KcrOY5ZlgLazXWfa9BUPdbXiDNk +m7LoCb2deL+y+cvL92xuu9Vuu3coKPxpVR3wodrJHLvWma22QagNR1wVb3f7agBypJm0/Yjr4+bSfRK0 +tNsmCtsMpGmlsFMYae0gl6IVR5VMTohetSf2/Fu2YsSpeBfAp3AN2vM3lfJtrC3WqVhWG+rnNa4ye5N0 +OLELdewYwHyeHOq6UQKJ7Bx7andRhogpVp0SeQGtu2y44/PfnaWQXB2z6I4oRipqmwSHLDyvC9sZX4jq +d9zLWdJ3RrpeER0hC9XG1fa3WXG2sVJfjEyd54MFMO5/sgQhU+lbvDlXs2HkIx/bbNUz4yuaE4PD5xcO +9votaJDw3m4zFVBww8m+PO3ddHUUC672lP0jCZcsjYw2WlZNt5bC5DSvvzCVvDzIF5dc3IKKXpeWwadN +fLxzbUCRumfDes0yuw9E+nPKhbLCatXIGlp8c/wpQ+XyWD/SVI/vCJjHAzbYPY7nIVYp0FAnCQ6kpBbI +wb/6GovuiB5bl/zHc5iWw17zy+F//CjAv2RJUgEd4uiQWIOKohSd6yjUWbsvybIyGF+/DLs7F/ZbQqTi +qxP8h0s0CxgTowyBYncfYLOmD2AybNVQUPIE5DNIANKV2xWPTQo8NqZ/oDYFlaobqazmViTfrgM=""" + , "research.ipynb": """NIiAgzU8gzaJ3YEIWysBh0e0xxm9rpAWDE4Pir/wzKtla/wcbs98GU5cdOxgd7Gjlcu0zNbFzE5x8Eyx qSuh3cQU17xQSisPxvjfDD/h2z9AnFT1jD1Vhc+Nn5ngwpgCA6P5fHT4VhPgaKDp7r9zc8pAURcSd04M @@ -192,5 +233,31 @@ def _get_expected_encrypted_files_content() -> dict: HrFPt9ElvzsATZvrloOCorTqbWc5BYmXb+u4MZ4vLtnU2wq/j5B+DvSswQkXsvtlGDsNPwLyi4dZuIVV Oae0ese2fAU8lmosUY95ghYxEOGrMHg5ZPklje/afjpxwKAAgTfWqozYPdpNL+MJEqrVA9YRq5wSvjuX UGw0ehtO8qY5FmPGcUlkBGuqmd7r6aLE4mosoZrc/UyZb+clWNYJITRLFJbQpWm3EU/Xrt5UM8uWwEdV -bFWAAkX56MyDHwJefC1nkA==""" +bFWAAkX56MyDHwJefC1nkA==""", + "chinese_research.ipynb": + """YujNshgrEbvBBeZs6Dod4uQhoSpPAQRn31qHGUcoacZbmpPpm9XoTKOCz9/v3zcFkD/xNP88Ry/Q7Zra +X1k6SjoQsswUB4MM0i4HwieZCug7dKjarlO3OAN/RrMeH2x7DvJQsjDNKMlE1JdLQ2gZXcolLWRoQCsO +TFb/wXx5VhU9XGF756OTKDQmweIkLS8RNHhXgiC0eMwYlPafDz+EA5DDe9p6Vx+xb1wHs7UP+Hhz/ikj +8rL4JWrCRJVbCX0riZE9omwPnAAO2M5kyVNwArMc+H7PIE7zKJqhGwSzt+uXvOCv/3fHazbTEwHErhKK +padpAPsRsJVlgfgm8epD9KywctYvtHpmN1io47yXM4yhWQsLduBqSig4W/rPd54OYPL1af6v+mUhFWdm +XV4mQzO+crVCmEvyKIw85Ai1uXzOs2r10UNS5e+reD+jRz9pg9ZSzUY0wyTfvdL1FG9PJSmsK2uLnC2x +WNfjKW0sbmIOYy2gm8oz0cEOSE303KB//p5Tl57zorzPp2UTNPJZFW9YKD0NGglWKPCtJYDsLNX9gJu5 +5Z7+a/S3GeizpV7VbvsoKZw7xYxLbKCfW2eJzgiaDE3XKMyXm6ohS+zZUC+5C1/Fidx2GyzMViDfF+sg +0dmwlxShkESdVHa8AigMkcJ1lIjeTiiBnqU6ujqe9t/HnderOfit2ZLUjEW06ogA32WVzsNXQfpiF1My +fPY92a/uv0Z7hW0FyaJeKC0PhVCfcXWIqjZ3vRx3otDgYGn+fy/Y6dcHZ8gsIMwG0Amd1bxU2hssxXqR +sUiTaZYetwQzoy8qci2hxo7GTdndELWChmZ6IpbdvnLdnMVHfDBE14n7IhrShtk02R9is/hn0BbwK2Hu +UvrYZowKcXKdHcofPR413ak9xlvgNwlyquy4q2NWdYlfxb2vN9QorhhSd5GKyhksbVOTfeklUdRCOza6 +neXoiR2e8rv0BNnaBa4vnAhNxB+vp9MeTGFMqfvCRw7HuRT3+wJHwgtP1qjVK7n2jUF1dmAj6Bnxl7ju +Y0AEUsh+ioGjv1Jwn5WKEYuCFNN1YrttCabJP6JI+yjbzf6n6O6Ex10Zmea3rpxLAZ8Jpqm/A0b27XpT +FNEfo86uR5WO5yCmeUAtUCanknoXh41wmA762eJPMXubqlGQGijde3ZSaaSoxHaeCrfxhd63hqxxd8Uf +c7BA4yFmNpn9N9ZRwaSYDqsLmqbdvxhyBJQd3bu1aIMPX2NcxpGV87kjbfNRQCmdvj+H1/n+pFm/4MgU +xEndzUvoSQvRjIeU4eB2R5Um4j/beLMFxd6Is6ku2B3ypYqg9cqcaDuGbXzZ6mxLnpoVCPFCvDsRWJ8c +blGlOV0YfbzUDYlTFWxO/cs3hVOSpjhOVANOAtfQFt9ZLa00B8t1tRCNvjM7EX0nHf41T69c4V7ex+OJ +/5XNCwuWoHZ2GJSni3bxjZ3ZxhGhCkIvxIgGrUTmt1wGOKGKwjl88uD5bDWX4+sjom2oDGqQTvkIlZJn +kKiRBRvuG4VAv0QAv73+QURV0RGxMgedEjIFd8R9Yf2mb7IENzgq2SQSL065qWzoCRTBF+jVOP8fXdzs +KL21W4y756fM3nKMkFGQZbjPeHO5ojDjT/U3mMimgC/3haZy5mmLde9NJFHWM8SuEoA/0bnCgZV++vpZ +kqzmoRw8H4RE+oBT8W+ch6CZvEYYsTuAXIPe1cQBcNxanqk4Uh8gwlEko/zfffPS7r1FR3+pe0AajG+o +wT72mv1dhrRifrr0MVEZe1iRUdPwEjBttJjCr5bnnbmswSKf2fEg0cHRBv25z9t33mj4kth/T2W5zkw3 +Zbni33aJFF6uM9VECyU1QlEz5Eu8lhecWs5ZxFtjT73K/5tqmcwNYx7sO1UpT3QPF1DQ7RlP1yTTkTw2 +s0ntvYgXO0YOeItR43fpHw==""" }