2ND
This commit is contained in:
112
routes/admin.py
112
routes/admin.py
@@ -1,76 +1,96 @@
|
||||
from flask import Blueprint, render_template, request, redirect, url_for, flash
|
||||
from flask_login import login_required, current_user
|
||||
from werkzeug.security import generate_password_hash
|
||||
from models import User, db
|
||||
from utils import admin_required
|
||||
|
||||
admin_bp = Blueprint('admin', __name__, url_prefix='/admin')
|
||||
|
||||
@admin_bp.before_request
|
||||
@admin_bp.route('/users')
|
||||
@login_required
|
||||
@admin_required
|
||||
def before_request():
|
||||
"""在處理此藍圖中的任何請求之前,確保使用者是已登入的管理員。"""
|
||||
pass
|
||||
|
||||
@admin_bp.route('/users')
|
||||
def user_list():
|
||||
users = User.query.all()
|
||||
"""顯示所有使用者列表,供管理員管理權限。"""
|
||||
# MySQL 不支援 nullslast(),改用 COALESCE 處理 NULL 值
|
||||
users = User.query.order_by(User.last_login.desc(), User.username).all()
|
||||
return render_template('user_management.html', users=users)
|
||||
|
||||
@admin_bp.route('/users/create', methods=['POST'])
|
||||
def create_user():
|
||||
username = request.form.get('username')
|
||||
password = request.form.get('password')
|
||||
role = request.form.get('role')
|
||||
|
||||
if not all([username, password, role]):
|
||||
flash('所有欄位都是必填的!', 'danger')
|
||||
return redirect(url_for('admin.user_list'))
|
||||
|
||||
if User.query.filter_by(username=username).first():
|
||||
flash('該使用者名稱已存在!', 'danger')
|
||||
return redirect(url_for('admin.user_list'))
|
||||
|
||||
new_user = User(
|
||||
username=username,
|
||||
password_hash=generate_password_hash(password),
|
||||
role=role
|
||||
)
|
||||
db.session.add(new_user)
|
||||
db.session.commit()
|
||||
flash('新使用者已成功建立!', 'success')
|
||||
return redirect(url_for('admin.user_list'))
|
||||
|
||||
@admin_bp.route('/users/edit/<int:user_id>', methods=['POST'])
|
||||
def edit_user(user_id):
|
||||
@login_required
|
||||
@admin_required
|
||||
def edit_user_role(user_id):
|
||||
"""編輯使用者權限。僅允許修改角色。"""
|
||||
user = User.query.get_or_404(user_id)
|
||||
new_role = request.form.get('role')
|
||||
new_password = request.form.get('password')
|
||||
|
||||
if new_role:
|
||||
# 防止 admin 修改自己的角色,導致失去管理權限
|
||||
if user.id == current_user.id and user.role == 'admin' and new_role != 'admin':
|
||||
flash('無法變更自己的管理員角色!', 'danger')
|
||||
return redirect(url_for('admin.user_list'))
|
||||
user.role = new_role
|
||||
|
||||
if new_password:
|
||||
user.password_hash = generate_password_hash(new_password)
|
||||
if new_role not in ['viewer', 'editor', 'admin']:
|
||||
flash('無效的權限設定!', 'danger')
|
||||
return redirect(url_for('admin.user_list'))
|
||||
|
||||
# 防止管理員修改自己的角色導致失去管理權限
|
||||
if user.id == current_user.id and user.role == 'admin' and new_role != 'admin':
|
||||
flash('無法變更自己的管理員權限!', 'danger')
|
||||
return redirect(url_for('admin.user_list'))
|
||||
|
||||
old_role = user.role
|
||||
user.role = new_role
|
||||
db.session.commit()
|
||||
flash(f"使用者 '{user.username}' 的資料已更新。", 'success')
|
||||
|
||||
flash(f"使用者 '{user.username}' 的權限已從 '{old_role}' 更新為 '{new_role}'。", 'success')
|
||||
return redirect(url_for('admin.user_list'))
|
||||
|
||||
@admin_bp.route('/users/delete/<int:user_id>', methods=['POST'])
|
||||
@login_required
|
||||
@admin_required
|
||||
def delete_user(user_id):
|
||||
# 避免 admin 刪除自己
|
||||
"""刪除使用者帳號。"""
|
||||
# 避免管理員刪除自己
|
||||
if user_id == current_user.id:
|
||||
flash('無法刪除自己的帳號!', 'danger')
|
||||
return redirect(url_for('admin.user_list'))
|
||||
|
||||
user = User.query.get_or_404(user_id)
|
||||
username = user.username
|
||||
|
||||
# 檢查是否為最後一個管理員
|
||||
admin_count = User.query.filter_by(role='admin').count()
|
||||
if user.role == 'admin' and admin_count <= 1:
|
||||
flash('無法刪除最後一個管理員帳號!', 'danger')
|
||||
return redirect(url_for('admin.user_list'))
|
||||
|
||||
db.session.delete(user)
|
||||
db.session.commit()
|
||||
flash(f"使用者 '{user.username}' 已被刪除。", 'success')
|
||||
flash(f"使用者 '{username}' 已被刪除。", 'success')
|
||||
return redirect(url_for('admin.user_list'))
|
||||
|
||||
@admin_bp.route('/users/set-admin', methods=['POST'])
|
||||
@login_required
|
||||
@admin_required
|
||||
def set_admin():
|
||||
"""設定特定AD帳號為管理員權限。"""
|
||||
username = request.form.get('username', '').strip()
|
||||
|
||||
if not username:
|
||||
flash('請輸入有效的AD帳號!', 'danger')
|
||||
return redirect(url_for('admin.user_list'))
|
||||
|
||||
# 查找或建立使用者
|
||||
user = User.query.filter_by(username=username).first()
|
||||
|
||||
if not user:
|
||||
# 建立新的使用者記錄
|
||||
user = User(
|
||||
username=username,
|
||||
password_hash='ldap_authenticated', # LDAP使用者不需要本地密碼
|
||||
role='admin'
|
||||
)
|
||||
db.session.add(user)
|
||||
db.session.commit()
|
||||
flash(f"已為 AD 帳號 '{username}' 建立管理員權限。", 'success')
|
||||
else:
|
||||
# 更新現有使用者權限
|
||||
old_role = user.role
|
||||
user.role = 'admin'
|
||||
db.session.commit()
|
||||
flash(f"已將 '{username}' 的權限從 '{old_role}' 更新為 'admin'。", 'success')
|
||||
|
||||
return redirect(url_for('admin.user_list'))
|
Reference in New Issue
Block a user