Coverage for opt/mealie/lib/python3.12/site-packages/mealie/core/security/security.py: 95%
37 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 03:04 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 03:04 +0000
1import secrets
2from datetime import UTC, datetime, timedelta
3from pathlib import Path
5import jwt
6from sqlalchemy.orm.session import Session
8from mealie.core import root_logger
9from mealie.core.config import get_app_settings
10from mealie.core.security.hasher import get_hasher
11from mealie.core.security.providers.auth_provider import AuthProvider
12from mealie.core.security.providers.credentials_provider import CredentialsProvider
13from mealie.core.security.providers.ldap_provider import LDAPProvider
14from mealie.schema.user.auth import CredentialsRequest, CredentialsRequestForm
16ALGORITHM = "HS256"
18logger = root_logger.get_logger("security")
21def get_auth_provider(session: Session, data: CredentialsRequestForm) -> AuthProvider:
22 settings = get_app_settings()
24 credentials_request = CredentialsRequest(**data.__dict__)
25 if settings.LDAP_ENABLED: 25 ↛ 26line 25 didn't jump to line 26 because the condition on line 25 was never true
26 return LDAPProvider(session, credentials_request)
28 return CredentialsProvider(session, credentials_request)
31def create_access_token(data: dict, expires_delta: timedelta | None = None) -> str:
32 settings = get_app_settings()
34 to_encode = data.copy()
35 expires_delta = expires_delta or timedelta(hours=settings.TOKEN_TIME)
37 expire = datetime.now(UTC) + expires_delta
39 to_encode["exp"] = expire
40 return jwt.encode(to_encode, settings.SECRET, algorithm=ALGORITHM)
43def create_file_token(file_path: Path) -> str:
44 token_data = {"file": str(file_path)}
45 return create_access_token(token_data, expires_delta=timedelta(minutes=30))
48def create_recipe_slug_token(file_path: str | Path) -> str:
49 token_data = {"slug": str(file_path)}
50 return create_access_token(token_data, expires_delta=timedelta(minutes=30))
53def hash_password(password: str) -> str:
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)
58def url_safe_token() -> str:
59 """Generates a cryptographic token without embedded data. Used for password reset tokens and invitation tokens"""
60 return secrets.token_urlsafe(24)