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):
"""Check if user has staff-level permissions (includes new 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):
"""Get user-friendly role name"""
@@ -3001,7 +3005,7 @@ def toggle_qr_status_api(qr_id):
return redirect(url_for('dashboard'))
@app.route('/attendance')
# @admin_required
@login_required
def attendance_report():
"""Safe attendance report with backward compatibility for location_accuracy and fixed datetime handling"""
try:
@@ -3009,6 +3013,7 @@ def attendance_report():
# Log attendance report access
try:
user_role = session.get('role', 'unknown')
logger_handler.logger.info(f"User {session.get('username', 'unknown')} accessed attendance report")
except Exception as log_error:
print(f"⚠️ Logging error (non-critical): {log_error}")
@@ -3090,7 +3095,7 @@ def attendance_report():
conditions.append("ad.employee_id LIKE :employee")
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:
conditions.append("qc.project_id = :project_id")
params['project_id'] = int(project_filter)
@@ -3279,7 +3284,8 @@ def attendance_report():
project_filter=project_filter,
today_date=today_date,
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:
print(f"❌ Error loading attendance report: {e}")
@@ -3491,14 +3497,21 @@ def attendance_stats_api():
return jsonify({'error': 'Failed to fetch attendance statistics'}), 500
@app.route('/export-configuration')
@admin_required
@login_required
def export_configuration():
"""Route to display export configuration page"""
try:
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
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")
except Exception as log_error:
print(f"⚠️ Logging error (non-critical): {log_error}")
@@ -3573,10 +3586,16 @@ def export_configuration():
return redirect(url_for('attendance_report'))
@app.route('/generate-excel-export', methods=['POST'])
@admin_required
@login_required
def generate_excel_export():
"""Generate and download Excel file with selected columns in specified order"""
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")
# Log export action using your existing logger
+21 -1
View File
@@ -1017,8 +1017,19 @@ function exportAttendanceWithAccuracy() {
}
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
console.log("Export button clicked - redirecting to configuration page");
console.log(`Export button clicked by ${userRole} - redirecting to configuration page`);
// Get current filters
const currentFilters = getCurrentFilters();
@@ -1053,6 +1064,15 @@ function getCurrentFilters() {
// Add a quick CSV export function as backup (keep existing functionality)
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
const params = new URLSearchParams();
const filters = getCurrentFilters();
+4 -1
View File
@@ -10,7 +10,7 @@
{% endblock %}
{% block content %}
<div class="attendance-page">
<div class="attendance-page" data-user-role="{{ session.role }}">
<!-- Header Section -->
<div class="attendance-header">
<div class="header-content">
@@ -22,10 +22,12 @@
</div>
<div class="header-actions">
{% if session.role in ['admin', 'payroll'] %}
<button onclick="exportAttendance()" class="btn btn-success">
<i class="fas fa-download"></i>
Export Data
</button>
{% endif %}
<button onclick="refreshReport()" class="btn btn-secondary">
<i class="fas fa-sync-alt"></i>
Refresh
@@ -622,5 +624,6 @@ document.addEventListener('DOMContentLoaded', function() {
console.log('✅ Admin/Payroll edit/delete buttons have been activated');
}
});
window.userRole = '{{ session.role }}';
</script>
{% endblock %}