| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- import * as R from 'ramda'
- import { WAF_RULE_OPTS_MAP, WAF_RULE_TYPES, WAF_RULE_TYPES_MAP, RATE_LIMIT_RULE_TYPES } from '../constants'
- export const encodeRuleListToDescription = (ruleList) => {
- const list = []
- ruleList.forEach(rules => {
- const listInner = []
- rules.forEach(rule => {
- const { type, name, opt, value } = rule
- if (type && opt && WAF_RULE_OPTS_MAP[opt]) {
- const valueType = WAF_RULE_TYPES_MAP[type].valueType
- const str = WAF_RULE_OPTS_MAP[opt].valueFormat(type, name, formatRuleValue(value, R.is(Function, valueType) ? valueType(opt) : valueType, ''))
- listInner.push(str)
- }
- })
- list.push(`(${listInner.join(' and ')})`)
- })
- return list.join(' or ')
- }
- export const decodeRuleExpression = (expr = '', defaultValue = []) => {
- const list = splitExpr(expr)
- const ret = []
- list.forEach(arr => {
- const group = []
- arr.forEach(str => {
- for (const key in WAF_RULE_OPTS_MAP) {
- const decode = WAF_RULE_OPTS_MAP[key].decodeDescription ? WAF_RULE_OPTS_MAP[key].decodeDescription(str) : null
- if (decode) {
- group.push(decode)
- break
- }
- }
- })
- if (group.length) {
- ret.push(group)
- }
- })
- return ret.length ? ret : defaultValue
- }
- export const decodeRateLimitCustomRules = (rules) => {
- return rules.map(rule => {
- let row = {}
- for (let i = 0; i < RATE_LIMIT_RULE_TYPES.length; i++) {
- const item = RATE_LIMIT_RULE_TYPES[i]
- const decode = item.decodeDescription ? item.decodeDescription(rule) : null
- if (decode) {
- row = decode
- break
- }
- }
- return row
- })
- }
- function smartSplit (expr, sep) {
- const result = []
- let buf = ''
- let paren = 0
- let inQuote = false
- let quoteChar = ''
- let i = 0
- const sepLen = sep.length
- while (i < expr.length) {
- // 检查引号
- if (!inQuote && (expr[i] === '"' || expr[i] === "'")) {
- inQuote = true
- quoteChar = expr[i]
- buf += expr[i]
- i++
- continue
- }
- if (inQuote && expr[i] === quoteChar) {
- inQuote = false
- buf += expr[i]
- i++
- continue
- }
- // 检查括号
- if (!inQuote) {
- if (expr[i] === '(') paren++
- if (expr[i] === ')') paren--
- }
- // 检查分隔符
- if (!inQuote && paren === 0) {
- if (expr.slice(i, i + sepLen).toLowerCase() === sep &&
- (i + sepLen === expr.length || /[\s(]/.test(expr[i + sepLen]))) {
- result.push(buf.trim())
- buf = ''
- i += sepLen
- continue
- }
- }
- buf += expr[i]
- i++
- }
- if (buf.trim()) result.push(buf.trim())
- return result.map(str => {
- if (str.startsWith('(') && str.endsWith(')')) {
- return str.slice(1, -1)
- }
- return str
- })
- }
- // 递归拆分
- function splitExpr (expr) {
- // 先按 or 拆
- const orParts = smartSplit(expr, 'or')
- // 每一段再按 and 拆
- return orParts.map(part => smartSplit(part, 'and'))
- }
- export const formatRuleValue = (originValue, valueType, defaultValue = undefined) => {
- let value = defaultValue
- if (valueType === 'multi-select') {
- if ((originValue && R.is(String, originValue)) || R.is(Number, originValue)) {
- value = [originValue]
- } else if (R.is(Boolean, originValue)) {
- value = []
- } else if (R.is(Array, originValue)) {
- value = originValue
- } else {
- value = []
- }
- } else if (valueType === 'single-select') {
- if ((originValue && R.is(String, originValue)) || R.is(Number, originValue)) {
- value = [originValue]
- } else if (R.is(Boolean, originValue)) {
- value = []
- } else if (R.is(Array, originValue)) {
- value = originValue.length ? originValue[0] : []
- } else {
- value = []
- }
- } else if (valueType === 'input' || valueType === 'input-number') {
- if (R.is(Boolean, originValue)) {
- value = undefined
- } else if (R.is(Array, originValue)) {
- value = originValue.length ? originValue[0] : []
- } else if (R.is(Number, originValue) || R.is(String, originValue)) {
- value = originValue
- }
- } else if (valueType === 'switch') {
- if (R.is(Boolean, originValue)) {
- value = originValue
- } else {
- value = false
- }
- }
- return value
- }
- export const getRuleConfig = (rule) => {
- const ruleTypes = WAF_RULE_TYPES
- const ret = { valueType: 'input', isShowName: false }
- if (rule.type) {
- const target = ruleTypes.filter(item => item.type === rule.type)
- if (target.length) {
- ret.valueType = R.is(Function, target[0].valueType) ? target[0].valueType(rule.opt) : target[0].valueType
- ret.isShowName = R.is(Function, target[0].isShowName) ? target[0].isShowName(rule.type, rule.opt) : target[0].isShowName
- ret.optDisabled = target[0].optDisabled
- ret.valueOpts = R.is(Function, target[0].valueOpts) ? target[0].valueOpts(ret.valueType) : target[0].valueOpts || []
- ret.opts = target[0].opts || []
- if (target[0].valueExtra) {
- ret.valueExtra = R.is(Function, target[0].valueExtra) ? target[0].valueExtra(rule.type, rule.opt) : target[0].valueExtra
- }
- ret.props = R.is(Function, target[0].props) ? target[0].props(rule.type, rule.opt) : target[0].props || {}
- }
- }
- return ret
- }
|