"""Board sharing functionality.""" import secrets import string from datetime import datetime from sqlalchemy.orm import Session from app.database.models.share_link import ShareLink def generate_secure_token(length: int = 64) -> str: """ Generate a cryptographically secure random token for share links. Args: length: Length of the token (default 64 characters) Returns: URL-safe random string """ # Use URL-safe characters (alphanumeric + - and _) alphabet = string.ascii_letters + string.digits + "-_" return "".join(secrets.choice(alphabet) for _ in range(length)) def validate_share_link_token(token: str, db: Session) -> ShareLink | None: """ Validate a share link token and return the share link if valid. A share link is valid if: - Token exists - Not revoked - Not expired (if expires_at is set) Args: token: The share link token db: Database session Returns: ShareLink if valid, None otherwise """ share_link = ( db.query(ShareLink) .filter( ShareLink.token == token, ShareLink.is_revoked == False, # noqa: E712 ) .first() ) if share_link is None: return None # Check expiration if share_link.expires_at and share_link.expires_at < datetime.utcnow(): return None # Update access tracking share_link.access_count += 1 share_link.last_accessed_at = datetime.utcnow() db.commit() return share_link def check_permission(share_link: ShareLink, required_permission: str) -> bool: """ Check if a share link has the required permission level. Args: share_link: The share link to check required_permission: Required permission level ('view-only' or 'view-comment') Returns: True if permission granted, False otherwise """ if required_permission == "view-only": # Both view-only and view-comment can view return share_link.permission_level in ("view-only", "view-comment") elif required_permission == "view-comment": # Only view-comment can comment return share_link.permission_level == "view-comment" return False