提交 3c36c705 编写于 作者: R rq0 提交者: LINGuanRen

implement mysql function VALIDATE_PASSWORD_STRENGTH()

上级 da6f7be7
......@@ -277,7 +277,7 @@ public:
return result;
}
template <typename foreach_char_func>
static int foreach_char(common::ObString& str, common::ObCollationType collation_type, foreach_char_func& func)
static int foreach_char(const common::ObString &str, common::ObCollationType collation_type, foreach_char_func &func)
{
int ret = common::OB_SUCCESS;
int32_t wchar = 0;
......
......@@ -336,6 +336,7 @@
#define N_OPERATOR_MONITOR_INFO "op_info"
#define N_PLAN_MONITOR_INFO "plan_info"
#define N_ANY_VAL "any_value"
#define N_VALIDATE_PASSWORD_STRENGTH "validate_password_strength"
// common comparison operator
#define N_LESS_THAN "<"
#define N_GREATER_THAN ">"
......
......@@ -464,6 +464,8 @@ ob_set_subtarget(ob_sql engine
engine/expr/ob_expr_calc_urowid.cpp
engine/expr/ob_expr_cardinality.cpp
engine/expr/ob_expr_coll_pred.cpp
engine/expr/ob_expr_validate_password_strength.cpp
engine/expr/ob_expr_validate_password_strength.h
engine/expr/ob_expr_benchmark.cpp
engine/expr/ob_expr_benchmark.h
engine/join/ob_basic_nested_loop_join.cpp
......
......@@ -187,6 +187,7 @@
#include "ob_expr_degrees.h"
#include "ob_expr_weight_string.h"
#include "ob_expr_any_value.h"
#include "ob_expr_validate_password_strength.h"
#include "ob_expr_benchmark.h"
namespace oceanbase {
......@@ -704,7 +705,7 @@ static ObExpr::EvalFunc g_expr_eval_functions[] = {
NULL, /* 440 */
ObExprTimestamp::calc_timestamp1, /* 441 */
ObExprTimestamp::calc_timestamp2, /* 442 */
NULL, /* 443 */
ObExprValidatePasswordStrength::eval_password_strength, /* 443 */
NULL, /* 444 */
NULL, /* 445 */
NULL, /* 446 */
......
......@@ -271,6 +271,7 @@
#include "sql/engine/expr/ob_expr_degrees.h"
#include "sql/engine/expr/ob_expr_weight_string.h"
#include "sql/engine/expr/ob_expr_any_value.h"
#include "sql/engine/expr/ob_expr_validate_password_strength.h"
#include "sql/engine/expr/ob_expr_benchmark.h"
using namespace oceanbase::common;
......@@ -683,6 +684,7 @@ void ObExprOperatorFactory::register_expr_operators()
REG_OP(ObExprTimeFormat);
REG_OP(ObExprTimestamp);
REG_OP(ObExprDegrees);
REG_OP(ObExprValidatePasswordStrength);
REG_OP(ObExprWeightString);
REG_OP(ObExprBenchmark);
REG_OP(ObExprDay);
......
// Copyright (c) 2021 Alibaba Inc. All Rights Reserved.
// Author:
// renqing <sean.yyj@antgroup.com>
#define USING_LOG_PREFIX SQL_ENG
#include "ob_expr_validate_password_strength.h"
#include "sql/session/ob_sql_session_info.h"
#include "sql/engine/ob_exec_context.h"
using namespace oceanbase::common;
using namespace oceanbase::sql;
namespace oceanbase {
namespace sql {
const ObValidatePasswordFunc ObExprValidatePasswordStrength::validate_funcs_[STRENGTH_MAX] = {
NULL, // STRENGTH_WEAK is default strength, need no validation
ObExprValidatePasswordStrength::validate_password_lessweak,
ObExprValidatePasswordStrength::validate_password_low,
ObExprValidatePasswordStrength::validate_password_medium,
ObExprValidatePasswordStrength::validate_password_strong,
};
ObExprValidatePasswordStrength::ObExprValidatePasswordStrength(ObIAllocator &alloc)
: ObFuncExprOperator(
alloc, T_FUN_SYS_VALIDATE_PASSWORD_STRENGTH, N_VALIDATE_PASSWORD_STRENGTH, 1, NOT_ROW_DIMENSION)
{}
ObExprValidatePasswordStrength::~ObExprValidatePasswordStrength()
{}
int ObExprValidatePasswordStrength::calc_result_type1(
ObExprResType &type, ObExprResType &type1, ObExprTypeCtx &type_ctx) const
{
int ret = OB_SUCCESS;
UNUSED(type_ctx);
type.set_int();
type.set_scale(common::ObAccuracy::DDL_DEFAULT_ACCURACY[common::ObIntType].scale_);
type.set_precision(common::ObAccuracy::DDL_DEFAULT_ACCURACY[common::ObIntType].precision_);
type1.set_calc_type(common::ObVarcharType);
ObExprOperator::calc_result_flag1(type, type1);
return ret;
}
int ObExprValidatePasswordStrength::calc_result1(ObObj &result, const ObObj &obj1, ObExprCtx &expr_ctx) const
{
int ret = OB_SUCCESS;
if (OB_ISNULL(expr_ctx.my_session_) || OB_ISNULL(expr_ctx.calc_buf_)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("Invalid argument", KP(expr_ctx.my_session_), KP(expr_ctx.calc_buf_), K(ret));
} else if (obj1.is_null()) {
result.set_null();
} else {
ObString password;
int strength = 0;
if (OB_FAIL(ObCharset::charset_convert(*expr_ctx.calc_buf_,
obj1.get_string(),
obj1.get_collation_type(),
ObCharset::get_system_collation(),
password))) {
LOG_WARN("fail to convert password to sys collation", K(obj1), K(ret));
} else if (OB_FAIL(calc_password_strength(password, *expr_ctx.my_session_, strength))) {
LOG_WARN("fail to calc password strength", K(password), K(ret));
} else {
result.set_int(strength);
}
}
return ret;
}
int ObExprValidatePasswordStrength::cg_expr(ObExprCGCtx &op_cg_ctx, const ObRawExpr &raw_expr, ObExpr &rt_expr) const
{
int ret = OB_SUCCESS;
UNUSED(op_cg_ctx);
UNUSED(raw_expr);
rt_expr.eval_func_ = eval_password_strength;
return ret;
}
int ObExprValidatePasswordStrength::eval_password_strength(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res_datum)
{
int ret = OB_SUCCESS;
ObDatum *pwd_param = NULL;
ObCollationType c_src = ObCollationType::CS_TYPE_INVALID;
ObString password_orig;
ObString password;
int strength = 0;
const ObBasicSessionInfo *session = ctx.exec_ctx_.get_my_session();
if (OB_ISNULL(session)) {
LOG_WARN("session is null", K(ret));
} else if (OB_FAIL(expr.args_[0]->eval(ctx, pwd_param))) {
LOG_WARN("eval arg failed", K(ret));
} else if (pwd_param->is_null()) {
res_datum.set_null();
} else if (FALSE_IT(password_orig = pwd_param->get_string())) {
} else if (FALSE_IT(c_src = expr.args_[0]->obj_meta_.get_collation_type())) {
} else if (OB_FAIL(ObCharset::charset_convert(
ctx.exec_ctx_.get_allocator(), password_orig, c_src, ObCharset::get_system_collation(), password))) {
LOG_WARN("fail to convert password to sys collation", K(password_orig), K(c_src), K(ret));
} else if (OB_FAIL(calc_password_strength(password, *session, strength))) {
LOG_WARN("fail to calc password strength", K(password), K(ret));
} else {
res_datum.set_int(strength);
}
return ret;
}
int ObExprValidatePasswordStrength::calc_password_strength(
const ObString &password, const ObBasicSessionInfo &session, int &strength)
{
int ret = OB_SUCCESS;
bool passed = true;
strength = 0;
for (int i = STRENGTH_LESSWEAK; OB_SUCC(ret) && passed && i < STRENGTH_MAX; ++i) {
if (OB_FAIL(validate_funcs_[i](password, session, passed))) {
LOG_WARN("failed to validate", K(password), K(i), K(ret));
} else if (passed) {
strength = i * PASSWORD_STRENGTH_MULTIPLIER;
}
}
return ret;
}
int ObExprValidatePasswordStrength::validate_password_lessweak(
const ObString &password, const ObBasicSessionInfo &session, bool &passed)
{
int ret = OB_SUCCESS;
int64_t check_user_name = 0;
passed = false;
if (OB_FAIL(session.get_sys_variable(share::SYS_VAR_VALIDATE_PASSWORD_CHECK_USER_NAME, check_user_name))) {
LOG_WARN("fail to get validate_password_length", K(ret));
} else {
passed = password.length() >= VALID_PASSWORD_LENGTH_MIN &&
(!check_user_name && !ObCharset::case_insensitive_equal(password, session.get_user_name()));
}
return ret;
}
int ObExprValidatePasswordStrength::validate_password_low(
const ObString &password, const ObBasicSessionInfo &session, bool &passed)
{
int ret = OB_SUCCESS;
uint64_t valid_pw_len = 0;
passed = false;
if (OB_FAIL(session.get_sys_variable(share::SYS_VAR_VALIDATE_PASSWORD_LENGTH, valid_pw_len))) {
LOG_WARN("fail to get validate_password_length", K(ret));
} else {
passed = password.length() >= valid_pw_len;
}
return ret;
}
int ObExprValidatePasswordStrength::validate_password_medium(
const ObString &password, const ObBasicSessionInfo &session, bool &passed)
{
int ret = OB_SUCCESS;
uint64_t valid_mix_case_count = 0;
uint64_t valid_number_count = 0;
uint64_t valid_special_count = 0;
uint64_t lower_count = 0;
uint64_t upper_count = 0;
uint64_t digit_count = 0;
uint64_t special_count = 0;
passed = false;
if (OB_FAIL(session.get_sys_variable(share::SYS_VAR_VALIDATE_PASSWORD_MIXED_CASE_COUNT, valid_mix_case_count))) {
LOG_WARN("fail to get validate_password_mixed_case_count", K(ret));
} else if (OB_FAIL(session.get_sys_variable(share::SYS_VAR_VALIDATE_PASSWORD_NUMBER_COUNT, valid_number_count))) {
LOG_WARN("fail to get validate_password_number_count", K(ret));
} else if (OB_FAIL(
session.get_sys_variable(share::SYS_VAR_VALIDATE_PASSWORD_SPECIAL_CHAR_COUNT, valid_special_count))) {
LOG_WARN("fail to get validate_password_special_char_count", K(ret));
} else {
auto handle_char_func = [&lower_count, &upper_count, &digit_count, &special_count](ObString, int wchar) -> int {
int ret = OB_SUCCESS;
if (islower(wchar)) {
lower_count++;
} else if (isupper(wchar)) {
upper_count++;
} else if (isdigit(wchar)) {
digit_count++;
} else {
special_count++;
}
return ret;
};
OZ(ObCharsetUtils::foreach_char(password, ObCharset::get_system_collation(), handle_char_func));
}
if (OB_SUCC(ret)) {
passed = lower_count >= valid_mix_case_count && upper_count >= valid_mix_case_count &&
digit_count >= valid_number_count && special_count >= valid_special_count;
}
return ret;
}
int ObExprValidatePasswordStrength::validate_password_strong(
const ObString &password, const ObBasicSessionInfo &session, bool &passed)
{
int ret = OB_SUCCESS;
UNUSED(password);
UNUSED(session);
// Check if the password matches the words in the dictionary file. The dictionary file is not
// supported in OB yet, so this validation always passed
passed = true;
return ret;
}
} // namespace sql
} // namespace oceanbase
// Copyright (c) 2021 Alibaba Inc. All Rights Reserved.
// Author:
// renqing <sean.yyj@antgroup.com>
#ifndef SRC_SQL_ENGINE_EXPR_OB_EXPR_VALIDATE_PASSWORD_STRENGTH_H_
#define SRC_SQL_ENGINE_EXPR_OB_EXPR_VALIDATE_PASSWORD_STRENGTH_H_
#include "sql/engine/expr/ob_expr_operator.h"
namespace oceanbase {
namespace sql {
typedef int (*ObValidatePasswordFunc)(
const common::ObString &password, const ObBasicSessionInfo &session, bool &passed);
class ObExprValidatePasswordStrength : public ObFuncExprOperator {
public:
enum PasswordStrength {
STRENGTH_WEAK = 0,
STRENGTH_LESSWEAK,
STRENGTH_LOW,
STRENGTH_MEDIUM,
STRENGTH_STRONG,
STRENGTH_MAX,
};
explicit ObExprValidatePasswordStrength(common::ObIAllocator &alloc);
virtual ~ObExprValidatePasswordStrength();
virtual int calc_result_type1(ObExprResType &type, ObExprResType &type1, common::ObExprTypeCtx &type_ctx) const;
virtual int calc_result1(common::ObObj &result, const common::ObObj &obj1, common::ObExprCtx &expr_ctx) const;
virtual int cg_expr(ObExprCGCtx &op_cg_ctx, const ObRawExpr &raw_expr, ObExpr &rt_expr) const override;
static int eval_password_strength(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res_datum);
private:
static int calc_password_strength(const common::ObString &password, const ObBasicSessionInfo &session, int &strength);
static int validate_password_lessweak(
const common::ObString &password, const ObBasicSessionInfo &session, bool &passed);
static int validate_password_low(const common::ObString &password, const ObBasicSessionInfo &session, bool &passed);
static int validate_password_medium(
const common::ObString &password, const ObBasicSessionInfo &session, bool &passed);
static int validate_password_strong(
const common::ObString &password, const ObBasicSessionInfo &session, bool &passed);
static const int64_t VALID_PASSWORD_LENGTH_MIN = 4;
static const int64_t PASSWORD_STRENGTH_MULTIPLIER = 25;
static const ObValidatePasswordFunc validate_funcs_[STRENGTH_MAX];
// disallow copy
DISALLOW_COPY_AND_ASSIGN(ObExprValidatePasswordStrength);
};
} // namespace sql
} // namespace oceanbase
#endif /* SRC_SQL_ENGINE_EXPR_OB_EXPR_VALIDATE_PASSWORD_STRENGTH_H_ */
......@@ -428,6 +428,7 @@ typedef enum ObItemType {
T_FUN_SYS_PI = 713,
T_FUN_SYS_ANY_VALUE = 714,
T_FUN_SYS_DEGREES = 715,
T_FUN_SYS_VALIDATE_PASSWORD_STRENGTH = 716,
T_FUN_SYS_BENCHMARK = 720,
T_FUN_SYS_EXPORT_SET = 721,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册