Spaces:
Runtime error
Runtime error
File size: 7,140 Bytes
7ac74fa fad1332 7ac74fa fad1332 7ac74fa fad1332 7ac74fa fad1332 7ac74fa fad1332 7ac74fa fad1332 7ac74fa fad1332 7ac74fa fad1332 7ac74fa fad1332 7ac74fa fad1332 7ac74fa fad1332 7ac74fa fad1332 7ac74fa fad1332 7ac74fa fad1332 7ac74fa fad1332 7ac74fa |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# auth/auth_manager.py
import streamlit as st
import json
import os
from pathlib import Path
import hashlib
from datetime import datetime, timedelta
class AuthManager:
def __init__(self):
"""Initialize AuthManager with storage in HuggingFace's /data directory"""
# Use HuggingFace's /data directory for persistent storage
self.storage_path = Path("/data/users")
self.ensure_storage()
# Initialize demo user if not exists
self._init_demo_user()
# Initialize session state for auth
if 'auth' not in st.session_state:
st.session_state.auth = {
'authenticated': False,
'user': None,
'login_time': None
}
def ensure_storage(self):
"""Ensure storage directories exist and are writable"""
try:
# Create main storage directory
self.storage_path.mkdir(parents=True, exist_ok=True)
# Test write permissions
test_file = self.storage_path / ".write_test"
test_file.touch()
test_file.unlink()
except Exception as e:
st.error(f"Failed to access storage: {str(e)}")
raise RuntimeError("Storage is not accessible")
def _init_demo_user(self):
"""Initialize demo Synaptyx user"""
demo_user = {
"username": "synaptyx",
"password_hash": self._hash_password("demo"),
"display_name": "Synaptyx Demo",
"storage_path": "/data/users/synaptyx",
"created_at": datetime.now().isoformat(),
"last_login": None,
"settings": {
"expertise_level": "Intermediate",
"theme": "default",
"notifications_enabled": True
}
}
user_file = self.storage_path / "synaptyx.json"
if not user_file.exists():
# Create user storage directories
user_storage = Path(demo_user["storage_path"])
for dir_name in ["chats", "images", "context", "exports"]:
(user_storage / dir_name).mkdir(parents=True, exist_ok=True)
# Save user data
with open(user_file, "w") as f:
json.dump(demo_user, f, indent=4)
def _hash_password(self, password):
"""Hash password using SHA-256 with salt"""
salt = "synaptyx_salt" # In production, use a proper salt management system
salted = password + salt
return hashlib.sha256(salted.encode()).hexdigest()
def login(self, username, password):
"""Authenticate user and set up session"""
try:
user_file = self.storage_path / f"{username}.json"
if not user_file.exists():
return False
with open(user_file, "r") as f:
user_data = json.load(f)
if user_data["password_hash"] == self._hash_password(password):
# Update last login
user_data["last_login"] = datetime.now().isoformat()
with open(user_file, "w") as f:
json.dump(user_data, f, indent=4)
# Update session state
st.session_state.auth = {
'authenticated': True,
'user': user_data,
'login_time': datetime.now().isoformat()
}
return True
return False
except Exception as e:
st.error(f"Login error: {str(e)}")
return False
def is_authenticated(self):
"""Check if user is authenticated and session is valid"""
if not st.session_state.auth.get('authenticated'):
return False
# Check session age (optional)
if st.session_state.auth.get('login_time'):
login_time = datetime.fromisoformat(st.session_state.auth['login_time'])
session_age = datetime.now() - login_time
# Session timeout after 12 hours
if session_age > timedelta(hours=12):
self.logout()
return False
return True
def get_user_storage_paths(self):
"""Get user's storage paths"""
if not self.is_authenticated():
return None
base_path = Path(st.session_state.auth['user']["storage_path"])
return {
"chats": base_path / "chats",
"images": base_path / "images",
"context": base_path / "context",
"exports": base_path / "exports"
}
def get_user_settings(self):
"""Get user's settings"""
if not self.is_authenticated():
return None
return st.session_state.auth['user'].get('settings', {})
def update_user_settings(self, settings):
"""Update user's settings"""
if not self.is_authenticated():
return False
try:
user_file = self.storage_path / f"{st.session_state.auth['user']['username']}.json"
with open(user_file, "r") as f:
user_data = json.load(f)
user_data['settings'].update(settings)
with open(user_file, "w") as f:
json.dump(user_data, f, indent=4)
# Update session state
st.session_state.auth['user'] = user_data
return True
except Exception as e:
st.error(f"Failed to update settings: {str(e)}")
return False
def logout(self):
"""Log out user and clear session"""
if 'auth' in st.session_state:
st.session_state.auth = {
'authenticated': False,
'user': None,
'login_time': None
}
def get_user_stats(self):
"""Get user's usage statistics"""
if not self.is_authenticated():
return None
try:
stats = {
'total_analyses': 0,
'total_chats': 0,
'storage_used': 0
}
paths = self.get_user_storage_paths()
if not paths:
return stats
# Count analyses and chats
stats['total_chats'] = len(list(paths['chats'].glob('*.json')))
# Calculate storage used
for path in paths.values():
if path.exists():
stats['storage_used'] += sum(f.stat().st_size
for f in path.rglob('*')
if f.is_file())
# Convert to MB
stats['storage_used'] = round(stats['storage_used'] / (1024 * 1024), 2)
return stats
except Exception as e:
st.error(f"Failed to get user stats: {str(e)}")
return None |