'wip(logging):调整日志记录方式'
This commit is contained in:
@@ -3,9 +3,9 @@ from flask import session, redirect, url_for, request
|
|||||||
from flask_login import current_user, login_user
|
from flask_login import current_user, login_user
|
||||||
from flask_restful import Resource, reqparse
|
from flask_restful import Resource, reqparse
|
||||||
|
|
||||||
from applications.common.admin_log import login_log, admin_log
|
|
||||||
from applications.common.gen_captcha import add_auth_session
|
from applications.common.gen_captcha import add_auth_session
|
||||||
from applications.common.utils.http import fail_api, success_api
|
from applications.common.utils.http import fail_api, success_api
|
||||||
|
from applications.common.utils.rights import record_logging
|
||||||
from applications.models import CompanyUser
|
from applications.models import CompanyUser
|
||||||
|
|
||||||
|
|
||||||
@@ -41,9 +41,10 @@ class Login(Resource):
|
|||||||
# 登录
|
# 登录
|
||||||
login_user(user)
|
login_user(user)
|
||||||
# 记录登录日志
|
# 记录登录日志
|
||||||
login_log(request, uid=user.id, is_access=True)
|
record_logging()
|
||||||
|
|
||||||
# 存入权限
|
# 存入权限
|
||||||
add_auth_session()
|
add_auth_session()
|
||||||
return success_api(msg="登录成功")
|
return success_api(msg="登录成功")
|
||||||
login_log(request, uid=user.id, is_access=False)
|
record_logging()
|
||||||
return fail_api(msg="用户名或密码错误")
|
return fail_api(msg="用户名或密码错误")
|
||||||
|
|||||||
@@ -6,14 +6,14 @@ from sqlalchemy import desc
|
|||||||
from applications.common.utils.http import fail_api, success_api, table_api
|
from applications.common.utils.http import fail_api, success_api, table_api
|
||||||
from applications.common.utils.rights import authorize
|
from applications.common.utils.rights import authorize
|
||||||
from applications.extensions import db
|
from applications.extensions import db
|
||||||
from applications.models import AdminLog
|
from applications.models import LoggingModel
|
||||||
from applications.models import CompanyUser, RightsRole, CompanyDepartment
|
from applications.models import CompanyUser, RightsRole, CompanyDepartment
|
||||||
|
|
||||||
|
|
||||||
def get_current_user_logs():
|
def get_current_user_logs():
|
||||||
""" 获取当前用户日志 """
|
""" 获取当前用户日志 """
|
||||||
log = AdminLog.query.filter_by(url='/passport/login').filter_by(uid=current_user.id).order_by(
|
log = LoggingModel.query.filter_by(url='/passport/login').filter_by(uid=current_user.id).order_by(
|
||||||
desc(AdminLog.create_at)).limit(10)
|
desc(LoggingModel.create_at)).limit(10)
|
||||||
return log
|
return log
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,56 +0,0 @@
|
|||||||
from flask_login import current_user
|
|
||||||
|
|
||||||
from applications.extensions import db
|
|
||||||
from applications.models import AdminLog
|
|
||||||
|
|
||||||
|
|
||||||
def login_log(request, uid, is_access):
|
|
||||||
info = {
|
|
||||||
'method': request.method,
|
|
||||||
'url': request.path,
|
|
||||||
'ip': request.remote_addr,
|
|
||||||
'user_agent': request.headers.get('User-Agent'),
|
|
||||||
'desc': request.form.get('username'),
|
|
||||||
'uid': uid,
|
|
||||||
'success': int(is_access)
|
|
||||||
|
|
||||||
}
|
|
||||||
log = AdminLog(
|
|
||||||
url=info.get('url'),
|
|
||||||
ip=info.get('ip'),
|
|
||||||
user_agent=info.get('user_agent'),
|
|
||||||
desc=info.get('desc'),
|
|
||||||
uid=info.get('uid'),
|
|
||||||
method=info.get('method'),
|
|
||||||
success=info.get('success')
|
|
||||||
)
|
|
||||||
db.session.add(log)
|
|
||||||
db.session.flush()
|
|
||||||
db.session.commit()
|
|
||||||
return log.id
|
|
||||||
|
|
||||||
|
|
||||||
def admin_log(request, is_access):
|
|
||||||
info = {
|
|
||||||
'method': request.method,
|
|
||||||
'url': request.path,
|
|
||||||
'ip': request.remote_addr,
|
|
||||||
'user_agent': request.headers.get('User-Agent'),
|
|
||||||
'desc': str(dict(request.values)),
|
|
||||||
'uid': current_user.id,
|
|
||||||
'success': int(is_access)
|
|
||||||
|
|
||||||
}
|
|
||||||
log = AdminLog(
|
|
||||||
url=info.get('url'),
|
|
||||||
ip=info.get('ip'),
|
|
||||||
user_agent=info.get('user_agent'),
|
|
||||||
desc=info.get('desc'),
|
|
||||||
uid=info.get('uid'),
|
|
||||||
method=info.get('method'),
|
|
||||||
success=info.get('success')
|
|
||||||
)
|
|
||||||
db.session.add(log)
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
return log.id
|
|
||||||
@@ -1,7 +1,64 @@
|
|||||||
|
import typing as t
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
|
||||||
from flask import abort, request, jsonify, session
|
from flask import abort, request, jsonify, session
|
||||||
from flask_login import login_required
|
from flask_login import login_required
|
||||||
from applications.common.admin_log import admin_log
|
from flask_login import current_user
|
||||||
|
|
||||||
|
from applications.extensions import db
|
||||||
|
from applications.models import LoggingModel
|
||||||
|
|
||||||
|
|
||||||
|
def record_logging(success: bool = True) -> None:
|
||||||
|
"""
|
||||||
|
记录用户日志数据
|
||||||
|
"""
|
||||||
|
info = {
|
||||||
|
'method': request.method,
|
||||||
|
'url': request.path,
|
||||||
|
'ip': request.remote_addr,
|
||||||
|
'user_agent': request.headers.get('User-Agent'),
|
||||||
|
'desc': str(dict(request.values)),
|
||||||
|
'uid': current_user.id,
|
||||||
|
'success': success
|
||||||
|
}
|
||||||
|
log = LoggingModel()
|
||||||
|
for key, value in info.items():
|
||||||
|
setattr(log, key, value)
|
||||||
|
|
||||||
|
db.session.add(log)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
def view_logging_required(func: t.Callable) -> t.Callable:
|
||||||
|
"""
|
||||||
|
日志装饰器,用于记录请求
|
||||||
|
"""
|
||||||
|
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(*args, **kwargs) -> t.Callable:
|
||||||
|
record_logging()
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
def permission_required(permission: str) -> t.Callable:
|
||||||
|
"""
|
||||||
|
权限装饰器,用于过滤需要的权限
|
||||||
|
"""
|
||||||
|
|
||||||
|
def decorator(func: t.Callable):
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(*args, **kwargs) -> t.Callable:
|
||||||
|
if permission not in session.get('permissions'):
|
||||||
|
record_logging(success=False)
|
||||||
|
abort(403)
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
def authorize(power: str, log: bool = False):
|
def authorize(power: str, log: bool = False):
|
||||||
@@ -11,17 +68,15 @@ def authorize(power: str, log: bool = False):
|
|||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
if power not in session.get('permissions'):
|
if power not in session.get('permissions'):
|
||||||
if log:
|
if log:
|
||||||
admin_log(request=request, is_access=False)
|
record_logging()
|
||||||
if request.method == 'GET':
|
if request.method == 'GET':
|
||||||
abort(403)
|
abort(403)
|
||||||
else:
|
else:
|
||||||
return jsonify(success=False, msg="权限不足!")
|
return jsonify(success=False, msg="权限不足!")
|
||||||
if log:
|
if log:
|
||||||
admin_log(request=request, is_access=True)
|
record_logging()
|
||||||
return func(*args, **kwargs)
|
return func(*args, **kwargs)
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from applications.models.file import FilePhoto
|
from applications.models.file import FilePhoto
|
||||||
from applications.models.log import AdminLog
|
from applications.models.log import LoggingModel
|
||||||
from applications.models.rights import RightsPower, RightsRole, role_power, user_role
|
from applications.models.rights import RightsPower, RightsRole, role_power, user_role
|
||||||
from applications.models.users import CompanyDepartment, CompanyUser
|
from applications.models.users import CompanyDepartment, CompanyUser
|
||||||
|
|||||||
@@ -2,14 +2,13 @@ from applications.extensions import db
|
|||||||
from .base import BaseModel
|
from .base import BaseModel
|
||||||
|
|
||||||
|
|
||||||
class AdminLog(db.Model, BaseModel):
|
class LoggingModel(db.Model, BaseModel):
|
||||||
__tablename__ = 'admin_admin_log'
|
__tablename__ = 'lg_logging'
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
method = db.Column(db.String(10))
|
method = db.Column(db.String(10))
|
||||||
uid = db.Column(db.Integer)
|
uid = db.Column(db.Integer, default=None)
|
||||||
url = db.Column(db.String(255))
|
url = db.Column(db.String(255))
|
||||||
desc = db.Column(db.Text)
|
desc = db.Column(db.Text)
|
||||||
ip = db.Column(db.String(255))
|
ip = db.Column(db.String(255))
|
||||||
success = db.Column(db.Integer)
|
success = db.Column(db.Boolean, default=True)
|
||||||
user_agent = db.Column(db.Text)
|
user_agent = db.Column(db.Text)
|
||||||
|
|
||||||
|
|||||||
@@ -1,24 +1,27 @@
|
|||||||
from flask import render_template, request
|
from flask import render_template, request
|
||||||
|
|
||||||
from applications.common.utils.rights import authorize
|
from applications.common.utils.rights import permission_required, view_logging_required
|
||||||
from applications.models import CompanyDepartment
|
from applications.models import CompanyDepartment
|
||||||
from applications.view import index_bp
|
from applications.view import index_bp
|
||||||
|
|
||||||
|
|
||||||
@index_bp.get('/dept')
|
@index_bp.get('/dept')
|
||||||
@authorize("admin:dept:main", log=True)
|
@view_logging_required
|
||||||
|
@permission_required("admin:dept:main")
|
||||||
def dept_index():
|
def dept_index():
|
||||||
return render_template('admin/department/dept.html')
|
return render_template('admin/department/dept.html')
|
||||||
|
|
||||||
|
|
||||||
@index_bp.get('/dept/add')
|
@index_bp.get('/dept/add')
|
||||||
@authorize("admin:dept:add", log=True)
|
@view_logging_required
|
||||||
|
@permission_required("admin:dept:add")
|
||||||
def add():
|
def add():
|
||||||
return render_template('admin/department/dept_add.html')
|
return render_template('admin/department/dept_add.html')
|
||||||
|
|
||||||
|
|
||||||
@index_bp.get('/dept/edit')
|
@index_bp.get('/dept/edit')
|
||||||
@authorize("admin:dept:edit", log=True)
|
@view_logging_required
|
||||||
|
@permission_required("admin:dept:edit")
|
||||||
def edit():
|
def edit():
|
||||||
dept_id = request.args.get("deptId", type=int)
|
dept_id = request.args.get("deptId", type=int)
|
||||||
dept = CompanyDepartment.query.get(dept_id)
|
dept = CompanyDepartment.query.get(dept_id)
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
from flask import render_template
|
from flask import render_template
|
||||||
|
|
||||||
from applications.view import index_bp
|
from applications.view import index_bp
|
||||||
from applications.common.utils.rights import authorize
|
from applications.common.utils.rights import authorize, view_logging_required, permission_required
|
||||||
|
|
||||||
|
|
||||||
# 图片管理
|
|
||||||
@index_bp.get('/file')
|
@index_bp.get('/file')
|
||||||
@authorize("admin:file:main", log=True)
|
@view_logging_required
|
||||||
|
@permission_required("admin:file:main")
|
||||||
def file_index():
|
def file_index():
|
||||||
return render_template('admin/file/photo.html')
|
return render_template('admin/file/photo.html')
|
||||||
|
|
||||||
|
|
||||||
# 图片管理
|
|
||||||
@index_bp.get('/file/photo/add')
|
@index_bp.get('/file/photo/add')
|
||||||
@authorize("admin:file:main", log=True)
|
@view_logging_required
|
||||||
|
@permission_required("admin:file:main")
|
||||||
def file_photo_add():
|
def file_photo_add():
|
||||||
return render_template('admin/file/photo_add.html')
|
return render_template('admin/file/photo_add.html')
|
||||||
|
|||||||
@@ -4,26 +4,26 @@ from flask_restful import marshal
|
|||||||
from applications.common.serialization import log_fields
|
from applications.common.serialization import log_fields
|
||||||
|
|
||||||
from applications.common.utils.http import table_api
|
from applications.common.utils.http import table_api
|
||||||
from applications.common.utils.rights import authorize
|
from applications.common.utils.rights import authorize, permission_required
|
||||||
from applications.models import AdminLog
|
from applications.models import LoggingModel
|
||||||
|
|
||||||
logs_bp = Blueprint('logs', __name__, url_prefix='/logs')
|
logs_bp = Blueprint('logs', __name__, url_prefix='/logs')
|
||||||
|
|
||||||
|
|
||||||
@logs_bp.get('/')
|
@logs_bp.get('/')
|
||||||
@authorize("admin:log:main")
|
@permission_required("admin:log:main")
|
||||||
def index():
|
def index():
|
||||||
return render_template('admin/logs_temp/main.html')
|
return render_template('admin/logs_temp/main.html')
|
||||||
|
|
||||||
|
|
||||||
@logs_bp.get('/login_log')
|
@logs_bp.get('/login_log')
|
||||||
@authorize("admin:log:main")
|
@permission_required("admin:log:main")
|
||||||
def login_log():
|
def login_log():
|
||||||
page = request.args.get('page', type=int)
|
page = request.args.get('page', type=int)
|
||||||
limit = request.args.get('limit', type=int)
|
limit = request.args.get('limit', type=int)
|
||||||
log_paginate = AdminLog.query.filter_by(
|
log_paginate = LoggingModel.query.filter_by(
|
||||||
url='/api/v1/passport/login').order_by(
|
url='/api/v1/passport/login').order_by(
|
||||||
desc(AdminLog.create_at)).paginate(
|
desc(LoggingModel.create_at)).paginate(
|
||||||
page=page, per_page=limit, error_out=False)
|
page=page, per_page=limit, error_out=False)
|
||||||
data = marshal(log_paginate.items, log_fields)
|
data = marshal(log_paginate.items, log_fields)
|
||||||
|
|
||||||
@@ -31,13 +31,13 @@ def login_log():
|
|||||||
|
|
||||||
|
|
||||||
@logs_bp.get('/access_log')
|
@logs_bp.get('/access_log')
|
||||||
@authorize("admin:log:main")
|
@permission_required("admin:log:main")
|
||||||
def operate_log():
|
def operate_log():
|
||||||
page = request.args.get('page', type=int)
|
page = request.args.get('page', type=int)
|
||||||
limit = request.args.get('limit', type=int)
|
limit = request.args.get('limit', type=int)
|
||||||
log_paginate = AdminLog.query.filter(
|
log_paginate = LoggingModel.query.filter(
|
||||||
AdminLog.url != '/api/v1/passport/login').order_by(
|
LoggingModel.url != '/api/v1/passport/login').order_by(
|
||||||
desc(AdminLog.create_at)).paginate(
|
desc(LoggingModel.create_at)).paginate(
|
||||||
page=page, per_page=limit, error_out=False)
|
page=page, per_page=limit, error_out=False)
|
||||||
data = marshal(log_paginate.items, log_fields)
|
data = marshal(log_paginate.items, log_fields)
|
||||||
return table_api(data=data, count=log_paginate.total, code=0)
|
return table_api(data=data, count=log_paginate.total, code=0)
|
||||||
|
|||||||
@@ -1,18 +1,20 @@
|
|||||||
from flask import render_template
|
from flask import render_template
|
||||||
|
|
||||||
from applications.common.utils.rights import authorize
|
from applications.common.utils.rights import authorize, permission_required, view_logging_required
|
||||||
from applications.models import RightsPower
|
from applications.models import RightsPower
|
||||||
from applications.view import index_bp
|
from applications.view import index_bp
|
||||||
|
|
||||||
|
|
||||||
@index_bp.get('/rights/')
|
@index_bp.get('/rights/')
|
||||||
@authorize("admin:power:main", log=True)
|
@view_logging_required
|
||||||
|
@permission_required("admin:power:main")
|
||||||
def rights_index():
|
def rights_index():
|
||||||
return render_template('admin/rights/rights.html')
|
return render_template('admin/rights/rights.html')
|
||||||
|
|
||||||
|
|
||||||
@index_bp.get('/rights/power/<int:power_id>')
|
@index_bp.get('/rights/power/<int:power_id>')
|
||||||
@authorize("admin:power:edit", log=True)
|
@view_logging_required
|
||||||
|
@permission_required("admin:power:edit")
|
||||||
def rights_edit(power_id):
|
def rights_edit(power_id):
|
||||||
power = RightsPower.query.filter_by(id=power_id).first()
|
power = RightsPower.query.filter_by(id=power_id).first()
|
||||||
icon = str(power.icon).split()
|
icon = str(power.icon).split()
|
||||||
@@ -24,6 +26,7 @@ def rights_edit(power_id):
|
|||||||
|
|
||||||
|
|
||||||
@index_bp.get('/rights/add')
|
@index_bp.get('/rights/add')
|
||||||
@authorize("admin:power:main", log=True)
|
@view_logging_required
|
||||||
|
@permission_required("admin:power:main")
|
||||||
def rights_add():
|
def rights_add():
|
||||||
return render_template('admin/rights/rights_add.html')
|
return render_template('admin/rights/rights_add.html')
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from flask import Blueprint, render_template
|
from flask import Blueprint, render_template
|
||||||
|
|
||||||
from applications.common.utils.rights import authorize
|
from applications.common.utils.rights import authorize, permission_required, view_logging_required
|
||||||
|
|
||||||
from applications.models import RightsRole
|
from applications.models import RightsRole
|
||||||
|
|
||||||
@@ -9,27 +9,31 @@ role_bp = Blueprint('role', __name__, url_prefix='/admin/role')
|
|||||||
|
|
||||||
# 角色而管理
|
# 角色而管理
|
||||||
@role_bp.get('/')
|
@role_bp.get('/')
|
||||||
@authorize("admin:role:main", log=True)
|
@view_logging_required
|
||||||
|
@permission_required("admin:role:main")
|
||||||
def main():
|
def main():
|
||||||
return render_template('admin/roles/roles.html')
|
return render_template('admin/roles/roles.html')
|
||||||
|
|
||||||
|
|
||||||
# 角色授权操作
|
# 角色授权操作
|
||||||
@role_bp.get('/power/<int:role_id>')
|
@role_bp.get('/power/<int:role_id>')
|
||||||
@authorize("admin:role:power", log=True)
|
@view_logging_required
|
||||||
|
@permission_required("admin:role:power")
|
||||||
def power(role_id):
|
def power(role_id):
|
||||||
return render_template('admin/roles/roles_power.html', role_id=role_id)
|
return render_template('admin/roles/roles_power.html', role_id=role_id)
|
||||||
|
|
||||||
|
|
||||||
# 角色编辑
|
# 角色编辑
|
||||||
@authorize("admin:role:edit", log=True)
|
|
||||||
@role_bp.get('/edit/<int:role_id>')
|
@role_bp.get('/edit/<int:role_id>')
|
||||||
|
@view_logging_required
|
||||||
|
@permission_required("admin:role:edit")
|
||||||
def role_editor(role_id):
|
def role_editor(role_id):
|
||||||
role = RightsRole.query.filter_by(id=role_id).first()
|
role = RightsRole.query.filter_by(id=role_id).first()
|
||||||
return render_template('admin/roles/roles_edit.html', role=role)
|
return render_template('admin/roles/roles_edit.html', role=role)
|
||||||
|
|
||||||
|
|
||||||
@authorize("admin:role:edit", log=True)
|
|
||||||
@role_bp.get('/add')
|
@role_bp.get('/add')
|
||||||
|
@view_logging_required
|
||||||
|
@permission_required("admin:role:edit")
|
||||||
def role_add():
|
def role_add():
|
||||||
return render_template('admin/roles/roles_add.html')
|
return render_template('admin/roles/roles_add.html')
|
||||||
|
|||||||
+20
-16
@@ -2,28 +2,30 @@ from flask import render_template
|
|||||||
from flask_login import login_required, current_user
|
from flask_login import login_required, current_user
|
||||||
from sqlalchemy import desc
|
from sqlalchemy import desc
|
||||||
|
|
||||||
from applications.common.utils.rights import authorize
|
from applications.common.utils.rights import authorize, permission_required, view_logging_required
|
||||||
from applications.models import AdminLog, RightsRole, CompanyUser
|
from applications.models import LoggingModel, RightsRole, CompanyUser
|
||||||
from . import index_bp
|
from . import index_bp
|
||||||
|
|
||||||
|
|
||||||
# 用户增加
|
# 用户增加
|
||||||
@index_bp.get('/users/')
|
@index_bp.get('/users/')
|
||||||
@authorize("admin:user:main", log=True)
|
@view_logging_required
|
||||||
|
@permission_required("admin:user:main")
|
||||||
def users_main():
|
def users_main():
|
||||||
return render_template('admin/users/users.html')
|
return render_template('admin/users/users.html')
|
||||||
|
|
||||||
|
|
||||||
@index_bp.get('/users/center')
|
@index_bp.get('/users/add')
|
||||||
@login_required
|
@view_logging_required
|
||||||
def users_center():
|
@permission_required("admin:user:add")
|
||||||
user_logs = AdminLog.query.filter_by(url='/passport/login').filter_by(uid=current_user.id).order_by(
|
def users_add_view():
|
||||||
desc(AdminLog.create_at)).limit(10)
|
roles = RightsRole.query.all()
|
||||||
return render_template('admin/users/profile.html', user_info=current_user, user_logs=user_logs)
|
return render_template('admin/users/users_add.html', roles=roles)
|
||||||
|
|
||||||
|
|
||||||
@index_bp.get('/users/<user_id>')
|
@index_bp.get('/users/<user_id>')
|
||||||
@authorize("admin:user:edit", log=True)
|
@view_logging_required
|
||||||
|
@permission_required("admin:user:edit")
|
||||||
def users_user_id_view(user_id):
|
def users_user_id_view(user_id):
|
||||||
# 获取编辑用户信息
|
# 获取编辑用户信息
|
||||||
user = CompanyUser.query.filter_by(id=user_id).first()
|
user = CompanyUser.query.filter_by(id=user_id).first()
|
||||||
@@ -34,12 +36,14 @@ def users_user_id_view(user_id):
|
|||||||
return render_template('admin/users/users_edit.html', user=user, roles=roles, checked_roles=checked_roles)
|
return render_template('admin/users/users_edit.html', user=user, roles=roles, checked_roles=checked_roles)
|
||||||
|
|
||||||
|
|
||||||
|
@index_bp.get('/users/center')
|
||||||
|
@login_required
|
||||||
|
def users_center():
|
||||||
|
user_logs = LoggingModel.query.filter_by(url='/passport/login').filter_by(uid=current_user.id).order_by(
|
||||||
|
desc(LoggingModel.create_at)).limit(10)
|
||||||
|
return render_template('admin/users/profile.html', user_info=current_user, user_logs=user_logs)
|
||||||
|
|
||||||
|
|
||||||
@index_bp.get('/users/avatar')
|
@index_bp.get('/users/avatar')
|
||||||
def users_avatar_view():
|
def users_avatar_view():
|
||||||
return render_template('admin/users/profile_avatar.html')
|
return render_template('admin/users/profile_avatar.html')
|
||||||
|
|
||||||
|
|
||||||
@index_bp.get('/users/add')
|
|
||||||
def users_add_view():
|
|
||||||
roles = RightsRole.query.all()
|
|
||||||
return render_template('admin/users/users_add.html', roles=roles)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user