Fix export page role issue

This commit is contained in:
Nguyen Ngo
2025-08-15 15:48:41 -04:00
parent ed88d5fe3a
commit ec18c62ed8
3 changed files with 49 additions and 7 deletions
+24 -5
View File
@@ -70,6 +70,10 @@ class User(db.Model):
def has_staff_permissions(self): def has_staff_permissions(self):
"""Check if user has staff-level permissions (includes new roles)""" """Check if user has staff-level permissions (includes new roles)"""
return self.role in STAFF_LEVEL_ROLES return self.role in STAFF_LEVEL_ROLES
def has_export_permissions(user_role):
"""Check if user role has export permissions"""
return user_role in ['admin', 'payroll']
def get_role_display_name(self): def get_role_display_name(self):
"""Get user-friendly role name""" """Get user-friendly role name"""
@@ -3001,7 +3005,7 @@ def toggle_qr_status_api(qr_id):
return redirect(url_for('dashboard')) return redirect(url_for('dashboard'))
@app.route('/attendance') @app.route('/attendance')
# @admin_required @login_required
def attendance_report(): def attendance_report():
"""Safe attendance report with backward compatibility for location_accuracy and fixed datetime handling""" """Safe attendance report with backward compatibility for location_accuracy and fixed datetime handling"""
try: try:
@@ -3009,6 +3013,7 @@ def attendance_report():
# Log attendance report access # Log attendance report access
try: try:
user_role = session.get('role', 'unknown')
logger_handler.logger.info(f"User {session.get('username', 'unknown')} accessed attendance report") logger_handler.logger.info(f"User {session.get('username', 'unknown')} accessed attendance report")
except Exception as log_error: except Exception as log_error:
print(f"⚠️ Logging error (non-critical): {log_error}") print(f"⚠️ Logging error (non-critical): {log_error}")
@@ -3090,7 +3095,7 @@ def attendance_report():
conditions.append("ad.employee_id LIKE :employee") conditions.append("ad.employee_id LIKE :employee")
params['employee'] = f"%{employee_filter}%" params['employee'] = f"%{employee_filter}%"
# FIXED: Apply project filter using SQL approach (not ORM) # Apply project filter using SQL approach (not ORM)
if project_filter: if project_filter:
conditions.append("qc.project_id = :project_id") conditions.append("qc.project_id = :project_id")
params['project_id'] = int(project_filter) params['project_id'] = int(project_filter)
@@ -3279,7 +3284,8 @@ def attendance_report():
project_filter=project_filter, project_filter=project_filter,
today_date=today_date, today_date=today_date,
current_date_formatted=current_date_formatted, current_date_formatted=current_date_formatted,
has_location_accuracy_feature=has_location_accuracy) has_location_accuracy_feature=has_location_accuracy,
user_role=user_role)
except Exception as e: except Exception as e:
print(f"❌ Error loading attendance report: {e}") print(f"❌ Error loading attendance report: {e}")
@@ -3491,14 +3497,21 @@ def attendance_stats_api():
return jsonify({'error': 'Failed to fetch attendance statistics'}), 500 return jsonify({'error': 'Failed to fetch attendance statistics'}), 500
@app.route('/export-configuration') @app.route('/export-configuration')
@admin_required @login_required
def export_configuration(): def export_configuration():
"""Route to display export configuration page""" """Route to display export configuration page"""
try: try:
print("📊 Export configuration route accessed") print("📊 Export configuration route accessed")
# Check if user has export permissions
user_role = session.get('role')
if user_role not in ['admin', 'payroll']:
logger_handler.logger.warning(f"User {session.get('username', 'unknown')} (role: {user_role}) attempted to access export configuration without permissions")
flash('Access denied. Only administrators and payroll staff can access export configuration.', 'error')
return redirect(url_for('attendance_report'))
# Log export configuration access using your existing logger # Log export configuration access using your existing logger
try: try:
logger_handler.logger.info(f"User {session.get('username', 'unknown')} (role: {user_role}) accessed export configuration")
logger_handler.logger.info(f"User {session.get('username', 'unknown')} accessed export configuration page") logger_handler.logger.info(f"User {session.get('username', 'unknown')} accessed export configuration page")
except Exception as log_error: except Exception as log_error:
print(f"⚠️ Logging error (non-critical): {log_error}") print(f"⚠️ Logging error (non-critical): {log_error}")
@@ -3573,10 +3586,16 @@ def export_configuration():
return redirect(url_for('attendance_report')) return redirect(url_for('attendance_report'))
@app.route('/generate-excel-export', methods=['POST']) @app.route('/generate-excel-export', methods=['POST'])
@admin_required @login_required
def generate_excel_export(): def generate_excel_export():
"""Generate and download Excel file with selected columns in specified order""" """Generate and download Excel file with selected columns in specified order"""
try: try:
user_role = session.get('role')
if user_role not in ['admin', 'payroll']:
logger_handler.logger.warning(f"User {session.get('username', 'unknown')} (role: {user_role}) attempted unauthorized Excel export")
flash('Access denied. Only administrators and payroll staff can export data.', 'error')
return redirect(url_for('attendance_report'))
print("📊 Excel export generation started") print("📊 Excel export generation started")
# Log export action using your existing logger # Log export action using your existing logger
+21 -1
View File
@@ -1017,8 +1017,19 @@ function exportAttendanceWithAccuracy() {
} }
function exportAttendance() { function exportAttendance() {
// Check user role before proceeding
const userRole = window.userRole; // Read from global variable set in template
console.log("Template - session.role:", '{{ session.role }}');
console.log("Template - window.userRole set to:", window.userRole);
if (!['admin', 'payroll'].includes(userRole)) {
console.log("Export access denied - insufficient privileges");
alert("Access denied. Only administrators and payroll staff can export data.");
return;
}
// Log export action // Log export action
console.log("Export button clicked - redirecting to configuration page"); console.log(`Export button clicked by ${userRole} - redirecting to configuration page`);
// Get current filters // Get current filters
const currentFilters = getCurrentFilters(); const currentFilters = getCurrentFilters();
@@ -1053,6 +1064,15 @@ function getCurrentFilters() {
// Add a quick CSV export function as backup (keep existing functionality) // Add a quick CSV export function as backup (keep existing functionality)
function exportAttendanceCSV() { function exportAttendanceCSV() {
// Check user role before proceeding
const userRole = window.userRole;
if (!['admin', 'payroll'].includes(userRole)) {
console.log("CSV export access denied - insufficient privileges");
alert("Access denied. Only administrators and payroll staff can export data.");
return;
}
// Build export URL with current filters for CSV // Build export URL with current filters for CSV
const params = new URLSearchParams(); const params = new URLSearchParams();
const filters = getCurrentFilters(); const filters = getCurrentFilters();
+4 -1
View File
@@ -10,7 +10,7 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="attendance-page"> <div class="attendance-page" data-user-role="{{ session.role }}">
<!-- Header Section --> <!-- Header Section -->
<div class="attendance-header"> <div class="attendance-header">
<div class="header-content"> <div class="header-content">
@@ -22,10 +22,12 @@
</div> </div>
<div class="header-actions"> <div class="header-actions">
{% if session.role in ['admin', 'payroll'] %}
<button onclick="exportAttendance()" class="btn btn-success"> <button onclick="exportAttendance()" class="btn btn-success">
<i class="fas fa-download"></i> <i class="fas fa-download"></i>
Export Data Export Data
</button> </button>
{% endif %}
<button onclick="refreshReport()" class="btn btn-secondary"> <button onclick="refreshReport()" class="btn btn-secondary">
<i class="fas fa-sync-alt"></i> <i class="fas fa-sync-alt"></i>
Refresh Refresh
@@ -622,5 +624,6 @@ document.addEventListener('DOMContentLoaded', function() {
console.log('✅ Admin/Payroll edit/delete buttons have been activated'); console.log('✅ Admin/Payroll edit/delete buttons have been activated');
} }
}); });
window.userRole = '{{ session.role }}';
</script> </script>
{% endblock %} {% endblock %}