From 4ae5c52de95e70f3301dac73c18055dce7f86864 Mon Sep 17 00:00:00 2001 From: Michael Genson <71845777+michael-genson@users.noreply.github.com> Date: Wed, 24 Jan 2024 22:03:16 +0000 Subject: [PATCH 1/2] refactor to use bcrypt directly --- mealie/core/security/hasher.py | 17 +++++++++-------- tests/unit_tests/core/test_security.py | 4 ++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/mealie/core/security/hasher.py b/mealie/core/security/hasher.py index aed59bf47ec8..638a36a463e4 100644 --- a/mealie/core/security/hasher.py +++ b/mealie/core/security/hasher.py @@ -1,7 +1,7 @@ from functools import lru_cache from typing import Protocol -from passlib.context import CryptContext +import bcrypt from mealie.core.config import get_app_settings @@ -22,15 +22,16 @@ class FakeHasher: return password == hashed -class PasslibHasher: - def __init__(self) -> None: - self.ctx = CryptContext(schemes=["bcrypt"], deprecated="auto") - +class BcryptHasher: def hash(self, password: str) -> str: - return self.ctx.hash(password) + password_bytes = password.encode("utf-8") + hashed = bcrypt.hashpw(password_bytes, bcrypt.gensalt()) + return hashed.decode("utf-8") def verify(self, password: str, hashed: str) -> bool: - return self.ctx.verify(password, hashed) + password_bytes = password.encode("utf-8") + hashed_bytes = hashed.encode("utf-8") + return bcrypt.checkpw(password_bytes, hashed_bytes) @lru_cache(maxsize=1) @@ -40,4 +41,4 @@ def get_hasher() -> Hasher: if settings.TESTING: return FakeHasher() - return PasslibHasher() + return BcryptHasher() diff --git a/tests/unit_tests/core/test_security.py b/tests/unit_tests/core/test_security.py index 688157cab7b6..911e8f36998c 100644 --- a/tests/unit_tests/core/test_security.py +++ b/tests/unit_tests/core/test_security.py @@ -1,7 +1,7 @@ from pytest import MonkeyPatch from mealie.core.config import get_app_settings -from mealie.core.security.hasher import FakeHasher, PasslibHasher, get_hasher +from mealie.core.security.hasher import BcryptHasher, FakeHasher, get_hasher def test_get_hasher(monkeypatch: MonkeyPatch): @@ -16,7 +16,7 @@ def test_get_hasher(monkeypatch: MonkeyPatch): hasher = get_hasher() - assert isinstance(hasher, PasslibHasher) + assert isinstance(hasher, BcryptHasher) get_app_settings.cache_clear() get_hasher.cache_clear() From 4d3ea5d23117025e1e05a48d080bc07285d048e7 Mon Sep 17 00:00:00 2001 From: Michael Genson <71845777+michael-genson@users.noreply.github.com> Date: Wed, 24 Jan 2024 22:04:33 +0000 Subject: [PATCH 2/2] remove passlib --- poetry.lock | 20 +------------------- pyproject.toml | 1 - 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/poetry.lock b/poetry.lock index 6201fff868d4..6d6e2e955cda 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1427,23 +1427,6 @@ files = [ {file = "paginate-0.5.6.tar.gz", hash = "sha256:5e6007b6a9398177a7e1648d04fdd9f8c9766a1a945bceac82f1929e8c78af2d"}, ] -[[package]] -name = "passlib" -version = "1.7.4" -description = "comprehensive password hashing framework supporting over 30 schemes" -optional = false -python-versions = "*" -files = [ - {file = "passlib-1.7.4-py2.py3-none-any.whl", hash = "sha256:aa6bca462b8d8bda89c70b382f0c298a20b5560af6cbfa2dce410c0a2fb669f1"}, - {file = "passlib-1.7.4.tar.gz", hash = "sha256:defd50f72b65c5402ab2c573830a6978e5f202ad0d984793c8dde2c4152ebe04"}, -] - -[package.extras] -argon2 = ["argon2-cffi (>=18.2.0)"] -bcrypt = ["bcrypt (>=3.1.0)"] -build-docs = ["cloud-sptheme (>=1.10.1)", "sphinx (>=1.6)", "sphinxcontrib-fulltoc (>=1.2.0)"] -totp = ["cryptography"] - [[package]] name = "pathspec" version = "0.11.2" @@ -2024,7 +2007,6 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -2949,4 +2931,4 @@ pgsql = ["psycopg2-binary"] [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "1056e07519c6fbc4e768132d2fbc56810d61e13c110e171440e034f64b49156f" +content-hash = "74abc70211e0cb70a408700f5677595bccbc6f587ee593290c5e0c87e06824ca" diff --git a/pyproject.toml b/pyproject.toml index 887994b7cf7b..6962f2f21541 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,6 @@ gunicorn = "^21.0.0" httpx = "^0.26.0" lxml = "^5.0.0" orjson = "^3.8.0" -passlib = "^1.7.4" psycopg2-binary = { version = "^2.9.1", optional = true } pydantic = "^1.10.4" pyhumps = "^3.5.3"