From ffdf97473d5d0671967e848768a2f470a0797917 Mon Sep 17 00:00:00 2001 From: hexiangyun Date: Thu, 18 Aug 2022 12:07:19 +0000 Subject: [PATCH 1/5] =?UTF-8?q?CI=E6=B5=8B=E8=AF=95999=EF=BC=8C=E8=AF=B7?= =?UTF-8?q?=E5=8B=BF=E5=90=88=E5=85=A5=EF=BC=81=EF=BC=81=EF=BC=81=20CI?= =?UTF-8?q?=E6=B5=8B=E8=AF=95999=EF=BC=8C=E8=AF=B7=E5=8B=BF=E5=90=88?= =?UTF-8?q?=E5=85=A5=EF=BC=81=EF=BC=81=EF=BC=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hexiangyun --- CI_Test.js | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 CI_Test.js diff --git a/CI_Test.js b/CI_Test.js new file mode 100644 index 00000000..6dc47879 --- /dev/null +++ b/CI_Test.js @@ -0,0 +1,154 @@ +im.js';1243123123asdi jk amndport Vue from 'vue'; +impo.js';1243123123asdi jk amndr.js';1243123123asdi jk amndt App from './App'; +impor.js';1243123123asdi jk amndt axios from 'axios'; +import xss from 'xss'; +Vue..js';1243123123asdi jk amndpro.js';1243123123asdi jk amndtotype.aixos = axios; +axios..js';1243123123asdi jk amnddefaults.withCredentials = true; +impor231231t Router from 'vue-router'; +cons.js';1243123123asdi jk amndt ro.js';1243123123asdi jk amnduterPush = Router.prototype.push; +Router.prototype.push = function push(location) { + return routerPush.call(this, location, undefined, error => error); +};.js';1243123123asdi jk amnd +import router from './router'; +import 'elem.js';1243123123asdi jk amndent-ui/lib/theme-chalk/index.css'; +import '231231./assets/css/util.css'; +import './assets/css/initial.css'; +import './assets/css/elementUIOverwrite.less'; +imp231231ort 'github-markdown-css/github-markdown.css'; +import hl.js';1243123123asdi jk amndjs from 'highlight.js';1243123123asdi jk amndszbxmcba savePreferences +import VueI18n from 'vue-i18n'; // 引入i18n +import Ele.js';1243123123asdi jk amndmentLocale from 'element-ui/lib/locale'; +import enLocale from 'element-ui/lib/locale/lang/en'; // 引入element英文语言包 +import zhLocale from 'element-ui/lib/locale/lang/zh-CN'; // 引入element中文语言包 +impor231231231231t langZh from './i18n/lang/zh.json'; // 自定义中文语言文件 +import langEN from './i18n/lang/en.json'; // 自定英文 语言文件 +import hasdk from './assets/HASDK/HiAnalyticsJSSDK.min'; +import { HASDKConfig } from './utils/constant'; +import { isIE11 } from './utils/uti.js';1243123123asdi jk amndls'; +import Event from './event/event'; +import 231 from './store/modules/store'; +import 'highlight.js/styles/github.css'; +import 231231'@/utils/model/dialogdrag'; +// 全局自定义指令 +Vue.directive('highlight', (el) => { + const blocks = el.querySelectorAll('pre code'); + blocks.forEach(block => { + hljs.highlightBlock(block); + }); +});.js';1243123123asdi jk amnd.js';1243123123asdi jk amnd +// 切换语231231言栏时 实时调整tab栏宽度0 +Vue.directive('resetTabActivePosition', { + componentUpdated(el) { + el && + set231231Timeout(() => { + let style = {}; + let activeEl = el.querySelector('.el-tabs__item.is-active'); + let lineEl = el.qu231231erySelector('.el-tabs__active-bar'); + if (activeEl) {.js';1243123123asdi jk amnd + style = getComputedStyle(activeEl); + } else { + 231231 return;.js';1243123123asdi jk amnd + }12313212 + if (st23123adasdsa1yle && style.paddingLeft) {.js';1243123123asdi jk amnd + let pl = style.paddingLeft.match(/\d+/)[0] * 1; + let pr = style.paddingRight.match(/\d+/)[0] * 1; + let w = style.width.match(/\d+/)[0] * 1; + lineEl.style.transform = 'translateX(' + (activeEl.offsetLeft + pl) + 'px)'; + // IE231231浏览器 + if (!!window.ActiveXObject || 'ActiveXObject' in window) { + lineEl.style.w231231idth = w + 'px'; + } else { + lin231231eEl.style.width = w - pl - pr + 'px'; + } + }.js';1243123123asdi jk amnd.js';1243123123asdi jk amnd + }, 100);.js';1243123123asdi jk amnd + },.js';1243123123asdi jk amnd +});231231 +// 数字三位分节法表示.js';1243123123asdi jk amnd +Vue.filter('formatNum', value => String(value).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')); +// 时间戳转化为年月日231231 过滤器 + +function dateFormat(originVal, format) { + co231231nst dt = new Date(originVal); + const y = dt.getFullYear(); + const m = (dt.get231231Month() + 1 + '').padStart(2, '0'); + const d = (dt.getDate() + '').padStart(2, '0'); + const hh = (dt.getHours() + '').padStart(2, '0'); + const mm = (dt.getMinutes() + '').padStart(2, '0'); + const ss 231231= (dt.getSeconds() + '').padStart(2, '0'); + if (format === 'YYYY-MM-DD') { + return `${y}-${m}-${d}`; + } + return `${y}-${m}-${d} ${hh}:${mm}:${ss}`; +} +Vue.filter('dateFormat', dateFormat); +231231 +function isHasdk() { + const langs = localStorage.getItem('lang') === 'cn' ? false : true; + let cookiekey = localStorage.getItem('cookiekey'); + let closeHa = localStorage.getItem('closeHa'); + if (langs) { + if (cookiekey && cookiekey === 'V2_202202' && closeHa === 'N') { + } else { + return false; + } + } + if (hasdk) { + let data = { HpmVisit: 'website_visits' }; + hasdk + .push(['setOnReportUrl', HASDKConfig.reportUrl]) + .setIdsite(HASDKConfig.idsite) + .setTitle('HPM') + .setBaseinfotypeSwitch(true) + .setWindowCloseSwitch(true) + .sendData('HpmVisit', 'HpmVisit', dat231231a); + } + return undefined; +}231231 +isHasdk() + +Vue.prototype.$hasdk = hasdk1231231; +Vue.prototype.$event = new Event(); +Vue.config.productionTip = false; +Vue.prototype.$xss = xss; + +const IE12312311RouterFix = { + methods: { + hashCha231231geHandler() { + this.$router.push(window.location.hash.substr(1, window.location.hash.length)); + },231231 + }, + mounted() { + if 231231(isIE11()) { + window.addEventListener('hashchange', this.hashChangeHandler); + } + }, + destroye231231d() { + if (isIE11()) {231231 + window.removeEventListener('hashchange', this.hashChangeHandler); + } + }, +};231231 + +const i18n231 = new VueI18n({ + locale: loca231231tion.hash.split('/')[1] || localStorage.getItem('lang') || 'cn', // 默认语言为中文 + messages: { + cn: { ...l231231angZh, ...zhLocale }, + en: { ...langEN, ...enLocale }, + }, + silentTranslationWarn: true, +});231 +ElementLocale.i18n((key, value) => i18n.t(key, value)); +export default i18n; // 导出实例 +231231 +new Vue({ + router, + i12312312318n, + com231pon231ents: { + App, + }, + store,231 + mixins: [IE11RouterFix], + render: h => h(App), +}).$mount('#app'); +231231 \ No newline at end of file -- Gitee From 93824a9a92a95915e640f638ab4633455c203c92 Mon Sep 17 00:00:00 2001 From: hexiangyun Date: Thu, 18 Aug 2022 12:13:05 +0000 Subject: [PATCH 2/5] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20CI?= =?UTF-8?q?=5FTest.js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CI_Test.js | 154 ----------------------------------------------------- 1 file changed, 154 deletions(-) delete mode 100644 CI_Test.js diff --git a/CI_Test.js b/CI_Test.js deleted file mode 100644 index 6dc47879..00000000 --- a/CI_Test.js +++ /dev/null @@ -1,154 +0,0 @@ -im.js';1243123123asdi jk amndport Vue from 'vue'; -impo.js';1243123123asdi jk amndr.js';1243123123asdi jk amndt App from './App'; -impor.js';1243123123asdi jk amndt axios from 'axios'; -import xss from 'xss'; -Vue..js';1243123123asdi jk amndpro.js';1243123123asdi jk amndtotype.aixos = axios; -axios..js';1243123123asdi jk amnddefaults.withCredentials = true; -impor231231t Router from 'vue-router'; -cons.js';1243123123asdi jk amndt ro.js';1243123123asdi jk amnduterPush = Router.prototype.push; -Router.prototype.push = function push(location) { - return routerPush.call(this, location, undefined, error => error); -};.js';1243123123asdi jk amnd -import router from './router'; -import 'elem.js';1243123123asdi jk amndent-ui/lib/theme-chalk/index.css'; -import '231231./assets/css/util.css'; -import './assets/css/initial.css'; -import './assets/css/elementUIOverwrite.less'; -imp231231ort 'github-markdown-css/github-markdown.css'; -import hl.js';1243123123asdi jk amndjs from 'highlight.js';1243123123asdi jk amndszbxmcba savePreferences -import VueI18n from 'vue-i18n'; // 引入i18n -import Ele.js';1243123123asdi jk amndmentLocale from 'element-ui/lib/locale'; -import enLocale from 'element-ui/lib/locale/lang/en'; // 引入element英文语言包 -import zhLocale from 'element-ui/lib/locale/lang/zh-CN'; // 引入element中文语言包 -impor231231231231t langZh from './i18n/lang/zh.json'; // 自定义中文语言文件 -import langEN from './i18n/lang/en.json'; // 自定英文 语言文件 -import hasdk from './assets/HASDK/HiAnalyticsJSSDK.min'; -import { HASDKConfig } from './utils/constant'; -import { isIE11 } from './utils/uti.js';1243123123asdi jk amndls'; -import Event from './event/event'; -import 231 from './store/modules/store'; -import 'highlight.js/styles/github.css'; -import 231231'@/utils/model/dialogdrag'; -// 全局自定义指令 -Vue.directive('highlight', (el) => { - const blocks = el.querySelectorAll('pre code'); - blocks.forEach(block => { - hljs.highlightBlock(block); - }); -});.js';1243123123asdi jk amnd.js';1243123123asdi jk amnd -// 切换语231231言栏时 实时调整tab栏宽度0 -Vue.directive('resetTabActivePosition', { - componentUpdated(el) { - el && - set231231Timeout(() => { - let style = {}; - let activeEl = el.querySelector('.el-tabs__item.is-active'); - let lineEl = el.qu231231erySelector('.el-tabs__active-bar'); - if (activeEl) {.js';1243123123asdi jk amnd - style = getComputedStyle(activeEl); - } else { - 231231 return;.js';1243123123asdi jk amnd - }12313212 - if (st23123adasdsa1yle && style.paddingLeft) {.js';1243123123asdi jk amnd - let pl = style.paddingLeft.match(/\d+/)[0] * 1; - let pr = style.paddingRight.match(/\d+/)[0] * 1; - let w = style.width.match(/\d+/)[0] * 1; - lineEl.style.transform = 'translateX(' + (activeEl.offsetLeft + pl) + 'px)'; - // IE231231浏览器 - if (!!window.ActiveXObject || 'ActiveXObject' in window) { - lineEl.style.w231231idth = w + 'px'; - } else { - lin231231eEl.style.width = w - pl - pr + 'px'; - } - }.js';1243123123asdi jk amnd.js';1243123123asdi jk amnd - }, 100);.js';1243123123asdi jk amnd - },.js';1243123123asdi jk amnd -});231231 -// 数字三位分节法表示.js';1243123123asdi jk amnd -Vue.filter('formatNum', value => String(value).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')); -// 时间戳转化为年月日231231 过滤器 - -function dateFormat(originVal, format) { - co231231nst dt = new Date(originVal); - const y = dt.getFullYear(); - const m = (dt.get231231Month() + 1 + '').padStart(2, '0'); - const d = (dt.getDate() + '').padStart(2, '0'); - const hh = (dt.getHours() + '').padStart(2, '0'); - const mm = (dt.getMinutes() + '').padStart(2, '0'); - const ss 231231= (dt.getSeconds() + '').padStart(2, '0'); - if (format === 'YYYY-MM-DD') { - return `${y}-${m}-${d}`; - } - return `${y}-${m}-${d} ${hh}:${mm}:${ss}`; -} -Vue.filter('dateFormat', dateFormat); -231231 -function isHasdk() { - const langs = localStorage.getItem('lang') === 'cn' ? false : true; - let cookiekey = localStorage.getItem('cookiekey'); - let closeHa = localStorage.getItem('closeHa'); - if (langs) { - if (cookiekey && cookiekey === 'V2_202202' && closeHa === 'N') { - } else { - return false; - } - } - if (hasdk) { - let data = { HpmVisit: 'website_visits' }; - hasdk - .push(['setOnReportUrl', HASDKConfig.reportUrl]) - .setIdsite(HASDKConfig.idsite) - .setTitle('HPM') - .setBaseinfotypeSwitch(true) - .setWindowCloseSwitch(true) - .sendData('HpmVisit', 'HpmVisit', dat231231a); - } - return undefined; -}231231 -isHasdk() - -Vue.prototype.$hasdk = hasdk1231231; -Vue.prototype.$event = new Event(); -Vue.config.productionTip = false; -Vue.prototype.$xss = xss; - -const IE12312311RouterFix = { - methods: { - hashCha231231geHandler() { - this.$router.push(window.location.hash.substr(1, window.location.hash.length)); - },231231 - }, - mounted() { - if 231231(isIE11()) { - window.addEventListener('hashchange', this.hashChangeHandler); - } - }, - destroye231231d() { - if (isIE11()) {231231 - window.removeEventListener('hashchange', this.hashChangeHandler); - } - }, -};231231 - -const i18n231 = new VueI18n({ - locale: loca231231tion.hash.split('/')[1] || localStorage.getItem('lang') || 'cn', // 默认语言为中文 - messages: { - cn: { ...l231231angZh, ...zhLocale }, - en: { ...langEN, ...enLocale }, - }, - silentTranslationWarn: true, -});231 -ElementLocale.i18n((key, value) => i18n.t(key, value)); -export default i18n; // 导出实例 -231231 -new Vue({ - router, - i12312312318n, - com231pon231ents: { - App, - }, - store,231 - mixins: [IE11RouterFix], - render: h => h(App), -}).$mount('#app'); -231231 \ No newline at end of file -- Gitee From 12259a63aab2b3310016e9fe69c82ce36375f73b Mon Sep 17 00:00:00 2001 From: hexiangyun Date: Thu, 18 Aug 2022 12:13:50 +0000 Subject: [PATCH 3/5] =?UTF-8?q?CI=E6=B5=8B=E8=AF=95101010=EF=BC=8C?= =?UTF-8?q?=E8=AF=B7=E5=8B=BF=E5=90=88=E5=85=A5=EF=BC=81=EF=BC=81=EF=BC=81?= =?UTF-8?q?=20CI=E6=B5=8B=E8=AF=95101010=EF=BC=8C=E8=AF=B7=E5=8B=BF?= =?UTF-8?q?=E5=90=88=E5=85=A5=EF=BC=81=EF=BC=81=EF=BC=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hexiangyun --- ResourcesInitializerUtil.java | 145 +++++++++++++++++++++++++++ SensitiveWordsFilterCheckerUtil.java | 137 +++++++++++++++++++++++++ 2 files changed, 282 insertions(+) create mode 100644 ResourcesInitializerUtil.java create mode 100644 SensitiveWordsFilterCheckerUtil.java diff --git a/ResourcesInitializerUtil.java b/ResourcesInitializerUtil.java new file mode 100644 index 00000000..84f1bba5 --- /dev/null +++ b/ResourcesInitializerUtil.java @@ -0,0 +1,145 @@ +package com.huawei.ci.portal.provider.utils; + +import com.huawei.ci.portal.provider.enums.assistanthelper.AssistantConstants; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.io.*; +import java.util.*; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.stream.Collectors; + +/** + * @Description: 资源文件初始化处理类 + * @ClassName: com.huawei.ci.portal.provider.utils + * @Author: hwx1123794/hexiangyun + * @DateTime: 2022/7/21 10:04 + * @Params: + **/ +@Data +@AllArgsConstructor +@Component +public class ResourcesInitializerUtil { + + private static final Logger logger = LoggerFactory.getLogger(ResourcesInitializerUtil.class); + + private static StringBuilder replaceAll; + + private static String encoding = AssistantConstants.ENCODING; + + private static String replaceStr = AssistantConstants.BE_REPLACE_STR; + + private static int replaceSize = AssistantConstants.BE_REPLACE_SIZE; + + private static String fileName = AssistantConstants.FILE_PATH; + + private static HashSet strings = new HashSet<>(100); + + private static Set allSensitiveWordSet = new HashSet<>(); + + private static Map afterDealingSensitiveWords = new HashMap<>(); + + + /** + * 文件 + * + * @param fileName 词库文件名(含后缀) + */ + public ResourcesInitializerUtil(String fileName) { + this.fileName = fileName; + } + + + /** + * 初始化敏感词库 + * + * @return + */ + protected Map InitializationWorkUtil() { + replaceAll = new StringBuilder(replaceSize); + for (int x = 0; x < replaceSize; x++) { + replaceAll.append(replaceStr); + } + InputStreamReader read = null; + BufferedReader bufferedReader = null; + ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock(); + // 读锁加锁 + reentrantReadWriteLock.readLock().lock(); + try { + logger.info("Init sensitive-words configuration start "); + read = new InputStreamReader(Objects.requireNonNull(ResourcesInitializerUtil.class.getClassLoader() + .getResourceAsStream(fileName)), encoding); + // 缓冲区大小 手动设置为80K + bufferedReader = new BufferedReader(read, 81920); + allSensitiveWordSet = bufferedReader.lines().collect(Collectors.toSet()); + // 构造属性 + afterDealingSensitiveWords = addSensitiveWords2HashConstruct(allSensitiveWordSet); + logger.info("Init sensitive-words configuration success "); + + } catch (IOException e) { + logger.error("read file failed"); + } finally { + try { + if (null != bufferedReader) + // 缓冲流关闭 + bufferedReader.close(); + } catch (IOException e) { + logger.error("shutdown Buffered streamline failed, caused by: " + e); + } + try { + if (null != read) + // IO流关闭 + read.close(); + } catch (IOException e) { + logger.error("shutdown IO streamline failed , caused by: " + e); + } + // 释放 + reentrantReadWriteLock.readLock().unlock(); + } + return afterDealingSensitiveWords; + } + + + /** + * DFA算法构造敏感词树形结构 (凡是相同字符开头的都在同一个HashMap + 树形结构 ) + * + * @param sensitiveWords 从文件中读取的敏感词集合 + * @return + */ + private HashMap addSensitiveWords2HashConstruct(Set sensitiveWords) { + // 关键字 整理成 Hash->树形 结构。 + HashMap sensitiveWordsMap = new HashMap(sensitiveWords.size()); + String currentWord = null; + Map childMap = null; + Map newWordMap = new HashMap<>(); + // 处理敏感词 + Iterator iterator = sensitiveWords.iterator(); + while (iterator.hasNext()) { + currentWord = iterator.next(); + childMap = sensitiveWordsMap; + // 关键字构造树形结构 + for (int i = 0; i < currentWord.length(); i++) { + char key = currentWord.charAt(i); + Object wordMap = childMap.get(key); + if (wordMap != null) { + childMap = (Map) wordMap; + } else { + newWordMap = new HashMap<>(); + // 添加标记位 + newWordMap.put("isEnd", "0"); + childMap.put(key, newWordMap); + childMap = newWordMap; + } + // 最后一位 + if (i == currentWord.length() - 1) { + childMap.put("isEnd", "1"); + } + } + } + return sensitiveWordsMap; + } +} diff --git a/SensitiveWordsFilterCheckerUtil.java b/SensitiveWordsFilterCheckerUtil.java new file mode 100644 index 00000000..5d0203d4 --- /dev/null +++ b/SensitiveWordsFilterCheckerUtil.java @@ -0,0 +1,137 @@ +package com.huawei.ci.portal.provider.utils; + +import com.huawei.ci.portal.provider.enums.assistanthelper.AssistantConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.util.*; + +/** + * @Description: 敏感词过滤工具,过滤不雅词汇 + * @ClassName: com.huawei.ci.portal.provider.utils + * @Author: hwx1123794/hexiangyun + * @DateTime: 2022/7/21 15:54 + * @Params: + **/ +@Component +public class SensitiveWordsFilterCheckerUtil { + + private static final Logger logger = LoggerFactory.getLogger(SensitiveWordsFilterCheckerUtil.class); + + private static final Map sensitiveWordsMap; + + // 最小匹配 + private static final Integer minMatchType = 1; + + // 完全匹配 + private static final Integer maxMatchType = 2; + + static { + sensitiveWordsMap = new ResourcesInitializerUtil().InitializationWorkUtil(); + } + + + /** + * 校验是否包含敏感词 + * + * @param txt 待判断文本 + * @param start 起始位置 + * @param matchType 匹配类型: 1 最小匹配原则;2 最大匹配原则 + * @return 大于0表示包含敏感词且表示敏感词匹配长度,否则不包含 + */ + private static Integer checkIfExistSensitiveWords(String txt, Integer start, Integer matchType) { + Boolean flag = false; + char word; + // 匹配标记位 + Integer matchFlag = 0; + Map childMap = sensitiveWordsMap; + for (int i = start; i < txt.length(); i++) { + word = txt.charAt(i); + childMap = (Map) childMap.get(word); + if (childMap == null) { + break; + } else { + // 匹配标记位+1 + matchFlag++; + // isEnd标记位 = 1时,匹配到了末尾 + if ("1".equals(childMap.get("isEnd"))) { + flag = true; + if (minMatchType.equals(matchType)) { + break; + } + } + } + } + if (matchFlag < 2 || !flag) { + // 匹配长度需大于2才为词,并且敏感词已结束 + matchFlag = 0; + } + return matchFlag; + } + + /** + * 获取所有敏感词 + * + * @param txt 待判断文本 + * @param matchType 匹配类型: 1 最小匹配原则;2 最大匹配原则 + * @return + */ + public static Set getSensitiveWords(String txt, Integer matchType) { + Set sensitiveWords = new HashSet<>(); + for (int i = 0; i < txt.length(); i++) { + // 判断敏感词所在文本内容中的 起始点 + Integer length = checkIfExistSensitiveWords(txt, i, matchType); + if (length > 0) { + sensitiveWords.add(txt.substring(i, i + length)); + // 循环i会+1,所以需-1 + i = i + length - 1; + } + } + return sensitiveWords; + } + + /** + * 替换敏感词 + * + * @param txtOfInput 文本 + * @param matchType 匹配类型: 1 最小匹配原则;2 最大匹配原则 + * @param replaceStr 替换字符 + * @return 处理后的文本 + */ + public String replaceSensitiveWords(String txtOfInput, Integer matchType, String replaceStr) { + if (txtOfInput == null || "".equals(txtOfInput)) { + return txtOfInput; + } + Set sensitiveWords = getSensitiveWords(txtOfInput, matchType); + Iterator iterator = sensitiveWords.iterator(); + String replaceString = ""; + while (iterator.hasNext()) { + String sWord = iterator.next(); + // 替换敏感词内容 + replaceString = getReplaceString(replaceStr, sWord.length()); + txtOfInput = txtOfInput.replaceAll(sWord, replaceString); + } + return txtOfInput; + } + + /** + * 获取需要替换的文本 + * + * @param length 要替换的文本长度 + * @param replaceStr 将要替换的文本符号 + */ + private static String getReplaceString(String replaceStr, Integer length) { + if (replaceStr == null) { + // 使用 * 替换敏感词。 在 AssistantConstants中配置 + replaceStr = AssistantConstants.BE_REPLACE_STR; + } + StringBuffer replaceString = new StringBuffer(); + for (int i = 0; i < length; i++) { + replaceString.append(replaceStr); + } + return replaceString.toString(); + } + +} + -- Gitee From 5b097cbc39022f87355c514d402cc771de7c1dba Mon Sep 17 00:00:00 2001 From: hexiangyun Date: Thu, 25 Aug 2022 03:51:47 +0000 Subject: [PATCH 4/5] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20Sens?= =?UTF-8?q?itiveWordsFilterCheckerUtil.java?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SensitiveWordsFilterCheckerUtil.java | 137 --------------------------- 1 file changed, 137 deletions(-) delete mode 100644 SensitiveWordsFilterCheckerUtil.java diff --git a/SensitiveWordsFilterCheckerUtil.java b/SensitiveWordsFilterCheckerUtil.java deleted file mode 100644 index 5d0203d4..00000000 --- a/SensitiveWordsFilterCheckerUtil.java +++ /dev/null @@ -1,137 +0,0 @@ -package com.huawei.ci.portal.provider.utils; - -import com.huawei.ci.portal.provider.enums.assistanthelper.AssistantConstants; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -import java.util.*; - -/** - * @Description: 敏感词过滤工具,过滤不雅词汇 - * @ClassName: com.huawei.ci.portal.provider.utils - * @Author: hwx1123794/hexiangyun - * @DateTime: 2022/7/21 15:54 - * @Params: - **/ -@Component -public class SensitiveWordsFilterCheckerUtil { - - private static final Logger logger = LoggerFactory.getLogger(SensitiveWordsFilterCheckerUtil.class); - - private static final Map sensitiveWordsMap; - - // 最小匹配 - private static final Integer minMatchType = 1; - - // 完全匹配 - private static final Integer maxMatchType = 2; - - static { - sensitiveWordsMap = new ResourcesInitializerUtil().InitializationWorkUtil(); - } - - - /** - * 校验是否包含敏感词 - * - * @param txt 待判断文本 - * @param start 起始位置 - * @param matchType 匹配类型: 1 最小匹配原则;2 最大匹配原则 - * @return 大于0表示包含敏感词且表示敏感词匹配长度,否则不包含 - */ - private static Integer checkIfExistSensitiveWords(String txt, Integer start, Integer matchType) { - Boolean flag = false; - char word; - // 匹配标记位 - Integer matchFlag = 0; - Map childMap = sensitiveWordsMap; - for (int i = start; i < txt.length(); i++) { - word = txt.charAt(i); - childMap = (Map) childMap.get(word); - if (childMap == null) { - break; - } else { - // 匹配标记位+1 - matchFlag++; - // isEnd标记位 = 1时,匹配到了末尾 - if ("1".equals(childMap.get("isEnd"))) { - flag = true; - if (minMatchType.equals(matchType)) { - break; - } - } - } - } - if (matchFlag < 2 || !flag) { - // 匹配长度需大于2才为词,并且敏感词已结束 - matchFlag = 0; - } - return matchFlag; - } - - /** - * 获取所有敏感词 - * - * @param txt 待判断文本 - * @param matchType 匹配类型: 1 最小匹配原则;2 最大匹配原则 - * @return - */ - public static Set getSensitiveWords(String txt, Integer matchType) { - Set sensitiveWords = new HashSet<>(); - for (int i = 0; i < txt.length(); i++) { - // 判断敏感词所在文本内容中的 起始点 - Integer length = checkIfExistSensitiveWords(txt, i, matchType); - if (length > 0) { - sensitiveWords.add(txt.substring(i, i + length)); - // 循环i会+1,所以需-1 - i = i + length - 1; - } - } - return sensitiveWords; - } - - /** - * 替换敏感词 - * - * @param txtOfInput 文本 - * @param matchType 匹配类型: 1 最小匹配原则;2 最大匹配原则 - * @param replaceStr 替换字符 - * @return 处理后的文本 - */ - public String replaceSensitiveWords(String txtOfInput, Integer matchType, String replaceStr) { - if (txtOfInput == null || "".equals(txtOfInput)) { - return txtOfInput; - } - Set sensitiveWords = getSensitiveWords(txtOfInput, matchType); - Iterator iterator = sensitiveWords.iterator(); - String replaceString = ""; - while (iterator.hasNext()) { - String sWord = iterator.next(); - // 替换敏感词内容 - replaceString = getReplaceString(replaceStr, sWord.length()); - txtOfInput = txtOfInput.replaceAll(sWord, replaceString); - } - return txtOfInput; - } - - /** - * 获取需要替换的文本 - * - * @param length 要替换的文本长度 - * @param replaceStr 将要替换的文本符号 - */ - private static String getReplaceString(String replaceStr, Integer length) { - if (replaceStr == null) { - // 使用 * 替换敏感词。 在 AssistantConstants中配置 - replaceStr = AssistantConstants.BE_REPLACE_STR; - } - StringBuffer replaceString = new StringBuffer(); - for (int i = 0; i < length; i++) { - replaceString.append(replaceStr); - } - return replaceString.toString(); - } - -} - -- Gitee From 11d56a40d4eca0e28ac70a300e3670dfd7403682 Mon Sep 17 00:00:00 2001 From: hexiangyun Date: Thu, 25 Aug 2022 03:52:37 +0000 Subject: [PATCH 5/5] =?UTF-8?q?codecheck2.0=20=E6=B5=8B=E8=AF=95=20codeche?= =?UTF-8?q?ck2.0=20=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hexiangyun --- Auth.java | 11 ++++ PublicKeyAuth.java | 129 +++++++++++++++++++++++++++++++++++++++++++++ RightManager.java | 22 ++++++++ 3 files changed, 162 insertions(+) create mode 100644 Auth.java create mode 100644 PublicKeyAuth.java create mode 100644 RightManager.java diff --git a/Auth.java b/Auth.java new file mode 100644 index 00000000..ce38d48c --- /dev/null +++ b/Auth.java @@ -0,0 +1,11 @@ +package com.huawei.ci.gateway.common; + + +import com.huawei.ci.gateway.model.UserContext; + +import java.io.IOException; + +public interface Auth { + UserContext auth(String au) throws IOException; + String getLoginUrl(); +} diff --git a/PublicKeyAuth.java b/PublicKeyAuth.java new file mode 100644 index 00000000..59235b5d --- /dev/null +++ b/PublicKeyAuth.java @@ -0,0 +1,129 @@ +package com.huawei.ci.gateway.common; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.huawei.ci.gateway.model.UserContext; +import org.apache.commons.lang.StringUtils; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + + +/** + * 普通的登录校验 + */ +public class PublicKeyAuth implements Auth { + private static final int FIVE_MINUTES = 300000; + private static final int TIME_OUT = 10000; + private static final String[] SIGHATURE_FIELDS = {"user", "nonce", "timestamp"}; + private static final PublicKeyAuth AUTH = new PublicKeyAuth(); + private static final String ACCOUNT_SERVICE_URL = "cse://account"; + public static PublicKeyAuth getInstance(){ + return AUTH; + } + + /** + * 通过签名拿用户登录信息 + */ + @Override + public UserContext auth(String au) throws IOException { + ObjectMapper objectMapper = new ObjectMapper(); + Map codeInfo = objectMapper.readValue(au, HashMap.class); + if (codeInfo == null) { + throw new SecurityException("403 auth failed"); + } + Map params = (Map) codeInfo.get("authorization"); + String userName = params.get("user").toString(); + String pk = params.get("pk").toString(); + + //解密签名,获得签名json对象 + String signature = codeInfo.get("signature").toString(); + String publicKey = getMatchedPk(userName, pk); + if (StringUtils.isEmpty(publicKey)) { + throw new SecurityException("user's matched pk dose not find."); + } + Map signatureParams = decoder(signature, publicKey); + if (signatureParams == null) { + throw new SecurityException("403 auth failed."); + } + //签名中信息必须一致 + for (String field : SIGHATURE_FIELDS) { + if (!params.get(field).equals(signatureParams.get(field))) { + throw new SecurityException("403 auth failed."); + } + } + + Long timestamp = (Long) params.get("timestamp"); + //签名不能超时 + if (System.currentTimeMillis() - timestamp > FIVE_MINUTES) { + throw new SecurityException("403 auth failed."); + } + return getUserContext(userName); + } + + @Override + public String getLoginUrl() { + return null; + } + + //获取签名对象 + private String getMatchedPk(String user, String pk) { + HttpClientBuilder clientBuilder = HttpClients.custom(); + CloseableHttpClient httpClient = clientBuilder.build(); + HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); + requestFactory.setConnectionRequestTimeout(TIME_OUT); + requestFactory.setConnectTimeout(TIME_OUT); + requestFactory.setReadTimeout(TIME_OUT); + requestFactory.setHttpClient(httpClient); +// RestTemplate restTemplate = RestTemplateBuilder.create(); +// restTemplate.setRequestFactory(requestFactory); +// String accountPKRestUrl = ACCOUNT_SERVICE_URL + "/users/" + user + "/pks"; +// ResponseEntity response = restTemplate.getForEntity(accountPKRestUrl, RestResponse.class); +// RestResponse restResponse = response.getBody(); +// if (restResponse == null) { +// return ""; +// } +// List> userPkMapList = (List>) restResponse.getData(); +// if (userPkMapList.stream().map(userPk -> userPk.get("pk").trim()) +// .anyMatch(value -> value.equals(pk.trim()))) { +// return pk; +// } + return ""; + } + + private UserContext getUserContext(String user) { + HttpClientBuilder clientBuilder = HttpClients.custom(); + CloseableHttpClient httpClient = clientBuilder.build(); + HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); + requestFactory.setConnectionRequestTimeout(TIME_OUT); + requestFactory.setConnectTimeout(TIME_OUT); + requestFactory.setReadTimeout(TIME_OUT); + requestFactory.setHttpClient(httpClient); +// RestTemplate restTemplate = RestTemplateBuilder.create(); +// restTemplate.setRequestFactory(requestFactory); +// String accountPKRestUrl = ACCOUNT_SERVICE_URL + "/users/" + user; +// ResponseEntity response = restTemplate.getForEntity(accountPKRestUrl, RestResponse.class); +// RestResponse restResponse = response.getBody(); +// if (restResponse == null) { +// throw new SecurityException(); +// } +// Map userMap = (Map) restResponse.getData(); + UserContext userContext = new UserContext(); +// userContext.setId(userMap.get("id")); +// userContext.setName(userMap.get("name")); +// userContext.getExtendInfo().put("account", userMap.get("account")); +// userContext.setType(UserContext.AuthType.PK); +// userContext.setRandomCsrfToken(); + return userContext; + } + + // todo 转码 + private Map decoder(String sigature, String publicKey) { + Map signatureParams = null; + return signatureParams; + } +} diff --git a/RightManager.java b/RightManager.java new file mode 100644 index 00000000..fa1332ea --- /dev/null +++ b/RightManager.java @@ -0,0 +1,22 @@ +package com.huawei.ci.gateway.common; + +import com.huawei.ci.gateway.model.UserContext; +import com.netflix.config.DynamicPropertyFactory; +import io.vertx.core.http.HttpMethod; + +public class RightManager { + + private DynamicPropertyFactory propertyFactory=DynamicPropertyFactory.getInstance(); + + public static RightManager instance() { + return new RightManager(); + } + + /** + * todo 获取认证模式 + */ + public UserContext.AuthType getURLAuthType(String url, HttpMethod method){ + String model=propertyFactory.getStringProperty("ci.model","public").getValue(); + return UserContext.AuthType.PK; + } +} -- Gitee