Moderator404 commited on
Commit
be1722b
·
verified ·
1 Parent(s): 9eee8d2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +78 -8
app.py CHANGED
@@ -24,7 +24,7 @@ logger = logging.getLogger(__name__)
24
 
25
  app = Flask(__name__)
26
 
27
- # ---------- CORS and session (unchanged) ----------
28
  CORS(app, resources={r"/*": {"origins": "*"}}, supports_credentials=False,
29
  allow_headers=["Content-Type", "Authorization"], methods=["GET", "POST", "OPTIONS"])
30
 
@@ -56,7 +56,7 @@ if not HF_TOKEN:
56
  hf_client = None
57
  else:
58
  hf_client = OpenAI(base_url="https://router.huggingface.co/v1", api_key=HF_TOKEN)
59
- HF_MODEL = "google/gemma-2-2b-it:featherless-ai"
60
 
61
  def mock_response(message, rag_context, ticket_context):
62
  msg_lower = message.lower()
@@ -72,10 +72,72 @@ def mock_response(message, rag_context, ticket_context):
72
  return "Hello! I'm TMCBot. How can I help you today?"
73
  return "I'm here to help with cables, orders, and technical support. Could you provide more details?"
74
 
75
- # ---------- Database and RAG (unchanged) ----------
76
  db = DatabaseManager()
77
  rag_helper = RAGHelper(use_vector_search=True)
78
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  # ---------- ChatBot class (original, with send_message replaced) ----------
80
  class ChatBot:
81
  def __init__(self, db_manager, configured_model="mistral:7b"):
@@ -543,6 +605,14 @@ Summary:"""
543
  def create_ticket_from_chat(self, user_id, subject, description, category, priority, conversation_id):
544
  return self.db_manager.create_support_ticket(user_id, subject, description, category, conversation_id, priority)
545
 
 
 
 
 
 
 
 
 
546
  # ------------------------------------------------------------------
547
  # End of ChatBot class
548
  # ------------------------------------------------------------------
@@ -741,9 +811,8 @@ IMPORTANT: Respond with ONLY the number (1-10). Do not include any explanation,
741
  return None, None
742
 
743
  def get_ai_security_analysis(prompt):
744
- # In the HF version, we can call the router for security analysis.
745
- # However, to avoid recursive calls, we'll fall back to a simple rule-based score.
746
- # For a production system, you could call a dedicated security model, but here we return 2 (safe).
747
  logger.info("Security analysis using rule-based fallback (safe score 2)")
748
  return 2
749
 
@@ -866,6 +935,7 @@ def admin():
866
  return redirect(url_for('admin_tickets'))
867
 
868
  @app.route('/admin/tickets')
 
869
  def admin_tickets():
870
  return render_template('admin_tickets.html')
871
 
@@ -1072,8 +1142,8 @@ def get_conversations():
1072
  @app.route('/api/health')
1073
  def health_check():
1074
  try:
1075
- response = requests.get("http://localhost:11434/api/tags", timeout=5)
1076
- ollama_status = response.status_code == 200
1077
  except:
1078
  ollama_status = False
1079
  try:
 
24
 
25
  app = Flask(__name__)
26
 
27
+ # ---------- CORS and session ----------
28
  CORS(app, resources={r"/*": {"origins": "*"}}, supports_credentials=False,
29
  allow_headers=["Content-Type", "Authorization"], methods=["GET", "POST", "OPTIONS"])
30
 
 
56
  hf_client = None
57
  else:
58
  hf_client = OpenAI(base_url="https://router.huggingface.co/v1", api_key=HF_TOKEN)
59
+ HF_MODEL = "google/gemma-2-2b-it:featherless-ai" # or "google/gemma-2-2b-it"
60
 
61
  def mock_response(message, rag_context, ticket_context):
62
  msg_lower = message.lower()
 
72
  return "Hello! I'm TMCBot. How can I help you today?"
73
  return "I'm here to help with cables, orders, and technical support. Could you provide more details?"
74
 
75
+ # ---------- Database and RAG ----------
76
  db = DatabaseManager()
77
  rag_helper = RAGHelper(use_vector_search=True)
78
 
79
+ # ---------- Authentication helpers (must be defined before routes) ----------
80
+ def is_authenticated():
81
+ session_id = session.get('session_id')
82
+ user_id = session.get('user_id')
83
+ if not session_id or not user_id:
84
+ return False
85
+ user = db.get_user_by_session(session_id)
86
+ return user and user['id'] == user_id
87
+
88
+ def refresh_session_timeout():
89
+ if 'session_id' in session:
90
+ session.permanent = True
91
+
92
+ def require_auth(f):
93
+ @wraps(f)
94
+ def decorated_function(*args, **kwargs):
95
+ if not is_authenticated():
96
+ return jsonify({'success': False, 'error': 'Authentication required'}), 401
97
+ return f(*args, **kwargs)
98
+ return decorated_function
99
+
100
+ def require_role(required_role):
101
+ def decorator(f):
102
+ @wraps(f)
103
+ def decorated_function(*args, **kwargs):
104
+ user_id = session.get('user_id')
105
+ if not user_id:
106
+ return jsonify({'error': 'Authentication required'}), 401
107
+ user_role = db.get_user_role(user_id)
108
+ allowed_roles = ['admin'] if required_role == 'admin' else ['admin', 'staff', 'user']
109
+ if user_role not in allowed_roles:
110
+ logger.warning(f"Unauthorized role access attempt: user {user_id}, role {user_role}, required {required_role}")
111
+ return jsonify({'error': 'Insufficient privileges'}), 403
112
+ return f(*args, **kwargs)
113
+ return decorated_function
114
+ return decorator
115
+
116
+ def require_resource_ownership(resource_type):
117
+ def decorator(f):
118
+ @wraps(f)
119
+ def decorated_function(*args, **kwargs):
120
+ user_id = session.get('user_id')
121
+ if not user_id:
122
+ return jsonify({'error': 'Authentication required'}), 401
123
+ resource_id = kwargs.get('ticket_id') or kwargs.get('conversation_id')
124
+ if not resource_id:
125
+ data = request.get_json() if request.is_json else {}
126
+ resource_id = data.get('ticket_id') or data.get('conversation_id')
127
+ if not resource_id:
128
+ return jsonify({'error': 'Resource ID required'}), 400
129
+ if resource_type == 'ticket':
130
+ if not db.user_owns_ticket(user_id, resource_id):
131
+ logger.warning(f"Unauthorized ticket access attempt: user {user_id}, ticket {resource_id}")
132
+ return jsonify({'error': 'Access denied'}), 403
133
+ elif resource_type == 'conversation':
134
+ if not db.user_owns_conversation(user_id, resource_id):
135
+ logger.warning(f"Unauthorized conversation access attempt: user {user_id}, conversation {resource_id}")
136
+ return jsonify({'error': 'Access denied'}), 403
137
+ return f(*args, **kwargs)
138
+ return decorated_function
139
+ return decorator
140
+
141
  # ---------- ChatBot class (original, with send_message replaced) ----------
142
  class ChatBot:
143
  def __init__(self, db_manager, configured_model="mistral:7b"):
 
605
  def create_ticket_from_chat(self, user_id, subject, description, category, priority, conversation_id):
606
  return self.db_manager.create_support_ticket(user_id, subject, description, category, conversation_id, priority)
607
 
608
+ def get_available_models(self):
609
+ # For HF version, we don't have models list; return a placeholder
610
+ return [HF_MODEL]
611
+
612
+ def check_ollama_health(self):
613
+ # Not needed for HF version, but kept for compatibility
614
+ return True
615
+
616
  # ------------------------------------------------------------------
617
  # End of ChatBot class
618
  # ------------------------------------------------------------------
 
811
  return None, None
812
 
813
  def get_ai_security_analysis(prompt):
814
+ # For the HF version, we can call the router for security analysis.
815
+ # To avoid recursive calls, we fall back to a simple rule-based score.
 
816
  logger.info("Security analysis using rule-based fallback (safe score 2)")
817
  return 2
818
 
 
935
  return redirect(url_for('admin_tickets'))
936
 
937
  @app.route('/admin/tickets')
938
+ @require_role('admin')
939
  def admin_tickets():
940
  return render_template('admin_tickets.html')
941
 
 
1142
  @app.route('/api/health')
1143
  def health_check():
1144
  try:
1145
+ # For HF version, ollama is not used; return a placeholder
1146
+ ollama_status = True
1147
  except:
1148
  ollama_status = False
1149
  try: