pull/105/head
Apex Liu 2017-11-04 18:21:48 +08:00
parent f5392091f9
commit 37f8fc8b6f
7 changed files with 152 additions and 169 deletions

View File

@ -3,82 +3,14 @@
$app.on_init = function (cb_stack) {
console.log($app.options);
$app.dom = {
// 邮件系统设置
mail: {
smtp_server: $('#smtp-server-info'),
smtp_port: $('#smtp-port-info'),
smtp_ssl: $('#smtp-ssl-info'),
smtp_sender: $('#smtp-sender-info'),
btn_edit_mail_config: $('#btn-edit-mail-config'),
dlg_edit_mail_config: $('#dlg-edit-mail-config'),
edit_smtp_server: $('#edit-smtp-server'),
edit_smtp_port: $('#edit-smtp-port'),
edit_smtp_ssl: $('#edit-smtp-ssl'),
edit_smtp_sender: $('#edit-smtp-sender'),
edit_smtp_password: $('#edit-smtp-password'),
edit_smtp_test_recipient: $('#edit-smtp-test-recipient'),
btn_send_test_mail: $('#btn-send-test-mail'),
msg_send_test_mail: $('#msg-send-test-mail'),
btn_save_mail_config: $('#btn-save-mail-config')
}
};
$app.smtp = $app.create_config_smtp();
cb_stack.add($app.smtp.init);
//=========================================
// 邮件系统配置相关
//=========================================
// $app.update_mail_info = function (smtp) {
// if (0 === smtp.server.length) {
// var not_set = '<span class="error">未设置</span>';
// $app.dom.mail.smtp_server.html(not_set);
// $app.dom.mail.smtp_port.html(not_set);
// $app.dom.mail.smtp_ssl.html(not_set);
// $app.dom.mail.smtp_sender.html(not_set);
// } else {
// $app.dom.mail.smtp_server.html(smtp.server);
// $app.dom.mail.smtp_port.html(smtp.port);
// $app.dom.mail.smtp_sender.html(smtp.sender);
//
// if (smtp.ssl)
// $app.dom.mail.smtp_ssl.html('是');
// else
// $app.dom.mail.smtp_ssl.html('否');
// }
// };
//
// $app.update_mail_info($app.options.sys_cfg.smtp);
$app.smtp = $app.create_config_smtp();
cb_stack.add($app.smtp.init);
// $app.dom.mail.btn_edit_mail_config.click(function () {
// var smtp = $app.options.sys_cfg.smtp;
//
// $app.dom.mail.edit_smtp_server.val(smtp.server);
//
// $app.dom.mail.edit_smtp_port.val(smtp.port);
//
// if (!smtp.ssl)
// $app.dom.mail.edit_smtp_ssl.removeClass('tp-selected');
// else
// $app.dom.mail.edit_smtp_ssl.removeClass('tp-selected').addClass('tp-selected');
//
// $app.dom.mail.edit_smtp_sender.val(smtp.sender);
// $app.dom.mail.edit_smtp_password.val('');
//
// $app.dom.mail.dlg_edit_mail_config.modal();
// });
// $app.dom.mail.btn_edit_mail_config.trigger('click');
// $app.dom.mail.edit_smtp_ssl.click(function () {
// if ($app.dom.mail.edit_smtp_ssl.hasClass('tp-selected'))
// $app.dom.mail.edit_smtp_ssl.removeClass('tp-selected');
// else
// $app.dom.mail.edit_smtp_ssl.addClass('tp-selected');
// });
// $app.dom.mail.btn_send_test_mail.click($app._on_btn_send_test_mail);
// $app.dom.mail.btn_save_mail_config.click($app._on_btn_save_mail_config);
$app.sec = $app.create_config_sec();
cb_stack.add($app.sec.init);
cb_stack.exec();
};
@ -139,11 +71,6 @@ $app.create_config_smtp = function () {
_smtp.dom.port.html(smtp.port);
_smtp.dom.sender.html(smtp.sender);
_smtp.dom.ssl.html(smtp.ssl ? '是' : '否');
//
// if (smtp.ssl)
// _smtp.dom.ssl.html('是');
// else
// _smtp.dom.ssl.html('否');
}
};
@ -278,4 +205,75 @@ $app.create_config_smtp = function () {
return _smtp;
};
$app.create_config_sec = function () {
var _sec = {};
_sec.dom = {
btn_save: $('#btn-save-secure-config'),
btn_password_allow_reset: $('#sec-allow-reset-password'),
btn_password_force_strong: $('#sec-force-strong-password'),
input_password_timeout: $('#sec-password-timeout'),
input_session_timeout: $('#sec-session-timeout'),
input_login_retry: $('#sec-login-retry'),
input_lock_timeout: $('#sec-lock-timeout'),
btn_auth_username_password: $('#sec-auth-username-password'),
btn_auth_username_password_captcha: $('#sec-auth-username-password-captcha'),
btn_auth_username_oath: $('#sec-auth-username-oath'),
btn_auth_username_password_oath: $('#sec-auth-username-password-oath')
};
_sec.init = function (cb_stack) {
_sec.update_dom_password($app.options.sys_cfg.password);
_sec.update_dom_login($app.options.sys_cfg.login);
$('#tab-security').find('.tp-checkbox.tp-editable').click(function () {
if ($(this).hasClass('tp-selected'))
$(this).removeClass('tp-selected');
else
$(this).addClass('tp-selected');
});
_sec.dom.btn_save.click(function () {
_sec.on_btn_save();
});
cb_stack.exec();
};
_sec.update_dom_password = function (password) {
_sec.dom.btn_password_allow_reset.removeClass('tp-selected');
if (password.allow_reset)
_sec.dom.btn_password_allow_reset.addClass('tp-selected');
_sec.dom.btn_password_force_strong.removeClass('tp-selected');
if (password.force_strong)
_sec.dom.btn_password_force_strong.addClass('tp-selected');
_sec.dom.input_password_timeout.val(password.timeout);
};
_sec.update_dom_login = function (login) {
_sec.dom.input_session_timeout.val(login.session_timeout);
_sec.dom.input_login_retry.val(login.retry);
_sec.dom.input_lock_timeout.val(login.lock_timeout);
_sec.dom.btn_auth_username_password.removeClass('tp-selected');
if (login.auth & TP_LOGIN_AUTH_USERNAME_PASSWORD)
_sec.dom.btn_auth_username_password.addClass('tp-selected');
if (login.auth & TP_LOGIN_AUTH_USERNAME_PASSWORD_CAPTCHA)
_sec.dom.btn_auth_username_password_captcha.addClass('tp-selected');
if (login.auth & TP_LOGIN_AUTH_USERNAME_OATH)
_sec.dom.btn_auth_username_oath.addClass('tp-selected');
if (login.auth & TP_LOGIN_AUTH_USERNAME_PASSWORD_OATH)
_sec.dom.btn_auth_username_password_oath.addClass('tp-selected');
};
_sec.on_btn_save = function() {
var _password_allow_reset = _sec.dom.btn_password_allow_reset.hasClass('tp-selected');
};
return _sec;
};

View File

@ -18,7 +18,7 @@
<div class="box box-nav-tabs">
<ul class="nav nav-tabs">
<li class="active"><a href="#tab-security" data-toggle="tab">安全</a></li>
<li><a href="#tab-email" data-toggle="tab">邮件系统</a></li>
<li><a href="#tab-smtp" data-toggle="tab">邮件系统</a></li>
<li><a href="#tab-storage" data-toggle="tab">存储</a></li>
<li><a href="#tab-backup" data-toggle="tab">备份</a></li>
</ul>
@ -33,21 +33,21 @@
<tr>
<td class="key">找回密码</td>
<td class="value">
<div id="sec-allow-reset-password" class="tp-checkbox tp-editable tp-selected">允许用户找回密码</div>
<div id="sec-allow-reset-password" class="tp-checkbox tp-editable">允许用户找回密码</div>
<span class="desc">关闭此功能,只能由管理员为用户重置密码。默认开启。</span>
</td>
</tr>
<tr>
<td class="key">密码强度</td>
<td class="value">
<div id="sec-force-strong-password" class="tp-checkbox tp-editable tp-selected">强制使用强密码</div>
<div id="sec-force-strong-password" class="tp-checkbox tp-editable">强制使用强密码</div>
<span class="desc">至少8个英文字符必须包含大写字母、小写字母、数字和标点符号。默认开启。</span>
</td>
</tr>
<tr>
<td class="key">密码有效期</td>
<td class="value">
<input type="text" value="0"/><span class="unit">天</span><span class="desc">0~180。密码过期后用户将无法登录为0则密码永不过期。默认为0。</span>
<input id="sec-password-timeout" type="text" value="0"/><span class="unit">天</span><span class="desc">0~180。密码过期后用户将无法登录为0则密码永不过期。默认为0。</span>
</td>
</tr>
@ -60,19 +60,19 @@
<tr>
<td class="key">WEB会话超时</td>
<td class="value">
<input type="text" value="30"/><span class="unit">分钟</span><span class="desc">5~1440。超过设定时长无操作用户将被强制登出。默认为30分钟。</span>
<input id="sec-session-timeout" type="text" value="30"/><span class="unit">分钟</span><span class="desc">5~1440。超过设定时长无操作用户将被强制登出。默认为30分钟。</span>
</td>
</tr>
<tr>
<td class="key">密码尝试次数</td>
<td class="value">
<input type="text" value="0"/><span class="unit">次</span><span class="desc">0~10。密码连续错误超过设定次数用户将被临时锁定为0则不限制。默认为0。</span>
<input id="sec-login-retry" type="text" value="0"/><span class="unit">次</span><span class="desc">0~10。密码连续错误超过设定次数用户将被临时锁定为0则不限制。默认为0。</span>
</td>
</tr>
<tr>
<td class="key">临时锁定时长</td>
<td class="value">
<input type="text" value="30"/><span class="unit">分钟</span><span class="desc">0~9999。用户被临时锁定的持续时间为0则持续到由管理员解锁。默认为30分钟。</span>
<input id="sec-lock-timeout" type="text" value="30"/><span class="unit">分钟</span><span class="desc">0~9999。用户被临时锁定的持续时间为0则持续到由管理员解锁。默认为30分钟。</span>
</td>
</tr>
<tr>
@ -84,19 +84,25 @@
<tr>
<td class="key"></td>
<td class="value">
<div id="sec-allow-reset-password" class="tp-checkbox tp-editable tp-selected">用户名 + 密码</div>
<div id="sec-auth-username-password" class="tp-checkbox tp-editable">用户名 + 密码</div>
</td>
</tr>
<tr>
<td class="key"></td>
<td class="value">
<div id="sec-allow-reset-password" class="tp-checkbox tp-editable tp-selected">用户名 + 密码 + 验证码</div>
<div id="sec-auth-username-password-captcha" class="tp-checkbox tp-editable">用户名 + 密码 + 验证码</div>
</td>
</tr>
<tr>
<td class="key"></td>
<td class="value">
<div id="sec-allow-reset-password" class="tp-checkbox tp-editable tp-selected">用户名 + 密码 + 身份认证器动态密码</div>
<div id="sec-auth-username-oath" class="tp-checkbox tp-editable">用户名 + 身份认证器动态密码</div>
</td>
</tr>
<tr>
<td class="key"></td>
<td class="value">
<div id="sec-auth-username-password-oath" class="tp-checkbox tp-editable">用户名 + 密码 + 身份认证器动态密码</div>
</td>
</tr>
</table>
@ -106,7 +112,7 @@
</div>
<!-- panel for mail config -->
<div class="tab-pane" id="tab-email">
<div class="tab-pane" id="tab-smtp">
<table class="table table-info-list">
<tr>
<td class="key">SMTP服务器</td>

View File

@ -468,12 +468,12 @@ class AppConfig(BaseAppConfig):
_password = {}
self.sys.password = tp_convert_to_attr_dict(_password)
if not self.sys.password.is_exists('find'):
self.sys.password.find = True
if not self.sys.password.is_exists('strong'):
self.sys.password.strong = True
if not self.sys.password.is_exists('allow_reset'):
self.sys.password.allow_reset = True
if not self.sys.password.is_exists('force_strong'):
self.sys.password.force_strong = True
if not self.sys.password.is_exists('timeout'):
self.sys.password.timeout = 30
self.sys.password.timeout = 0
# =====================================
# 登录相关
@ -492,7 +492,7 @@ class AppConfig(BaseAppConfig):
if not self.sys.login.is_exists('lock_timeout'):
self.sys.login.lock_timeout = 30 # 30 min
if not self.sys.login.is_exists('auth'):
self.sys.login.auth = TP_LOGIN_AUTH_USERNAME_PASSWORD | TP_LOGIN_AUTH_USERNAME_PASSWORD_CAPTCHA | TP_LOGIN_AUTH_USERNAME_OATH
self.sys.login.auth = TP_LOGIN_AUTH_USERNAME_PASSWORD | TP_LOGIN_AUTH_USERNAME_PASSWORD_CAPTCHA | TP_LOGIN_AUTH_USERNAME_OATH | TP_LOGIN_AUTH_USERNAME_PASSWORD_OATH
# print('==login==', json.dumps(self.sys.login, separators=(',', ':')))
# =====================================

View File

@ -704,16 +704,16 @@ class DatabaseInit:
'INSERT INTO `{}config` (`name`, `value`) VALUES ("db_ver", "{}");'.format(self.db.table_prefix, self.db.DB_VERSION)
)
self._db_exec(
'设置初始化配置',
[
'INSERT INTO `{}config` (`name`, `value`) VALUES ("smtp_server", "");'.format(self.db.table_prefix),
'INSERT INTO `{}config` (`name`, `value`) VALUES ("smtp_port", "-1");'.format(self.db.table_prefix),
'INSERT INTO `{}config` (`name`, `value`) VALUES ("smtp_ssl", "-1");'.format(self.db.table_prefix),
'INSERT INTO `{}config` (`name`, `value`) VALUES ("smtp_sender", "");'.format(self.db.table_prefix),
'INSERT INTO `{}config` (`name`, `value`) VALUES ("smtp_password", "");'.format(self.db.table_prefix),
]
)
# self._db_exec(
# '设置初始化配置',
# [
# 'INSERT INTO `{}config` (`name`, `value`) VALUES ("smtp_server", "");'.format(self.db.table_prefix),
# 'INSERT INTO `{}config` (`name`, `value`) VALUES ("smtp_port", "-1");'.format(self.db.table_prefix),
# 'INSERT INTO `{}config` (`name`, `value`) VALUES ("smtp_ssl", "-1");'.format(self.db.table_prefix),
# 'INSERT INTO `{}config` (`name`, `value`) VALUES ("smtp_sender", "");'.format(self.db.table_prefix),
# 'INSERT INTO `{}config` (`name`, `value`) VALUES ("smtp_password", "");'.format(self.db.table_prefix),
# ]
# )
privilege_admin = TP_PRIVILEGE_ALL
privilege_ops = TP_PRIVILEGE_LOGIN_WEB | TP_PRIVILEGE_OPS

View File

@ -46,6 +46,7 @@ class TPDatabase:
self.current_ver = 0
self.auto_increment = ''
self.place_holder = ''
self._table_prefix = ''
self._conn_pool = None
@ -109,6 +110,7 @@ class TPDatabase:
def _init_sqlite(self, db_file):
self.db_type = self.DB_TYPE_SQLITE
self.auto_increment = 'AUTOINCREMENT'
self.place_holder = '?'
self.sqlite_file = db_file
self._table_prefix = 'tp_'
@ -124,6 +126,7 @@ class TPDatabase:
def _init_mysql(self, mysql_host, mysql_port, mysql_db, mysql_prefix, mysql_user, mysql_password):
self.db_type = self.DB_TYPE_MYSQL
self.auto_increment = 'AUTO_INCREMENT'
self.place_holder = '%s'
self._table_prefix = mysql_prefix
self.mysql_host = mysql_host
@ -196,10 +199,11 @@ class TPDatabase:
# log.d('[db] cost {} seconds.\n'.format(_end - _start))
return ret
def exec(self, sql):
log.d('[db] {}\n'.format(sql))
def exec(self, sql, args=()):
# log.d('[db] {}\n'.format(sql, args))
print('[db]', sql, args)
# _start = datetime.datetime.utcnow().timestamp()
ret = self._conn_pool.exec(sql)
ret = self._conn_pool.exec(sql, args)
# _end = datetime.datetime.utcnow().timestamp()
# log.d('[db] cost {} seconds.\n'.format(_end - _start))
return ret
@ -327,11 +331,11 @@ class TPDatabasePool:
return None
return self._do_query(_conn, sql)
def exec(self, sql):
def exec(self, sql, args):
_conn = self._get_connect()
if _conn is None:
return False
return self._do_exec(_conn, sql)
return self._do_exec(_conn, sql, args)
def transaction(self, sql_list):
_conn = self._get_connect()
@ -363,7 +367,7 @@ class TPDatabasePool:
def _do_query(self, conn, sql):
return None
def _do_exec(self, conn, sql):
def _do_exec(self, conn, sql, args):
return None
def _do_transaction(self, conn, sql_list):
@ -401,10 +405,10 @@ class TPSqlitePool(TPDatabasePool):
finally:
cursor.close()
def _do_exec(self, conn, sql):
def _do_exec(self, conn, sql, args):
try:
with conn:
conn.execute(sql)
conn.execute(sql, args)
return True
except Exception as e:
log.e('[sqlite] _do_exec() failed: {}\n'.format(e.__str__()))

View File

@ -75,7 +75,7 @@ class DoRoleUpdateHandler(TPBaseJsonHandler):
return self.write_json(TPE_PARAM)
if role_id == 0:
err, role_id = system_model.add_role(self, role_id, role_name, privilege)
err, role_id = system_model.add_role(self, role_name, privilege)
else:
if role_id == 1:
return self.write_json(TPE_FAILED, '禁止修改系统管理员角色!')
@ -246,8 +246,8 @@ class DoSaveCfgSmtpHandler(TPBaseJsonHandler):
return self.write_json(TPE_PARAM)
# 调用Model模块来操作数据库
code, msg = system_model.save_mail_config(_server, _port, _ssl, _sender, _password)
if code == TPE_OK:
err = system_model.save_smtp_config(self, _server, _port, _ssl, _sender, _password)
if err == TPE_OK:
# 同时更新内存缓存
get_cfg().sys.smtp.server = _server
get_cfg().sys.smtp.port = _port
@ -255,4 +255,4 @@ class DoSaveCfgSmtpHandler(TPBaseJsonHandler):
get_cfg().sys.smtp.sender = _sender
get_cfg().sys_smtp_password = _password
self.write_json(code, message=msg)
self.write_json(err)

View File

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
import json
from app.const import *
from app.base.db import get_db, SQL
from app.base.logger import log
@ -7,26 +8,38 @@ from app.base.utils import tp_timestamp_utc_now
from . import syslog
def save_mail_config(_server, _port, _ssl, _sender, _password):
log.v('save mail config.\n')
def save_smtp_config(handler, _server, _port, _ssl, _sender, _password):
db = get_db()
sql_list = list()
sql_list.append('UPDATE `{}config` SET `value`="{}" WHERE `name`="smtp_server";'.format(db.table_prefix, _server))
sql_list.append('UPDATE `{}config` SET `value`="{}" WHERE `name`="smtp_port";'.format(db.table_prefix, _port))
sql_list.append('UPDATE `{}config` SET `value`="{}" WHERE `name`="smtp_ssl";'.format(db.table_prefix, _ssl))
sql_list.append('UPDATE `{}config` SET `value`="{}" WHERE `name`="smtp_sender";'.format(db.table_prefix, _sender))
sql_list.append('UPDATE `{}config` SET `value`="{}" WHERE `name`="smtp_password";'.format(db.table_prefix, _password))
_smtp = {
'server': _server,
'port': _port,
'ssl': _ssl,
'sender': _sender,
'password': _password
}
ret = db.transaction(sql_list)
if ret:
return TPE_OK, ''
str_smtp = json.dumps(_smtp, separators=(',', ':'))
return TPE_FAILED, '数据库操作失败'
sql = 'SELECT name FROM `{dbtp}config` WHERE name="smtp";'.format(dbtp=db.table_prefix)
db_ret = db.query(sql)
if db_ret is not None and len(db_ret) > 0:
sql = 'UPDATE `{dbtp}config` SET value={dbph} WHERE name="smtp";'.format(dbtp=db.table_prefix, dbph=db.place_holder)
db_ret = db.exec(sql, (str_smtp,))
else:
sql = 'INSERT INTO `{dbtp}config` (name, value) VALUES ("smtp", {dbph});'.format(dbtp=db.table_prefix, dbph=db.place_holder)
db_ret = db.exec(sql, (str_smtp,))
if not db_ret:
return TPE_DATABASE
operator = handler.get_current_user()
syslog.sys_log(operator, handler.request.remote_ip, TPE_OK, "更新SMTP设置")
return TPE_OK
def add_role(handler, role_id, role_name, privilege):
def add_role(handler, role_name, privilege):
db = get_db()
_time_now = tp_timestamp_utc_now()
operator = handler.get_current_user()
@ -39,8 +52,7 @@ def add_role(handler, role_id, role_name, privilege):
sql = 'INSERT INTO `{}role` (name, privilege, creator_id, create_time) VALUES ' \
'("{name}", {privilege}, {creator_id}, {create_time});' \
''.format(db.table_prefix,
name=role_name, privilege=privilege, creator_id=operator['id'], create_time=_time_now)
''.format(db.table_prefix, name=role_name, privilege=privilege, creator_id=operator['id'], create_time=_time_now)
db_ret = db.exec(sql)
if not db_ret:
return TPE_DATABASE, 0
@ -104,40 +116,3 @@ def remove_role(handler, role_id):
syslog.sys_log(handler.get_current_user(), handler.request.remote_ip, TPE_OK, "删除角色:{}".format(role_name))
return TPE_OK
# def get_config_list():
# try:
# from eom_app.module.common import get_db_con
# from eom_app.module.common import DbItem
# sql_exec = get_db_con()
# field_a = ['name', 'value']
# string_sql = 'SELECT {} FROM ts_config as a ;'.format(','.join(['a.{}'.format(i) for i in field_a]))
# db_ret = sql_exec.ExecProcQuery(string_sql)
# h = dict()
# for item in db_ret:
# x = DbItem()
# x.load(item, ['a_{}'.format(i) for i in field_a])
# h[x.a_name] = x.a_value
#
# return h
# except Exception as e:
# return None
#
#
# def set_config(change_list):
# from eom_app.module.common import get_db_con
# sql_exec = get_db_con()
# #
# for item in change_list:
# name = item['name']
# value = item['value']
# str_sql = 'UPDATE ts_config SET value = \'{}\' ' \
# ' WHERE name = \'{}\''.format(value, name)
# ret = sql_exec.ExecProcNonQuery(str_sql)
#
# return ret
#
# def get_config_list():
# print(cfg.base)
# return cfg.base