Author: Farida Khalaf
Originally Published at:
Publish date: 02-11-2025
from flask import Flask, jsonify, request
from functools import wraps
import psycopg2
import os
import logging
app = Flask(__name__)
logging.basicConfig(level=logging.INFO)
# Simple user authentication (in production, use proper auth system like Flask-Login)
USERS = {
‘admin’: {’password’: ‘hashed_admin_pass’, ‘role’: ‘admin’, ‘id’: 1},
‘user1’: {’password’: ‘hashed_user_pass’, ‘role’: ‘user’, ‘id’: 2}
}
class User:
def __init__(self, user_id, role):
self.id = user_id
self.role = role
def check_credentials(username, password):
“”“Verify user credentials - use proper password hashing in production”“”
user = USERS.get(username)
# In production, use bcrypt.checkpw() or similar
return user and user[’password’] == password
def get_user(username):
“”“Retrieve user object from username”“”
user_data = USERS.get(username)
if user_data:
return User(user_data[’id’], user_data[’role’])
return None
def require_auth(f):
“”“Decorator to require authentication for routes”“”
@wraps(f)
def decorated(*args, **kwargs):
auth = request.authorization
if not auth or not check_credentials(auth.username, auth.password):
return jsonify({’error’: ‘Authentication required’}), 401
current_user = get_user(auth.username)
return f(current_user=current_user, *args, **kwargs)
return decorated
@app.route(”/api/tickets”, methods=[’GET’])
@require_auth
def get_tickets(current_user):
# Credentials from environment variables
conn = psycopg2.connect(os.getenv(’DATABASE_URL’))
cursor = conn.cursor()
# Filter by user permissions - only return specific columns
if current_user.role == ‘admin’:
cursor.execute(
“SELECT id, title, status, assigned_to, created_at FROM support_tickets”
)
else:
# Users only see their assigned tickets
cursor.execute(
“SELECT id, title, status, assigned_to, created_at FROM support_tickets WHERE assigned_to = %s”,
(current_user.id,)
)
tickets = cursor.fetchall()
cursor.close()
conn.close()
# Audit logging
logging.info(f”User {current_user.id} accessed {len(tickets)} tickets”)
return jsonify(tickets)
if __name__ == ‘__main__’:
# Only bind to localhost in development
app.run(host=’127.0.0.1’, port=5000