Coverage for opt/mealie/lib/python3.12/site-packages/mealie/core/security/security.py: 90%

37 statements  

« prev     ^ index     » next       coverage.py v7.10.6, created at 2025-11-25 15:32 +0000

1import secrets 1a

2from datetime import UTC, datetime, timedelta 1a

3from pathlib import Path 1a

4 

5import jwt 1a

6from sqlalchemy.orm.session import Session 1a

7 

8from mealie.core import root_logger 1a

9from mealie.core.config import get_app_settings 1a

10from mealie.core.security.hasher import get_hasher 1a

11from mealie.core.security.providers.auth_provider import AuthProvider 1a

12from mealie.core.security.providers.credentials_provider import CredentialsProvider 1a

13from mealie.core.security.providers.ldap_provider import LDAPProvider 1a

14from mealie.schema.user.auth import CredentialsRequest, CredentialsRequestForm 1a

15 

16ALGORITHM = "HS256" 1a

17 

18logger = root_logger.get_logger("security") 1a

19 

20 

21def get_auth_provider(session: Session, data: CredentialsRequestForm) -> AuthProvider: 1a

22 settings = get_app_settings() 1cdefghijkb

23 

24 credentials_request = CredentialsRequest(**data.__dict__) 1cdefghijkb

25 if settings.LDAP_ENABLED: 25 ↛ 26line 25 didn't jump to line 26 because the condition on line 25 was never true1cdefghijkb

26 return LDAPProvider(session, credentials_request) 

27 

28 return CredentialsProvider(session, credentials_request) 1cdefghijkb

29 

30 

31def create_access_token(data: dict, expires_delta: timedelta | None = None) -> str: 1a

32 settings = get_app_settings() 1cdefghijklb

33 

34 to_encode = data.copy() 1cdefghijklb

35 expires_delta = expires_delta or timedelta(hours=settings.TOKEN_TIME) 1cdefghijklb

36 

37 expire = datetime.now(UTC) + expires_delta 1cdefghijklb

38 

39 to_encode["exp"] = expire 1cdefghijklb

40 return jwt.encode(to_encode, settings.SECRET, algorithm=ALGORITHM) 1cdefghijklb

41 

42 

43def create_file_token(file_path: Path) -> str: 1a

44 token_data = {"file": str(file_path)} 

45 return create_access_token(token_data, expires_delta=timedelta(minutes=30)) 

46 

47 

48def create_recipe_slug_token(file_path: str | Path) -> str: 1a

49 token_data = {"slug": str(file_path)} 

50 return create_access_token(token_data, expires_delta=timedelta(minutes=30)) 

51 

52 

53def hash_password(password: str) -> str: 1a

54 """Takes in a raw password and hashes it. Used prior to saving a new password to the database.""" 

55 return get_hasher().hash(password) 1am

56 

57 

58def url_safe_token() -> str: 1a

59 """Generates a cryptographic token without embedded data. Used for password reset tokens and invitation tokens""" 

60 return secrets.token_urlsafe(24)