mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-12-10 12:25:14 -05:00
feat: Allow using OIDC auth cache instead of session (#5746)
Co-authored-by: Michael Genson <71845777+michael-genson@users.noreply.github.com>
This commit is contained in:
@@ -19,6 +19,8 @@ from mealie.routes._base.routers import UserAPIRouter
|
||||
from mealie.schema.user import PrivateUser
|
||||
from mealie.schema.user.auth import CredentialsRequestForm
|
||||
|
||||
from .auth_cache import AuthCache
|
||||
|
||||
public_router = APIRouter(tags=["Users: Authentication"])
|
||||
user_router = UserAPIRouter(tags=["Users: Authentication"])
|
||||
logger = root_logger.get_logger("auth")
|
||||
@@ -27,7 +29,7 @@ remember_me_duration = timedelta(days=14)
|
||||
|
||||
settings = get_app_settings()
|
||||
if settings.OIDC_READY:
|
||||
oauth = OAuth()
|
||||
oauth = OAuth(cache=AuthCache())
|
||||
scope = None
|
||||
if settings.OIDC_SCOPES_OVERRIDE:
|
||||
scope = settings.OIDC_SCOPES_OVERRIDE
|
||||
|
||||
51
mealie/routes/auth/auth_cache.py
Normal file
51
mealie/routes/auth/auth_cache.py
Normal file
@@ -0,0 +1,51 @@
|
||||
import time
|
||||
from typing import Any
|
||||
|
||||
|
||||
class AuthCache:
|
||||
def __init__(self, threshold: int = 500, default_timeout: float = 300):
|
||||
self.default_timeout = default_timeout
|
||||
self._cache: dict[str, tuple[float, Any]] = {}
|
||||
self.clear = self._cache.clear
|
||||
self._threshold = threshold
|
||||
|
||||
def _prune(self):
|
||||
if len(self._cache) > self._threshold:
|
||||
now = time.time()
|
||||
toremove = []
|
||||
for idx, (key, (expires, _)) in enumerate(self._cache.items()):
|
||||
if (expires != 0 and expires <= now) or idx % 3 == 0:
|
||||
toremove.append(key)
|
||||
for key in toremove:
|
||||
self._cache.pop(key, None)
|
||||
|
||||
def _normalize_timeout(self, timeout: float | None) -> float:
|
||||
if timeout is None:
|
||||
timeout = self.default_timeout
|
||||
if timeout > 0:
|
||||
timeout = time.time() + timeout
|
||||
return timeout
|
||||
|
||||
async def get(self, key: str) -> Any:
|
||||
try:
|
||||
expires, value = self._cache[key]
|
||||
if expires == 0 or expires > time.time():
|
||||
return value
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
async def set(self, key: str, value: Any, timeout: float | None = None) -> bool:
|
||||
expires = self._normalize_timeout(timeout)
|
||||
self._prune()
|
||||
self._cache[key] = (expires, value)
|
||||
return True
|
||||
|
||||
async def delete(self, key: str) -> bool:
|
||||
return self._cache.pop(key, None) is not None
|
||||
|
||||
async def has(self, key: str) -> bool:
|
||||
try:
|
||||
expires, value = self._cache[key]
|
||||
return expires == 0 or expires > time.time()
|
||||
except KeyError:
|
||||
return False
|
||||
Reference in New Issue
Block a user