Files
cli-anything-codimd/cli_anything/codimd/core/session.py

89 lines
2.5 KiB
Python

"""
Session management for CodiMD CLI.
"""
import os
import json
from pathlib import Path
from typing import Optional, Dict, Any
from datetime import datetime, timedelta
import hashlib
class Session:
"""Session manager for CodiMD authentication."""
def __init__(self, config_dir: Path):
self.session_file = config_dir / "session.json"
self._session = self._load_session()
def _load_session(self) -> dict:
"""Load session from file."""
if self.session_file.exists():
with open(self.session_file, "r") as f:
return json.load(f)
return {}
def save_session(self):
"""Save session to file."""
with open(self.session_file, "w") as f:
json.dump(self._session, f, indent=2)
def is_authenticated(self) -> bool:
"""Check if user is authenticated."""
cookies = self._session.get("cookies", {})
if not cookies:
return False
# Check if session is expired (24 hours)
expires_at = self._session.get("expires_at")
if expires_at:
expire_time = datetime.fromisoformat(expires_at)
if datetime.now() > expire_time:
self.clear()
return False
return bool(cookies)
def set_cookies(self, cookies: Dict[str, str]):
"""Set session cookies."""
self._session["cookies"] = cookies
# Set expiration to 24 hours from now
self._session["expires_at"] = (
datetime.now() + timedelta(hours=24)
).isoformat()
self.save_session()
def get_cookies(self) -> Dict[str, str]:
"""Get session cookies."""
return self._session.get("cookies", {})
def set_user(self, user_data: Dict[str, Any]):
"""Set current user data."""
self._session["user"] = user_data
self.save_session()
def get_user(self) -> Optional[Dict[str, Any]]:
"""Get current user data."""
return self._session.get("user")
def clear(self):
"""Clear session data."""
self._session = {}
self.save_session()
@property
def user_id(self) -> Optional[str]:
"""Get current user ID."""
user = self.get_user()
return user.get("id") if user else None
@property
def username(self) -> Optional[str]:
"""Get current username."""
user = self.get_user()
if not user:
return None
# CodiMD returns name directly, not nested in profile
return user.get("name") or user.get("profile", {}).get("name")