Add File
This commit is contained in:
158
src/landppt/services/share_service.py
Normal file
158
src/landppt/services/share_service.py
Normal file
@@ -0,0 +1,158 @@
|
||||
"""
|
||||
Project Share Service
|
||||
Handles generation and validation of public share links for presentations
|
||||
"""
|
||||
|
||||
import secrets
|
||||
import logging
|
||||
from typing import Optional
|
||||
from sqlalchemy.orm import Session
|
||||
from ..database.models import Project
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ShareService:
|
||||
"""Service for managing project sharing functionality"""
|
||||
|
||||
def __init__(self, db: Session):
|
||||
self.db = db
|
||||
|
||||
def generate_share_token(self, project_id: str) -> Optional[str]:
|
||||
"""
|
||||
Generate a unique share token for a project, or return existing one
|
||||
|
||||
Args:
|
||||
project_id: The project ID to generate a share link for
|
||||
|
||||
Returns:
|
||||
The generated share token, or None if project not found
|
||||
"""
|
||||
try:
|
||||
# Get the project
|
||||
project = self.db.query(Project).filter(
|
||||
Project.project_id == project_id
|
||||
).first()
|
||||
|
||||
if not project:
|
||||
logger.error(f"Project {project_id} not found")
|
||||
return None
|
||||
|
||||
# If project already has a valid share token, return it
|
||||
if project.share_token:
|
||||
# Enable sharing if it was disabled
|
||||
if not project.share_enabled:
|
||||
project.share_enabled = True
|
||||
self.db.commit()
|
||||
logger.info(f"Re-enabled sharing for project {project_id}")
|
||||
else:
|
||||
logger.info(f"Returning existing share token for project {project_id}")
|
||||
return project.share_token
|
||||
|
||||
# Generate a new secure random token
|
||||
share_token = secrets.token_urlsafe(32)
|
||||
|
||||
# Update project with share token and enable sharing
|
||||
project.share_token = share_token
|
||||
project.share_enabled = True
|
||||
self.db.commit()
|
||||
|
||||
logger.info(f"Generated new share token for project {project_id}")
|
||||
return share_token
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating share token: {e}")
|
||||
self.db.rollback()
|
||||
return None
|
||||
|
||||
def disable_sharing(self, project_id: str) -> bool:
|
||||
"""
|
||||
Disable sharing for a project
|
||||
|
||||
Args:
|
||||
project_id: The project ID to disable sharing for
|
||||
|
||||
Returns:
|
||||
True if successful, False otherwise
|
||||
"""
|
||||
try:
|
||||
project = self.db.query(Project).filter(
|
||||
Project.project_id == project_id
|
||||
).first()
|
||||
|
||||
if not project:
|
||||
logger.error(f"Project {project_id} not found")
|
||||
return False
|
||||
|
||||
project.share_enabled = False
|
||||
self.db.commit()
|
||||
|
||||
logger.info(f"Disabled sharing for project {project_id}")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error disabling sharing: {e}")
|
||||
self.db.rollback()
|
||||
return False
|
||||
|
||||
def validate_share_token(self, share_token: str) -> Optional[Project]:
|
||||
"""
|
||||
Validate a share token and return the associated project
|
||||
|
||||
Args:
|
||||
share_token: The share token to validate
|
||||
|
||||
Returns:
|
||||
The Project object if valid, None otherwise
|
||||
"""
|
||||
try:
|
||||
project = self.db.query(Project).filter(
|
||||
Project.share_token == share_token,
|
||||
Project.share_enabled == True
|
||||
).first()
|
||||
|
||||
if not project:
|
||||
logger.warning(f"Invalid or disabled share token")
|
||||
return None
|
||||
|
||||
return project
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error validating share token: {e}")
|
||||
return None
|
||||
|
||||
def get_share_info(self, project_id: str) -> dict:
|
||||
"""
|
||||
Get sharing information for a project
|
||||
|
||||
Args:
|
||||
project_id: The project ID
|
||||
|
||||
Returns:
|
||||
Dictionary with share information
|
||||
"""
|
||||
try:
|
||||
project = self.db.query(Project).filter(
|
||||
Project.project_id == project_id
|
||||
).first()
|
||||
|
||||
if not project:
|
||||
return {
|
||||
"enabled": False,
|
||||
"share_token": None,
|
||||
"share_url": None
|
||||
}
|
||||
|
||||
return {
|
||||
"enabled": project.share_enabled,
|
||||
"share_token": project.share_token,
|
||||
"share_url": f"/share/{project.share_token}" if project.share_token else None
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting share info: {e}")
|
||||
return {
|
||||
"enabled": False,
|
||||
"share_token": None,
|
||||
"share_url": None
|
||||
}
|
||||
Reference in New Issue
Block a user