支持LDAP用户登录了。
parent
1f04977aba
commit
2fa413d46b
|
@ -9,6 +9,11 @@ $app.on_init = function (cb_stack) {
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log($app.options);
|
console.log($app.options);
|
||||||
|
if(!$app.options.core_cfg.detected) {
|
||||||
|
$tp.notify_error('核心服务未启动,无法进行远程连接!');
|
||||||
|
cb_stack.exec();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
cb_stack
|
cb_stack
|
||||||
.add($app.create_controls)
|
.add($app.create_controls)
|
||||||
|
|
|
@ -8,7 +8,7 @@ import hashlib
|
||||||
import threading
|
import threading
|
||||||
import random
|
import random
|
||||||
|
|
||||||
__all__ = ['AttrDict', 'tp_make_dir']
|
__all__ = ['AttrDict', 'tp_make_dir', 'tp_timestamp_utc_now', 'tp_generate_random']
|
||||||
|
|
||||||
|
|
||||||
class AttrDict(dict):
|
class AttrDict(dict):
|
||||||
|
|
|
@ -111,8 +111,11 @@ class DoLoginHandler(TPBaseJsonHandler):
|
||||||
if err != TPE_OK:
|
if err != TPE_OK:
|
||||||
if err == TPE_NOT_EXISTS:
|
if err == TPE_NOT_EXISTS:
|
||||||
err = TPE_USER_AUTH
|
err = TPE_USER_AUTH
|
||||||
syslog.sys_log({'username': username, 'surname': username}, self.request.remote_ip, TPE_NOT_EXISTS, '登录失败,用户`{}`不存在'.format(username))
|
syslog.sys_log({'username': username, 'surname': username}, self.request.remote_ip, TPE_NOT_EXISTS,
|
||||||
return self.write_json(err)
|
'登录失败,用户`{}`不存在'.format(username))
|
||||||
|
return self.write_json(err)
|
||||||
|
elif err == TPE_PRIVILEGE:
|
||||||
|
return self.write_json(err, '尚未分配角色,请联系管理员')
|
||||||
|
|
||||||
# 判断此用户是否被允许使用当前登录认证方式
|
# 判断此用户是否被允许使用当前登录认证方式
|
||||||
auth_type = user_info.auth_type
|
auth_type = user_info.auth_type
|
||||||
|
@ -122,54 +125,6 @@ class DoLoginHandler(TPBaseJsonHandler):
|
||||||
if (auth_type & login_type) != login_type:
|
if (auth_type & login_type) != login_type:
|
||||||
return self.write_json(TPE_USER_AUTH, '不允许使用此身份认证方式')
|
return self.write_json(TPE_USER_AUTH, '不允许使用此身份认证方式')
|
||||||
|
|
||||||
# err, user_info = user.get_by_username(username)
|
|
||||||
# if err != TPE_OK:
|
|
||||||
# if err == TPE_NOT_EXISTS:
|
|
||||||
# syslog.sys_log({'username': username, 'surname': username}, self.request.remote_ip, TPE_NOT_EXISTS, '登录失败,用户`{}`不存在'.format(username))
|
|
||||||
# return self.write_json(err)
|
|
||||||
#
|
|
||||||
# if user_info.privilege == 0:
|
|
||||||
# # 尚未为此用户设置角色
|
|
||||||
# return self.write_json(TPE_PRIVILEGE, '用户尚未分配角色')
|
|
||||||
#
|
|
||||||
# if user_info['state'] == TP_STATE_LOCKED:
|
|
||||||
# # 用户已经被锁定,如果系统配置为一定时间后自动解锁,则更新一下用户信息
|
|
||||||
# if sys_cfg.login.lock_timeout != 0:
|
|
||||||
# if tp_timestamp_utc_now() - user_info.lock_time > sys_cfg.login.lock_timeout * 60:
|
|
||||||
# user_info.fail_count = 0
|
|
||||||
# user_info.state = TP_STATE_NORMAL
|
|
||||||
# if user_info['state'] == TP_STATE_LOCKED:
|
|
||||||
# syslog.sys_log(user_info, self.request.remote_ip, TPE_USER_LOCKED, '登录失败,用户已被锁定')
|
|
||||||
# return self.write_json(TPE_USER_LOCKED)
|
|
||||||
# elif user_info['state'] == TP_STATE_DISABLED:
|
|
||||||
# syslog.sys_log(user_info, self.request.remote_ip, TPE_USER_DISABLED, '登录失败,用户已被禁用')
|
|
||||||
# return self.write_json(TPE_USER_DISABLED)
|
|
||||||
# elif user_info['state'] != TP_STATE_NORMAL:
|
|
||||||
# syslog.sys_log(user_info, self.request.remote_ip, TPE_FAILED, '登录失败,系统内部错误')
|
|
||||||
# return self.write_json(TPE_FAILED)
|
|
||||||
#
|
|
||||||
# err_msg = ''
|
|
||||||
# if login_type in [TP_LOGIN_AUTH_USERNAME_PASSWORD, TP_LOGIN_AUTH_USERNAME_PASSWORD_CAPTCHA, TP_LOGIN_AUTH_USERNAME_PASSWORD_OATH]:
|
|
||||||
# # 如果系统配置了密码有效期,则检查用户的密码是否失效
|
|
||||||
# if sys_cfg.password.timeout != 0:
|
|
||||||
# pass
|
|
||||||
#
|
|
||||||
# if not tp_password_verify(password, user_info['password']):
|
|
||||||
# err, is_locked = user.update_fail_count(self, user_info)
|
|
||||||
# if is_locked:
|
|
||||||
# err_msg = '用户被临时锁定!'
|
|
||||||
# syslog.sys_log(user_info, self.request.remote_ip, TPE_USER_AUTH, '登录失败,密码错误!{}'.format(err_msg))
|
|
||||||
# return self.write_json(TPE_USER_AUTH)
|
|
||||||
#
|
|
||||||
# if login_type in [TP_LOGIN_AUTH_USERNAME_OATH, TP_LOGIN_AUTH_USERNAME_PASSWORD_OATH]:
|
|
||||||
# # use oath
|
|
||||||
# if not tp_oath_verify_code(user_info['oath_secret'], oath):
|
|
||||||
# err, is_locked = user.update_fail_count(self, user_info)
|
|
||||||
# if is_locked:
|
|
||||||
# err_msg = '用户被临时锁定!'
|
|
||||||
# syslog.sys_log(user_info, self.request.remote_ip, TPE_OATH_MISMATCH, "登录失败,身份验证器动态验证码错误!{}".format(err_msg))
|
|
||||||
# return self.write_json(TPE_OATH_MISMATCH)
|
|
||||||
|
|
||||||
self._user = user_info
|
self._user = user_info
|
||||||
self._user['_is_login'] = True
|
self._user['_is_login'] = True
|
||||||
# del self._user['password']
|
# del self._user['password']
|
||||||
|
|
|
@ -12,7 +12,8 @@ class Ldap(object):
|
||||||
self._server = ldap3.Server(ldap_host, ldap_port, connect_timeout=5, use_ssl=False)
|
self._server = ldap3.Server(ldap_host, ldap_port, connect_timeout=5, use_ssl=False)
|
||||||
self._base_dn = base_dn
|
self._base_dn = base_dn
|
||||||
|
|
||||||
def _parse_attr_map(self, attr_map):
|
@staticmethod
|
||||||
|
def _parse_attr_map(attr_map):
|
||||||
attrs_ldap = []
|
attrs_ldap = []
|
||||||
attrs_tp = []
|
attrs_tp = []
|
||||||
|
|
||||||
|
@ -33,7 +34,7 @@ class Ldap(object):
|
||||||
|
|
||||||
return attrs_ldap, attrs_tp, ''
|
return attrs_ldap, attrs_tp, ''
|
||||||
|
|
||||||
def get_all_attr(self, admin, password, filter):
|
def get_all_attr(self, admin, password, search_filter):
|
||||||
conn = ldap3.Connection(
|
conn = ldap3.Connection(
|
||||||
self._server, user=admin, password=password, check_names=True, lazy=False, raise_exceptions=False
|
self._server, user=admin, password=password, check_names=True, lazy=False, raise_exceptions=False
|
||||||
)
|
)
|
||||||
|
@ -55,7 +56,7 @@ class Ldap(object):
|
||||||
ret = conn.search(
|
ret = conn.search(
|
||||||
search_base=self._base_dn,
|
search_base=self._base_dn,
|
||||||
size_limit=1,
|
size_limit=1,
|
||||||
search_filter=filter, # (&(objectClass=person))
|
search_filter=search_filter, # (&(objectClass=person))
|
||||||
search_scope=ldap3.SUBTREE,
|
search_scope=ldap3.SUBTREE,
|
||||||
attributes=['*']
|
attributes=['*']
|
||||||
)
|
)
|
||||||
|
@ -76,7 +77,7 @@ class Ldap(object):
|
||||||
result[attr_name] = attr_val
|
result[attr_name] = attr_val
|
||||||
return TPE_OK, result, ''
|
return TPE_OK, result, ''
|
||||||
|
|
||||||
def list_users(self, admin, password, filter, attr_map, size_limit=0):
|
def list_users(self, admin, password, search_filter, attr_map, size_limit=0):
|
||||||
attrs_ldap, attrs_tp, msg = self._parse_attr_map(attr_map)
|
attrs_ldap, attrs_tp, msg = self._parse_attr_map(attr_map)
|
||||||
if attrs_ldap is None:
|
if attrs_ldap is None:
|
||||||
return TPE_PARAM, None, '属性映射格式错误: {}'.format(msg)
|
return TPE_PARAM, None, '属性映射格式错误: {}'.format(msg)
|
||||||
|
@ -103,7 +104,7 @@ class Ldap(object):
|
||||||
ret = conn.search(
|
ret = conn.search(
|
||||||
search_base=self._base_dn,
|
search_base=self._base_dn,
|
||||||
size_limit=size_limit,
|
size_limit=size_limit,
|
||||||
search_filter=filter, # (&(objectClass=person))
|
search_filter=search_filter, # (&(objectClass=person))
|
||||||
search_scope=ldap3.SUBTREE,
|
search_scope=ldap3.SUBTREE,
|
||||||
attributes=attrs_ldap
|
attributes=attrs_ldap
|
||||||
)
|
)
|
||||||
|
@ -135,4 +136,22 @@ class Ldap(object):
|
||||||
return TPE_OK, result, ''
|
return TPE_OK, result, ''
|
||||||
|
|
||||||
def valid_user(self, user_dn, password):
|
def valid_user(self, user_dn, password):
|
||||||
return False
|
conn = ldap3.Connection(
|
||||||
|
self._server, user=user_dn, password=password, check_names=True, lazy=False, raise_exceptions=False
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
conn.open()
|
||||||
|
except Exception as e:
|
||||||
|
log.e(str(e))
|
||||||
|
return TPE_FAILED, '无法连接到LDAP服务器'
|
||||||
|
|
||||||
|
conn.bind()
|
||||||
|
if not (
|
||||||
|
('result' in conn.result and 0 == conn.result['result'])
|
||||||
|
and
|
||||||
|
('description' in conn.result and 'success' == conn.result['description'])
|
||||||
|
):
|
||||||
|
return TPE_USER_AUTH, '认证失败'
|
||||||
|
|
||||||
|
return TPE_OK, ''
|
||||||
|
|
|
@ -10,7 +10,7 @@ import time
|
||||||
import hashlib
|
import hashlib
|
||||||
import struct
|
import struct
|
||||||
|
|
||||||
__all__ = ['verify_oath_code', 'gen_oath_qrcode']
|
__all__ = ['tp_oath_generate_secret', 'tp_oath_verify_code', 'tp_oath_generate_qrcode']
|
||||||
|
|
||||||
|
|
||||||
def tp_oath_generate_secret():
|
def tp_oath_generate_secret():
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# import hashlib
|
|
||||||
|
|
||||||
from app.base.configs import tp_cfg
|
from app.base.configs import tp_cfg
|
||||||
from app.base.db import get_db, SQL
|
from app.base.db import get_db, SQL
|
||||||
from app.base.logger import log
|
from app.base.logger import log
|
||||||
|
@ -11,6 +9,7 @@ from app.model import syslog
|
||||||
from app.base.stats import tp_stats
|
from app.base.stats import tp_stats
|
||||||
from app.logic.auth.password import tp_password_verify, tp_password_generate_secret
|
from app.logic.auth.password import tp_password_verify, tp_password_generate_secret
|
||||||
from app.logic.auth.oath import tp_oath_verify_code
|
from app.logic.auth.oath import tp_oath_verify_code
|
||||||
|
from app.logic.auth.ldap import Ldap
|
||||||
|
|
||||||
|
|
||||||
def get_user_info(user_id):
|
def get_user_info(user_id):
|
||||||
|
@ -18,7 +17,10 @@ def get_user_info(user_id):
|
||||||
获取一个指定的用户的详细信息,包括关联的角色的详细信息、所属组的详细信息等等
|
获取一个指定的用户的详细信息,包括关联的角色的详细信息、所属组的详细信息等等
|
||||||
"""
|
"""
|
||||||
s = SQL(get_db())
|
s = SQL(get_db())
|
||||||
s.select_from('user', ['id', 'type', 'auth_type', 'username', 'surname', 'password', 'oath_secret', 'role_id', 'state', 'email', 'create_time', 'last_login', 'last_ip', 'last_chpass', 'mobile', 'qq', 'wechat', 'desc'], alt_name='u')
|
s.select_from('user',
|
||||||
|
['id', 'type', 'auth_type', 'username', 'surname', 'ldap_dn', 'password', 'oath_secret', 'role_id',
|
||||||
|
'state', 'fail_count', 'lock_time', 'email', 'create_time', 'last_login', 'last_ip', 'last_chpass',
|
||||||
|
'mobile', 'qq', 'wechat', 'desc'], alt_name='u')
|
||||||
s.left_join('role', ['name', 'privilege'], join_on='r.id=u.role_id', alt_name='r', out_map={'name': 'role'})
|
s.left_join('role', ['name', 'privilege'], join_on='r.id=u.role_id', alt_name='r', out_map={'name': 'role'})
|
||||||
s.where('u.id="{}"'.format(user_id))
|
s.where('u.id="{}"'.format(user_id))
|
||||||
err = s.query()
|
err = s.query()
|
||||||
|
@ -33,7 +35,10 @@ def get_user_info(user_id):
|
||||||
|
|
||||||
def get_by_username(username):
|
def get_by_username(username):
|
||||||
s = SQL(get_db())
|
s = SQL(get_db())
|
||||||
s.select_from('user', ['id', 'type', 'auth_type', 'username', 'surname', 'password', 'oath_secret', 'role_id', 'state', 'fail_count', 'lock_time', 'email', 'create_time', 'last_login', 'last_ip', 'last_chpass', 'mobile', 'qq', 'wechat', 'desc'], alt_name='u')
|
s.select_from('user',
|
||||||
|
['id', 'type', 'auth_type', 'username', 'surname', 'ldap_dn', 'password', 'oath_secret', 'role_id',
|
||||||
|
'state', 'fail_count', 'lock_time', 'email', 'create_time', 'last_login', 'last_ip', 'last_chpass',
|
||||||
|
'mobile', 'qq', 'wechat', 'desc'], alt_name='u')
|
||||||
s.left_join('role', ['name', 'privilege'], join_on='r.id=u.role_id', alt_name='r', out_map={'name': 'role'})
|
s.left_join('role', ['name', 'privilege'], join_on='r.id=u.role_id', alt_name='r', out_map={'name': 'role'})
|
||||||
s.where('u.username="{}"'.format(username))
|
s.where('u.username="{}"'.format(username))
|
||||||
err = s.query()
|
err = s.query()
|
||||||
|
@ -55,17 +60,17 @@ def login(handler, username, password=None, oath_code=None, check_bind_oath=Fals
|
||||||
err, user_info = get_by_username(username)
|
err, user_info = get_by_username(username)
|
||||||
if err != TPE_OK:
|
if err != TPE_OK:
|
||||||
# if err == TPE_NOT_EXISTS:
|
# if err == TPE_NOT_EXISTS:
|
||||||
# syslog.sys_log({'username': username, 'surname': username}, handler.request.remote_ip, TPE_NOT_EXISTS, '用户身份验证失败,用户`{}`不存在'.format(username))
|
# syslog.sys_log({'username': username, 'surname': username}, handler.request.remote_ip, TPE_NOT_EXISTS,
|
||||||
|
# '用户身份验证失败,用户`{}`不存在'.format(username))
|
||||||
return err, None
|
return err, None
|
||||||
|
|
||||||
if user_info.privilege == 0:
|
if user_info.privilege == 0:
|
||||||
# 尚未为此用户设置角色
|
# 尚未为此用户设置角色
|
||||||
return TPE_PRIVILEGE, None
|
return TPE_PRIVILEGE, None
|
||||||
|
|
||||||
if check_bind_oath == True and len(user_info['oath_secret']) != 0:
|
if check_bind_oath and len(user_info['oath_secret']) != 0:
|
||||||
return TPE_OATH_ALREADY_BIND, None
|
return TPE_OATH_ALREADY_BIND, None
|
||||||
|
|
||||||
|
|
||||||
if user_info['state'] == TP_STATE_LOCKED:
|
if user_info['state'] == TP_STATE_LOCKED:
|
||||||
# 用户已经被锁定,如果系统配置为一定时间后自动解锁,则更新一下用户信息
|
# 用户已经被锁定,如果系统配置为一定时间后自动解锁,则更新一下用户信息
|
||||||
if sys_cfg.login.lock_timeout != 0:
|
if sys_cfg.login.lock_timeout != 0:
|
||||||
|
@ -84,15 +89,55 @@ def login(handler, username, password=None, oath_code=None, check_bind_oath=Fals
|
||||||
|
|
||||||
err_msg = ''
|
err_msg = ''
|
||||||
if password is not None:
|
if password is not None:
|
||||||
# 如果系统配置了密码有效期,则检查用户的密码是否失效
|
if user_info['type'] == TP_USER_TYPE_LOCAL:
|
||||||
if sys_cfg.password.timeout != 0:
|
# 如果系统配置了密码有效期,则检查用户的密码是否失效
|
||||||
pass
|
if sys_cfg.password.timeout != 0:
|
||||||
|
_time_now = tp_timestamp_utc_now()
|
||||||
|
if user_info['last_chpass'] + (sys_cfg.password.timeout * 60 * 60 * 24) < _time_now:
|
||||||
|
syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, '登录失败,用户密码已过期')
|
||||||
|
return TPE_USER_AUTH, None
|
||||||
|
|
||||||
if not tp_password_verify(password, user_info['password']):
|
if not tp_password_verify(password, user_info['password']):
|
||||||
err, is_locked = update_fail_count(handler, user_info)
|
err, is_locked = update_fail_count(handler, user_info)
|
||||||
if is_locked:
|
if is_locked:
|
||||||
err_msg = ',用户已被临时锁定'
|
err_msg = ',用户已被临时锁定'
|
||||||
syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, '登录失败,密码错误{}'.format(err_msg))
|
syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, '登录失败,密码错误{}'.format(err_msg))
|
||||||
|
return TPE_USER_AUTH, None
|
||||||
|
elif user_info['type'] == TP_USER_TYPE_LDAP:
|
||||||
|
try:
|
||||||
|
if len(tp_cfg().sys_ldap_password) == 0:
|
||||||
|
syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, 'LDAP未能正确配置,需要管理员密码')
|
||||||
|
return TPE_USER_AUTH, None
|
||||||
|
else:
|
||||||
|
_ldap_password = tp_cfg().sys_ldap_password
|
||||||
|
_ldap_server = tp_cfg().sys.ldap.server
|
||||||
|
_ldap_port = tp_cfg().sys.ldap.port
|
||||||
|
_ldap_base_dn = tp_cfg().sys.ldap.base_dn
|
||||||
|
except:
|
||||||
|
syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, 'LDAP未能正确配置')
|
||||||
|
return TPE_USER_AUTH, None
|
||||||
|
|
||||||
|
try:
|
||||||
|
ldap = Ldap(_ldap_server, _ldap_port, _ldap_base_dn)
|
||||||
|
ret, err_msg = ldap.valid_user(user_info['ldap_dn'], password)
|
||||||
|
if ret != TPE_OK:
|
||||||
|
if ret == TPE_USER_AUTH:
|
||||||
|
err, is_locked = update_fail_count(handler, user_info)
|
||||||
|
if is_locked:
|
||||||
|
err_msg = ',用户已被临时锁定'
|
||||||
|
syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH,
|
||||||
|
'LDAP用户登录失败,密码错误{}'.format(err_msg))
|
||||||
|
return TPE_USER_AUTH, None
|
||||||
|
else:
|
||||||
|
syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH,
|
||||||
|
'LDAP用户登录失败,{}'.format(err_msg))
|
||||||
|
return TPE_USER_AUTH, None
|
||||||
|
except:
|
||||||
|
syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, 'LDAP用户登录失败,发生内部错误')
|
||||||
|
return TPE_USER_AUTH, None
|
||||||
|
|
||||||
|
else:
|
||||||
|
syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, '登录失败,系统内部错误')
|
||||||
return TPE_USER_AUTH, None
|
return TPE_USER_AUTH, None
|
||||||
|
|
||||||
if oath_code is not None:
|
if oath_code is not None:
|
||||||
|
@ -104,7 +149,8 @@ def login(handler, username, password=None, oath_code=None, check_bind_oath=Fals
|
||||||
err, is_locked = update_fail_count(handler, user_info)
|
err, is_locked = update_fail_count(handler, user_info)
|
||||||
if is_locked:
|
if is_locked:
|
||||||
err_msg = ',用户已被临时锁定!'
|
err_msg = ',用户已被临时锁定!'
|
||||||
syslog.sys_log(user_info, handler.request.remote_ip, TPE_OATH_MISMATCH, "登录失败,身份验证器动态验证码错误{}".format(err_msg))
|
syslog.sys_log(user_info, handler.request.remote_ip, TPE_OATH_MISMATCH,
|
||||||
|
"登录失败,身份验证器动态验证码错误{}".format(err_msg))
|
||||||
return TPE_OATH_MISMATCH, None
|
return TPE_OATH_MISMATCH, None
|
||||||
|
|
||||||
del user_info['password']
|
del user_info['password']
|
||||||
|
@ -118,7 +164,8 @@ def login(handler, username, password=None, oath_code=None, check_bind_oath=Fals
|
||||||
def get_users(sql_filter, sql_order, sql_limit, sql_restrict, sql_exclude):
|
def get_users(sql_filter, sql_order, sql_limit, sql_restrict, sql_exclude):
|
||||||
dbtp = get_db().table_prefix
|
dbtp = get_db().table_prefix
|
||||||
s = SQL(get_db())
|
s = SQL(get_db())
|
||||||
s.select_from('user', ['id', 'type', 'auth_type', 'username', 'surname', 'role_id', 'state', 'email', 'last_login'], alt_name='u')
|
s.select_from('user', ['id', 'type', 'auth_type', 'username', 'surname', 'role_id', 'state', 'email', 'last_login'],
|
||||||
|
alt_name='u')
|
||||||
s.left_join('role', ['name', 'privilege'], join_on='r.id=u.role_id', alt_name='r', out_map={'name': 'role'})
|
s.left_join('role', ['name', 'privilege'], join_on='r.id=u.role_id', alt_name='r', out_map={'name': 'role'})
|
||||||
|
|
||||||
_where = list()
|
_where = list()
|
||||||
|
@ -126,20 +173,34 @@ def get_users(sql_filter, sql_order, sql_limit, sql_restrict, sql_exclude):
|
||||||
if len(sql_restrict) > 0:
|
if len(sql_restrict) > 0:
|
||||||
for k in sql_restrict:
|
for k in sql_restrict:
|
||||||
if k == 'group_id':
|
if k == 'group_id':
|
||||||
_where.append('u.id IN (SELECT mid FROM {dbtp}group_map WHERE type={gtype} AND gid={gid})'.format(dbtp=dbtp, gtype=TP_GROUP_USER, gid=sql_restrict[k]))
|
_sql = 'u.id IN (SELECT mid FROM {dbtp}group_map WHERE type={gtype} AND gid={gid})'
|
||||||
|
_where.append(_sql.format(dbtp=dbtp, gtype=TP_GROUP_USER, gid=sql_restrict[k]))
|
||||||
else:
|
else:
|
||||||
log.w('unknown restrict field: {}\n'.format(k))
|
log.w('unknown restrict field: {}\n'.format(k))
|
||||||
|
|
||||||
if len(sql_exclude) > 0:
|
if len(sql_exclude) > 0:
|
||||||
for k in sql_exclude:
|
for k in sql_exclude:
|
||||||
if k == 'group_id':
|
if k == 'group_id':
|
||||||
_where.append('u.id NOT IN (SELECT mid FROM {dbtp}group_map WHERE type={gtype} AND gid={gid})'.format(dbtp=dbtp, gtype=TP_GROUP_USER, gid=sql_exclude[k]))
|
_where.append(
|
||||||
|
'u.id NOT IN ('
|
||||||
|
'SELECT mid FROM {dbtp}group_map WHERE type={gtype} AND gid={gid})'
|
||||||
|
''.format(dbtp=dbtp, gtype=TP_GROUP_USER, gid=sql_exclude[k]))
|
||||||
elif k == 'ops_policy_id':
|
elif k == 'ops_policy_id':
|
||||||
_where.append('u.id NOT IN (SELECT rid FROM {dbtp}ops_auz WHERE policy_id={pid} AND rtype={rtype})'.format(dbtp=dbtp, pid=sql_exclude[k], rtype=TP_USER))
|
_where.append(
|
||||||
|
'u.id NOT IN (SELECT rid FROM {dbtp}ops_auz WHERE policy_id={pid} AND rtype={rtype})'
|
||||||
|
''.format(dbtp=dbtp, pid=sql_exclude[k], rtype=TP_USER))
|
||||||
elif k == 'auditor_policy_id':
|
elif k == 'auditor_policy_id':
|
||||||
_where.append('u.id NOT IN (SELECT rid FROM {dbtp}audit_auz WHERE policy_id={pid} AND `type`={ptype} AND rtype={rtype})'.format(dbtp=dbtp, pid=sql_exclude[k], ptype=TP_POLICY_OPERATOR, rtype=TP_USER))
|
_where.append(
|
||||||
|
'u.id NOT IN ('
|
||||||
|
'SELECT rid FROM {dbtp}audit_auz WHERE policy_id={pid} '
|
||||||
|
'AND `type`={ptype} AND rtype={rtype}'
|
||||||
|
')'.format(dbtp=dbtp, pid=sql_exclude[k], ptype=TP_POLICY_OPERATOR, rtype=TP_USER))
|
||||||
elif k == 'auditee_policy_id':
|
elif k == 'auditee_policy_id':
|
||||||
_where.append('u.id NOT IN (SELECT rid FROM {dbtp}audit_auz WHERE policy_id={pid} AND `type`={ptype} AND rtype={rtype})'.format(dbtp=dbtp, pid=sql_exclude[k], ptype=TP_POLICY_ASSET, rtype=TP_USER))
|
_where.append(
|
||||||
|
'u.id NOT IN ('
|
||||||
|
'SELECT rid FROM {dbtp}audit_auz WHERE policy_id={pid} '
|
||||||
|
'AND `type`={ptype} AND rtype={rtype}'
|
||||||
|
')'.format(dbtp=dbtp, pid=sql_exclude[k], ptype=TP_POLICY_ASSET, rtype=TP_USER))
|
||||||
else:
|
else:
|
||||||
log.w('unknown exclude field: {}\n'.format(k))
|
log.w('unknown exclude field: {}\n'.format(k))
|
||||||
|
|
||||||
|
@ -152,7 +213,12 @@ def get_users(sql_filter, sql_order, sql_limit, sql_restrict, sql_exclude):
|
||||||
elif k == 'state':
|
elif k == 'state':
|
||||||
_where.append('u.state={filter}'.format(filter=sql_filter[k]))
|
_where.append('u.state={filter}'.format(filter=sql_filter[k]))
|
||||||
elif k == 'search':
|
elif k == 'search':
|
||||||
_where.append('(u.username LIKE "%{filter}%" OR u.surname LIKE "%{filter}%" OR u.email LIKE "%{filter}%" OR u.desc LIKE "%{filter}%")'.format(filter=sql_filter[k]))
|
_where.append('('
|
||||||
|
'u.username LIKE "%{filter}%" '
|
||||||
|
'OR u.surname LIKE "%{filter}%" '
|
||||||
|
'OR u.email LIKE "%{filter}%" '
|
||||||
|
'OR u.desc LIKE "%{filter}%"'
|
||||||
|
')'.format(filter=sql_filter[k]))
|
||||||
|
|
||||||
if len(_where) > 0:
|
if len(_where) > 0:
|
||||||
s.where('( {} )'.format(' AND '.join(_where)))
|
s.where('( {} )'.format(' AND '.join(_where)))
|
||||||
|
@ -211,11 +277,16 @@ def create_users(handler, user_list, success, failed):
|
||||||
else:
|
else:
|
||||||
_password = ''
|
_password = ''
|
||||||
|
|
||||||
sql = 'INSERT INTO `{}user` (`type`, `auth_type`, `password`, `username`, `surname`, `role_id`, `state`, `email`, `creator_id`, `create_time`, `last_login`, `last_chpass`, `desc`) VALUES ' \
|
sql = 'INSERT INTO `{}user` (' \
|
||||||
'({user_type}, 0, "{password}", "{username}", "{surname}", 0, {state}, "{email}", {creator_id}, {create_time}, {last_login}, {last_chpass}, "{desc}");' \
|
'`role_id`, `username`, `surname`, `type`, `ldap_dn`, `auth_type`, `password`, ' \
|
||||||
''.format(db.table_prefix, user_type=user['type'],
|
'`state`, `email`, `creator_id`, `create_time`, `last_login`, `last_chpass`, `desc`' \
|
||||||
username=user['username'], surname=user['surname'], password=_password, state=TP_STATE_NORMAL, email=user['email'],
|
') VALUES (' \
|
||||||
creator_id=operator['id'], create_time=_time_now, last_login=0, last_chpass=0, desc=user['desc'])
|
'0, "{username}", "{surname}", {user_type}, "{ldap_dn}", 0, "{password}", ' \
|
||||||
|
'{state}, "{email}", {creator_id}, {create_time}, {last_login}, {last_chpass}, "{desc}");' \
|
||||||
|
''.format(db.table_prefix, username=user['username'], surname=user['surname'], user_type=user['type'],
|
||||||
|
ldap_dn=user['ldap_dn'], password=_password, state=TP_STATE_NORMAL, email=user['email'],
|
||||||
|
creator_id=operator['id'], create_time=_time_now, last_login=0, last_chpass=_time_now,
|
||||||
|
desc=user['desc'])
|
||||||
db_ret = db.exec(sql)
|
db_ret = db.exec(sql)
|
||||||
if not db_ret:
|
if not db_ret:
|
||||||
failed.append({'line': user['_line'], 'error': '写入数据库时发生错误'})
|
failed.append({'line': user['_line'], 'error': '写入数据库时发生错误'})
|
||||||
|
@ -235,7 +306,7 @@ def create_users(handler, user_list, success, failed):
|
||||||
tp_stats().user_counter_change(cnt)
|
tp_stats().user_counter_change(cnt)
|
||||||
|
|
||||||
|
|
||||||
def create_user(handler, args):
|
def create_user(handler, user):
|
||||||
"""
|
"""
|
||||||
创建一个用户账号
|
创建一个用户账号
|
||||||
"""
|
"""
|
||||||
|
@ -243,29 +314,42 @@ def create_user(handler, args):
|
||||||
_time_now = tp_timestamp_utc_now()
|
_time_now = tp_timestamp_utc_now()
|
||||||
operator = handler.get_current_user()
|
operator = handler.get_current_user()
|
||||||
|
|
||||||
|
if 'type' not in user:
|
||||||
|
user['type'] = TP_USER_TYPE_LOCAL
|
||||||
|
if 'ldap_dn' not in user:
|
||||||
|
user['ldap_dn'] = ''
|
||||||
|
|
||||||
# 1. 判断此账号是否已经存在了
|
# 1. 判断此账号是否已经存在了
|
||||||
s = SQL(db)
|
s = SQL(db)
|
||||||
err = s.reset().select_from('user', ['id']).where('user.username="{}"'.format(args['username'])).query()
|
err = s.reset().select_from('user', ['id']).where('user.username="{}"'.format(user['username'])).query()
|
||||||
if err != TPE_OK:
|
if err != TPE_OK:
|
||||||
return err, 0
|
return err, 0
|
||||||
if len(s.recorder) > 0:
|
if len(s.recorder) > 0:
|
||||||
return TPE_EXISTS, 0
|
return TPE_EXISTS, 0
|
||||||
|
|
||||||
_password = tp_password_generate_secret(args['password'])
|
# _password = tp_password_generate_secret(user['password'])
|
||||||
|
if user['type'] == TP_USER_TYPE_LOCAL:
|
||||||
|
_password = tp_password_generate_secret(user['password'])
|
||||||
|
else:
|
||||||
|
_password = ''
|
||||||
|
|
||||||
sql = 'INSERT INTO `{}user` (`type`, `auth_type`, `password`, `username`, `surname`, `role_id`, `state`, `email`, `creator_id`, `create_time`, `last_login`, `last_chpass`, `desc`) VALUES ' \
|
sql = 'INSERT INTO `{}user` (' \
|
||||||
'(1, {auth_type}, "{password}", "{username}", "{surname}", {role}, {state}, "{email}", {creator_id}, {create_time}, {last_login}, {last_chpass}, "{desc}");' \
|
'`role_id`, `username`, `surname`, `type`, `ldap_dn`, `auth_type`, `password`, `state`, ' \
|
||||||
''.format(db.table_prefix, auth_type=args['auth_type'], password=_password,
|
'`email`, `creator_id`, `create_time`, `last_login`, `last_chpass`, `desc`' \
|
||||||
username=args['username'], surname=args['surname'], role=args['role'], state=TP_STATE_NORMAL, email=args['email'],
|
') VALUES (' \
|
||||||
creator_id=operator['id'],
|
'{role}, "{username}", "{surname}", {user_type}, "{ldap_dn}", {auth_type}, "{password}", {state}, ' \
|
||||||
create_time=_time_now, last_login=0, last_chpass=0, desc=args['desc'])
|
'"{email}", {creator_id}, {create_time}, {last_login}, {last_chpass}, "{desc}");' \
|
||||||
|
''.format(db.table_prefix, role=user['role'], username=user['username'], surname=user['surname'],
|
||||||
|
user_type=user['type'], ldap_dn=user['ldap_dn'], auth_type=user['auth_type'], password=_password,
|
||||||
|
state=TP_STATE_NORMAL, email=user['email'], creator_id=operator['id'], create_time=_time_now,
|
||||||
|
last_login=0, last_chpass=_time_now, desc=user['desc'])
|
||||||
db_ret = db.exec(sql)
|
db_ret = db.exec(sql)
|
||||||
if not db_ret:
|
if not db_ret:
|
||||||
return TPE_DATABASE, 0
|
return TPE_DATABASE, 0
|
||||||
|
|
||||||
_id = db.last_insert_id()
|
_id = db.last_insert_id()
|
||||||
|
|
||||||
syslog.sys_log(operator, handler.request.remote_ip, TPE_OK, "创建用户:{}".format(args['username']))
|
syslog.sys_log(operator, handler.request.remote_ip, TPE_OK, "创建用户:{}".format(user['username']))
|
||||||
|
|
||||||
# calc count of users.
|
# calc count of users.
|
||||||
err, cnt = s.reset().count('user')
|
err, cnt = s.reset().count('user')
|
||||||
|
@ -283,7 +367,7 @@ def update_user(handler, args):
|
||||||
|
|
||||||
# 1. 判断此账号是否已经存在
|
# 1. 判断此账号是否已经存在
|
||||||
sql = 'SELECT `username` FROM {dbtp}user WHERE `id`={dbph};'.format(dbtp=db.table_prefix, dbph=db.place_holder)
|
sql = 'SELECT `username` FROM {dbtp}user WHERE `id`={dbph};'.format(dbtp=db.table_prefix, dbph=db.place_holder)
|
||||||
db_ret = db.query(sql, (args['id'], ))
|
db_ret = db.query(sql, (args['id'],))
|
||||||
if db_ret is None or len(db_ret) == 0:
|
if db_ret is None or len(db_ret) == 0:
|
||||||
return TPE_NOT_EXISTS
|
return TPE_NOT_EXISTS
|
||||||
|
|
||||||
|
@ -295,9 +379,13 @@ def update_user(handler, args):
|
||||||
if db_ret is not None and len(db_ret) > 0:
|
if db_ret is not None and len(db_ret) > 0:
|
||||||
return TPE_EXISTS
|
return TPE_EXISTS
|
||||||
|
|
||||||
sql = 'UPDATE `{}user` SET `username`="{username}", `surname`="{surname}", `auth_type`={auth_type}, `role_id`={role}, `email`="{email}", `mobile`="{mobile}", `qq`="{qq}", `wechat`="{wechat}", `desc`="{desc}" WHERE `id`={user_id};' \
|
sql = 'UPDATE `{}user` SET ' \
|
||||||
|
'`username`="{username}", `surname`="{surname}", `auth_type`={auth_type}, ' \
|
||||||
|
'`role_id`={role}, `email`="{email}", `mobile`="{mobile}", `qq`="{qq}", ' \
|
||||||
|
'`wechat`="{wechat}", `desc`="{desc}" WHERE `id`={user_id};' \
|
||||||
''.format(db.table_prefix,
|
''.format(db.table_prefix,
|
||||||
username=args['username'], surname=args['surname'], auth_type=args['auth_type'], role=args['role'], email=args['email'],
|
username=args['username'], surname=args['surname'], auth_type=args['auth_type'], role=args['role'],
|
||||||
|
email=args['email'],
|
||||||
mobile=args['mobile'], qq=args['qq'], wechat=args['wechat'], desc=args['desc'],
|
mobile=args['mobile'], qq=args['qq'], wechat=args['wechat'], desc=args['desc'],
|
||||||
user_id=args['id']
|
user_id=args['id']
|
||||||
)
|
)
|
||||||
|
@ -308,17 +396,21 @@ def update_user(handler, args):
|
||||||
# 同步更新授权表和权限映射表
|
# 同步更新授权表和权限映射表
|
||||||
_uname = args['username']
|
_uname = args['username']
|
||||||
if len(args['surname']) > 0:
|
if len(args['surname']) > 0:
|
||||||
_uname += '('+args['surname']+')'
|
_uname += '(' + args['surname'] + ')'
|
||||||
sql_list = []
|
sql_list = []
|
||||||
# 运维授权
|
# 运维授权
|
||||||
sql = 'UPDATE `{}ops_auz` SET `name`="{uname}" WHERE (`rtype`={rtype} AND `rid`={rid});'.format(db.table_prefix, uname=_uname, rtype=TP_USER, rid=args['id'])
|
sql = 'UPDATE `{}ops_auz` SET `name`="{uname}" WHERE (`rtype`={rtype} AND `rid`={rid});' \
|
||||||
|
''.format(db.table_prefix, uname=_uname, rtype=TP_USER, rid=args['id'])
|
||||||
sql_list.append(sql)
|
sql_list.append(sql)
|
||||||
sql = 'UPDATE `{}ops_map` SET `u_name`="{uname}", `u_surname`="{surname}" WHERE (u_id={uid});'.format(db.table_prefix, uname=args['username'], surname=args['surname'], uid=args['id'])
|
sql = 'UPDATE `{}ops_map` SET `u_name`="{uname}", `u_surname`="{surname}" WHERE (u_id={uid});'.format(
|
||||||
|
db.table_prefix, uname=args['username'], surname=args['surname'], uid=args['id'])
|
||||||
sql_list.append(sql)
|
sql_list.append(sql)
|
||||||
# 审计授权
|
# 审计授权
|
||||||
sql = 'UPDATE `{}audit_auz` SET `name`="{uname}" WHERE (`rtype`={rtype} AND `rid`={rid});'.format(db.table_prefix, uname=_uname, rtype=TP_USER, rid=args['id'])
|
sql = 'UPDATE `{}audit_auz` SET `name`="{uname}" WHERE (`rtype`={rtype} AND `rid`={rid});' \
|
||||||
|
''.format(db.table_prefix, uname=_uname, rtype=TP_USER, rid=args['id'])
|
||||||
sql_list.append(sql)
|
sql_list.append(sql)
|
||||||
sql = 'UPDATE `{}audit_map` SET `u_name`="{uname}", `u_surname`="{surname}" WHERE (u_id={uid});'.format(db.table_prefix, uname=args['username'], surname=args['surname'], uid=args['id'])
|
sql = 'UPDATE `{}audit_map` SET `u_name`="{uname}", `u_surname`="{surname}" WHERE (u_id={uid});'.format(
|
||||||
|
db.table_prefix, uname=args['username'], surname=args['surname'], uid=args['id'])
|
||||||
sql_list.append(sql)
|
sql_list.append(sql)
|
||||||
|
|
||||||
if not db.transaction(sql_list):
|
if not db.transaction(sql_list):
|
||||||
|
@ -373,7 +465,8 @@ def set_password(handler, user_id, password):
|
||||||
return TPE_DATABASE
|
return TPE_DATABASE
|
||||||
|
|
||||||
if operator['id'] == 0:
|
if operator['id'] == 0:
|
||||||
syslog.sys_log({'username': name, 'surname': surname}, handler.request.remote_ip, TPE_OK, "用户 {} 通过邮件方式重置了密码".format(name))
|
syslog.sys_log({'username': name, 'surname': surname}, handler.request.remote_ip, TPE_OK,
|
||||||
|
"用户 {} 通过邮件方式重置了密码".format(name))
|
||||||
else:
|
else:
|
||||||
syslog.sys_log(operator, handler.request.remote_ip, TPE_OK, "为用户 {} 手动重置了密码".format(name))
|
syslog.sys_log(operator, handler.request.remote_ip, TPE_OK, "为用户 {} 手动重置了密码".format(name))
|
||||||
|
|
||||||
|
@ -434,7 +527,8 @@ def check_reset_token(token):
|
||||||
db.exec(sql, (_time_now - 3 * 24 * 60 * 60,))
|
db.exec(sql, (_time_now - 3 * 24 * 60 * 60,))
|
||||||
|
|
||||||
# 1. query user's id
|
# 1. query user's id
|
||||||
sql = 'SELECT user_id, create_time FROM `{dbtp}user_rpt` WHERE token={dbph};'.format(dbtp=db.table_prefix, dbph=db.place_holder)
|
sql = 'SELECT user_id, create_time FROM `{dbtp}user_rpt` WHERE token={dbph};'.format(dbtp=db.table_prefix,
|
||||||
|
dbph=db.place_holder)
|
||||||
db_ret = db.query(sql, (token,))
|
db_ret = db.query(sql, (token,))
|
||||||
if db_ret is None or len(db_ret) == 0:
|
if db_ret is None or len(db_ret) == 0:
|
||||||
return TPE_NOT_EXISTS, 0
|
return TPE_NOT_EXISTS, 0
|
||||||
|
@ -459,7 +553,9 @@ def update_login_info(handler, user_id):
|
||||||
db = get_db()
|
db = get_db()
|
||||||
_time_now = tp_timestamp_utc_now()
|
_time_now = tp_timestamp_utc_now()
|
||||||
|
|
||||||
sql = 'UPDATE `{}user` SET fail_count=0, last_login=login_time, last_ip=login_ip, login_time={login_time}, login_ip="{ip}" WHERE id={user_id};' \
|
sql = 'UPDATE `{}user` SET ' \
|
||||||
|
'fail_count=0, last_login=login_time, last_ip=login_ip, login_time={login_time},' \
|
||||||
|
' login_ip="{ip}" WHERE id={user_id};' \
|
||||||
''.format(db.table_prefix,
|
''.format(db.table_prefix,
|
||||||
login_time=_time_now, ip=handler.request.remote_ip, user_id=user_id
|
login_time=_time_now, ip=handler.request.remote_ip, user_id=user_id
|
||||||
)
|
)
|
||||||
|
@ -473,7 +569,8 @@ def update_oath_secret(handler, user_id, oath_secret):
|
||||||
db = get_db()
|
db = get_db()
|
||||||
|
|
||||||
s = SQL(db)
|
s = SQL(db)
|
||||||
err = s.select_from('user', ['username', 'surname'], alt_name='u').where('u.id={user_id}'.format(user_id=user_id)).query()
|
err = s.select_from('user', ['username', 'surname'], alt_name='u').where(
|
||||||
|
'u.id={user_id}'.format(user_id=user_id)).query()
|
||||||
if err != TPE_OK:
|
if err != TPE_OK:
|
||||||
return err
|
return err
|
||||||
if len(s.recorder) == 0:
|
if len(s.recorder) == 0:
|
||||||
|
@ -482,9 +579,11 @@ def update_oath_secret(handler, user_id, oath_secret):
|
||||||
username = s.recorder[0].username
|
username = s.recorder[0].username
|
||||||
surname = s.recorder[0].surname
|
surname = s.recorder[0].surname
|
||||||
|
|
||||||
sql = 'UPDATE `{dbtp}user` SET oath_secret="{secret}" WHERE id={user_id}'.format(dbtp=db.table_prefix, secret=oath_secret, user_id=user_id)
|
sql = 'UPDATE `{dbtp}user` SET oath_secret="{secret}" WHERE id={user_id}' \
|
||||||
|
''.format(dbtp=db.table_prefix, secret=oath_secret, user_id=user_id)
|
||||||
if db.exec(sql):
|
if db.exec(sql):
|
||||||
syslog.sys_log({'username': username, 'surname': surname}, handler.request.remote_ip, TPE_OK, "用户 {} 绑定了身份认证器".format(username))
|
syslog.sys_log({'username': username, 'surname': surname}, handler.request.remote_ip, TPE_OK,
|
||||||
|
"用户 {} 绑定了身份认证器".format(username))
|
||||||
return TPE_OK
|
return TPE_OK
|
||||||
else:
|
else:
|
||||||
return TPE_DATABASE
|
return TPE_DATABASE
|
||||||
|
@ -565,18 +664,21 @@ def remove_users(handler, users):
|
||||||
sql_list = []
|
sql_list = []
|
||||||
|
|
||||||
# 将用户从所在组中移除
|
# 将用户从所在组中移除
|
||||||
sql = 'DELETE FROM `{tpdp}group_map` WHERE type={t} AND mid IN ({ids});'.format(tpdp=db.table_prefix, t=TP_GROUP_USER, ids=str_users)
|
sql = 'DELETE FROM `{tpdp}group_map` WHERE type={t} AND mid IN ({ids});' \
|
||||||
|
''.format(tpdp=db.table_prefix, t=TP_GROUP_USER, ids=str_users)
|
||||||
sql_list.append(sql)
|
sql_list.append(sql)
|
||||||
# 删除用户
|
# 删除用户
|
||||||
sql = 'DELETE FROM `{tpdp}user` WHERE id IN ({ids});'.format(tpdp=db.table_prefix, ids=str_users)
|
sql = 'DELETE FROM `{tpdp}user` WHERE id IN ({ids});'.format(tpdp=db.table_prefix, ids=str_users)
|
||||||
sql_list.append(sql)
|
sql_list.append(sql)
|
||||||
# 将用户从运维授权中移除
|
# 将用户从运维授权中移除
|
||||||
sql = 'DELETE FROM `{}ops_auz` WHERE rtype={rtype} AND rid IN ({ids});'.format(db.table_prefix, rtype=TP_USER, ids=str_users)
|
sql = 'DELETE FROM `{}ops_auz` WHERE rtype={rtype} AND rid IN ({ids});' \
|
||||||
|
''.format(db.table_prefix, rtype=TP_USER, ids=str_users)
|
||||||
sql_list.append(sql)
|
sql_list.append(sql)
|
||||||
sql = 'DELETE FROM `{}ops_map` WHERE u_id IN ({ids});'.format(db.table_prefix, ids=str_users)
|
sql = 'DELETE FROM `{}ops_map` WHERE u_id IN ({ids});'.format(db.table_prefix, ids=str_users)
|
||||||
sql_list.append(sql)
|
sql_list.append(sql)
|
||||||
# 将用户从审计授权中移除
|
# 将用户从审计授权中移除
|
||||||
sql = 'DELETE FROM `{}audit_auz` WHERE rtype={rtype} AND rid IN ({ids});'.format(db.table_prefix, rtype=TP_USER, ids=str_users)
|
sql = 'DELETE FROM `{}audit_auz` WHERE rtype={rtype} AND rid IN ({ids});' \
|
||||||
|
''.format(db.table_prefix, rtype=TP_USER, ids=str_users)
|
||||||
sql_list.append(sql)
|
sql_list.append(sql)
|
||||||
sql = 'DELETE FROM `{}audit_map` WHERE u_id IN ({ids});'.format(db.table_prefix, ids=str_users)
|
sql = 'DELETE FROM `{}audit_map` WHERE u_id IN ({ids});'.format(db.table_prefix, ids=str_users)
|
||||||
sql_list.append(sql)
|
sql_list.append(sql)
|
||||||
|
|
Loading…
Reference in New Issue