mirror of https://github.com/tp4a/teleport
..try fix: password expired.
parent
1f248351cd
commit
84aab7b0af
|
@ -157,7 +157,7 @@ $app.login_account = function () {
|
||||||
}
|
}
|
||||||
} else if ($app.login_type === TP_LOGIN_AUTH_USERNAME_PASSWORD_OATH) {
|
} else if ($app.login_type === TP_LOGIN_AUTH_USERNAME_PASSWORD_OATH) {
|
||||||
var test_oath = '' + parseInt(str_oath);
|
var test_oath = '' + parseInt(str_oath);
|
||||||
if(str_oath.length === 6) {
|
if (str_oath.length === 6) {
|
||||||
for (; ;) {
|
for (; ;) {
|
||||||
if (test_oath.length < 6)
|
if (test_oath.length < 6)
|
||||||
test_oath = '0' + test_oath;
|
test_oath = '0' + test_oath;
|
||||||
|
@ -216,8 +216,14 @@ $app.do_account_login = function (username, password, captcha, oath, is_remember
|
||||||
window.location.href = $app.options.ref;
|
window.location.href = $app.options.ref;
|
||||||
} else {
|
} else {
|
||||||
$app.hide_op_box();
|
$app.hide_op_box();
|
||||||
$app.show_op_box('error', '登录失败:' + tp_error_msg(ret.code, ret.message));
|
|
||||||
$app.dom.captcha_image.attr('src', '/auth/captcha?h=36&rnd=' + Math.random());
|
$app.dom.captcha_image.attr('src', '/auth/captcha?h=36&rnd=' + Math.random());
|
||||||
|
|
||||||
|
if (ret.code === TPE_EXPIRED) {
|
||||||
|
// must change password before login.
|
||||||
|
window.location.href = '/user/change-expired-password?username=' + username;
|
||||||
|
}
|
||||||
|
|
||||||
|
$app.show_op_box('error', '登录失败:' + tp_error_msg(ret.code, ret.message));
|
||||||
console.log(ret);
|
console.log(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -285,6 +285,9 @@ function tp_error_msg(error_code, message) {
|
||||||
case TPE_DATABASE:
|
case TPE_DATABASE:
|
||||||
msg = '数据库操作失败';
|
msg = '数据库操作失败';
|
||||||
break;
|
break;
|
||||||
|
case TPE_EXPIRED:
|
||||||
|
msg = '已过期';
|
||||||
|
break;
|
||||||
|
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
// HTTP请求相关错误
|
// HTTP请求相关错误
|
||||||
|
@ -329,7 +332,7 @@ function tp_error_msg(error_code, message) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TPE_OATH_ALREADY_BIND:
|
case TPE_OATH_ALREADY_BIND:
|
||||||
msg = '该账号已经绑定了身份验证器,如无法使用,请联系管理员重置密码或更换登陆方式';
|
msg = '该账号已经绑定了身份验证器,如无法使用,请联系管理员重置密码或更换登录方式';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TPE_USER_LOCKED:
|
case TPE_USER_LOCKED:
|
||||||
|
|
|
@ -262,138 +262,3 @@ $app.on_save = function () {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// $app.on_send_find_password_email = function () {
|
|
||||||
// $app.hide_op_box();
|
|
||||||
// var str_username = $app.dom.find.input_username.val();
|
|
||||||
// var str_email = $app.dom.find.input_email.val();
|
|
||||||
// var str_captcha = $app.dom.find.input_captcha.val();
|
|
||||||
//
|
|
||||||
// if (str_username.length === 0) {
|
|
||||||
// $app.show_op_box('error', '账号未填写!');
|
|
||||||
// $app.dom.find.input_username.attr('data-content', "请填写您的账号!").focus().popover('show');
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (str_email.length === 0) {
|
|
||||||
// $app.show_op_box('error', '电子邮件地址未填写!');
|
|
||||||
// $app.dom.find.input_email.attr('data-content', "请填写您的电子邮件地址!").focus().popover('show');
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (!tp_is_email(str_email)) {
|
|
||||||
// $app.show_op_box('error', '无效的电子邮件地址!');
|
|
||||||
// $app.dom.find.input_email.attr('data-content', "请检查输入的电子邮件地址!").focus().popover('show');
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (str_captcha.length !== 4) {
|
|
||||||
// $app.show_op_box('error', '验证码错误!');
|
|
||||||
// $app.dom.find.input_captcha.attr('data-content', "验证码为4位数字和字母的组合,请重新填写!").focus().select().popover('show');
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// $app.dom.find.btn_submit.attr('disabled', 'disabled');
|
|
||||||
// $tp.ajax_post_json('/auth/verify-captcha', {captcha: str_captcha},
|
|
||||||
// function (ret) {
|
|
||||||
// if (ret.code === TPE_OK) {
|
|
||||||
// // 验证成功
|
|
||||||
// $app.hide_op_box();
|
|
||||||
// $app.show_op_box('wait', '<i class="fa fa-circle-o-notch fa-spin"></i> 正在发送密码重置确认函,请稍候...');
|
|
||||||
// $app.do_send_reset_email(str_username, str_email, str_captcha);
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// $app.dom.find.btn_submit.removeAttr('disabled');
|
|
||||||
// $app.hide_op_box();
|
|
||||||
// $app.show_op_box('error', tp_error_msg(ret.code, ret.message));
|
|
||||||
// $app.dom.captcha_image.attr('src', '/auth/captcha?h=28&rnd=' + Math.random());
|
|
||||||
// $app.dom.input_captcha.focus().select().val('');
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// function () {
|
|
||||||
// $app.hide_op_box();
|
|
||||||
// $app.show_op_box('error', '很抱歉,无法连接服务器!请稍后再试一次!');
|
|
||||||
// $app.dom.find.btn_submit.removeAttr('disabled');
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// $app.do_send_reset_email = function (str_username, str_email, str_captcha) {
|
|
||||||
// $tp.ajax_post_json('/user/do-reset-password', {
|
|
||||||
// mode: 3,
|
|
||||||
// username: str_username,
|
|
||||||
// email: str_email,
|
|
||||||
// captcha: str_captcha
|
|
||||||
// },
|
|
||||||
// function (ret) {
|
|
||||||
// if (ret.code === TPE_OK) {
|
|
||||||
// $app.dom.find.btn_submit.slideUp('fast');
|
|
||||||
// $app.show_op_box('success', '密码重置确认函已发送,请注意查收!');
|
|
||||||
// } else {
|
|
||||||
// $app.dom.find.btn_submit.removeAttr('disabled');
|
|
||||||
// $app.hide_op_box();
|
|
||||||
// var msg = '';
|
|
||||||
// if (ret.code === TPE_NOT_EXISTS)
|
|
||||||
// msg = tp_error_msg(ret.code, '用户不存在,请检查输入的用户和电子邮件地址是否匹配!');
|
|
||||||
// else
|
|
||||||
// msg = tp_error_msg(ret.code, ret.message);
|
|
||||||
// $app.show_op_box('error', msg);
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// function () {
|
|
||||||
// $app.dom.find.btn_submit.removeAttr('disabled');
|
|
||||||
// $app.hide_op_box();
|
|
||||||
// $app.show_op_box('error', '网络故障,密码重置确认函发送失败!');
|
|
||||||
// },
|
|
||||||
// 15000
|
|
||||||
// );
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// $app.on_set_new_password = function () {
|
|
||||||
// $app.hide_op_box();
|
|
||||||
// var str_password = $app.dom.set_password.input_password.val();
|
|
||||||
//
|
|
||||||
// if (str_password.length === 0) {
|
|
||||||
// $app.show_op_box('error', '密码未填写!');
|
|
||||||
// $app.dom.set_password.input_password.attr('data-content', "请设置您的新密码!").focus().popover('show');
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if ($app.options.force_strong) {
|
|
||||||
// if (!tp_check_strong_password(str_password)) {
|
|
||||||
// $app.show_op_box('error', tp_error_msg(TPE_FAILED, '抱歉,不能使用弱密码!'));
|
|
||||||
// $app.dom.set_password.input_password.attr('data-content', "请设置强密码:至少8位,必须包含大写字母、小写字母以及数字!").focus().popover('show');
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// $tp.ajax_post_json('/user/do-reset-password', {
|
|
||||||
// mode: 4,
|
|
||||||
// token: $app.options.token,
|
|
||||||
// password: str_password
|
|
||||||
// },
|
|
||||||
// function (ret) {
|
|
||||||
// $app.dom.find.btn_submit.removeAttr('disabled');
|
|
||||||
// if (ret.code === TPE_OK) {
|
|
||||||
// $app.show_op_box('success', '密码已重置,正在转到登录界面!');
|
|
||||||
// setTimeout(function () {
|
|
||||||
// window.location.href = '/';
|
|
||||||
// }, 2000);
|
|
||||||
// } else {
|
|
||||||
// var msg = '';
|
|
||||||
// if (ret.code === TPE_NOT_EXISTS)
|
|
||||||
// msg = tp_error_msg(ret.code, '无效的密码重置链接!');
|
|
||||||
// else
|
|
||||||
// msg = tp_error_msg(ret.code, ret.message);
|
|
||||||
// $app.show_op_box('error', msg);
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// function () {
|
|
||||||
// $app.dom.find.btn_submit.removeAttr('disabled');
|
|
||||||
// $app.hide_op_box();
|
|
||||||
// $app.show_op_box('error', '网络故障,密码重置失败!');
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
// };
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,238 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
$app.on_init = function (cb_stack) {
|
||||||
|
$app.dom = {
|
||||||
|
title: $('#title'),
|
||||||
|
icon_bg: $('#icon-bg'),
|
||||||
|
|
||||||
|
op_message: $('#message'),
|
||||||
|
|
||||||
|
error: {
|
||||||
|
area: $('#area-error'),
|
||||||
|
message: $('#area-error [data-field="message"]')
|
||||||
|
},
|
||||||
|
|
||||||
|
txt_username: $('#txt-username'),
|
||||||
|
txt_password: $('#txt-password'),
|
||||||
|
txt_new_password: $('#txt-new-password'),
|
||||||
|
btn_switch_password: $('#btn-switch-password'),
|
||||||
|
icon_switch_password: $('#icon-switch-password'),
|
||||||
|
txt_captcha: $('#txt-captcha'),
|
||||||
|
img_captcha: $('#img-captcha'),
|
||||||
|
btn_submit: $('#btn-submit'),
|
||||||
|
|
||||||
|
info: $('#info'),
|
||||||
|
|
||||||
|
find: {
|
||||||
|
area: $('#area-find-password'),
|
||||||
|
input_email: $('#area-find-password [data-field="input-email"]'),
|
||||||
|
input_captcha: $('#area-find-password [data-field="input-captcha"]'),
|
||||||
|
btn_submit: $('#area-find-password [data-field="btn-submit"]'),
|
||||||
|
message: $('#area-find-password [data-field="message"]')
|
||||||
|
},
|
||||||
|
|
||||||
|
set_password: {
|
||||||
|
area: $('#area-set-password'),
|
||||||
|
info: $('#area-set-password [data-field="info"]'),
|
||||||
|
input_password: $('#area-set-password [data-field="input-password"]'),
|
||||||
|
btn_switch_password: $('#area-set-password [data-field="btn-switch-password"]'),
|
||||||
|
btn_switch_password_icon: $('#area-set-password [data-field="btn-switch-password"] i'),
|
||||||
|
message: $('#area-set-password [data-field="message"]')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.dom.img_captcha.attr('src', '/auth/captcha?h=28&rnd=' + Math.random());
|
||||||
|
$app.dom.txt_password.focus();
|
||||||
|
$app.dom.txt_username.val($app.options.username);
|
||||||
|
if ($app.options.force_strong)
|
||||||
|
$app.dom.info.show();
|
||||||
|
|
||||||
|
$app.dom.img_captcha.click(function () {
|
||||||
|
$(this).attr('src', '/auth/captcha?h=28&rnd=' + Math.random());
|
||||||
|
$app.dom.txt_captcha.focus().val('');
|
||||||
|
});
|
||||||
|
|
||||||
|
$app.dom.btn_submit.click(function () {
|
||||||
|
$app.on_change_password();
|
||||||
|
});
|
||||||
|
|
||||||
|
$app.dom.txt_password.keydown(function (event) {
|
||||||
|
if (event.which === 13) {
|
||||||
|
$app.dom.txt_new_password.focus();
|
||||||
|
} else {
|
||||||
|
$app.hide_op_box();
|
||||||
|
$('[data-toggle="popover"]').popover('hide');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$app.dom.txt_new_password.keydown(function (event) {
|
||||||
|
if (event.which === 13) {
|
||||||
|
$app.dom.txt_captcha.focus();
|
||||||
|
} else {
|
||||||
|
$app.hide_op_box();
|
||||||
|
$('[data-toggle="popover"]').popover('hide');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$app.dom.txt_captcha.keydown(function (event) {
|
||||||
|
if (event.which === 13) {
|
||||||
|
$app.on_change_password();
|
||||||
|
} else {
|
||||||
|
$app.hide_op_box();
|
||||||
|
$('[data-toggle="popover"]').popover('hide');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$app.dom.btn_switch_password.click(function () {
|
||||||
|
if ('password' === $app.dom.txt_new_password.attr('type')) {
|
||||||
|
$app.dom.txt_new_password.attr('type', 'text');
|
||||||
|
$app.dom.icon_switch_password.removeClass('fa-eye').addClass('fa-eye-slash')
|
||||||
|
} else {
|
||||||
|
$app.dom.txt_new_password.attr('type', 'password');
|
||||||
|
$app.dom.icon_switch_password.removeClass('fa-eye-slash').addClass('fa-eye')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cb_stack.exec();
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.hide_op_box = function () {
|
||||||
|
$app.dom.op_message.hide();
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.show_op_box = function (op_type, op_msg) {
|
||||||
|
$app.dom.op_message.html(op_msg);
|
||||||
|
$app.dom.op_message.removeClass().addClass('op_box op_' + op_type);
|
||||||
|
$app.dom.op_message.show();
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.on_send_find_password_email = function () {
|
||||||
|
$app.hide_op_box();
|
||||||
|
var str_username = $app.dom.find.input_username.val();
|
||||||
|
var str_email = $app.dom.find.input_email.val();
|
||||||
|
var str_captcha = $app.dom.find.input_captcha.val();
|
||||||
|
|
||||||
|
if (str_username.length === 0) {
|
||||||
|
$app.show_op_box('error', '用户名未填写!');
|
||||||
|
$app.dom.find.input_username.attr('data-content', "请填写您的用户名!").focus().popover('show');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str_email.length === 0) {
|
||||||
|
$app.show_op_box('error', '电子邮件地址未填写!');
|
||||||
|
$app.dom.find.input_email.attr('data-content', "请填写您的电子邮件地址!").focus().popover('show');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tp_is_email(str_email)) {
|
||||||
|
$app.show_op_box('error', '无效的电子邮件地址!');
|
||||||
|
$app.dom.find.input_email.attr('data-content', "请检查输入的电子邮件地址!").focus().popover('show');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str_captcha.length !== 4) {
|
||||||
|
$app.show_op_box('error', '验证码错误!');
|
||||||
|
$app.dom.find.input_captcha.attr('data-content', "验证码为4位数字和字母的组合,请重新填写!").focus().select().popover('show');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$app.dom.find.btn_submit.attr('disabled', 'disabled');
|
||||||
|
$tp.ajax_post_json('/auth/verify-captcha', {captcha: str_captcha},
|
||||||
|
function (ret) {
|
||||||
|
if (ret.code === TPE_OK) {
|
||||||
|
// 验证成功
|
||||||
|
$app.hide_op_box();
|
||||||
|
$app.show_op_box('wait', '<i class="fa fa-circle-o-notch fa-spin"></i> 正在发送密码重置确认函,请稍候...');
|
||||||
|
$app.do_send_reset_email(str_username, str_email, str_captcha);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$app.dom.find.btn_submit.removeAttr('disabled');
|
||||||
|
$app.hide_op_box();
|
||||||
|
$app.show_op_box('error', tp_error_msg(ret.code, ret.message));
|
||||||
|
$app.dom.captcha_image.attr('src', '/auth/captcha?h=28&rnd=' + Math.random());
|
||||||
|
$app.dom.input_captcha.focus().select().val('');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
$app.hide_op_box();
|
||||||
|
$app.show_op_box('error', '很抱歉,无法连接服务器!请稍后再试一次!');
|
||||||
|
$app.dom.find.btn_submit.removeAttr('disabled');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.do_send_reset_email = function (str_username, str_email, str_captcha) {
|
||||||
|
$tp.ajax_post_json('/user/do-reset-password', {
|
||||||
|
mode: 3,
|
||||||
|
username: str_username,
|
||||||
|
email: str_email,
|
||||||
|
captcha: str_captcha
|
||||||
|
},
|
||||||
|
function (ret) {
|
||||||
|
if (ret.code === TPE_OK) {
|
||||||
|
$app.dom.find.btn_submit.slideUp('fast');
|
||||||
|
$app.show_op_box('success', '密码重置确认函已发送,请注意查收!');
|
||||||
|
} else {
|
||||||
|
$app.dom.find.btn_submit.removeAttr('disabled');
|
||||||
|
$app.hide_op_box();
|
||||||
|
var msg = '';
|
||||||
|
if (ret.code === TPE_NOT_EXISTS)
|
||||||
|
msg = tp_error_msg(ret.code, '用户不存在,请检查输入的用户和电子邮件地址是否匹配!');
|
||||||
|
else
|
||||||
|
msg = tp_error_msg(ret.code, ret.message);
|
||||||
|
$app.show_op_box('error', msg);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
$app.dom.find.btn_submit.removeAttr('disabled');
|
||||||
|
$app.hide_op_box();
|
||||||
|
$app.show_op_box('error', '网络故障,密码重置确认函发送失败!');
|
||||||
|
},
|
||||||
|
15000
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.on_set_new_password = function () {
|
||||||
|
$app.hide_op_box();
|
||||||
|
var str_password = $app.dom.set_password.input_password.val();
|
||||||
|
|
||||||
|
if (str_password.length === 0) {
|
||||||
|
$app.show_op_box('error', '密码未填写!');
|
||||||
|
$app.dom.set_password.input_password.attr('data-content', "请设置您的新密码!").focus().popover('show');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($app.options.force_strong) {
|
||||||
|
if (!tp_check_strong_password(str_password)) {
|
||||||
|
$app.show_op_box('error', tp_error_msg(TPE_FAILED, '抱歉,不能使用弱密码!'));
|
||||||
|
$app.dom.set_password.input_password.attr('data-content', "请设置强密码:至少8位,必须包含大写字母、小写字母以及数字!").focus().popover('show');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$tp.ajax_post_json('/user/do-reset-password', {
|
||||||
|
mode: 4,
|
||||||
|
token: $app.options.token,
|
||||||
|
password: str_password
|
||||||
|
},
|
||||||
|
function (ret) {
|
||||||
|
$app.dom.find.btn_submit.removeAttr('disabled');
|
||||||
|
if (ret.code === TPE_OK) {
|
||||||
|
$app.show_op_box('success', '密码已重置,正在转到登录界面!');
|
||||||
|
setTimeout(function () {
|
||||||
|
window.location.href = '/';
|
||||||
|
}, 2000);
|
||||||
|
} else {
|
||||||
|
var msg = '';
|
||||||
|
if (ret.code === TPE_NOT_EXISTS)
|
||||||
|
msg = tp_error_msg(ret.code, '无效的密码重置链接!');
|
||||||
|
else
|
||||||
|
msg = tp_error_msg(ret.code, ret.message);
|
||||||
|
$app.show_op_box('error', msg);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
$app.dom.find.btn_submit.removeAttr('disabled');
|
||||||
|
$app.hide_op_box();
|
||||||
|
$app.show_op_box('error', '网络故障,密码重置失败!');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,100 @@
|
||||||
|
<%!
|
||||||
|
page_title_ = '修改过期密码'
|
||||||
|
%>
|
||||||
|
<%inherit file="../page_single_base.mako"/>
|
||||||
|
|
||||||
|
<%block name="extend_js_file">
|
||||||
|
<script type="text/javascript" src="${ static_url('js/user/change-expired-password.js') }"></script>
|
||||||
|
</%block>
|
||||||
|
|
||||||
|
<%block name="embed_css">
|
||||||
|
<style type="text/css">
|
||||||
|
.input-addon-desc {
|
||||||
|
text-align: right;
|
||||||
|
font-size: 90%;
|
||||||
|
color: #707070;
|
||||||
|
}
|
||||||
|
|
||||||
|
.captcha-box {
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</%block>
|
||||||
|
|
||||||
|
<%block name="page_header">
|
||||||
|
<div class="container-fluid top-navbar">
|
||||||
|
<div class="brand"><a href="/"><span class="site-logo"></span></a></div>
|
||||||
|
<div class="breadcrumb-container">
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li><i class="fa fa-key"></i> 修改过期密码</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
## <a href="http://tp4a.com/" target="_blank"><span class="logo"></span></a>
|
||||||
|
</%block>
|
||||||
|
|
||||||
|
<div class="page-content">
|
||||||
|
<div class="info-box">
|
||||||
|
<div class="info-icon-box">
|
||||||
|
<i class="fa fa-key" style="color:#ffa043;"></i>
|
||||||
|
</div>
|
||||||
|
<div class="info-message-box">
|
||||||
|
<div id="title" class="title">密码已过期</div>
|
||||||
|
<hr/>
|
||||||
|
<div id="content" class="content">
|
||||||
|
|
||||||
|
<div id="area-input">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-5">
|
||||||
|
<div class="input-group">
|
||||||
|
<span class="input-group-addon"><i class="fa fa-user fa-fw"></i></span>
|
||||||
|
<input id="txt-username" type="text" class="form-control mono" disabled>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group" style="margin-top:10px;">
|
||||||
|
<span class="input-group-addon"><i class="fa fa-key fa-fw"></i></span>
|
||||||
|
<input id="txt-password" type="password" class="form-control mono" placeholder="输入当前密码" data-toggle="popover" data-trigger="manual" data-placement="top">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group" style="margin-top:10px;">
|
||||||
|
<span class="input-group-addon"><i class="fa fa-edit fa-fw"></i></span>
|
||||||
|
<input id="txt-new-password" type="password" class="form-control mono" placeholder="设置新密码" data-toggle="popover" data-trigger="manual" data-placement="top">
|
||||||
|
<span class="input-group-btn"><button class="btn btn-default" type="button" id="btn-switch-password"><i id="icon-switch-password" class="fa fa-eye fa-fw"></i></button></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group" style="margin-top:10px;">
|
||||||
|
<span class="input-group-addon"><i class="far fa-check-square fa-fw"></i></span>
|
||||||
|
<input id="txt-captcha" type="text" class="form-control" placeholder="验证码" data-toggle="popover" data-trigger="manual" data-placement="top">
|
||||||
|
<span class="input-group-addon captcha-box"><a href="javascript:;" tabindex="-1"><img id="img-captcha" src=""></a></span>
|
||||||
|
</div>
|
||||||
|
<p class="input-addon-desc">验证码,点击图片可更换</p>
|
||||||
|
|
||||||
|
<div style="margin:20px 0;">
|
||||||
|
<button type="button" class="btn btn-primary" data-field="btn-submit" style="width:100%;"><i class="fa fa-check fa-fw"></i> 确定修改</button>
|
||||||
|
<div id="message" style="display: none;"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-md-7">
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
<p>您的登陆密码已过期,根据系统设置,在您修改密码之前,将无法登陆TELEPORT系统。</p>
|
||||||
|
</div>
|
||||||
|
<div id="info" class="alert alert-warning" style="display:none;">
|
||||||
|
<p>注意,系统启用强密码策略,要求密码至少8位,必须包含大写字母、小写字母以及数字。</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%block name="embed_js">
|
||||||
|
<script type="text/javascript">
|
||||||
|
"use strict";
|
||||||
|
$app.add_options(${page_param});
|
||||||
|
console.log($app.options);
|
||||||
|
</script>
|
||||||
|
</%block>
|
|
@ -66,6 +66,8 @@ controllers = [
|
||||||
(r'/user/get-users', user.DoGetUsersHandler),
|
(r'/user/get-users', user.DoGetUsersHandler),
|
||||||
# - 用户重设密码页面 /auth/reset-password
|
# - 用户重设密码页面 /auth/reset-password
|
||||||
(r'/user/reset-password', user.ResetPasswordHandler),
|
(r'/user/reset-password', user.ResetPasswordHandler),
|
||||||
|
# - 用户密码过期,修改密码页面 /auth/change-password
|
||||||
|
(r'/user/change-expired-password', user.ChangeExpiredPasswordHandler),
|
||||||
# - [json] 重置密码
|
# - [json] 重置密码
|
||||||
(r'/user/do-reset-password', user.DoResetPasswordHandler),
|
(r'/user/do-reset-password', user.DoResetPasswordHandler),
|
||||||
# - 用户绑定OATH
|
# - 用户绑定OATH
|
||||||
|
|
|
@ -115,12 +115,13 @@ class DoLoginHandler(TPBaseJsonHandler):
|
||||||
syslog.sys_log({'username': '???', 'surname': '???'}, self.request.remote_ip, TPE_NOT_EXISTS, '登录失败,可能是攻击行为。试图使用用户名 {} 进行登录。'.format(username))
|
syslog.sys_log({'username': '???', 'surname': '???'}, self.request.remote_ip, TPE_NOT_EXISTS, '登录失败,可能是攻击行为。试图使用用户名 {} 进行登录。'.format(username))
|
||||||
return self.write_json(err)
|
return self.write_json(err)
|
||||||
|
|
||||||
err, user_info = user.login(self, username, password=password, oath_code=oath)
|
err, user_info, msg = user.login(self, username, password=password, oath_code=oath)
|
||||||
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
|
||||||
|
msg = '用户名或密码错误'
|
||||||
syslog.sys_log({'username': '???', 'surname': '???'}, self.request.remote_ip, TPE_NOT_EXISTS, '登录失败,用户`{}`不存在'.format(username))
|
syslog.sys_log({'username': '???', 'surname': '???'}, self.request.remote_ip, TPE_NOT_EXISTS, '登录失败,用户`{}`不存在'.format(username))
|
||||||
return self.write_json(err)
|
return self.write_json(err, msg)
|
||||||
|
|
||||||
# 判断此用户是否被允许使用当前登录认证方式
|
# 判断此用户是否被允许使用当前登录认证方式
|
||||||
auth_type = user_info.auth_type
|
auth_type = user_info.auth_type
|
||||||
|
|
|
@ -114,6 +114,16 @@ class ResetPasswordHandler(TPBaseHandler):
|
||||||
self.render('user/reset-password.mako', page_param=json.dumps(param))
|
self.render('user/reset-password.mako', page_param=json.dumps(param))
|
||||||
|
|
||||||
|
|
||||||
|
class ChangeExpiredPasswordHandler(TPBaseHandler):
|
||||||
|
def get(self):
|
||||||
|
_username = self.get_argument('username', None)
|
||||||
|
if _username is None:
|
||||||
|
return self.redirect('/')
|
||||||
|
|
||||||
|
param = {'username': _username, 'force_strong': tp_cfg().sys.password.force_strong}
|
||||||
|
self.render('user/change-expired-password.mako', page_param=json.dumps(param))
|
||||||
|
|
||||||
|
|
||||||
class BindOathHandler(TPBaseHandler):
|
class BindOathHandler(TPBaseHandler):
|
||||||
def get(self):
|
def get(self):
|
||||||
self.render('user/bind-oath.mako')
|
self.render('user/bind-oath.mako')
|
||||||
|
@ -147,7 +157,7 @@ class DoVerifyUserHandler(TPBaseJsonHandler):
|
||||||
except:
|
except:
|
||||||
check_bind_oath = False
|
check_bind_oath = False
|
||||||
|
|
||||||
err, user_info = user.login(self, username, password=password, check_bind_oath=check_bind_oath)
|
err, user_info, msg = user.login(self, username, password=password, check_bind_oath=check_bind_oath)
|
||||||
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
|
||||||
|
@ -173,7 +183,7 @@ class DoBindOathHandler(TPBaseJsonHandler):
|
||||||
except:
|
except:
|
||||||
return self.write_json(TPE_PARAM)
|
return self.write_json(TPE_PARAM)
|
||||||
|
|
||||||
err, user_info = user.login(self, username, password=password)
|
err, user_info, msg = user.login(self, username, password=password)
|
||||||
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
|
||||||
|
|
|
@ -56,20 +56,19 @@ def get_by_username(username):
|
||||||
|
|
||||||
def login(handler, username, password=None, oath_code=None, check_bind_oath=False):
|
def login(handler, username, password=None, oath_code=None, check_bind_oath=False):
|
||||||
sys_cfg = tp_cfg().sys
|
sys_cfg = tp_cfg().sys
|
||||||
|
msg = ''
|
||||||
|
|
||||||
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:
|
return err, None, msg
|
||||||
# syslog.sys_log({'username': username, 'surname': username}, handler.request.remote_ip, TPE_NOT_EXISTS,
|
|
||||||
# '用户身份验证失败,用户`{}`不存在'.format(username))
|
|
||||||
return err, None
|
|
||||||
|
|
||||||
if user_info.privilege == 0:
|
if user_info.privilege == 0:
|
||||||
# 尚未为此用户设置角色
|
# 尚未为此用户设置角色
|
||||||
return TPE_PRIVILEGE, None
|
msg = '登录失败,用户尚未分配权限'
|
||||||
|
return TPE_PRIVILEGE, None, msg
|
||||||
|
|
||||||
if check_bind_oath 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, msg
|
||||||
|
|
||||||
if user_info['state'] == TP_STATE_LOCKED:
|
if user_info['state'] == TP_STATE_LOCKED:
|
||||||
# 用户已经被锁定,如果系统配置为一定时间后自动解锁,则更新一下用户信息
|
# 用户已经被锁定,如果系统配置为一定时间后自动解锁,则更新一下用户信息
|
||||||
|
@ -78,14 +77,17 @@ def login(handler, username, password=None, oath_code=None, check_bind_oath=Fals
|
||||||
user_info.fail_count = 0
|
user_info.fail_count = 0
|
||||||
user_info.state = TP_STATE_NORMAL
|
user_info.state = TP_STATE_NORMAL
|
||||||
if user_info['state'] == TP_STATE_LOCKED:
|
if user_info['state'] == TP_STATE_LOCKED:
|
||||||
syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_LOCKED, '登录失败,用户已被临时锁定')
|
msg = '登录失败,用户已被临时锁定'
|
||||||
return TPE_USER_LOCKED, None
|
syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_LOCKED, msg)
|
||||||
|
return TPE_USER_LOCKED, None, msg
|
||||||
elif user_info['state'] == TP_STATE_DISABLED:
|
elif user_info['state'] == TP_STATE_DISABLED:
|
||||||
syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_DISABLED, '登录失败,用户已被禁用')
|
msg = '登录失败,用户已被禁用'
|
||||||
return TPE_USER_DISABLED, None
|
syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_DISABLED, msg)
|
||||||
|
return TPE_USER_DISABLED, None, msg
|
||||||
elif user_info['state'] != TP_STATE_NORMAL:
|
elif user_info['state'] != TP_STATE_NORMAL:
|
||||||
syslog.sys_log(user_info, handler.request.remote_ip, TPE_FAILED, '登录失败,用户状态异常')
|
msg = '登录失败,用户状态异常'
|
||||||
return TPE_FAILED, None
|
syslog.sys_log(user_info, handler.request.remote_ip, TPE_FAILED, msg)
|
||||||
|
return TPE_FAILED, None, msg
|
||||||
|
|
||||||
err_msg = ''
|
err_msg = ''
|
||||||
if password is not None:
|
if password is not None:
|
||||||
|
@ -94,28 +96,32 @@ def login(handler, username, password=None, oath_code=None, check_bind_oath=Fals
|
||||||
if sys_cfg.password.timeout != 0:
|
if sys_cfg.password.timeout != 0:
|
||||||
_time_now = tp_timestamp_utc_now()
|
_time_now = tp_timestamp_utc_now()
|
||||||
if user_info['last_chpass'] + (sys_cfg.password.timeout * 60 * 60 * 24) < _time_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, '登录失败,用户密码已过期')
|
msg = '登录失败,用户密码已过期'
|
||||||
return TPE_USER_AUTH, None
|
syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, msg)
|
||||||
|
return TPE_EXPIRED, None, msg
|
||||||
|
|
||||||
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))
|
msg = '登录失败,密码错误{}'.format(err_msg)
|
||||||
return TPE_USER_AUTH, None
|
syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, msg)
|
||||||
|
return TPE_USER_AUTH, None, msg
|
||||||
elif user_info['type'] == TP_USER_TYPE_LDAP:
|
elif user_info['type'] == TP_USER_TYPE_LDAP:
|
||||||
try:
|
try:
|
||||||
if len(tp_cfg().sys_ldap_password) == 0:
|
if len(tp_cfg().sys_ldap_password) == 0:
|
||||||
syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, 'LDAP未能正确配置,需要管理员密码')
|
msg = 'LDAP尚未配置'
|
||||||
return TPE_USER_AUTH, None
|
syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, msg)
|
||||||
|
return TPE_USER_AUTH, None, msg
|
||||||
else:
|
else:
|
||||||
_ldap_password = tp_cfg().sys_ldap_password
|
_ldap_password = tp_cfg().sys_ldap_password
|
||||||
_ldap_server = tp_cfg().sys.ldap.server
|
_ldap_server = tp_cfg().sys.ldap.server
|
||||||
_ldap_port = tp_cfg().sys.ldap.port
|
_ldap_port = tp_cfg().sys.ldap.port
|
||||||
_ldap_base_dn = tp_cfg().sys.ldap.base_dn
|
_ldap_base_dn = tp_cfg().sys.ldap.base_dn
|
||||||
except:
|
except:
|
||||||
syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, 'LDAP未能正确配置')
|
msg = 'LDAP尚未正确配置'
|
||||||
return TPE_USER_AUTH, None
|
syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, msg)
|
||||||
|
return TPE_USER_AUTH, None, msg
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ldap = Ldap(_ldap_server, _ldap_port, _ldap_base_dn)
|
ldap = Ldap(_ldap_server, _ldap_port, _ldap_base_dn)
|
||||||
|
@ -125,40 +131,42 @@ 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_USER_AUTH,
|
msg = 'LDAP用户验证失败{}'.format(err_msg)
|
||||||
'LDAP用户登录失败,密码错误{}'.format(err_msg))
|
syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, msg)
|
||||||
return TPE_USER_AUTH, None
|
return TPE_USER_AUTH, None, msg
|
||||||
else:
|
else:
|
||||||
syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH,
|
msg = 'LDAP用户登录失败,{}'.format(err_msg)
|
||||||
'LDAP用户登录失败,{}'.format(err_msg))
|
syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, msg)
|
||||||
return TPE_USER_AUTH, None
|
return TPE_USER_AUTH, None, msg
|
||||||
except:
|
except:
|
||||||
syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, 'LDAP用户登录失败,发生内部错误')
|
msg = 'LDAP用户登录失败,发生内部错误'
|
||||||
return TPE_USER_AUTH, None
|
syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, msg)
|
||||||
|
return TPE_USER_AUTH, None, msg
|
||||||
|
|
||||||
else:
|
else:
|
||||||
syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, '登录失败,系统内部错误')
|
msg = '登录失败,系统内部错误'
|
||||||
return TPE_USER_AUTH, None
|
syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, msg)
|
||||||
|
return TPE_USER_AUTH, None, msg
|
||||||
|
|
||||||
if oath_code is not None:
|
if oath_code is not None:
|
||||||
# use oath
|
# use oath
|
||||||
if len(user_info['oath_secret']) == 0:
|
if len(user_info['oath_secret']) == 0:
|
||||||
return TPE_OATH_MISMATCH, None
|
return TPE_OATH_MISMATCH, None, msg
|
||||||
|
|
||||||
if not tp_oath_verify_code(user_info['oath_secret'], oath_code):
|
if not tp_oath_verify_code(user_info['oath_secret'], oath_code):
|
||||||
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,
|
msg = '登录失败,身份验证器动态验证码错误{}'.format(err_msg)
|
||||||
"登录失败,身份验证器动态验证码错误{}".format(err_msg))
|
syslog.sys_log(user_info, handler.request.remote_ip, TPE_OATH_MISMATCH, msg)
|
||||||
return TPE_OATH_MISMATCH, None
|
return TPE_OATH_MISMATCH, None, msg
|
||||||
|
|
||||||
del user_info['password']
|
del user_info['password']
|
||||||
del user_info['oath_secret']
|
del user_info['oath_secret']
|
||||||
|
|
||||||
if len(user_info['surname']) == 0:
|
if len(user_info['surname']) == 0:
|
||||||
user_info['surname'] = user_info['username']
|
user_info['surname'] = user_info['username']
|
||||||
return TPE_OK, user_info
|
return TPE_OK, user_info, msg
|
||||||
|
|
||||||
|
|
||||||
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):
|
||||||
|
|
Loading…
Reference in New Issue