diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..1879e48a370ea47b43ed19755df4abb2d297fbe5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,24 @@
+
+# Binaries for programs and plugins
+*.exe
+*.exe~
+*.dll
+*.so
+*.dylib
+
+# Test binary, built with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+# Dependency directories (remove the comment below to include it)
+# vendor/
+.idea/
+.git/
+.gitee/
+go.sum
+logs/
+lastupdate.tmp
+commentsRouter_controllers.go
+commentsRouter___________________goWork_src_cvevulner_controllers.go
\ No newline at end of file
diff --git a/README.md b/README.md
index c4ae9957d10d2dbd02c6394a25596b31ac40ef17..18b87b9cc0f3bc24275742a820aace78287a543c 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,44 @@
-# cve-manager
+# cvevulner
#### 介绍
-Collect cve security vulnerabilities, submit the vulnerabilities to the corresponding version on gitee, notify the warehouse manager to repair, and finally publish the repaired information to an automated tool on the openEuler website.
+{**以下是码云平台说明,您可以替换此简介**
+码云是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台
+无论是个人、团队、或是企业,都能够用码云实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
#### 软件架构
软件架构说明
+##### issue 分析评论规则
+issue分析员注意事项
+1. 分析以/analysis标识开始
+2. 分析完结以 /end 结束
+3. 分析issue后需要在评论中修改issue中的模板字段值必须用对应评论标签包裹
+
+ | 模板字段中文名 | 模板字段英文名 | 评论标签 |
+ | ------------- | ------------- | ------------- |
+ | 漏洞编号 | Loophole number| [LN][/LN] |
+ | 漏洞组件 | loophole ascription component | [LAC][/LAC] |
+ | 漏洞版本 | loophole ascription version | [LAV][/LAV] |
+ | CVSS v3.0分值 | cvss v3.0 score | [CVS][/CVS] |
+ | CVSS 向量 | cvss V3.1 vector | [CVV][/CVV] |
+ | 漏洞 描述 | loophole description | [LD][/LD] |
+ | 影响分析说明 | impact analysis description | [IAD][/IAD] |
+ | 原理分析 | principle analysis | [PA][/PA] |
+ | openEuler评分 | openEuler score | [OES][/OES] |
+ | openEuler向量 | openEuler Vector | [OEV][/OEV] |
+ | 影响的版本 | impact version | [IV][/IV] |
+ | 规避方案和措施 | Circumvention plan or mitigation measures | [CPMM][/CPMM] |
+ | 影响的包 | impact wrap| [IW][/IW]
+- 分析issue填写模板(ps 每一次分析评论必须用/analysis指令 填写项可以一次填完也可不填写完 填写完成加上/done指令
+ /analysis
+ 影响分析说明:[IAD]此处为填写影响分析说明的内容[/IAD]
+ 原理分析:[PA]此处为填写原理分析的内容[/PA]
+ openEuler评分:[OES]此处为填写openEuler评分的内容[/OES]
+ openEuler向量:[OEV]此处为填写openEuler向量的内容[/OEV]
+ 影响的版本:[IV]此处为填写影响版本的内容[/IV]
+ 规避方案和措施:[IV]此处为填写规避方案和措施的内容[/IV]
+ 影响的包:[IW]此处为填写影响的包的内容(内容以英文逗号分隔)[/IW]
+ /done
+
#### 安装教程
diff --git a/common/aes.go b/common/aes.go
new file mode 100644
index 0000000000000000000000000000000000000000..c4a15c8d28c9613fb3c903beba938f7b74304886
--- /dev/null
+++ b/common/aes.go
@@ -0,0 +1,239 @@
+package common
+
+import (
+ "bytes"
+ "crypto/aes"
+ "crypto/cipher"
+ "encoding/base64"
+ "errors"
+ "flag"
+ "fmt"
+ "github.com/astaxie/beego/logs"
+ "math/rand"
+ "time"
+ jwt "github.com/dgrijalva/jwt-go"
+)
+
+
+//PKCS7 填充模式
+func PKCS7Padding(ciphertext []byte, blockSize int) []byte {
+ padding := blockSize - len(ciphertext)%blockSize
+ //Repeat()函数的功能是把切片[]byte{byte(padding)}复制padding个,然后合并成新的字节切片返回
+ padtext := bytes.Repeat([]byte{byte(padding)}, padding)
+ return append(ciphertext, padtext...)
+}
+
+//填充的反向操作,删除填充字符串
+func PKCS7UnPadding(origData []byte) ([]byte, error) {
+ //获取数据长度
+ length := len(origData)
+ if length == 0 {
+ return nil, errors.New("加密字符串错误!")
+ } else {
+ //获取填充字符串长度
+ unpadding := int(origData[length-1])
+ //截取切片,删除填充字节,并且返回明文
+ return origData[:(length - unpadding)], nil
+ }
+}
+
+//实现加密
+func AesEcrypt(origData []byte, key []byte) ([]byte, error) {
+ //创建加密算法实例
+ block, err := aes.NewCipher(key)
+ if err != nil {
+ return nil, err
+ }
+ //获取块的大小
+ blockSize := block.BlockSize()
+ //对数据进行填充,让数据长度满足需求
+ origData = PKCS7Padding(origData, blockSize)
+ //采用AES加密方法中CBC加密模式
+ blocMode := cipher.NewCBCEncrypter(block, key[:blockSize])
+ crypted := make([]byte, len(origData))
+ //执行加密
+ blocMode.CryptBlocks(crypted, origData)
+ return crypted, nil
+}
+
+//实现解密
+func AesDeCrypt(cypted []byte, key []byte) ([]byte, error) {
+ //创建加密算法实例
+ block, err := aes.NewCipher(key)
+ if err != nil {
+ return nil, err
+ }
+ //获取块大小
+ blockSize := block.BlockSize()
+ //创建加密客户端实例
+ blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
+ origData := make([]byte, len(cypted))
+ //这个函数也可以用来解密
+ blockMode.CryptBlocks(origData, cypted)
+ //去除填充字符串
+ origData, err = PKCS7UnPadding(origData)
+ if err != nil {
+ return nil, err
+ }
+ return origData, err
+}
+
+//加密base64
+func EnPwdCode(pwd []byte, key []byte) (string, error) {
+ result, err := AesEcrypt(pwd, key)
+ if err != nil {
+ return "", err
+ }
+ return base64.StdEncoding.EncodeToString(result), err
+}
+
+//解密
+func DePwdCode(pwd string, key []byte) ([]byte, error) {
+ //解密base64字符串
+ pwdByte, err := base64.StdEncoding.DecodeString(pwd)
+ if err != nil {
+ return nil, err
+ }
+ //执行AES解密
+ return AesDeCrypt(pwdByte, key)
+
+}
+//func main() {
+// str := []byte("12fff我是ww.topgoer.com的站长枯藤")
+// pwd, _ := EnPwdCode(str)
+// bytes, _ := DePwdCode(pwd)
+// fmt.Println(string(bytes))
+//}
+
+var (
+ length int
+ charset string
+)
+
+const (
+ NUmStr = "0123456789"
+ CharStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+ SpecStr = "+=-@#~,.[]()!%^*$"
+)
+
+//解析参数
+func parseArgs(lens int) {
+ //需要接受指针,就传递地址,&
+ //flag.IntVar(&length, "l", 16, "-l 生成密码的长度")
+ //flag.StringVar(&charset, "t", "num",
+ // //反引号以原样输出
+ // `-t 制定密码生成的字符集,
+ // num:只使用数字[0-9],
+ // char:只使用英文字母[a-zA-Z],
+ // mix:使用数字和字母,
+ // advance:使用数字、字母以及特殊字符`)
+ length = lens
+ charset = "advance"
+ flag.Parse()
+}
+
+//检测字符串中的空格
+func test1() {
+ for i := 0; i < len(CharStr); i++ {
+ if CharStr[i] != ' ' {
+ fmt.Printf("%c", CharStr[i])
+ }
+ }
+}
+
+func generatePasswd() string {
+ //初始化密码切片
+ var passwd []byte = make([]byte, length, length)
+ //源字符串
+ var sourceStr string
+ //判断字符类型,如果是数字
+ if charset == "num" {
+ sourceStr = NUmStr
+ //如果选的是字符
+ } else if charset == "char" {
+ sourceStr = charset
+ //如果选的是混合模式
+ } else if charset == "mix" {
+ sourceStr = fmt.Sprintf("%s%s", NUmStr, CharStr)
+ //如果选的是高级模式
+ } else if charset == "advance" {
+ sourceStr = fmt.Sprintf("%s%s%s", NUmStr, CharStr, SpecStr)
+ } else {
+ sourceStr = NUmStr
+ }
+ fmt.Println("source:", sourceStr)
+
+ //遍历,生成一个随机index索引,
+ for i := 0; i < length; i++ {
+ index := rand.Intn(len(sourceStr))
+ passwd[i] = sourceStr[index]
+ }
+ return string(passwd)
+}
+
+func GenPrivKey(lens int) string{
+ //随机种子
+ rand.Seed(time.Now().UnixNano())
+ parseArgs(lens)
+ //fmt.Printf("length:%d charset:%s\n", length, charset)
+ //test1()
+ passwd := generatePasswd()
+ fmt.Println(passwd)
+ fmt.Printf("length:%d charset:%s\n", length, charset)
+ return passwd
+}
+
+
+
+type Claims struct {
+ username string
+ password string
+ jwt.StandardClaims
+}
+
+func setting(jwtkey []byte, username, password string) (string, error){
+ expireTime := time.Now().Add(7 * 24 * time.Hour)
+ claims := &Claims{
+ username: username,
+ password: password,
+ StandardClaims: jwt.StandardClaims{
+ ExpiresAt: expireTime.Unix(), //过期时间
+ IssuedAt: time.Now().Unix(),
+ Issuer: "127.0.0.1", // 签名颁发者
+ Subject: "user token", //签名主题
+ },
+ }
+ token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
+ // fmt.Println(token)
+ tokenString, err := token.SignedString(jwtkey)
+ if err != nil {
+ logs.Error(err)
+ return "", err
+ }
+ return tokenString, nil
+}
+
+func GenToken(username, password string) (string, error){
+ pKey := GenPrivKey(16)
+ var jwtkey = []byte(pKey)
+ tokens,err := setting(jwtkey, username, password)
+ return tokens, err
+}
+
+////解析token
+//func getting(tokenString string) (string, struct{}){
+// token, claims, err := ParseToken(tokenString)
+// if err != nil || !token.Valid {
+// return "", struct{}{}
+// }
+// return token,
+//}
+//
+//func ParseToken(tokenString string) (*jwt.Token, *Claims, error) {
+// Claims := &Claims{}
+// token, err := jwt.ParseWithClaims(tokenString, Claims, func(token *jwt.Token) (i interface{}, err error) {
+// return jwtkey, nil
+// })
+// return token, Claims, err
+//}
+
diff --git a/common/common.go b/common/common.go
new file mode 100644
index 0000000000000000000000000000000000000000..0e798ddbaab478d190a6ec367ec82c1f15c0cbee
--- /dev/null
+++ b/common/common.go
@@ -0,0 +1,300 @@
+package common
+
+import (
+ "github.com/astaxie/beego"
+ "github.com/astaxie/beego/logs"
+ "strings"
+ "time"
+)
+
+func DesString(dbpwd string) (strs string) {
+ if "" != dbpwd || len(dbpwd) > 0 {
+ key := beego.AppConfig.String("key")
+ key1 := []byte(key)
+ bytes, _ := DePwdCode(dbpwd, key1)
+ strs = string(bytes)
+ } else {
+ strs = ""
+ }
+ return strs
+}
+
+
+func GetTokenExpirTime() (token_expir_time int) {
+ token_expir_time, err := beego.AppConfig.Int("token_expir_time")
+ if err == nil {
+ return token_expir_time
+ }
+ return 3
+}
+
+
+func VectorParams(Vector string, VectorMap map[string]string) map[string]string{
+ if Vector != "" || len(Vector) != 0{
+ VertorList := strings.Split(Vector, "/")
+ if VertorList != nil && len(VertorList) > 0 {
+ for _, vule := range VertorList {
+ if strings.Contains(vule, ":") {
+ SubList := strings.Split(vule, ":")
+ if SubList != nil && len(SubList) == 2 {
+ VerKey := strings.ToUpper(SubList[0])
+ verVule := strings.ToUpper(SubList[1])
+ switch VerKey {
+ case "AV":
+ if verVule == "N" {
+ VectorMap["NattackVector"] = "Network"
+ } else {
+ VectorMap["NattackVector"] = "Local"
+ }
+ case "AC":
+ if verVule == "L" {
+ VectorMap["NattackComplexity"] = "Low"
+ } else if verVule == "H"{
+ VectorMap["NattackComplexity"] = "High"
+ } else {
+ VectorMap["NattackComplexity"] = "None"
+ }
+ case "PR":
+ if verVule == "L" {
+ VectorMap["NprivilegeRequired"] = "Low"
+ } else if verVule == "H"{
+ VectorMap["NprivilegeRequired"] = "High"
+ } else {
+ VectorMap["NprivilegeRequired"] = "None"
+ }
+ case "UI":
+ if verVule == "L" {
+ VectorMap["NuserInteraction"] = "Low"
+ } else if verVule == "H"{
+ VectorMap["NuserInteraction"] = "High"
+ } else {
+ VectorMap["NuserInteraction"] = "None"
+ }
+ case "S":
+ if verVule == "U" {
+ VectorMap["Nscope"] = "Unchanged"
+ } else {
+ VectorMap["Nscope"] = "None"
+ }
+ case "C":
+ if verVule == "L" {
+ VectorMap["Nconfidentiality"] = "Low"
+ } else if verVule == "H"{
+ VectorMap["Nconfidentiality"] = "High"
+ } else {
+ VectorMap["Nconfidentiality"] = "None"
+ }
+ case "I":
+ if verVule == "L" {
+ VectorMap["Nintegrity"] = "Low"
+ } else if verVule == "H"{
+ VectorMap["Nintegrity"] = "High"
+ } else {
+ VectorMap["Nintegrity"] = "None"
+ }
+ case "A":
+ if verVule == "L" {
+ VectorMap["Navailability"] = "Low"
+ } else if verVule == "H"{
+ VectorMap["Navailability"] = "High"
+ } else {
+ VectorMap["Navailability"] = "None"
+ }
+ default:
+ VectorMap = make(map[string]string)
+ }
+ }
+ }
+ }
+ }
+ }
+ return VectorMap
+}
+
+func GetCurTime() string{
+ return time.Now().Format("2006-01-02 15:04:05")
+}
+
+func GetBeforeTime(days int) string {
+ nowTime := time.Now()
+ getTime := nowTime.AddDate(0, 0, days) //年,月,日 获取一天前的时间
+ resTime := getTime.Format("2006-01-02 15:04:05") //获取的时间的格式
+ logs.Info("获取:", days, "前的时间:", resTime)
+
+ //getTime = nowTime.AddDate(0, -1, 0) //年,月,日 获取一个月前的时间
+ //resTime = getTime.Format("2006-01-02 15:04:05") //获取的时间的格式
+ //fmt.Println(resTime)
+ //
+ //getTime = nowTime.AddDate(-2, 0, 0) //年,月,日 获取两年前的时间
+ //resTime = getTime.Format("20060102") //获取的时间的格式
+ //fmt.Println(resTime)
+ return resTime
+}
+
+func Catchs() {
+ if err := recover(); err != nil {
+ logs.Error("程序发生异常, err: ", err)
+ }
+}
+
+
+func DeletePreAndSufSpace(str string) string {
+ strList := []byte(str)
+ spaceCount, count := 0, len(strList)
+ for i := 0; i <= len(strList)-1; i++ {
+ if strList[i] == 32 {
+ spaceCount++
+ } else {
+ break
+ }
+ }
+ strList = strList[spaceCount:]
+ spaceCount, count = 0, len(strList)
+ for i := count - 1; i >= 0; i-- {
+ if strList[i] == 32 {
+ spaceCount++
+ } else {
+ break
+ }
+ }
+ return string(strList[:count-spaceCount])
+}
+
+type CveDescription struct {
+ EnDesc string `json:"en"`
+ ZhDesc string `json:"zh"`
+}
+
+type NodeCpe struct {
+ Cpe23Uri string `json:"cpe23Uri"`
+ CpeMatchString string `json:"cpeMatchString"`
+ Vulnerable string `json:"vulnerable"`
+}
+
+type ConfNodes struct {
+ Operator string `json:"operator"`
+ Cpe []NodeCpe `json:"cpe"`
+}
+
+type CveConfigurations struct {
+ Nodes []ConfNodes `json:"nodes"`
+}
+
+type BmCvssV3 struct {
+ VectorString string `json:"vectorString"`
+ AttackComplexity string `json:"attackComplexity"`
+ AttackVector string `json:"attackVector"`
+ AvailabilityImpact string `json:"availabilityImpact"`
+ BaseSeverity string `json:"baseSeverity"`
+ UserInteraction string `json:"userInteraction"`
+ BaseScore float64 `json:"baseScore"`
+ PrivilegesRequired string `json:"privilegesRequired"`
+ Version string `json:"version"`
+ ConfidentialityImpact string `json:"confidentialityImpact"`
+ IntegrityImpact string `json:"integrityImpact"`
+ Scope string `json:"scope"`
+}
+
+type ImBaseMetricV3 struct {
+ CvssV3 BmCvssV3 `json:"cvssV3"`
+ ImpactScore float64 `json:"impactScore"`
+ ExploitabilityScore float64 `json:"exploitabilityScore"`
+}
+
+type BmCvssV2 struct {
+ VectorString string `json:"vectorString"`
+ AccessComplexity string `json:"accessComplexity"`
+ AvailabilityImpact string `json:"availabilityImpact"`
+ Authentication string `json:"authentication"`
+ Version string `json:"version"`
+ BaseScore float64 `json:"baseScore"`
+ IntegrityImpact string `json:"integrityImpact"`
+ ConfidentialityImpact string `json:"confidentialityImpact"`
+ AccessVector string `json:"accessVector"`
+}
+
+type ImBaseMetricV2 struct {
+ AcInsufInfo string `json:"acInsufInfo"`
+ CvssV2 BmCvssV2 `json:"cvssV2"`
+ UserInteractionRequired string `json:"userInteractionRequired"`
+ Severity string `json:"severity"`
+ ObtainUserPrivilege string `json:"obtainUserPrivilege"`
+ ObtainAllPrivilege string `json:"obtainAllPrivilege"`
+ ImpactScore float64 `json:"impactScore"`
+ ExploitabilityScore float64 `json:"exploitabilityScore"`
+ ObtainOtherPrivilege string `json:"obtainOtherPrivilege"`
+}
+
+type CveImpact struct {
+ BaseMetricV3 ImBaseMetricV3 `jsong:"baseMetricV3"`
+ BaseMetricV2 ImBaseMetricV2 `jsong:"baseMetricV2"`
+}
+
+type CvePoc struct {
+ Source string `json:"source"`
+ Date string `json:"date"`
+ Path string `json:"path"`
+ Dbindex string `json:"dbindex"`
+ Url string `json:"url"`
+ Desc string `json:"desc"`
+}
+
+type CveEvent struct {
+ Title string `json:"title"`
+ Date string `json:"date"`
+ Description string `json:"description"`
+ Url string `json:"url"`
+}
+
+type CveReferenceData struct {
+ Url string `json:"url"`
+ Name string `json:"name"`
+ Refsource string `json:"refsource"`
+ Tags []string `json:"tags"`
+}
+
+type CveVulType struct {
+ Cwe string `json:"cwe"`
+ En string `json:"en"`
+ Zh string `json:"zh"`
+}
+
+type FixReferences struct {
+ Url string `json:"url"`
+ Refsource string `json:"refsource"`
+ Name string `json:"name"`
+ Tags []string `json:"tags"`
+}
+
+type CveFixSuggest struct {
+ Detail string `jsong:"detail"`
+ References []FixReferences `jsong:"references"`
+}
+
+type CveOriginData struct {
+ Ids string `json:"ids"`
+ CveNum string `json:"cveNum"`
+ UpdateType string `json:"updateType"`
+ CvePackName string `json:"cvePackName"`
+ PackName string `json:"packName"`
+ Description CveDescription `json:"description"`
+ Title string `json:"title"`
+ AffectProduct string `json:"affectProduct"`
+ Configurations CveConfigurations `json:"configurations"`
+ CnnvdID string `json:"cnnvdID"`
+ CnvdID string `json:"cnvdID"`
+ PublishedDate string `json:"publishedDate"`
+ Impact CveImpact `json:"impact"`
+ VulStatus string `json:"vulStatus"`
+ Poc CvePoc `json:"poc"`
+ Event CveEvent `json:"event"`
+ ReferenceData []CveReferenceData `json:"referenceData"`
+ VulType CveVulType `json:"vulType"`
+ FixSuggest CveFixSuggest `json:"fixSuggest"`
+ Version string `json:"version"`
+}
+
+type UploadData struct {
+ Token string `json:"Token"`
+ CveData []CveOriginData
+}
\ No newline at end of file
diff --git a/common/global.go b/common/global.go
new file mode 100644
index 0000000000000000000000000000000000000000..e5315f62d21f665fb9a701d422a73fcfa2c1cedd
--- /dev/null
+++ b/common/global.go
@@ -0,0 +1,25 @@
+package common
+
+import (
+ "fmt"
+ "os"
+)
+
+type GlobalVal struct {
+ Dbpwd string
+ ClientID string
+ ClientSecret string
+ GitPassword string
+ HookPwd string
+ GitToken string
+}
+
+func InitGlobal() {
+ var gVal GlobalVal
+ gVal.Dbpwd = os.Getenv("Dbpwd")
+ gVal.ClientID = os.Getenv("clientid")
+ gVal.ClientSecret = os.Getenv("clientsecret")
+ gVal.GitPassword = os.Getenv("gitpassword")
+ gVal.HookPwd = os.Getenv("hookpwd")
+ fmt.Println("globalval: ", gVal)
+}
\ No newline at end of file
diff --git a/common/logs.go b/common/logs.go
new file mode 100644
index 0000000000000000000000000000000000000000..423137ecd8e8838c6fea458484564fbeb90cda8e
--- /dev/null
+++ b/common/logs.go
@@ -0,0 +1,43 @@
+package common
+
+import (
+ "encoding/json"
+ "fmt"
+ "github.com/astaxie/beego/config"
+ "github.com/astaxie/beego/logs"
+)
+
+func InitLogger() (err error) {
+ BConfig, err := config.NewConfig("ini", "conf/app.conf")
+ if err != nil{
+ fmt.Println("config init error:", err)
+ return
+ }
+ maxlines, lerr := BConfig.Int64("log::maxlines")
+ if lerr != nil {
+ maxlines = 100000
+ }
+
+ logConf := make(map[string]interface{})
+ logConf["filename"] = BConfig.String("log::log_path")
+ level,_ := BConfig.Int("log::log_level")
+ logConf["level"] = level
+ logConf["maxlines"] = maxlines
+
+ confStr, err := json.Marshal(logConf)
+ if err != nil {
+ fmt.Println("marshal failed,err:", err)
+ return
+ }
+ logs.SetLogger(logs.AdapterFile, string(confStr))
+ logs.SetLogFuncCall(true)
+ return
+}
+
+func LogInit() {
+ err := InitLogger()
+ if err != nil {
+ fmt.Println(err)
+ }
+ fmt.Println("log init success !")
+}
\ No newline at end of file
diff --git a/conf/app.conf b/conf/app.conf
new file mode 100644
index 0000000000000000000000000000000000000000..c41a29d0df27b81cc4a126df2ecc3633311e9c7f
--- /dev/null
+++ b/conf/app.conf
@@ -0,0 +1,87 @@
+appname = cvevulner
+httpport = 80
+runmode = dev
+autorender = false
+copyrequestbody = true
+EnableDocs = true
+sqlconn =
+key = djS*@+8K9{J!ymk6
+initdb = 1
+loginkey = djS*@+8K9{-!yo%64
+# token 有效期,单位:天
+token_expir_time=3
+#分析指令
+analysisCmd = "/analysis"
+endCmd = "/done"
+rejectCmd = "/reject"
+approveCmd = "/approve"
+
+
+
+[mysql]
+dbhost = 127.0.0.1
+dbport = 3306
+#dbuser = "${DB_USER||root}"
+dbuser = "${DB_USER||cve}"
+dbname = cvevulner
+dbprefix = cve_
+maxidle = 30
+maxconn = 3000
+
+
+[log]
+log_level = 7
+#log_path = C:\GoPject\src\cvevulner\logs\cve.log
+log_path = logs/cve.log
+maxlines=10000
+maxsize=1024000
+
+[crontab]
+ymalflag = 2
+cveflag = 2
+oricveflag = 2
+getymal = 00 00 23 * * *
+getcve = 00 00 01 * * *
+oricvecheck = 00 00 02 * * *
+issueflag = 2
+createissue = * */5 * * * *
+test = 0/10 * * * * *
+issueoath = * * */20 * * *
+days = -30
+prcnum = 100
+
+
+[gitee]
+#owner = xwzQmxx
+#path = test
+#email = 1499273991@qq.com
+#redirect_uri = http://119.8.126.102:80/v1/issue/oauth/callback
+# -------jianjun gitee 配置 --------
+owner = zhangjianjun_code
+path = test1
+email = 7844966+zhangjianjun_code@user.noreply.gitee.com
+redirect_uri = http://159.138.2.2:80/v1/issue/oauth/callback
+
+scope = user_info projects pull_requests issues notes keys hook groups gists enterprises emails
+# 优先从系统环境变量获取 获取失败使用默认值 ****
+client_id = "${GITEE_CLIENT_ID||****}"
+client_secret = "${GITEE_CLIENT_SECRET||****}"
+password = "${GITEE_PASSWORD||****}"
+
+# git token
+git_token = "${issueaccesstoken||xxx}"
+
+[hook]
+#hookurl = http://159.138.2.2:80/issue
+hookurl = http://159.138.2.2:80/v1/issue/hook/event
+
+
+[yaml]
+apiurl = https://api.openeuler.org/pkgmanagedebug
+
+[cve]
+cveref = https://nvd.nist.gov/vuln/detail/
+openeulernum = 3000
+
+[reflink]
+comment_cmd = https://gitee.com/zhangjianjun_code/cvevulner/blob/dev/README.md
diff --git a/controllers/hook.go b/controllers/hook.go
new file mode 100644
index 0000000000000000000000000000000000000000..bbae07b22cb2363dfafe5bb672164a01489066af
--- /dev/null
+++ b/controllers/hook.go
@@ -0,0 +1,512 @@
+package controllers
+
+import (
+ "cvevulner/models"
+ "cvevulner/taskhandler"
+ "cvevulner/util"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "github.com/astaxie/beego"
+ "github.com/astaxie/beego/logs"
+ "os"
+ "strconv"
+ "strings"
+)
+
+var (
+ GiteeUserAgent = "git-oschina-hook" //gitee hook request flag
+ XGiteeToken = "X-Gitee-Token" // password or sign
+ XGIteeEventType = "X-Gitee-Event" //webhook event type
+ NoteHookType = "Note Hook" // type of comment
+ PullReqHookType = "merge_request_hooks" // type of pull request
+ PushTagHookType = "push_hooks/tag_push_hooks" // type of push or tag
+ IssueHookType = "Issue Hook" //type of issue
+)
+
+const (
+ CommentAnalysisCplTpl ="@%v %v"
+ ReviewPrivateLettersTpl = `%s(%s)analysis is over,CVEScore:%v;OpenEulerScore:%v。Please review!`
+ ReviewRejectScore = `@%v you submit issue score audit failed(reject by %v),Please re-analyze and submit!`
+ CommentReviewTpl = `@%v The CVE score needs to be reviewed (the review instruction /approve&/reject means agreement and rejection)。`
+ IssueRejectState = "rejected"
+ IssueCloseState = "closed"
+ IssueProgressState = "progressing"
+ IssueOpenState = "open"
+)
+
+type HookEventControllers struct {
+ beego.Controller
+}
+
+//Post handle gitee webhook
+// @router / [post]
+func (c *HookEventControllers) Post() {
+ if ok := c.isLegitimateHookEvent(); !ok {
+ return
+ }
+ eventType := c.Ctx.Request.Header.Get(XGIteeEventType)
+ switch eventType {
+ case NoteHookType: //handle comment hook data
+ c.handleNoteDate()
+ case PullReqHookType:
+ c.handlePullReq()
+ case IssueHookType:
+ c.handleIssue()
+ case PushTagHookType:
+ c.handlePushTag()
+ default:
+ logs.Info(eventType)
+ }
+}
+
+// @router / [get]
+func (c *HookEventControllers) Get() {
+ if ok := c.isLegitimateHookEvent(); !ok {
+ logs.Info("hah:", "giteeUseAgent")
+ return
+ }
+
+}
+
+// isLegitimateHookEvent according to gitee doc judge
+func (c *HookEventControllers) isLegitimateHookEvent() (ok bool) {
+ ok = true
+ //judge user agent
+ uAgent := c.Ctx.Request.Header.Get("User-Agent")
+ if uAgent != GiteeUserAgent {
+ ok = false
+ }
+ ctType := c.Ctx.Request.Header.Get("Content-Type")
+ if "application/json" != ctType {
+ ok = false
+ }
+ //judge hook password
+ xToken := c.Ctx.Request.Header.Get(XGiteeToken)
+ logs.Info(xToken)
+ return
+}
+
+func (c *HookEventControllers) handleNoteDate() {
+ //logs.Info(string(c.Ctx.Input.RequestBody))
+ var hookNote models.CommentPayload
+ err := json.Unmarshal(c.Ctx.Input.RequestBody, &hookNote)
+ if err != nil {
+ logs.Error(err)
+ return
+ }
+ if hookNote.Action == "comment" && hookNote.NoteableType == "Issue" {
+ //handle issue comment
+ go handleIssueComment(hookNote)
+ }
+}
+
+func (c *HookEventControllers) handlePullReq() {
+
+}
+
+func (c *HookEventControllers) handlePushTag() {
+
+}
+
+func (c *HookEventControllers) handleIssue() {
+ logs.Info(string(c.Ctx.Input.RequestBody))
+ issueHook := models.IssuePayload{}
+ err := json.Unmarshal(c.Ctx.Input.RequestBody, &issueHook)
+ if err != nil{
+ logs.Error(err)
+ return
+ }
+ if issueHook.Action == "state_change"{
+ //handle issue state change
+ err = handleIssueStateChange(&issueHook)
+ if err != nil {
+ logs.Error(err)
+ }
+ }
+
+}
+
+func handleIssueStateChange(issueHook *models.IssuePayload) error{
+ issueTmp := models.IssueTemplate{IssueNum: issueHook.Iid}
+ err := models.GetIssueTemplateByColName(&issueTmp, "issue_num")
+ if err != nil {
+ return err
+ }
+ switch issueHook.State {
+ case IssueOpenState:
+ issueTmp.Status = 1
+ case IssueProgressState:
+ issueTmp.Status = 2
+ case IssueCloseState:
+ issueTmp.Status = 3
+ if isNormalCloseIssue(issueTmp.CveId,issueTmp.IssueStatus){
+ issueTmp.IssueStatus = 2
+ }else {
+ issueTmp.IssueStatus = 6
+ }
+ case IssueRejectState:
+ issueTmp.Status = 4
+ if isNormalCloseIssue(issueTmp.CveId,issueTmp.IssueStatus){
+ issueTmp.IssueStatus = 2
+ }else {
+ issueTmp.IssueStatus = 6
+ }
+ }
+ issueTmp.StatusName = issueHook.Issue.StateName
+ err = models.UpdateIssueTemplate(&issueTmp, "status", "issue_status", "status_name")
+ return err
+}
+
+func isNormalCloseIssue(cveId int64,issueState int8) bool {
+ if issueState == 1{
+ return false
+ }
+ score, err := models.QueryIssueScore(cveId)
+ if err != nil {
+ logs.Error(err)
+ return false
+ }
+ if score.Ostatus != 3 {
+ return false
+ }
+ return true
+}
+
+func handleIssueComment(payload models.CommentPayload) {
+ if payload.Issue == nil || payload.Comment == nil {
+ return
+ }
+ if payload.Comment.User == nil {
+ return
+ }
+ issueNum := payload.Issue.Number //issue 编号
+ cBody := payload.Comment.Body //评论主体
+ cuAccount := payload.Comment.User.UserName //gitee 域地址
+ cmdRej := beego.AppConfig.DefaultString("rejectCmd", "/reject")
+ cmdApe := beego.AppConfig.DefaultString("approveCmd", "/approve")
+ if issueNum == "" || cuAccount == "" || cBody == "" {
+ return
+ }
+ if strings.HasPrefix(cBody, cmdRej) {
+ //审核拒绝 添加评论 @分析人
+ if !isReviewer(cuAccount){
+ return
+ }
+ issueTmp := models.IssueTemplate{IssueNum: issueNum}
+ err := models.GetIssueTemplateByColName(&issueTmp, "issue_num")
+ if err != nil {
+ logs.Error(err)
+ return
+ }
+ err = changeOpenEulerScoreStatus(issueTmp.CveId, 2)
+ if err != nil {
+ logs.Error(err)
+ }
+ accessToken := os.Getenv("issueaccesstoken")
+ owner := beego.AppConfig.String("gitee::owner")
+ path := beego.AppConfig.String("gitee::path")
+ taskhandler.AddCommentToIssue(fmt.Sprintf(ReviewRejectScore,issueTmp.Assignee,cuAccount),issueTmp.IssueNum,owner,path,accessToken)
+ } else if strings.HasPrefix(cBody, cmdApe) {
+ //审核通过 修改评分状态
+ if !isReviewer(cuAccount){
+ return
+ }
+ issueTmp := models.IssueTemplate{IssueNum: issueNum}
+ err := models.GetIssueTemplateByColName(&issueTmp, "issue_num")
+ if err != nil {
+ logs.Error(err)
+ return
+ }
+ err = changeOpenEulerScoreStatus(issueTmp.CveId, 3)
+ if err != nil {
+ logs.Error(err)
+ }
+ } else {
+ analysisComment(issueNum, cuAccount, cBody,&payload)
+ }
+
+}
+
+func isReviewer(path string) bool {
+ sr := models.SecurityReviewer{NameSpace: path}
+ return sr.Read("name_space")
+}
+
+func analysisComment(issueNum string, cuAccount string, cBody string,payload *models.CommentPayload) {
+ cmdAys := beego.AppConfig.DefaultString("analysisCmd", "/analysis")
+ cmdEnd := beego.AppConfig.DefaultString("endCmd", "/done")
+ issueTmp := models.IssueTemplate{IssueNum: issueNum}
+ err := models.GetIssueTemplateByColName(&issueTmp, "issue_num")
+ if err != nil {
+ logs.Error(err)
+ return
+ }
+ if cuAccount == issueTmp.Assignee && strings.Contains(cBody, cmdAys) {
+ //is Analyst comment and content start with '/analysis'
+ vMap := util.ParseCommentWithAllLabel(cBody)
+ if len(vMap) > 0 {
+ cols := make([]string, 0)
+ for k, v := range vMap {
+ switch k {
+ case "cve_analysis":
+ issueTmp.CveAnalysis = v
+ cols = append(cols, k)
+ case "principle_analysis":
+ issueTmp.PrincipleAnalysis = v
+ cols = append(cols, k)
+ case "openeuler_score":
+ fv, err := strconv.ParseFloat(v, 64)
+ if err == nil {
+ issueTmp.OpenEulerScore = fv
+ cols = append(cols, k)
+ }
+ case "openeuler_vector":
+ issueTmp.OpenEulerVector = v
+ cols = append(cols, k)
+ case "affected_version":
+ issueTmp.AffectedVersion = v
+ cols = append(cols, k)
+ case "solution":
+ issueTmp.Solution = v
+ cols = append(cols, k)
+ }
+ }
+ if len(cols) > 0 {
+ err := models.UpdateIssueTemplate(&issueTmp, cols...)
+ if err != nil {
+ logs.Error(err)
+ } else {
+ if _, ok := vMap["openeuler_vector"]; ok {
+ err := saveVectorData(vMap["openeuler_vector"], issueTmp.CveId)
+ if err != nil {
+ logs.Error(err)
+ }
+ }
+ if _, ok := vMap["openeuler_score"]; ok {
+ //更新分数到 score
+ score, err := models.QueryIssueScore(issueTmp.CveId)
+ if err != nil {
+ logs.Error(err)
+ } else {
+ score.OpenEulerScore = issueTmp.OpenEulerScore
+ score.Ostatus = 1
+ err := models.UpdateScore(&score, "openeuler_score","o_score_status")
+ if err != nil {
+ logs.Error(err)
+ }
+ }
+ }
+ }
+ }
+ if _, ok := vMap["issue_package"]; ok {
+ // handle comment package
+ err := handleCommentPackage(vMap["issue_package"], issueTmp.CveId)
+ if err != nil {
+ logs.Error(err)
+ }
+ }
+ }
+ // update gitee issue
+ commentUpdateIssue(issueTmp)
+ }
+ if cuAccount == issueTmp.Assignee && strings.Contains(cBody, cmdEnd) {
+ //Check whether the data is legal
+ if msg,ok :=checkIssueAnalysisComplete(&issueTmp);!ok{
+ //send comment to issue
+ msg = fmt.Sprintf(CommentAnalysisCplTpl,issueTmp.Assignee,msg)
+ accessToken := os.Getenv("issueaccesstoken")
+ owner := beego.AppConfig.String("gitee::owner")
+ path := beego.AppConfig.String("gitee::path")
+ taskhandler.AddCommentToIssue(msg,issueTmp.IssueNum,owner,path,accessToken)
+ }else {
+ //1. change issue status
+ issueTmp.IssueStatus = 3
+ err := models.UpdateIssueTemplate(&issueTmp, "issue_status")
+ if err != nil{
+ logs.Error(err)
+ }
+ //2. Are the cvsScore and openEuler score equal .If not equal, notify the auditor to review .
+ if issueTmp.OpenEulerScore != issueTmp.NVDScore {
+ //Notify the responsible person for review
+ notifyAuditorReview(payload,issueTmp)
+ }else {
+ // change score status
+ err := changeOpenEulerScoreStatus(issueTmp.CveId, 3)
+ if err != nil {
+ logs.Error(err)
+ }
+ }
+ }
+ }
+}
+
+func notifyAuditorReview(payload *models.CommentPayload,issueTmp models.IssueTemplate){
+ //Notify the responsible person for review
+ list, err := models.GetSecurityReviewerList()
+ if err != nil{
+ logs.Error(err)
+ return
+ }
+ accessToken := os.Getenv("issueaccesstoken")
+ content := fmt.Sprintf(ReviewPrivateLettersTpl,
+ payload.Issue.Title,payload.Issue.HtmlUrl,issueTmp.NVDScore,issueTmp.OpenEulerScore)
+ owner := beego.AppConfig.String("gitee::owner")
+ path := beego.AppConfig.String("gitee::path")
+ for _,v := range list{
+ taskhandler.SendPrivateLetters(accessToken,content,v.NameSpace)
+ //add @comment
+ msg := fmt.Sprintf(CommentReviewTpl,v.NameSpace)
+ taskhandler.AddCommentToIssue(msg,issueTmp.IssueNum,owner,path,accessToken)
+ }
+
+
+}
+
+func changeOpenEulerScoreStatus(cveId int64,status int8) error{
+ score, err := models.QueryIssueScore(cveId)
+ if err != nil {
+ return err
+ }
+ score.Ostatus = status
+ err = models.UpdateScore(&score, "o_score_status")
+ return err
+}
+
+func checkIssueAnalysisComplete(i *models.IssueTemplate) (msg string,ok bool) {
+ if i == nil {
+ logs.Error("issue template is nil")
+ return msg,false
+ }
+ ok = true
+ if i.OpenEulerScore == 0.0 {
+ msg = fmt.Sprintf("openEulerScore:%v",i.OpenEulerScore)
+ ok = false
+ return
+ }
+ if i.CveAnalysis == "" {
+ msg = fmt.Sprintf("影响性分析说明:%v",i.CveAnalysis)
+ ok = false
+ return
+ }
+ if i.PrincipleAnalysis == "" {
+ msg = fmt.Sprintf("原理分析:%v",i.PrincipleAnalysis)
+ ok = false
+ return
+ }
+ if i.OpenEulerVector == "" {
+ msg = fmt.Sprintf("OpenEulerVector:%v",i.OpenEulerVector)
+ ok = false
+ return
+ }
+ if i.AffectedVersion == "" {
+ msg = fmt.Sprintf("受影响的包:%v",i.OpenEulerVector)
+ ok = false
+ return
+ }
+ if i.Solution == ""{
+ msg = fmt.Sprintf("规避方案或消减措施:%v",i.OpenEulerVector)
+ ok = false
+ return
+ }
+ pkg, err := models.QueryPackageByCveId(i.CveId)
+ if err != nil {
+ return "受影响的包:",false
+ }
+ if len(pkg) == 0 {
+ return "受影响的包",false
+ }
+ return
+}
+
+func commentUpdateIssue(issueTmp models.IssueTemplate) {
+ accessToken := os.Getenv("issueaccesstoken")
+ owner := beego.AppConfig.String("gitee::owner")
+ path := beego.AppConfig.String("gitee::path")
+ if accessToken != "" && owner != "" && path != "" {
+ cvlnCenter := models.VulnCenter{}
+ err := models.GetVulnCenterByCVEID(&cvlnCenter, issueTmp.CveId)
+ if err != nil {
+ logs.Error(err)
+ } else {
+ _, err := taskhandler.UpdateIssueToGit(accessToken, owner, path, cvlnCenter, issueTmp)
+ if err != nil {
+ logs.Error(err)
+ }
+ }
+ }
+}
+
+func saveVectorData(vct string, cveId int64) error {
+ score, err := models.QueryIssueScore(cveId)
+ if err != nil {
+ return err
+ }
+ if vct == "" {
+ return errors.New("vct value is empty")
+ }
+ vMap, ok := util.VctToMap(vct)
+ if !ok {
+ return errors.New("vector value illegal")
+ }
+ upFields := make([]string, 0)
+ score.OvectorVule = vct
+ upFields = append(upFields, "o_vector_value")
+ avv := util.ReadVmValue(vMap["AV"])
+ if avv != "" {
+ score.OattackVector = avv
+ upFields = append(upFields, "o_attack_vector")
+ }
+ acv := util.ReadVmValue(vMap["AC"])
+ if acv != "" {
+ score.OattackComplexity = acv
+ upFields = append(upFields, "o_attack_complexity")
+ }
+ prv := util.ReadVmValue(vMap["PR"])
+ if prv != "" {
+ score.OprivilegeRequired = prv
+ upFields = append(upFields, "o_privilege_required")
+ }
+ uiv := util.ReadVmValue(vMap["UI"])
+ if uiv != "" {
+ score.OuserInteraction = uiv
+ upFields = append(upFields, "o_user_interaction")
+ }
+ sv := util.ReadVmValue(vMap["S"])
+ if sv != "" {
+ score.Oscope = sv
+ upFields = append(upFields, "o_scope")
+ }
+ cv := util.ReadVmValue(vMap["C"])
+ if cv != "" {
+ score.Oconfidentiality = cv
+ upFields = append(upFields, "o_confidentiality")
+ }
+ iv := util.ReadVmValue(vMap["I"])
+ if iv != "" {
+ score.Ointegrity = iv
+ upFields = append(upFields, "o_integrity")
+ }
+ av := util.ReadVmValue(vMap["A"])
+ if av != "" {
+ score.Oavailability = av
+ upFields = append(upFields, "o_availability")
+ }
+ if len(upFields) > 0 {
+ //执行更新
+ err = models.UpdateScore(&score, upFields...)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func handleCommentPackage(packageStr string, cveId int64) error {
+ packageStr = util.TrimString(packageStr)
+ err := models.UpdatePackageByCveId(packageStr, cveId)
+ if err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/controllers/issue.go b/controllers/issue.go
new file mode 100644
index 0000000000000000000000000000000000000000..a48d78622ebe0e22d0a272c5c810de5194a5929d
--- /dev/null
+++ b/controllers/issue.go
@@ -0,0 +1,73 @@
+package controllers
+
+import (
+ "cvevulner/errcode"
+ "encoding/json"
+ "github.com/astaxie/beego"
+ "github.com/astaxie/beego/logs"
+)
+
+type IssueOathCallbackController struct {
+ beego.Controller
+}
+
+
+func (c *IssueOathCallbackController) RetData(resp map[string]interface{}) {
+ c.Data["json"] =resp
+ c.ServeJSON()
+}
+
+// @Title UserLogin
+// @Description UserLogin
+// @Param body body models.User true "body for user content"
+// @Success 200 {int} models.User.Id
+// @Failure 403 body is empty
+// @router / [post]
+func (u *IssueOathCallbackController) Post() {
+ req := make(map[string]interface{})
+ resp := make(map[string]interface{})
+ resp["errno"]=errcode.RECODE_LOGINERR
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_LOGINERR)
+ resp["body"] = Result{}
+ defer u.RetData(resp)
+ json.Unmarshal(u.Ctx.Input.RequestBody,&req)
+ logs.Info("登录请求参数:", &req)
+ //判断是否合法
+ //if req["UserName"] == nil || req["PassWord"] ==nil{
+ // resp["errno"]=errcode.RECODE_DATAERR
+ // resp["errmsg"]=errcode.RecodeText(errcode.RECODE_DATAERR)
+ // resp["body"] = Result{}
+ // logs.Error("数据错误")
+ // return
+ //}
+ //password := fmt.Sprintf("%s", req["PassWord"])
+ //// 加密先注释
+ ////password = common.DesString(password)
+ //if password == "" || len(password) == 0{
+ // resp["errno"]=errcode.RECODE_PWDERR
+ // resp["errmsg"]=errcode.RecodeText(errcode.RECODE_PWDERR)
+ // logs.Error("密码解析错误", password)
+ // resp["body"] = Result{}
+ // return
+ //}
+ //var strc Result
+ //username := fmt.Sprintf("%s", req["UserName"])
+ //resp_model, err := models.GetCveUserByUser(username, password)
+ //logs.Info(resp_model)
+ //if resp_model!= nil && err == nil {
+ // token,terr := common.GenToken(username, password)
+ // if terr == nil {
+ // strc.Key = token
+ // logs.Info(resp_model[0]["user_id"])
+ // user_id := resp_model[0]["user_id"]
+ // strc.UserId = user_id
+ // resp["body"] = strc
+ // resp["errno"]=errcode.RECODE_OK
+ // resp["errmsg"]=errcode.RecodeText(errcode.RECODE_OK)
+ // models.UpdateToken(resp_model[0]["user_id"], token)
+ // return
+ // }
+ //}
+ return
+}
+
diff --git a/controllers/login.go b/controllers/login.go
new file mode 100644
index 0000000000000000000000000000000000000000..3282f2a14d7f7fa0ca1a3423f016bafcf1f6b604
--- /dev/null
+++ b/controllers/login.go
@@ -0,0 +1,82 @@
+package controllers
+
+import (
+ "cvevulner/common"
+ "cvevulner/errcode"
+ "cvevulner/models"
+ "encoding/json"
+ "fmt"
+ "github.com/astaxie/beego"
+ "github.com/astaxie/beego/logs"
+ "time"
+)
+
+type UserLoginController struct {
+ beego.Controller
+}
+
+type Result struct {
+ Key string `json:"Token"`
+ UserId interface{} `json:"UserId"`
+}
+
+func (c *UserLoginController) RetData(resp map[string]interface{}) {
+ c.Data["json"] =resp
+ c.ServeJSON()
+}
+
+// @Title UserLogin
+// @Description UserLogin
+// @Param body body models.User true "body for user content"
+// @Success 200 {int} models.User.Id
+// @Failure 403 body is empty
+// @router / [post]
+func (u *UserLoginController) Post() {
+ req := make(map[string]interface{})
+ resp := make(map[string]interface{})
+ resp["errno"]=errcode.RECODE_LOGINERR
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_LOGINERR)
+ resp["body"] = Result{}
+ defer u.RetData(resp)
+ json.Unmarshal(u.Ctx.Input.RequestBody,&req)
+ logs.Info("登录请求参数:", &req)
+ //判断是否合法
+ if req["UserName"] == nil || req["PassWord"] ==nil{
+ resp["errno"]=errcode.RECODE_DATAERR
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_DATAERR)
+ resp["body"] = Result{}
+ logs.Error("数据错误")
+ return
+ }
+ password := fmt.Sprintf("%s", req["PassWord"])
+ // 加密先注释
+ //password = common.DesString(password)
+ if password == "" || len(password) == 0{
+ resp["errno"]=errcode.RECODE_PWDERR
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_PWDERR)
+ logs.Error("密码解析错误", password)
+ resp["body"] = Result{}
+ return
+ }
+ var strc Result
+ username := fmt.Sprintf("%s", req["UserName"])
+ resp_model, err := models.GetCveUserByUser(username, password)
+ logs.Info(resp_model)
+ if resp_model!= nil && err == nil {
+ token, terr := common.GenToken(username, password)
+ if terr == nil {
+ strc.Key = token
+ logs.Info(resp_model[0]["user_id"])
+ user_id := resp_model[0]["user_id"]
+ strc.UserId = user_id
+ resp["body"] = strc
+ resp["errno"]=errcode.RECODE_OK
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_OK)
+ expirTime := common.GetTokenExpirTime()
+ newTime := time.Now().AddDate(0, 0, expirTime)
+ models.UpdateToken(resp_model[0]["user_id"], token, newTime)
+ return
+ }
+ }
+ return
+}
diff --git a/controllers/object.go b/controllers/object.go
new file mode 100644
index 0000000000000000000000000000000000000000..714a066211a634c5fa294172665b1178fffb49e3
--- /dev/null
+++ b/controllers/object.go
@@ -0,0 +1,92 @@
+package controllers
+
+import (
+ "cvevulner/models"
+ "encoding/json"
+
+ "github.com/astaxie/beego"
+)
+
+// Operations about object
+type ObjectController struct {
+ beego.Controller
+}
+
+// @Title Create
+// @Description create object
+// @Param body body models.Object true "The object content"
+// @Success 200 {string} models.Object.Id
+// @Failure 403 body is empty
+// @router / [post]
+func (o *ObjectController) Post() {
+ var ob models.Object
+ json.Unmarshal(o.Ctx.Input.RequestBody, &ob)
+ objectid := models.AddOne(ob)
+ o.Data["json"] = map[string]string{"ObjectId": objectid}
+ o.ServeJSON()
+}
+
+// @Title Get
+// @Description find object by objectid
+// @Param objectId path string true "the objectid you want to get"
+// @Success 200 {object} models.Object
+// @Failure 403 :objectId is empty
+// @router /:objectId [get]
+func (o *ObjectController) Get() {
+ objectId := o.Ctx.Input.Param(":objectId")
+ if objectId != "" {
+ ob, err := models.GetOne(objectId)
+ if err != nil {
+ o.Data["json"] = err.Error()
+ } else {
+ o.Data["json"] = ob
+ }
+ }
+ o.ServeJSON()
+}
+
+// @Title GetAll
+// @Description get all objects
+// @Success 200 {object} models.Object
+// @Failure 403 :objectId is empty
+// @router / [get]
+func (o *ObjectController) GetAll() {
+ obs := models.GetAll()
+ o.Data["json"] = obs
+ o.ServeJSON()
+}
+
+// @Title Update
+// @Description update the object
+// @Param objectId path string true "The objectid you want to update"
+// @Param body body models.Object true "The body"
+// @Success 200 {object} models.Object
+// @Failure 403 :objectId is empty
+// @router /:objectId [put]
+func (o *ObjectController) Put() {
+ objectId := o.Ctx.Input.Param(":objectId")
+ var ob models.Object
+ json.Unmarshal(o.Ctx.Input.RequestBody, &ob)
+
+ err := models.Update(objectId, ob.Score)
+ if err != nil {
+ o.Data["json"] = err.Error()
+ } else {
+ o.Data["json"] = "update success!"
+ }
+ o.ServeJSON()
+}
+
+// @Title Delete
+// @Description delete the object
+// @Param objectId path string true "The objectId you want to delete"
+// @Success 200 {string} delete success!
+// @Failure 403 objectId is empty
+// @router /:objectId [delete]
+func (o *ObjectController) Delete() {
+ objectId := o.Ctx.Input.Param(":objectId")
+ models.Delete(objectId)
+ o.Data["json"] = "delete success!"
+ o.ServeJSON()
+}
+
diff --git a/controllers/packages.go b/controllers/packages.go
new file mode 100644
index 0000000000000000000000000000000000000000..41ed97a62f96f80db9e6c2cf1216bcbe136f17ac
--- /dev/null
+++ b/controllers/packages.go
@@ -0,0 +1,292 @@
+package controllers
+
+import (
+ "cvevulner/errcode"
+ "cvevulner/models"
+ "github.com/astaxie/beego"
+ "github.com/astaxie/beego/logs"
+ "strings"
+)
+
+// Operations about Packages
+type PackagesController struct {
+ beego.Controller
+}
+
+func (c *PackagesController) RetData(resp map[string]interface{}) {
+ c.Data["json"] =resp
+ c.ServeJSON()
+}
+
+type PackagesInfoController struct {
+ beego.Controller
+}
+
+func (c *PackagesInfoController) RetData(resp map[string]interface{}) {
+ c.Data["json"] =resp
+ c.ServeJSON()
+}
+
+type PackageData struct {
+ Id int64 `json:"id"`
+ Name string `json:"name"`
+ Version string `json:"version"`
+ Release string `json:"release"`
+ OriginUrl string `json:"url"`
+ ReleaseTime string `json:"releaseTime"`
+ LatestVersion string `json:"latestVersion"`
+ LatestVersionTime string `json:"latestVersionTime"`
+}
+
+type Provide struct {
+ Name string `json:"name"`
+ Requiredby []string `json:"requiredby"`
+}
+
+type Require struct {
+ Name string `json:"name"`
+ Providedby []string `json:"providedby"`
+}
+
+type SubPack struct {
+ Name string `json:"name"`
+ Provides []Provide `json:"provides"`
+ Requires []Require `json:"requires"`
+}
+
+type PackageInfoData struct {
+ PkgName string `json:"pkgName"`
+ Version string `json:"version"`
+ Release string `json:"release"`
+ OriginUrl string `json:"url"`
+ GiteeUrl string `json:"giteeUrl"`
+ Summary string `json:"summary"`
+ Description string `json:"description"`
+ BuildRequired []string `json:"buildRequired"`
+ Subpack []SubPack `json:"subpack"`
+}
+
+// @Title Get packages
+// @Description get packages
+// @Param pageNum pageSize int true
+// @Success 200 {object} models.package
+// @Failure 403 :pageNum is err
+// @router / [get]
+func (u *PackagesController) Get() {
+ req := u.Ctx.Request
+ addr := req.RemoteAddr
+ logs.Info("Method: ",req.Method, "客户端请求的:addr: ", addr, "Header: ", req.Header, "body: ", req.Body)
+ resp := make(map[string]interface{})
+ var pd []PackageData
+ resp["errno"]=errcode.RECODE_UNKNOWERR
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_UNKNOWERR)
+ resp["body"] = []PackageData{}
+ resp["totalCount"] = 0
+ resp["totalPage"] = 0
+ defer u.RetData(resp)
+ var iw models.IpWhite
+ if addr != "" {
+ addrIp := strings.Split(addr, ":")
+ err := models.GetIpWhite(addrIp[0], &iw)
+ if err != nil {
+ resp["errno"]=errcode.RECODE_IPERR
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_IPERR)
+ return
+ }
+ } else {
+ resp["errno"]=errcode.RECODE_IPERR
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_IPERR)
+ return
+ }
+ token := u.GetString("token")
+ if token == "" {
+ resp["errno"]=errcode.RECODE_SESSIONERR
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_SESSIONERR)
+ return
+ } else {
+ ok := models.CheckToken(token)
+ if !ok {
+ resp["errno"]=errcode.RECODE_ROLEERR
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_ROLEERR)
+ return
+ }
+ }
+ PageNum, err := u.GetInt64("pageNum")
+ if err != nil {
+ logs.Error("pageNum, err: ", err)
+ resp["errno"]=errcode.RECODE_PARAMERR
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_PARAMERR)
+ return
+ }
+ PageSize, err := u.GetInt64("pageSize")
+ if err != nil {
+ logs.Error("PageSize, err: ", err)
+ resp["errno"]=errcode.RECODE_PARAMERR
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_PARAMERR)
+ return
+ }
+ QueryPkgName := u.GetString("queryPkgName")
+ if QueryPkgName != "" {
+ logs.Info("查询: ", QueryPkgName, " 包的相关信息")
+ }
+
+ totalNum := models.GetPackageNum(QueryPkgName)
+ if totalNum > 0 {
+ if PageSize >= totalNum {
+ resp["totalPage"] = 1
+ } else {
+ if totalNum % PageSize == 0 {
+ resp["totalPage"] = totalNum / PageSize
+ } else {
+ totalPage := totalNum / PageSize
+ totalPage += 1
+ resp["totalPage"] = totalPage
+ }
+ }
+ resp["totalCount"] = totalNum
+ ge, num, err := models.GetPackageList(PageSize, PageNum, QueryPkgName)
+ if num >0 && err == nil {
+ for _, g := range ge {
+ //logs.Info("添加第:", i, "条数据")
+ var pg PackageData
+ pg.Id = g.GitId
+ pg.Release = g.Release
+ pg.Version = g.Version
+ pg.LatestVersion = g.LatestVersion
+ pg.LatestVersionTime = g.LatestVersionTime
+ pg.Name = g.PackageName
+ pg.OriginUrl = g.OriginUrl
+ pg.ReleaseTime = g.ReleaseTime
+ pd = append(pd, pg)
+ }
+ resp["body"] = pd
+ resp["errno"]=errcode.RECODE_OK
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_OK)
+ }
+ } else {
+ resp["errno"]=errcode.RECODE_NODATA
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_NODATA)
+ return
+ }
+}
+
+
+// @Title Get packagesinfo
+// @Description get packagesinfo
+// @Param pkgName token string true
+// @Success 200 {object} models.package
+// @Failure 403 :pkgName is err
+// @router / [get]
+func (u *PackagesInfoController) Get() {
+ req := u.Ctx.Request
+ addr := req.RemoteAddr
+ logs.Info("Method: ",req.Method, "客户端请求的:addr: ", addr, "Header: ", req.Header, "body: ", req.Body)
+ resp := make(map[string]interface{})
+ var pd PackageInfoData
+ resp["errno"]=errcode.RECODE_UNKNOWERR
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_UNKNOWERR)
+ resp["body"] = PackageInfoData{}
+ defer u.RetData(resp)
+ var iw models.IpWhite
+ if addr != "" {
+ addrIp := strings.Split(addr, ":")
+ err := models.GetIpWhite(addrIp[0], &iw)
+ if err != nil {
+ resp["errno"]=errcode.RECODE_IPERR
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_IPERR)
+ return
+ }
+ } else {
+ resp["errno"]=errcode.RECODE_IPERR
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_IPERR)
+ return
+ }
+ token := u.GetString("token")
+ if token == "" {
+ resp["errno"]=errcode.RECODE_SESSIONERR
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_SESSIONERR)
+ return
+ } else {
+ ok := models.CheckToken(token)
+ if !ok {
+ resp["errno"]=errcode.RECODE_ROLEERR
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_ROLEERR)
+ return
+ }
+ }
+ pkgName := u.GetString("pkgName")
+ if pkgName == "" {
+ logs.Error("pkgName, 参数错误")
+ resp["errno"]=errcode.RECODE_PARAMERR
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_PARAMERR)
+ return
+ }
+ var gi models.GitPackageInfo
+ err := models.GetPackageInfo(pkgName, &gi)
+ if err != nil {
+ resp["errno"]=errcode.RECODE_NODATA
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_NODATA)
+ return
+ }
+ pd.OriginUrl = gi.OriginUrl
+ pd.Version = gi.Version
+ pd.PkgName = gi.PackageName
+ pd.Release = gi.Release
+ pd.Description = gi.Decription
+ pd.GiteeUrl = gi.GitUrl
+ pd.Summary = gi.Summary
+ if gi.BuildRequired != "" {
+ buildRequired := strings.Split(gi.BuildRequired, ",")
+ pd.BuildRequired = buildRequired
+ } else {
+ pd.BuildRequired = []string{}
+ }
+ gs, num, err := models.GetSubPackage(gi.DetailId)
+ if num > 0 && err == nil {
+ for _, gg := range gs {
+ var sp SubPack
+ sp.Name = gg.SubPackName
+ gsp, numx, errx := models.GetSubPackProvide(gg.SubId)
+ if numx > 0 && errx == nil {
+ for _, gps := range gsp {
+ var ssp Provide
+ ssp.Name = gps.ProvideName
+ gspr, numxx, errxx := models.GetSubPackrequiredby(gps.ProvideId)
+ if numxx > 0 && errxx == nil {
+ for _, grq := range gspr {
+ ssp.Requiredby = append(ssp.Requiredby, grq.Requiredby)
+ }
+ } else {
+ ssp.Requiredby = []string{}
+ }
+ sp.Provides = append(sp.Provides, ssp)
+ }
+ } else {
+ sp.Provides = []Provide{}
+ }
+ gpre, numm, err := models.GetSubPackRequire(gg.SubId)
+ if numm > 0 && err == nil {
+ for _, ges := range gpre {
+ var rssp Require
+ rssp.Name = ges.RequireName
+ if ges.Providedby != "" {
+ rssp.Providedby = strings.Split(ges.Providedby, ",")
+ } else {
+ rssp.Providedby = []string{}
+ }
+ sp.Requires = append(sp.Requires, rssp)
+ }
+ } else {
+ sp.Requires = []Require{}
+ }
+ pd.Subpack = append(pd.Subpack, sp)
+ }
+
+ } else {
+ pd.Subpack = []SubPack{}
+ }
+ resp["errno"]=errcode.RECODE_OK
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_OK)
+ resp["body"] = pd
+ return
+}
\ No newline at end of file
diff --git a/controllers/upload.go b/controllers/upload.go
new file mode 100644
index 0000000000000000000000000000000000000000..12045cb90e0c07fd9d5fbb6cb9cbf6884ecff300
--- /dev/null
+++ b/controllers/upload.go
@@ -0,0 +1,191 @@
+package controllers
+
+import (
+ "cvevulner/common"
+ "cvevulner/errcode"
+ "cvevulner/models"
+ "encoding/json"
+ "github.com/astaxie/beego"
+ "github.com/astaxie/beego/logs"
+ "strings"
+)
+
+type UserUploadController struct {
+ beego.Controller
+}
+
+type ResultData struct {
+ CveNum string `json:"CveNum"`
+ Status int `json:"Status"`
+}
+
+func (c *UserUploadController) RetData(resp map[string]interface{}) {
+ c.Data["json"] =resp
+ c.ServeJSON()
+}
+
+// @Title UserUpload
+// @Description UserUpload
+// @Param body body models.OriginUpstream true "body for user content"
+// @Success 200 {int} models.OriginUpstream.CveId
+// @Failure 403 body is empty
+// @router / [post]
+func (u *UserUploadController) Post() {
+ var uploaddata common.UploadData
+ var ResDataList []ResultData
+ resp := make(map[string]interface{})
+ resp["errno"]=errcode.RECODE_UNKNOWERR
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_UNKNOWERR)
+ resp["body"] = []ResultData{}
+ defer u.RetData(resp)
+ json.Unmarshal(u.Ctx.Input.RequestBody,&uploaddata)
+ logs.Info("Cve上传请求参数:", &uploaddata)
+ //判断是否合法
+ if uploaddata.Token == "" {
+ resp["errno"]=errcode.RECODE_SESSIONERR
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_SESSIONERR)
+ resp["body"] = []ResultData{}
+ logs.Error("token 校验失败")
+ return
+ } else {
+ // 校验token
+ ok := models.CheckToken(uploaddata.Token)
+ if !ok {
+ resp["errno"]=errcode.RECODE_SESSIONERR
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_SESSIONERR)
+ resp["body"] = []ResultData{}
+ logs.Error("token 校验失败")
+ return
+ }
+ }
+ if uploaddata.CveData == nil || len(uploaddata.CveData) == 0{
+ resp["errno"]=errcode.RECODE_NODATA
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_NODATA)
+ resp["body"] = []ResultData{}
+ logs.Error("数据为空")
+ return
+ }
+ //logs.Info(uploaddata.CveData, uploaddata.Token)
+ for _, CveDataDict := range uploaddata.CveData {
+ defer common.Catchs()
+ logs.Info("每一条请求参数: ", CveDataDict)
+ var ResData ResultData
+ ids := CveDataDict.Ids
+ if ids == "" {
+ ResData.CveNum = ids
+ ResData.Status = 1
+ ResDataList = append(ResDataList, ResData)
+ logs.Error("CveNum is null, cveDataDict:", CveDataDict)
+ continue
+ }
+ cveNum := CveDataDict.CveNum
+ if cveNum == "" {
+ logs.Error("cveNum 为空, ids: ", ids)
+ }
+ updateType := CveDataDict.UpdateType
+ cvePackName := CveDataDict.CvePackName
+ packName := CveDataDict.PackName
+ title := CveDataDict.Title
+ affectProduct := CveDataDict.AffectProduct
+ cnnvdID := CveDataDict.CnnvdID
+ cnvdID := CveDataDict.CnvdID
+ publishedDate := CveDataDict.PublishedDate
+ vulStatus := CveDataDict.VulStatus
+ if CveDataDict.Version == "" {
+ logs.Error("Version 为空, ids: ", ids)
+ }
+ version := CveDataDict.Version
+ var orCve models.OriginUpstream
+ if ids != "" {
+ ids = common.DeletePreAndSufSpace(ids)
+ }
+ orCve.Ids = ids
+ if cveNum != "" {
+ cveNum = common.DeletePreAndSufSpace(cveNum)
+ }
+ orCve.CveNum = cveNum
+ orCve.Version = version
+ orCve.UpdateType = updateType
+ orCve.CvePackName = cvePackName
+ if packName != "" {
+ packName = common.DeletePreAndSufSpace(packName)
+ }
+ orCve.PackName = packName
+ orCve.Title = title
+ if affectProduct == "" {
+ orCve.AffectProduct = packName
+ }
+ orCve.CnnvdID = cnnvdID
+ orCve.CnvdID = cnvdID
+ orCve.PublishedDate = publishedDate
+ gits, ok := models.QueryCveOpeneulerdata(packName, version)
+ if !ok {
+ orCve.IsExit = 0
+ } else {
+ orCve.IsExit = 1
+ logs.Info("对应src-openEuler的数据为: ", gits)
+ }
+ orCve.VulStatus = vulStatus
+ if strings.ToLower(updateType) == "delete" {
+ orCve.Status = 3
+ } else if strings.ToLower(updateType) == "update" {
+ orCve.Status = 1
+ } else {
+ orCve.Status = 0
+ }
+ orCve.CreateTime = common.GetCurTime()
+ orCve.UpdateTime = common.GetCurTime()
+ var od models.OriginUpstreamDesc
+ od.EnDescription = CveDataDict.Description.EnDesc
+ od.ZhDescription = CveDataDict.Description.ZhDesc
+ var ous models.OriginUpstreamConfig
+ ous.Nodes = " "
+ var osi models.OriginUpstreamImpact
+ osi.Impact = " "
+ var osp models.OriginUpstreamPoc
+ osp.Url = CveDataDict.Poc.Url
+ osp.Date = CveDataDict.Poc.Date
+ osp.Dbindex = CveDataDict.Poc.Dbindex
+ osp.Desc = CveDataDict.Poc.Desc
+ osp.Path = CveDataDict.Poc.Path
+ osp.Source = CveDataDict.Poc.Source
+ var ose models.OriginUpstreamEvent
+ ose.Date = CveDataDict.Event.Date
+ ose.Url = CveDataDict.Event.Url
+ ose.Description = CveDataDict.Event.Description
+ ose.Title = CveDataDict.Event.Title
+ var osv models.OriginUpstreamVulType
+ osv.ZhDesc = CveDataDict.VulType.Zh
+ osv.EnDesc = CveDataDict.VulType.En
+ osv.Cwe = CveDataDict.VulType.Cwe
+ var osf models.OriginUpstreamFixSuggest
+ osf.Detail = CveDataDict.FixSuggest.Detail
+ dbCve, ok := models.QueryCveOriginByIds(ids)
+ if ok {
+ if orCve.Status != 3 {
+ orCve.Status = 1
+ }
+ orCve.UpdateTime = common.GetCurTime()
+ if orCve.Status == 3 {
+ orCve.DeleteTime = common.GetCurTime()
+ }
+ logs.Info("当前插入的数据已经存在: ", dbCve)
+ }
+ _, err := models.CreateOriginCve(CveDataDict, &orCve, &od, &ous, &osi, &osp, &ose, &osv, &osf)
+ if err == nil {
+ logs.Info("cve 原始数据创建成功 CveNum:", CveDataDict.Ids)
+ ResData.CveNum = CveDataDict.Ids
+ ResData.Status = 0
+ ResDataList = append(ResDataList, ResData)
+ } else {
+ logs.Info("cve 创建失败 CveNum:", CveDataDict.Ids)
+ ResData.CveNum = CveDataDict.Ids
+ ResData.Status = 1
+ ResDataList = append(ResDataList, ResData)
+ }
+ }
+ resp["errno"]=errcode.RECODE_OK
+ resp["errmsg"]=errcode.RecodeText(errcode.RECODE_OK)
+ resp["body"] = ResDataList
+ return
+}
diff --git a/controllers/user.go b/controllers/user.go
new file mode 100644
index 0000000000000000000000000000000000000000..1c689d4d9de64f0867c21b3095748fc4ae85307b
--- /dev/null
+++ b/controllers/user.go
@@ -0,0 +1,119 @@
+package controllers
+
+import (
+ "cvevulner/models"
+ "encoding/json"
+
+ "github.com/astaxie/beego"
+)
+
+// Operations about Users
+type UserController struct {
+ beego.Controller
+}
+
+// @Title CreateUser
+// @Description create users
+// @Param body body models.User true "body for user content"
+// @Success 200 {int} models.User.Id
+// @Failure 403 body is empty
+// @router / [post]
+func (u *UserController) Post() {
+ var user models.User
+ json.Unmarshal(u.Ctx.Input.RequestBody, &user)
+ uid := models.AddUser(user)
+ u.Data["json"] = map[string]string{"uid": uid}
+ u.ServeJSON()
+}
+
+// @Title GetAll
+// @Description get all Users
+// @Success 200 {object} models.User
+// @router / [get]
+func (u *UserController) GetAll() {
+ users := models.GetAllUsers()
+ u.Data["json"] = users
+ u.ServeJSON()
+}
+
+// @Title Get
+// @Description get user by uid
+// @Param uid path string true "The key for staticblock"
+// @Success 200 {object} models.User
+// @Failure 403 :uid is empty
+// @router /:uid [get]
+func (u *UserController) Get() {
+ uid := u.GetString(":uid")
+ if uid != "" {
+ user, err := models.GetUser(uid)
+ if err != nil {
+ u.Data["json"] = err.Error()
+ } else {
+ u.Data["json"] = user
+ }
+ }
+ u.ServeJSON()
+}
+
+// @Title Update
+// @Description update the user
+// @Param uid path string true "The uid you want to update"
+// @Param body body models.User true "body for user content"
+// @Success 200 {object} models.User
+// @Failure 403 :uid is not int
+// @router /:uid [put]
+func (u *UserController) Put() {
+ uid := u.GetString(":uid")
+ if uid != "" {
+ var user models.User
+ json.Unmarshal(u.Ctx.Input.RequestBody, &user)
+ uu, err := models.UpdateUser(uid, &user)
+ if err != nil {
+ u.Data["json"] = err.Error()
+ } else {
+ u.Data["json"] = uu
+ }
+ }
+ u.ServeJSON()
+}
+
+// @Title Delete
+// @Description delete the user
+// @Param uid path string true "The uid you want to delete"
+// @Success 200 {string} delete success!
+// @Failure 403 uid is empty
+// @router /:uid [delete]
+func (u *UserController) Delete() {
+ uid := u.GetString(":uid")
+ models.DeleteUser(uid)
+ u.Data["json"] = "delete success!"
+ u.ServeJSON()
+}
+
+// @Title Login
+// @Description Logs user into the system
+// @Param username query string true "The username for login"
+// @Param password query string true "The password for login"
+// @Success 200 {string} login success
+// @Failure 403 user not exist
+// @router /login [get]
+func (u *UserController) Login() {
+ username := u.GetString("username")
+ password := u.GetString("password")
+ if models.Login(username, password) {
+ u.Data["json"] = "login success"
+ } else {
+ u.Data["json"] = "user not exist"
+ }
+ u.ServeJSON()
+}
+
+// @Title logout
+// @Description Logs out current logged in user session
+// @Success 200 {string} logout success
+// @router /logout [get]
+func (u *UserController) Logout() {
+ u.Data["json"] = "logout success"
+ u.ServeJSON()
+}
+
diff --git a/errcode/errcode.go b/errcode/errcode.go
new file mode 100644
index 0000000000000000000000000000000000000000..c47f459370f2e641a4af46bbe720c992ed954152
--- /dev/null
+++ b/errcode/errcode.go
@@ -0,0 +1,51 @@
+package errcode
+
+
+const (
+ RECODE_OK = "200"
+ RECODE_DBERR = "4001"
+ RECODE_NODATA = "4002"
+ RECODE_DATAEXIST = "4003"
+ RECODE_DATAERR = "4004"
+ RECODE_SESSIONERR = "4101"
+ RECODE_LOGINERR = "4102"
+ RECODE_PARAMERR = "4103"
+ RECODE_USERERR = "4104"
+ RECODE_ROLEERR = "4105"
+ RECODE_PWDERR = "4106"
+ RECODE_REQERR = "4201"
+ RECODE_IPERR = "4202"
+ RECODE_THIRDERR = "4301"
+ RECODE_IOERR = "4302"
+ RECODE_SERVERERR = "4500"
+ RECODE_UNKNOWERR = "4501"
+)
+
+var recodeText = map[string]string{
+ RECODE_OK: "成功",
+ RECODE_DBERR: "数据库查询错误",
+ RECODE_NODATA: "无数据",
+ RECODE_DATAEXIST: "数据已存在",
+ RECODE_DATAERR: "数据错误",
+ RECODE_SESSIONERR: "用户未登录",
+ RECODE_LOGINERR: "用户登录失败",
+ RECODE_PARAMERR: "请求参数错误",
+ RECODE_USERERR: "用户不存在或未激活",
+ RECODE_ROLEERR: "登录身份错误",
+ RECODE_PWDERR: "密码错误",
+ RECODE_REQERR: "非法请求或请求次数受限",
+ RECODE_IPERR: "IP受限",
+ RECODE_THIRDERR: "第三方系统错误",
+ RECODE_IOERR: "文件读写错误",
+ RECODE_SERVERERR: "内部错误",
+ RECODE_UNKNOWERR: "未知错误",
+
+}
+
+func RecodeText(code string)string {
+ str,ok := recodeText[code]
+ if ok {
+ return str
+ }
+ return RecodeText(RECODE_UNKNOWERR)
+}
\ No newline at end of file
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000000000000000000000000000000000000..68466c20f9addecb88c8fd070f3ee523393ed9cc
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,16 @@
+module cvevulner
+
+go 1.14
+
+require (
+ github.com/astaxie/beego v1.12.2
+ github.com/dgrijalva/jwt-go v3.2.0+incompatible
+ github.com/go-sql-driver/mysql v1.5.0
+ github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e // indirect
+ github.com/lib/pq v1.2.0 // indirect
+ github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 // indirect
+ github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337
+ golang.org/x/sys v0.0.0-20200819091447-39769834ee22 // indirect
+ golang.org/x/text v0.3.2 // indirect
+ gopkg.in/yaml.v2 v2.3.0 // indirect
+)
diff --git a/main.go b/main.go
new file mode 100644
index 0000000000000000000000000000000000000000..d80e0ea7d6a82e98f2833989eece809cd5e45f06
--- /dev/null
+++ b/main.go
@@ -0,0 +1,29 @@
+package main
+
+import (
+ "cvevulner/common"
+ "cvevulner/models"
+ _ "cvevulner/routers"
+ "cvevulner/task"
+ "github.com/astaxie/beego"
+)
+
+func init() {
+ // 初始化全局变量
+ common.InitGlobal()
+ // 初始化日志
+ common.LogInit()
+ // 初始化数据库
+ models.Initdb()
+ // 初始化定时任务
+ task.InitTask()
+}
+
+func main() {
+ if beego.BConfig.RunMode == "dev" {
+ beego.BConfig.WebConfig.DirectoryIndex = true
+ beego.BConfig.WebConfig.StaticDir["/swagger"] = "swagger"
+ }
+ beego.Run()
+
+}
diff --git a/models/common.go b/models/common.go
new file mode 100644
index 0000000000000000000000000000000000000000..0d6ab1223bbf5177764bc4e557157e5495367400
--- /dev/null
+++ b/models/common.go
@@ -0,0 +1,28 @@
+package models
+
+import (
+ "github.com/astaxie/beego/logs"
+ "time"
+)
+
+func Time2Str() string {
+ const shortForm = "2006-01-02 15:04:05"
+ t := time.Now()
+ str := t.Format(shortForm)
+ return str
+}
+
+func CheckToken(token string) bool {
+ var ou OtherUser
+ err := GetUserByToken(token, &ou)
+ if err != nil {
+ logs.Error("token: ", token, ", 错误")
+ return false
+ }
+ now := Time2Str()
+ logs.Info("token: now: ", now, ",expir: ", ou.ExpirationTime)
+ if now > ou.ExpirationTime {
+ return false
+ }
+ return true
+}
diff --git a/models/cve.go b/models/cve.go
new file mode 100644
index 0000000000000000000000000000000000000000..2d45af1ab5226846d725327c73388ed53328cd6e
--- /dev/null
+++ b/models/cve.go
@@ -0,0 +1,449 @@
+package models
+
+import (
+ "cvevulner/common"
+ "github.com/astaxie/beego/logs"
+ "github.com/astaxie/beego/orm"
+)
+
+func QueryOriginCve(days string, prcnum int) ([]OriginUpstream, int64, error) {
+ o := orm.NewOrm()
+ var os []OriginUpstream
+ num, err := o.Raw("select cve_id,cve_un_ids,cve_num, update_type,cve_packname," +
+ "git_packname,cve_title,affect_porduct,cnnvd_id,cnvd_id,published_date,vul_status,cve_status,version"+
+ " from cve_origin_upstream where update_time >= ? and cve_status in (?, ?) and is_exit = ? "+
+ "order by cve_id asc limit ?", days, 0, 1, 1, prcnum).QueryRows(&os)
+ if err == nil && num > 0 {
+ logs.Info("cve_origin_upstream 查询结果: ", num)
+ } else {
+ logs.Info("当前无新增或者更新的cve, cur_time:", common.GetCurTime(), "err: ", err)
+ }
+ return os, num, err
+}
+
+
+func QueryCveDesc(cveId int64) (OriginUpstreamDesc, bool){
+ o := orm.NewOrm()
+ var cveDesc OriginUpstreamDesc
+ err := o.Raw("select * from cve_origin_upstream_desc where cve_id = ?", cveId).QueryRow(&cveDesc)
+ if err != nil {
+ logs.Error(cveId, "cve_origin_upstream_desc cve描述查询不到")
+ return cveDesc,false
+ } else {
+ return cveDesc,true
+ }
+}
+
+func QueryCveImpact(cveId int64) (OriginUpstreamImpact, bool){
+ o := orm.NewOrm()
+ var cveImpact OriginUpstreamImpact
+ err := o.Raw("select * from cve_origin_upstream_impact where cve_id = ?", cveId).QueryRow(&cveImpact)
+ if err != nil {
+ logs.Error(cveId, "cve_origin_upstream_impact cve impact查询不到")
+ return cveImpact,false
+ } else {
+ return cveImpact,true
+ }
+}
+
+func QueryCveScore(impactId int64, typex string) (OriginUpstreamImpactScore, bool){
+ o := orm.NewOrm()
+ var cveScore OriginUpstreamImpactScore
+ if typex == "v3" {
+ err := o.Raw("select * from cve_origin_upstream_impact_score where " +
+ "impact_id = ? and base_met_v3=? and cvss_v3=?", impactId, 1, 1).QueryRow(&cveScore)
+ if err != nil {
+ logs.Error(impactId, "cve_origin_upstream_impact_score cve score查询不到")
+ return cveScore,false
+ } else {
+ return cveScore,true
+ }
+ } else {
+ err := o.Raw("select * from cve_origin_upstream_impact_score where " +
+ "impact_id = ? and base_met_v2=? and cvss_v2=?", impactId, 1, 1).QueryRow(&cveScore)
+ if err != nil {
+ logs.Error(impactId, "cve_origin_upstream_impact_score cve score查询不到")
+ return cveScore,false
+ } else {
+ return cveScore,true
+ }
+ }
+
+}
+
+func QueryCveCvssV3(scoreId int64) (OriginUpstreamImpactScoreV3, bool){
+ o := orm.NewOrm()
+ var cveScoreV3 OriginUpstreamImpactScoreV3
+ err := o.Raw("select * from cve_origin_upstream_impact_score_v3 where score_id = ?", scoreId).QueryRow(&cveScoreV3)
+ if err != nil {
+ logs.Error(scoreId, "cve_origin_upstream_impact_score_v3 cve cvssv3 查询不到")
+ return cveScoreV3,false
+ } else {
+ return cveScoreV3,true
+ }
+}
+
+func QueryCveByNum(cvenum string) (VulnCenter, bool){
+ o := orm.NewOrm()
+ var cve VulnCenter
+ err := o.Raw("select * from cve_vuln_center where cve_num = ?", cvenum).QueryRow(&cve)
+ if err != nil {
+ logs.Error(cvenum, "cve_vuln_center 查询不到")
+ return cve,false
+ } else {
+ return cve,true
+ }
+}
+
+func QueryScoreByCveId(CveId int64) (Score, bool){
+ o := orm.NewOrm()
+ var score Score
+ err := o.Raw("select * from cve_score where cve_id = ?", CveId).QueryRow(&score)
+ if err != nil {
+ logs.Error(CveId, "cve_score 查询不到")
+ return score,false
+ } else {
+ return score,true
+ }
+}
+
+func QueryOpenEulerSAByCveId(CveId int64) (OpenEulerSA, bool){
+ o := orm.NewOrm()
+ op := OpenEulerSA{CveId: CveId}
+ err := o.Read(&op, "CveId")
+ if err == orm.ErrNoRows {
+ logs.Error(CveId, "cve_open_euler_s_a 查询不到")
+ return op,false
+ } else if err == orm.ErrMissPK {
+ logs.Error(CveId, "cve_open_euler_s_a pk 查询不到")
+ return op,false
+ } else {
+ return op,true
+ }
+}
+
+func QuerySecNoticeByCveId(CveId int64) (SecurityNotice, bool){
+ o := orm.NewOrm()
+ var secNotice SecurityNotice
+ err := o.Raw("select * from cve_security_notice where cve_id = ?", CveId).QueryRow(&secNotice)
+ if err != nil {
+ logs.Error(CveId, "cve_security_notice 查询不到")
+ return secNotice,false
+ } else {
+ return secNotice,true
+ }
+}
+
+func CreateSecurityNotice(sec *SecurityNotice) (SecId int64, err error){
+ o := orm.NewOrm()
+ errs := o.Begin()
+ if errs == nil {
+ var num int64
+ if num, err = o.Insert(sec); err == nil {
+ logs.Info("insert cve_security_notice success, num:, cveNum", num, sec.CveNum)
+ }else {
+ logs.Error("insert cve_security_notice failed, cveNum:", sec.CveNum)
+ o.Rollback()
+ return 0, err
+ }
+ SecId = sec.SecId
+ o.Commit()
+ } else {
+ logs.Error("事务创建失败,cveNum:", sec.CveNum)
+ return 0, errs
+ }
+ return SecId, nil
+}
+
+func CreateScore(score *Score) (Id int64, err error){
+ o := orm.NewOrm()
+ errs := o.Begin()
+ if errs == nil {
+ var num int64
+ if num, err = o.Insert(score); err == nil {
+ logs.Info("insert cve_score success, num:, cveNum:", num, score.CveNum)
+ } else {
+ logs.Error("insert cve_score failed, score:", score, "err:", err)
+ o.Rollback()
+ return 0, err
+ }
+ Id = score.Id
+ o.Commit()
+ } else {
+ logs.Error("事务创建失败,cveNum:", score.CveNum)
+ return 0, errs
+ }
+ return Id, nil
+}
+
+func CreateOpenEulerSA(op *OpenEulerSA) (OpenId int64, err error){
+ o := orm.NewOrm()
+ errs := o.Begin()
+ if errs == nil {
+ var num int64
+ if num, err = o.Insert(op); err == nil {
+ logs.Info("insert cve_open_euler_s_a success, num:, ", num, "CveId:", op.CveId)
+ } else {
+ logs.Error("insert cve_open_euler_s_a failed, CveId:", op.CveId, "err:", err)
+ o.Rollback()
+ return 0, err
+ }
+ OpenId = op.OpenId
+ o.Commit()
+ } else {
+ logs.Error("事务创建失败,cveId:", op.CveId)
+ return 0, errs
+ }
+ return OpenId, nil
+}
+
+func CreateScoreRecord(sc *ScoreRecord) (scoreId int64, err error){
+ o := orm.NewOrm()
+ errs := o.Begin()
+ if errs == nil {
+ var num int64
+ if num, err = o.Insert(sc); err == nil {
+ logs.Info("insert cve_score_record success, num:, ", num, "CveId:", sc.CveId)
+ } else {
+ logs.Error("insert cve_score_record failed, CveId:", sc.CveId, "err:", err)
+ o.Rollback()
+ return 0, err
+ }
+ scoreId = sc.Id
+ o.Commit()
+ } else {
+ logs.Error("事务创建失败,cveId:", sc.CveId)
+ return 0, errs
+ }
+ return scoreId, nil
+}
+
+func CreateCveRelat(cve *VulnCenter, sec *SecurityNotice, score * Score, op *OpenEulerSA, sc *ScoreRecord) (cveid int64, err error) {
+ o := orm.NewOrm()
+ errs := o.Begin()
+ if errs == nil {
+ var num int64
+ if num, err = o.Insert(cve); err == nil {
+ logs.Info("insert cve_vuln_center success, num:, cveNum:", num, cve.CveNum)
+ } else {
+ logs.Error("insert cve_vuln_center failed, CveNum:", cve.CveNum)
+ o.Rollback()
+ return 0, err
+ }
+ sec.CveId = num
+ cveid = num
+ op.CveId = cveid
+ if num, err = o.Insert(op); err == nil {
+ logs.Info("insert cve_open_euler_s_a success, num:, cveNum:", num, cve.CveNum)
+ } else {
+ logs.Error("insert cve_open_euler_s_a failed, CveNum:", cve.CveNum)
+ o.Rollback()
+ return 0, err
+ }
+ sec.OpenId = num
+ score.OpenId = num
+ if num, err = o.Insert(sec); err == nil {
+ logs.Info("insert cve_security_notice success, num:, cveNum", num, cve.CveNum)
+ }else {
+ logs.Error("insert cve_security_notice failed, cveNum:", cve.CveNum)
+ o.Rollback()
+ return 0, err
+ }
+ score.CveId = cveid
+ if num, err = o.Insert(score); err == nil {
+ logs.Info("insert cve_score success, num:, cveNum:", num, cve.CveNum)
+ } else {
+ logs.Error("insert cve_score failed, CveNum:", cve.CveNum)
+ o.Rollback()
+ return 0, err
+ }
+ sc.CveId = cveid
+ if num, err = o.Insert(sc); err == nil {
+ logs.Info("insert cve_score_record, num:, CveId:", num, cve.CveId)
+ } else {
+ logs.Error("insert cve_score_record failed, CveId:", cve.CveId)
+ o.Rollback()
+ return 0, err
+ }
+ o.Commit()
+ } else {
+ logs.Error("事务创建失败,CveId:", cve.CveId)
+ return 0, errs
+ }
+ return cveid, nil
+}
+
+func UpdateCveRelat(cve *VulnCenter, sec *SecurityNotice, score * Score) (err error) {
+ o := orm.NewOrm()
+ errs := o.Begin()
+ if errs == nil {
+ var cv VulnCenter
+ err := o.Raw("select cve_id from cve_vuln_center where cve_id = ?", cve.CveId).QueryRow(&cv)
+ if err == nil {
+ var num int64
+ cve.CveId = cv.CveId
+ if num, err = o.Update(cve); err == nil {
+ logs.Info("update cve_vuln_center success, num:, cveNum", num, cve.CveNum)
+ }else {
+ logs.Error("update cve_vuln_center failed, CveId:", cve.CveId)
+ o.Rollback()
+ return err
+ }
+ } else {
+ logs.Error("update cve_security_notice failed, CveId:", cve.CveId)
+ o.Rollback()
+ return err
+ }
+ var se SecurityNotice
+ err = o.Raw("select sec_id from cve_security_notice where cve_id = ?", cve.CveId).QueryRow(&se)
+ if err == nil {
+ var num int64
+ sec.SecId = se.SecId
+ if num, err = o.Update(sec); err == nil {
+ logs.Info("update cve_security_notice success, num:, cve.CveId", num, cve.CveId)
+ } else {
+ logs.Error("update cve_security_notice failed, CveId:", cve.CveId)
+ o.Rollback()
+ return err
+ }
+ }else {
+ logs.Error("update cve_security_notice failed, CveId:", cve.CveId)
+ o.Rollback()
+ return err
+ }
+ var sc Score
+ err = o.Raw("select id from cve_score where cve_id = ?", cve.CveId).QueryRow(&sc)
+ if err == nil {
+ var num int64
+ score.Id = sc.Id
+ if num, err = o.Update(score); err == nil {
+ logs.Info("update cve_score success, num:, cve.CveId:", num, cve.CveId)
+ } else {
+ logs.Error("update cve_score failed, CveId:", cve.CveId)
+ o.Rollback()
+ return err
+ }
+ }else {
+ logs.Error("update cve_score failed, CveId:", cve.CveId)
+ o.Rollback()
+ return err
+ }
+ }else {
+ logs.Error("事务创建失败,CveId:", cve.CveId)
+ return errs
+ }
+ o.Commit()
+ return nil
+}
+
+func UpdateCveRelat1(cve *VulnCenter, sec *SecurityNotice) (err error) {
+ o := orm.NewOrm()
+ errs := o.Begin()
+ if errs == nil {
+ v := VulnCenter{CveId: cve.CveId}
+ if err = o.Read(&v, "CveId"); err == nil {
+ var num int64
+ if num, err = o.Update(cve); err == nil {
+ logs.Info("update cve_vuln_center success, num:, cveNum", num, cve.CveNum)
+ }else {
+ logs.Error("update cve_vuln_center failed, CveId:", cve.CveId)
+ o.Rollback()
+ return err
+ }
+ } else {
+ logs.Error("update cve_security_notice failed, CveId:", cve.CveId)
+ o.Rollback()
+ return err
+ }
+ se := SecurityNotice{CveId: cve.CveId}
+ if err = o.Read(&se, "CveId"); err == nil {
+ var num int64
+ if num, err = o.Update(sec); err == nil {
+ logs.Info("update cve_security_notice success, num:, cve.CveId:", num, cve.CveId)
+ } else {
+ logs.Error("update cve_security_notice failed, CveId:", cve.CveId)
+ o.Rollback()
+ return err
+ }
+ }else {
+ logs.Error("update cve_security_notice failed, CveId:", cve.CveId)
+ o.Rollback()
+ return err
+ }
+ }else {
+ logs.Error("事务创建失败,CveId:", cve.CveId)
+ return errs
+ }
+ o.Commit()
+ return nil
+}
+
+func UpdateCveRelat2(cve *VulnCenter, score * Score) (err error) {
+ o := orm.NewOrm()
+ errs := o.Begin()
+ if errs == nil {
+ v := VulnCenter{CveId: cve.CveId}
+ if err = o.Read(&v, "CveId"); err == nil {
+ var num int64
+ if num, err = o.Update(cve); err == nil {
+ logs.Info("update cve_vuln_center success, num:, cveNum", num, cve.CveNum)
+ }else {
+ logs.Error("update cve_vuln_center failed, CveId:", cve.CveId)
+ o.Rollback()
+ return err
+ }
+ } else {
+ logs.Error("update cve_security_notice failed, CveId:", cve.CveId)
+ o.Rollback()
+ return err
+ }
+ sc := Score{CveId: cve.CveId}
+ if err = o.Read(&sc, "CveId"); err == nil {
+ var num int64
+ if num, err = o.Update(score); err == nil {
+ logs.Info("update cve_score success, num:, cve.CveId", num, cve.CveId)
+ } else {
+ logs.Error("update cve_score failed, CveId:", cve.CveId)
+ o.Rollback()
+ return err
+ }
+ }else {
+ logs.Error("update cve_score failed, CveId:", cve.CveId)
+ o.Rollback()
+ return err
+ }
+ }else {
+ logs.Error("事务创建失败,CveId:", cve.CveId)
+ return errs
+ }
+ o.Commit()
+ return nil
+}
+
+func QueryOpenSaLastId() (OpenEulerSA, error){
+ o := orm.NewOrm()
+ var os OpenEulerSA
+ err := o.Raw("select openeuler_id, openeuler_sa_num from cve_open_euler_s_a order by openeuler_id desc limit 1").QueryRow(&os)
+ if err == nil {
+ logs.Info("OpenEulerSA 查询结果:", os)
+ }
+ return os, err
+}
+
+
+func UpdateOriginStatus(updatetime, pakName, version string, cveId int64) (bool){
+ o := orm.NewOrm()
+ res, err := o.Raw("UPDATE cve_origin_upstream SET " +
+ "cve_status = ?, update_time = ? where cve_id = ? and git_packname = ? and version = ?", 2, updatetime, cveId, pakName, version).Exec()
+ if err == nil {
+ num, _ := res.RowsAffected()
+ if num > 0 {
+ logs.Info("cve_origin_upstream row affected nums: ", num, ",cveId: ", cveId, ",", updatetime, pakName, version)
+ return true
+ }
+ return false
+ } else {
+ logs.Error("更新失败, cve_origin_upstream, ", ",cveId: ", cveId, ",", updatetime, pakName, version, ", err: ", err)
+ return false
+ }
+}
\ No newline at end of file
diff --git a/models/giteeissue.go b/models/giteeissue.go
new file mode 100644
index 0000000000000000000000000000000000000000..e0acc198c037ee53731fff89969a9136289bae20
--- /dev/null
+++ b/models/giteeissue.go
@@ -0,0 +1,27 @@
+package models
+
+import "time"
+
+//GiteOriginIssue 码云上已经存在的issue
+type GiteOriginIssue struct {
+ Id int64 `orm:"pk;auto"`
+ IssueId int64 `json:"issue_id" orm:"unique"`
+ Url string ` description:"issue gitee 链接"`
+ Number string `orm:"size(50);unique" description:"issue 编号"`
+ State string `orm:"size(50)" description:"issue 状态"`
+ Title string `orm:"null" description:"issue 标题"`
+ CveNumber string `json:"cve_number" description:"CVE 编号"`
+ Body string `orm:"null;type(text)" description:"issue 主体"`
+ IssueCreate string `json:"issue_create" description:"issue 创建者"`
+ IssueAssignee string `json:"issue_assignee" orm:"null" description:"issue 责任人"`
+ RepoPath string `json:"repo_path" description:"仓库空间地址"`
+ RepoUrl string `json:"repo_url" description:"仓库码云地址链接"`
+ IssueType string `json:"issue_type" description:"issue 类型"`
+ IssueExistTpl bool `json:"issue_exist_tpl" description:"此 issue 是否有对应的模板"`
+ SecurityHole bool `json:"security_hole" description:"是否为安全漏洞"`
+ IssueCreateAt time.Time `json:"issue_create_at" orm:"null" description:"issue 创建的时间"`
+ IssueUpdateAt time.Time `json:"issue_update_at" orm:"null" description:"issue 更新的时间"`
+ IssueFinishAt time.Time `json:"issue_finish_at" orm:"null" description:"issue 关闭的时间"`
+ GrabTime time.Time `json:"grab_time" orm:"auto_now;type(datetime)" description:"记录当前issue抓取的时间"`
+
+}
diff --git a/models/hookevent.go b/models/hookevent.go
new file mode 100644
index 0000000000000000000000000000000000000000..ab45f4115ee97d7ab884d1e3ede07e416cc91fcf
--- /dev/null
+++ b/models/hookevent.go
@@ -0,0 +1,89 @@
+package models
+
+import "time"
+
+type HookUser struct {
+ Id int64
+ Login string //同下username
+ Name string //用户的昵称
+ Email string //用户的邮箱
+ UserName string `json:"username"` //用户的码云个人空间地址
+ AvatarUrl string `json:"avatar_url"` //用户头像
+ SiteAdmin bool `json:"site_admin"` //是不是管理员
+
+}
+
+type HookIssue struct {
+ Id int64
+ Number string
+ Title string
+ State string
+ HtmlUrl string `json:"html_url"` //评论在码云上的url
+ Body string
+ StateName string `json:"state_name"`
+ User HookUser
+ Assignee HookUser
+ Repository HookRepository
+ CreateAt time.Time `json:"create_at"`
+ UpdateAt time.Time `json:"update_at"`
+ FinishedAt time.Time `json:"finished_at"`
+ IssueType string `json:"issue_type"`
+ SecurityHole bool `json:"security_hole"`
+}
+
+type HookRepository struct {
+ Id int64
+ FullName string `json:"full_name"`
+ Url string `json:"url"`
+ Path string
+ Name string
+ Owner HookUser
+ Private bool
+ public bool
+}
+
+type HookComment struct {
+ User *HookUser //评论的作者信息
+ HtmlUrl string `json:"html_url"` //评论在码云上的url
+ Id int64
+ Body string //评论的内容
+ CreateAt time.Time `json:"create_at"`
+ UpdateAt time.Time `json:"update_at"`
+}
+
+//CommentPayload hook data triggered by a comment task operation
+type CommentPayload struct {
+ Action string // 动作 comment
+ HookName string `json:"hook_name"`
+ Password string //钩子的密码
+ HookId int64 `json:"hook_id"` //钩子ID
+ HookUrl string `json:"hook_url"` //钩子的路由
+ Timestamp string
+ Sign string //钩子根据密钥计算的签名
+ Comment *HookComment //评论数据
+ Note string //被评论目标的评论数据
+ NoteableType string `json:"noteable_type"` //被评论的目标类型
+ NoteableId int64 `json:"noteable_id"` //被评论的目标ID
+ Title string //被评论的目标标题
+ PerId string `json:"per_iid"` //被评论的目标标识
+ ShortCommitId string `json:"short_commit_id"` //被评论的commit提交中的简短sha
+ Issue *HookIssue
+}
+
+type IssuePayload struct {
+ HookId int64 `json:"hook_id"` // 钩子 id。
+ HookUrl string `json:"hook_url"` // 钩子路由。
+ HookName string `json:"hook_name"` // 钩子名,固定为 issue_hooks。
+ Password string `json:"password"` // 钩子密码
+ Action string //issue 状态
+ Issue HookIssue //issue 信息
+ Sender HookUser //触发 hook 的用户信息。
+ TargetUser HookUser `json:"target_user"` //被委托处理 issue 的用户信息
+ User HookUser //issue 的创建者
+ Assignee HookUser //issue 的负责人
+ Iid string //issue 的标识
+ Title string //issue 的标题
+ Description string //issue 的描述
+ State string //issue 的状态
+ Url string //issue 在码云上的url
+}
diff --git a/models/initdb.go b/models/initdb.go
new file mode 100644
index 0000000000000000000000000000000000000000..8939542de3832c02ccd50264b3731b32ebffa83b
--- /dev/null
+++ b/models/initdb.go
@@ -0,0 +1,80 @@
+package models
+
+import (
+ "cvevulner/common"
+ "database/sql"
+ "github.com/astaxie/beego"
+ "github.com/astaxie/beego/config"
+ "github.com/astaxie/beego/logs"
+ "github.com/astaxie/beego/orm"
+ _ "github.com/go-sql-driver/mysql"
+ "os"
+)
+
+func Initdb() {
+ BConfig, err := config.NewConfig("ini", "conf/app.conf")
+ if err != nil{
+ logs.Error("config init error:", err)
+ return
+ }
+ //ConnDb()
+ dbhost := BConfig.String("mysql::dbhost")
+ dbport := BConfig.String("mysql::dbport")
+ dbuser := BConfig.String("mysql::dbuser")
+ dbname := BConfig.String("mysql::dbname")
+ dbpwd := os.Getenv("dbpwd")
+ key := beego.AppConfig.String("key")
+ key1 := []byte(key)
+ bytes, _ := common.DePwdCode(dbpwd, key1)
+ maxidle, lerr := BConfig.Int("mysql::maxidle")
+ if lerr != nil {
+ maxidle = 30
+ }
+
+ maxconn, lerr := BConfig.Int("mysql::maxconn")
+ if lerr != nil {
+ maxconn = 3000
+ }
+ dns := dbuser + ":" + string(bytes) + "@tcp(" + dbhost + ":" + dbport + ")/" + dbname + "?charset=utf8"
+ errx := orm.RegisterDriver("mysql", orm.DRMySQL)
+ if errx != nil {
+ logs.Error("RegisterDriver, orm err: ", errx)
+ return
+ }
+ errorm := orm.RegisterDataBase("default", "mysql", dns, maxidle, maxconn)
+ if errorm != nil {
+ logs.Error("RegisterDataBase failed", "errorm: ", errorm)
+ return
+ }
+ logs.Info("mysql 连接成功")
+ res := CreateDb()
+ if res {
+ logs.Info("mysql table init success !")
+ } else {
+ logs.Error("mysql table init failed!")
+ }
+}
+
+func ConnDb() (*sql.DB, error){
+ BConfig, err := config.NewConfig("ini", "conf/app.conf")
+ if err != nil{
+ logs.Error("config init error:", err)
+ return nil, err
+ }
+ dbhost := BConfig.String("mysql::dbhost")
+ dbport := BConfig.String("mysql::dbport")
+ dbuser := BConfig.String("mysql::dbuser")
+ dbname := BConfig.String("mysql::dbname")
+ dbpwd := os.Getenv("dbpwd")
+ key := beego.AppConfig.String("key")
+ key1 := []byte(key)
+ bytes, _ := common.DePwdCode(dbpwd, key1)
+ dns := dbuser + ":" + string(bytes) + "@tcp(" + dbhost + ":" + dbport + ")/" + dbname + "?charset=utf8"
+ db, err := sql.Open("mysql", dns)
+ if err != nil {
+ logs.Error("连接数据库出错", err, "@tcp(" + dbhost + ":" + dbport + ")/" + dbname)
+ return nil, err
+ }
+ logs.Info("数据库连接成功, db: ", db)
+ return db, nil
+}
diff --git a/models/issue.go b/models/issue.go
new file mode 100644
index 0000000000000000000000000000000000000000..f9ac7ad65e4ff2a490fb2f114ba2c41e6de4ac66
--- /dev/null
+++ b/models/issue.go
@@ -0,0 +1,311 @@
+package models
+
+import (
+ "cvevulner/common"
+ "cvevulner/util"
+ "errors"
+ "fmt"
+ "github.com/astaxie/beego/logs"
+ "github.com/astaxie/beego/orm"
+ "strings"
+ "sync"
+)
+
+var mutex sync.Mutex
+
+func QueryIssue(days string, prcnum int) ([]VulnCenter, error) {
+ o := orm.NewOrm()
+ var vc []VulnCenter
+ num, err := o.Raw("select cve_id,cve_num,cve_desc,cve_version,repair_time,pack_name,cve_url,cve_level"+
+ " from cve_vuln_center where update_time >= ? and cve_status in (?, ?) "+
+ "order by cve_id asc limit ?", days, 0, 1, prcnum).QueryRows(&vc)
+ if err == nil && num > 0 {
+ logs.Info("cve_vuln_center 查询结果:", vc)
+ } else {
+ logs.Info("当前无cve,需要提交issue, cur_time:", common.GetCurTime(), "err: ", err)
+ }
+ return vc, err
+}
+
+func GetVulnCenterByCVEID(vc *VulnCenter, cveId int64, fields ...string) error {
+ o := orm.NewOrm()
+ var fieldsStr string
+ if len(fields) == 0 {
+ fieldsStr = "*"
+ } else {
+ fieldsStr = strings.Join(fields, ",")
+ }
+ sqlStr := fmt.Sprintf(`select %v from cve_vuln_center where cve_id=?`, fieldsStr)
+ err := o.Raw(sqlStr, cveId).QueryRow(vc)
+ return err
+}
+
+func QueryIssueSecurity(cveId int64) (SecurityNotice, error) {
+ o := orm.NewOrm()
+ var sn SecurityNotice
+ err := o.Raw("select sec_id, cve_id,cve_num,openeuler_id,introduction,summary,theme,"+
+ "description,influence_component,affect_product,reference_link"+
+ " from cve_security_notice where cve_id = ?", cveId).QueryRow(&sn)
+ if err == nil {
+ logs.Info("cve_security_notice 查询结果:", sn)
+ } else {
+ logs.Info("查询 cve_security_notic err, cveId: ", cveId, "err: ", err)
+ }
+ return sn, err
+}
+
+func QueryIssueScore(cveId int64) (Score, error) {
+ o := orm.NewOrm()
+ var sc Score
+ err := o.Raw("select *"+
+ " from cve_score where cve_id = ?", cveId).QueryRow(&sc)
+ if err == nil {
+ logs.Info("cve_score 查询结果:", sc)
+ } else {
+ logs.Info("查询 cve_score err, cveId: ", cveId, "err: ", err)
+ }
+ return sc, err
+}
+
+func QueryIssueScoreRecord(cveId int64, status int8) (ScoreRecord, error) {
+ o := orm.NewOrm()
+ var sr ScoreRecord
+ err := o.Raw("select id, cve_id, nvd_score, n_vector_value"+
+ " from cve_score_record where cve_id = ? and status = ? order by id desc limit 1", cveId, status).QueryRow(&sr)
+ if err == nil {
+ logs.Info("cve_score_record 查询结果:", sr)
+ } else {
+ logs.Info("查询 cve_score_record err, cveId: ", cveId, "err: ", err)
+ }
+ return sr, err
+}
+
+func GetIssueTemplet(it *IssueTemplate) (localIt IssueTemplate, value bool) {
+ o := orm.NewOrm()
+ err := o.Raw("select *"+
+ " from cve_issue_template where cve_id = ? ", it.CveId).QueryRow(&localIt)
+ if err == nil {
+ logs.Info("cve_issue_template 查询结果:", localIt)
+ return localIt, true
+ } else {
+ logs.Info("查询 cve_issue_template err, cveId: ", it.CveId, "err: ", err)
+ return localIt, false
+ }
+}
+
+func GetIssueTemplateByColName(it *IssueTemplate, colName string) error {
+ o := orm.NewOrm()
+ err := o.Read(it, colName)
+ return err
+}
+
+func UpdateIssueTemplate(it *IssueTemplate, fields ...string) error {
+ o := orm.NewOrm()
+ _, err := o.Update(it, fields...)
+ return err
+}
+
+func UpdateScore(s *Score, fields ...string) error {
+ o := orm.NewOrm()
+ _, err := o.Update(s, fields...)
+ return err
+}
+
+func UpdatePackageByCveId(pkgStr string, cveId int64) error {
+ mutex.Lock()
+ defer mutex.Unlock()
+ if pkgStr == "" || cveId == 0 {
+ return errors.New("param pkgStr,cveId must be not empty")
+ }
+ ps := strings.Split(pkgStr, ",")
+ if len(ps) > 0 {
+ sec := struct {
+ SecId int64
+ }{}
+ secSql := `SELECT sec_id FROM cve_security_notice WHERE cve_id = ?`
+ o := orm.NewOrm()
+ err := o.Raw(secSql, cveId).QueryRow(&sec)
+ if err != nil {
+ return err
+ }
+ for _, v := range ps {
+ tv := util.TrimString(v)
+ if tv == "" {
+ continue
+ }
+ pkg := Package{SecId: sec.SecId, PackName: tv}
+ errx := o.Read(&pkg, "sec_id", "pack_name")
+ if errx == orm.ErrNoRows {
+ pkg.PackUrl = fmt.Sprintf(`https://repo.openeuler.org/openEuler-20.03-LTS/update/aarch64/Packages/%s`, tv)
+ _, errx = o.Insert(&pkg)
+ }
+ }
+ return nil
+ //===== 先删除 再修改 =====
+ /*delPkgSql := `DELETE FROM cve_package WHERE sec_id = ?`
+ err = o.Begin()
+ if err != nil {
+ return err
+ }
+ _, err = o.Raw(delPkgSql, sec.SecId).Exec()
+ if err != nil {
+ err = o.Rollback()
+ return err
+ }
+ pkgVals := make([]Package, 0)
+ for _, v := range ps {
+ pkgUrl := fmt.Sprintf(`https://repo.openeuler.org/openEuler-20.03-LTS/update/aarch64/Packages/%s`, v)
+ pv := Package{SecId: sec.SecId, PackName: v, PackUrl: pkgUrl}
+ pkgVals = append(pkgVals, pv)
+ }
+ _, err = o.InsertMulti(1, pkgVals)
+ if err != nil {
+ _ = o.Rollback()
+ return err
+ }
+ err = o.Commit()
+ if err != nil {
+ return err
+ }*/
+ }
+ return nil
+}
+
+func QueryPackageByCveId(cveId int64) ([]Package, error) {
+ sqlStr := `SELECT * FROM cve_package WHERE sec_id = (SELECT sec_id FROM cve_security_notice WHERE cve_id = ?)`
+ var res []Package
+ o := orm.NewOrm()
+ _, err := o.Raw(sqlStr, cveId).QueryRows(&res)
+ return res, err
+}
+
+func CreateIssueTemplet(it *IssueTemplate) (issTempId int64, err error) {
+ o := orm.NewOrm()
+ var localIt IssueTemplate
+ errx := o.Raw("select *"+
+ " from cve_issue_template where cve_id = ? ", it.CveId).QueryRow(&localIt)
+ if errx != nil {
+ // 创建
+ var issTempId int64
+ if issTempId, err = o.Insert(it); err == nil {
+ logs.Info("insert cve_issue_template success, issTempId: ", issTempId, "cveNum: ", it.CveNum)
+ } else {
+ logs.Error("insert issTempId failed, cveNum:", it.CveNum, "err: ", err)
+ return 0, err
+ }
+ return issTempId, nil
+ } else {
+ // 更新
+ it.TemplateId = localIt.TemplateId
+ if num, err := o.Update(it); err == nil {
+ logs.Info("update cve_issue_template success, num: ", num, "cveNum: ", it.CveNum)
+ } else {
+ logs.Error("update issTempId failed, cveNum:", it.CveNum, "err: ", err)
+ return 0, err
+ }
+ return it.TemplateId, nil
+ }
+}
+
+func GetIssueHook(ih *IssueHooks) (localh IssueHooks, value bool) {
+ o := orm.NewOrm()
+ var localIh IssueHooks
+ localIh.CveId = ih.CveId
+ localIh.IssueNum = ih.IssueNum
+ err := o.Raw("select *"+
+ " from cve_issue_hooks where cve_id = ? and issue_num = ?", ih.CveId, ih.IssueNum).QueryRow(&localIh)
+ if err == nil {
+ logs.Info("cve_issue_hooks 查询结果:", localIh)
+ return localIh, true
+ } else {
+ logs.Info("查询 cve_issue_hooks err, cveId: ", ih.CveId, "err: ", err)
+ return localIh, false
+ }
+}
+
+func CreateDepositHooks(ih *IssueHooks) (issHookId int64, err error) {
+ o := orm.NewOrm()
+ var localIh IssueHooks
+ localIh.CveId = ih.CveId
+ localIh.IssueNum = ih.IssueNum
+ errx := o.Raw("select *"+
+ " from cve_issue_hooks where cve_id = ? and issue_num = ?", ih.CveId, ih.IssueNum).QueryRow(&localIh)
+ if errx == nil {
+ logs.Info("cve_issue_hooks 查询结果:", localIh)
+ ih.Id = localIh.Id
+ if num, err := o.Update(ih); err == nil {
+ logs.Info("update cve_issue_hook success, issHookId: ", num, "IssueNum: ", ih.IssueNum)
+ } else {
+ logs.Error("update cve_issue_hook failed, IssueNum:", ih.IssueNum, "err: ", err)
+ return 0, err
+ }
+ return ih.Id, nil
+ } else {
+ logs.Info("查询 cve_issue_hooks err, cveId: ", ih.CveId, "err: ", err)
+ var issHookId int64
+ if issHookId, err = o.Insert(ih); err == nil {
+ logs.Info("insert cve_issue_hook success, issHookId: ", issHookId, "IssueNum: ", ih.IssueNum)
+ } else {
+ logs.Error("insert cve_issue_hook failed, IssueNum:", ih.IssueNum, "err: ", err)
+ return 0, err
+ }
+ return issHookId, nil
+ }
+}
+
+func UpdateSecNotice(sec *SecurityNotice) (secId int64, err error) {
+ o := orm.NewOrm()
+ var localSec SecurityNotice
+ localSec.CveId = sec.CveId
+ localSec.CveNum = sec.CveNum
+ errx := o.Raw("select *"+
+ " from cve_security_notice where cve_id = ? and cve_num = ?", sec.CveId, sec.CveNum).QueryRow(&localSec)
+ if errx == nil {
+ logs.Info("cve_security_notice 查询结果:", localSec)
+ sec.SecId = localSec.SecId
+ sec.OpenId = localSec.OpenId
+ sec.InfluenceComponent = localSec.InfluenceComponent
+ sec.ReferenceLink = localSec.ReferenceLink
+ if num, err := o.Update(sec); err == nil {
+ logs.Info("update cve_security_notice success, SecId: ", num, "CveNum: ", sec.CveNum)
+ } else {
+ logs.Error("update cve_security_notice failed, SecId:", sec.SecId, "err: ", err)
+ return 0, err
+ }
+ return sec.SecId, nil
+ } else {
+ logs.Info("查询 cve_security_notic err, cveId: ", sec.CveId, "err: ", err)
+ var SecId int64
+ if SecId, err = o.Insert(sec); err == nil {
+ logs.Info("insert cve_security_notice success, SecId: ", SecId, "CveNum: ", sec.CveNum)
+ } else {
+ logs.Error("insert cve_security_notice failed, CveNum:", sec.CveNum, "err: ", err)
+ return 0, err
+ }
+ return SecId, nil
+ }
+}
+
+func UpdateIssueStatus(iss VulnCenter, status int8) (secId int64) {
+ o := orm.NewOrm()
+ _ = o.Raw("UPDATE cve_vuln_center SET cve_status = ? WHERE cve_id = ? and cve_num = ?", status, iss.CveId, iss.CveNum).QueryRow()
+ return
+}
+
+func UpdateIssueScore(iss VulnCenter, status int8) (id int64) {
+ o := orm.NewOrm()
+ _ = o.Raw("UPDATE cve_score SET n_score_status = ? WHERE cve_id = ? and cve_num = ?", status, iss.CveId, iss.CveNum).QueryRow()
+ return
+}
+
+func UpdateIssueScoreRe(iss VulnCenter, status int8) (id int64) {
+ o := orm.NewOrm()
+ _ = o.Raw("UPDATE cve_score_record SET status = ? WHERE cve_id = ? and status = ?", status, iss.CveId, 0).QueryRow()
+ return
+}
+
+func UpdateIssueCommentId(issueNum, cveNum string, commentId int64) (id int64) {
+ o := orm.NewOrm()
+ _ = o.Raw("UPDATE cve_issue_template SET comment_id = ? WHERE issue_num = ? and cve_num = ?", commentId, issueNum, cveNum).QueryRow()
+ return
+}
\ No newline at end of file
diff --git a/models/login.go b/models/login.go
new file mode 100644
index 0000000000000000000000000000000000000000..6e391ee1bcc3a7fec081fa6ec4df61c12395deda
--- /dev/null
+++ b/models/login.go
@@ -0,0 +1,29 @@
+package models
+
+import (
+ "github.com/astaxie/beego/orm"
+ "time"
+)
+
+func GetCveUserByUser(username, pwd string) (maps []orm.Params, err error) {
+ o := orm.NewOrm()
+ var num int64
+ num, err = o.Raw("select user_id FROM cve_other_user WHERE user_name=? and pass_word=?", username, pwd).Values(&maps)
+ if err == nil && num > 0 {
+ return maps, nil
+ }
+ return nil, err
+}
+
+func UpdateToken(Userid interface{} ,token string, newTime time.Time) bool{
+ o:=orm.NewOrm()
+ _ = o.Raw("update cve_other_user set aes_key=?,expiration_time=? where user_id=?", token, newTime, Userid).QueryRow()
+ return true
+}
+
+func GetUserByToken(token string, ou * OtherUser) (err error) {
+ o := orm.NewOrm()
+ err = o.Raw("select * FROM cve_other_user WHERE aes_key=?", token).QueryRow(ou)
+ return err
+}
+
diff --git a/models/modeldb.go b/models/modeldb.go
new file mode 100644
index 0000000000000000000000000000000000000000..c9d5b14ee6717719a90b8264cf823727139838a5
--- /dev/null
+++ b/models/modeldb.go
@@ -0,0 +1,457 @@
+package models
+
+import (
+ "github.com/astaxie/beego"
+ "github.com/astaxie/beego/config"
+ "github.com/astaxie/beego/logs"
+ "github.com/astaxie/beego/orm"
+ "time"
+)
+
+type IpWhite struct {
+ IPId int `orm:"pk;auto;column(ip_id)"` // 自增的值
+ MachineName string `orm:"size(128);column(machine_name)" description:"机器名称"`
+ MachineIp string `orm:"size(128);column(machine_ip);index" description:"机器ip"`
+ AccessCount int64 `orm:"default(0);column(access_count)" description:"0: 不受限制; 10000:可以连续访问次数"`
+}
+
+type OtherUser struct {
+ UerId int `orm:"pk;auto;column(user_id)"` // 自增的值
+ UserName string `orm:"size(64);column(user_name)"`
+ PassWord string `orm:"size(256);column(pass_word)"`
+ AesKey string `orm:"size(512);colnum(aes_key)"`
+ ExpirationTime string `orm:"size(32);column(expiration_time)" description:"token的过期时间"`
+ CreateTime time.Time `orm:"auto_now;type(datetime);column(create_time)"`
+ UpdateTime time.Time `orm:"auto_now;type(datetime);column(update_time)"`
+ DeleteTime time.Time `orm:"auto_now;type(datetime);column(delete_time)"`
+}
+
+type AdminUser struct {
+ UerId int `orm:"pk;auto;column(user_id)"` // 自增的值
+ UserName string `orm:"size(64);column(user_name)"`
+ PassWord string `orm:"size(256);column(pass_word)"`
+ CreateTime time.Time `orm:"auto_now;type(datetime);column(create_time)"`
+}
+
+type VulnCenter struct {
+ CveId int64 `orm:"pk;auto;column(cve_id)"`
+ CveNum string `orm:"size(256);column(cve_num);unique" description:"cve编号"`
+ Description string `orm:"size(8192);column(cve_desc)" description:"cve描述"`
+ CveLevel string `orm:"size(32);column(cve_level)" description:"致命(Critical);严重(High);中等(Medium);一般(Low);其他"`
+ Status int8 `orm:"default(0);column(cve_status)" description:"0:cve新增;1:数据已变化;2:已创建issue"`
+ CveVersion string `orm:"size(128);column(cve_version)" description:"cve归属版本"`
+ RepairTime string `orm:"size(32);column(repair_time)" description:"cve修复时间"`
+ PackName string `orm:"size(1024);column(pack_name)" description:"cve对应得包名称"`
+ CveUrl string `orm:"size(2048);column(cve_url)" description:"cve下载链接"`
+ CreateTime time.Time `orm:"auto_now_add;type(datetime);column(create_time)"`
+ UpdateTime time.Time `orm:"auto_now;type(datetime);column(update_time)"`
+ DeleteTime time.Time `orm:"auto_now;type(datetime);column(delete_time)"`
+}
+
+type OpenEulerSA struct {
+ OpenId int64 `orm:"pk;auto;column(openeuler_id)"`
+ CveId int64 `orm:"index;column(cve_id)"`
+ PublicDate string `orm:"size(16);column(public_date);null" description:"安全公告时间"`
+ OpenEulerSANum string `orm:"size(128);column(openeuler_sa_num);unique" description:"安全公告"`
+}
+
+type ScoreRecord struct {
+ Id int64 `orm:"pk;auto"`
+ CveId int64 `orm:"index;column(cve_id)"`
+ NVDScore float64 `orm:"digits(10);decimals(1);column(nvd_score)"`
+ NvectorVule string `orm:"size(256);column(n_vector_value)" description:"nvd vector 原始值"`
+ Status int8 `orm:"default(0);column(status)" description:"0:未处理;1:已处理"`
+ CreateTime time.Time `orm:"auto_now_add;type(datetime);column(create_time)"`
+}
+
+type Score struct {
+ Id int64 `orm:"pk;auto"`
+ CveId int64 `orm:"index;column(cve_id)"`
+ CveNum string `orm:"size(256);column(cve_num)" description:"cve编号"`
+ NVDScore float64 `orm:"digits(10);decimals(1);column(nvd_score)" description:"nvd 评分"`
+ OpenEulerScore float64 `orm:"digits(10);decimals(1);column(openeuler_score)" description:"openeuler评分"`
+ NvectorVule string `orm:"size(256);column(n_vector_value)" description:"nvd vector 原始值"`
+ OvectorVule string `orm:"size(256);column(o_vector_value)" description:"openeuler vector 原始值"`
+ NattackVector string `orm:"size(64);column(n_attack_vector)"`
+ OattackVector string `orm:"size(64);column(o_attack_vector)"`
+ NattackComplexity string `orm:"size(64);column(n_attack_complexity)"`
+ OattackComplexity string `orm:"size(64);column(o_attack_complexity)"`
+ NprivilegeRequired string `orm:"size(64);column(n_privilege_required)"`
+ OprivilegeRequired string `orm:"size(64);column(o_privilege_required)"`
+ NuserInteraction string `orm:"size(64);column(n_user_interaction)"`
+ OuserInteraction string `orm:"size(64);column(o_user_interaction)"`
+ Nscope string `orm:"size(64);column(n_scope)"`
+ Oscope string `orm:"size(64);column(o_scope)"`
+ Nconfidentiality string `orm:"size(64);column(n_confidentiality)"`
+ Oconfidentiality string `orm:"size(64);column(o_confidentiality)"`
+ Nintegrity string `orm:"size(64);column(n_integrity)"`
+ Ointegrity string `orm:"size(64);column(o_integrity)"`
+ Navailability string `orm:"size(64);column(n_availability)"`
+ Oavailability string `orm:"size(64);column(o_availability)"`
+ ScoreType string `orm:"size(16);column(score_type)"`
+ OpenId int64 `orm:"unique;column(openeuler_id);null"`
+ Nstatus int8 `orm:"default(0);column(n_score_status)" description:"0:新增评分,无改变;1:修改nvd评分;2:已提交issue;3:已处理"`
+ Ostatus int8 `orm:"default(0);column(o_score_status)" description:"0:新增评分,无改变;1:修改nvd评分;2:修改评分未通过;3:修改评分已通过"`
+ CreateTime time.Time `orm:"auto_now_add;type(datetime);column(create_time)"`
+ UpdateTime time.Time `orm:"auto_now;type(datetime);column(update_time)"`
+ DeleteTime time.Time `orm:"auto_now;type(datetime);column(delete_time)"`
+}
+
+type SecurityNotice struct {
+ SecId int64 `orm:"pk;auto;column(sec_id)" description:"安全公告"`
+ CveId int64 `orm:"index;column(cve_id)"`
+ CveNum string `orm:"size(256);column(cve_num)" description:"cve编号"`
+ OpenId int64 `orm:"unique;column(openeuler_id);null" description:"OpenEulerSA"`
+ Introduction string `orm:"size(256);null;column(introduction)" description:"简介"`
+ Summary string `orm:"size(256);null;column(summary)" description:"概要"`
+ Theme string `orm:"size(2048);null;column(theme)" description:"主题"`
+ Description string `orm:"size(8192);column(description)" description:"安全公告描述"`
+ InfluenceComponent string `orm:"size(256);null;column(influence_component)" description:"影响组件"`
+ AffectProduct string `orm:"size(256);null;column(affect_product)" description:"影响产品"`
+ ReferenceLink string `orm:"size(1024);null;column(reference_link)" description:"参考链接"`
+ Status int8 `orm:"default(0);column(sec_status)" description:"0:未发布;1:已发布"`
+ AffectStatus string `orm:"size(16);null;column(affect_status)" description:"Fixed:已解决;UnFixed:未解决;UnAffected:不影响"`
+ CreateTime time.Time `orm:"auto_now_add;type(datetime);column(create_time)"`
+ UpdateTime time.Time `orm:"auto_now;type(datetime);column(update_time)"`
+ DeleteTime time.Time `orm:"auto_now;type(datetime);column(delete_time)"`
+}
+
+type Package struct {
+ Id int64 `orm:"pk;auto"`
+ SecId int64 `orm:"index;column(sec_id)"`
+ PackName string `orm:"size(1024);null;column(pack_name)" description:"包名"`
+ PackUrl string `orm:"size(2048);null;column(pack_url)" description:"包下载链接"`
+}
+
+type IssueTemplate struct {
+ TemplateId int64 `orm:"pk;auto;column(template_id)"`
+ CveId int64 `orm:"index;column(cve_id)"`
+ CveNum string `orm:"size(256);column(cve_num)" description:"cve编号"`
+ OwnedComponent string `orm:"size(256);column(owned_component)" description:"漏洞归属组件"`
+ OwnedVersion string `orm:"size(256);column(owned_version)" description:"漏洞归属版本"`
+ NVDScore float64 `orm:"digits(10);decimals(1);column(nvd_score)" description:"nvd评分"`
+ OpenEulerScore float64 `orm:"digits(10);decimals(1);column(openeuler_score)" description:"openeuler评分"`
+ NVDVector string `orm:"size(256);column(nvd_vector)" description:"nvd评分向量"`
+ OpenEulerVector string `orm:"size(256);column(openeuler_vector)" description:"openeuler评分向量"`
+ CveBrief string `orm:"size(4096);column(cve_brief)" description:"漏洞简述"`
+ CveAnalysis string `orm:"size(4096);column(cve_analysis)" description:"影响性分析说明"`
+ PrincipleAnalysis string `orm:"size(4096);column(principle_analysis)" description:"原理分析"`
+ AffectedVersion string `orm:"size(256);column(affected_version)" description:"受影响的版本"`
+ Solution string `orm:"size(1024);column(solution)" description:"规避方案或消减措施"`
+ IssueId int64 `orm:"column(issue_id)" description:"issue的id"`
+ IssueNum string `orm:"size(64);column(issue_num);index" description:"issue编号"`
+ Assignee string `orm:"size(128);column(issue_assignee)" description:"issue所属责任人"`
+ Status int8 `orm:"default(0);column(status)" description:"1:待办的;2:进行中;3:已完成;4:已拒绝"`
+ StatusName string `orm:"size(128);column(status_name)" description:"issue状态名称"`
+ IssueStatus int8 `orm:"default(0);column(issue_status)" description:"1:待分析;2:已正常关闭;3已分析,待修复;4:已修复;5:已发布;6:已异常关闭"`
+ IssueLabel string `orm:"size(256);column(issue_label)" description:"issue标签, cve/Undisclosed, cve/Disclosed"`
+ Owner string `orm:"size(128);column(owner)" description:"仓库地址"`
+ Repo string `orm:"size(128);column(repo)" description:"仓库路径"`
+ Title string `orm:"size(512);column(title)" description:"issue标题"`
+ IssueType string `orm:"size(64);column(issue_type)" description:"CVE和安全问题"`
+ Collaborators string `orm:"size(128);column(collaborators);null" description:"协助者"`
+ Milestone string `orm:"size(64);column(milestone);null" description:"里程碑序号"`
+ Program string `orm:"size(64);column(program);null" description:"项目编号"`
+ SecurityHole int8 `orm:"default(0);column(security_hole)" description:"是否是私有issue"`
+ CveLevel string `orm:"size(32);column(cve_level)" description:"致命(Critical);严重(High);中等(Medium);一般(Low);其他"`
+ CommentId int64 `orm:"column(comment_id), null" description:"首条评论id"`
+ CreateTime time.Time `orm:"auto_now_add;type(datetime);column(create_time)"`
+ UpdateTime time.Time `orm:"auto_now;type(datetime);column(update_time)"`
+ DeleteTime time.Time `orm:"auto_now;type(datetime);column(delete_time)"`
+}
+
+type IssueHooks struct {
+ Id int64 `orm:"pk;auto"`
+ CveId int64 `orm:"index;column(cve_id)"`
+ IssueId int64 `orm:"column(issue_id)" description:"issue的id"`
+ IssueNum string `orm:"size(64);column(issue_num);index" description:"issue编号"`
+ HookId int64`orm:"column(hook_id)" decrtiption:"钩子id"`
+ Owner string `orm:"size(128);column(owner)" description:"仓库地址"`
+ Repo string `orm:"size(128);column(repo)" description:"仓库路径"`
+ HookUrl string `orm:"size(512);column(hook_url)" description:"回调地址"`
+ PushEvent int8 `orm:"column(push_event);default(1)" description:"Push代码到仓库; 默认1:已监听; 0: 未监听"`
+ TagPushEvent int8 `orm:"column(tag_push_events);default(1)" description:"提交Tag到仓库, 默认1:已监听; 0: 未监听"`
+ IssueEvent int8 `orm:"column(issues_events);default(1)" description:"创建/关闭Issue, 默认1:已监听; 0: 未监听"`
+ NoteEvent int8 `orm:"column(note_events);default(1)" description:"评论了Issue/代码等等, 默认1:已监听; 0: 未监听"`
+ MergeRequestEvent int8 `orm:"column(merge_requests_events);default(1)" description:"合并请求和合并后, 默认1:已监听; 0: 未监听"`
+}
+
+type GitPackageTable struct {
+ TableId int64 `orm:"pk;auto;column(table_id)"`
+ TableName string `orm:"size(128);column(table_name)" description:"数据库pkginfo下的表名,如:mainline, bringInRely"`
+}
+
+type GitOpenEuler struct {
+ GitId int64 `orm:"pk;auto;column(git_id)"`
+ PackageId int64 `orm:"index;column(package_id)" description:"获取到的包id"`
+ PackageName string `orm:"column(package_name);size(256)" description:"包名称"`
+ Version string `orm:"size(64);column(version);index" description:"版本号"`
+ Release string `orm:"size(128);column(release)" description:"release 版本号"`
+ OriginUrl string `orm:"size(512);column(origin_url)" description:"gitee上的地址"`
+ License string `orm:"size(4096);column(license)" description:"license"`
+ Feature string `orm:"size(128);column(feature)" description:"特性"`
+ MainTainer string `orm:"size(128);column(main_tainer)" description:"维护人"`
+ MainTainLevel int8 `orm:"column(main_tain_level);default(1)" description:"软件包维护级别"`
+ ReleaseTime string `orm:"size(32);column(release_time)" description:"当前版本发布时间"`
+ UsedTime string `orm:"size(32);column(used_time)" description:"当天减去所用版本的发布日期"`
+ LatestVersion string `orm:"size(128);column(latest_version)" description:"最新版本号"`
+ LatestVersionTime string `orm:"size(32);column(latest_version_time)" description:"最新版本发布时间"`
+ IssueCount int64 `orm:"column(issue_count);default(0)" description:"该软件包仓库下的issue总数"`
+ TableId int64 `orm:"index;column(table_id)" description:"表id,外键"`
+ TableName string `orm:"size(128);column(table_name)" description:"数据库pkginfo下的表名,如:mainline, bringInRely"`
+ Status int8 `orm:"default(0);column(status)" description:"0: 代表新数据; 1:已推送; 2:代表已废弃"`
+ CreateTime time.Time `orm:"auto_now_add;type(datetime);column(create_time)"`
+ UpdateTime time.Time `orm:"auto_now;type(datetime);column(update_time)"`
+ DeleteTime time.Time `orm:"auto_now;type(datetime);column(delete_time)"`
+}
+
+type GitPackageInfo struct {
+ DetailId int64 `orm:"pk;auto;column(detail_id)"`
+ GitId int64 `orm:"index;column(git_id)" description:"包id,外键"`
+ Ids int64 `orm:"index;column(git_ids)" description:"原始数据id来源"`
+ PackageName string `orm:"column(package_name);size(256)" description:"包名称"`
+ Version string `orm:"size(64);column(version);index" description:"版本号"`
+ Release string `orm:"size(128);column(release)" description:"release 版本号"`
+ OriginUrl string `orm:"size(512);column(origin_url)" description:"上游社区链接"`
+ License string `orm:"size(4096);column(license)" description:"license"`
+ Feature string `orm:"size(128);column(feature)" description:"特性"`
+ MainTainer string `orm:"size(128);column(main_tainer)" description:"维护人"`
+ MainTainLevel int8 `orm:"column(main_tain_level);default(1)" description:"软件包维护级别"`
+ GitUrl string `orm:"size(512);column(git_url)" description:"gitee上的地址"`
+ Summary string `orm:"size(1024);column(summary)" description:"summary"`
+ Decription string `orm:"size(8092);column(decription)" description:"decription"`
+ BuildRequired string `orm:"size(4096);column(build_require)" description:"源码包的编译依赖"`
+ Status int8 `orm:"default(0);column(status)" description:"0: 代表新数据; 1:已推送; 2:代表已废弃"`
+ CreateTime time.Time `orm:"auto_now_add;type(datetime);column(create_time)"`
+ UpdateTime time.Time `orm:"auto_now;type(datetime);column(update_time)"`
+ DeleteTime time.Time `orm:"auto_now;type(datetime);column(delete_time)"`
+}
+
+type GitSubPack struct {
+ SubId int64 `orm:"pk;auto;column(sub_id)"`
+ DetailId int64 `orm:"index;column(detail_id)" description:"包id,外键"`
+ Ids int64 `orm:"index;column(ids)" description:"原始数据id来源"`
+ SubPackName string `orm:"size(256);column(sub_pack_name)" description:"二进制包名"`
+}
+
+type GitSubPackRequire struct {
+ RequireId int64 `orm:"pk;auto;column(require_id)"`
+ SubId int64 `orm:"index;column(sub_id)" description:"包id,外键"`
+ Ids int64 `orm:"index;column(ids)" description:"原始数据id来源"`
+ RequireName string `orm:"size(256);column(require_name)" description:"二进制包名"`
+ Providedby string `orm:"size(4096);column(providedb)" description:"提供该组件的二进制包"`
+}
+
+type GitSubPackProvides struct {
+ ProvideId int64 `orm:"pk;auto;column(provide_id)"`
+ SubId int64 `orm:"index;column(sub_id)" description:"包id,外键"`
+ Ids int64 `orm:"index;column(ids)" description:"原始数据id来源"`
+ ProvideName string `orm:"size(256);column(provide_name)" description:"依赖的组件名称"`
+ Requiredby string `orm:"size(256);column(requiredb)" description:"依赖该组件的二进制包列表"`
+}
+
+type GitSubPackRequiredby struct {
+ Id int64 `orm:"pk;auto;column(id)"`
+ ProvideId int64 `orm:"index;column(provide_id)"description:"包id,外键"`
+ Requiredby string `orm:"size(256);column(requiredb)" description:"依赖该组件的二进制包列表"`
+}
+
+
+type OriginUpstream struct {
+ CveId int64 `orm:"pk;auto;column(cve_id)"`
+ Ids string `orm:"size(256);column(cve_un_ids);unique"description:"唯一编号,根据此字段去重数据, 唯一识别码,可以填cve编号"`
+ CveNum string `orm:"size(256);column(cve_num);index"description:"cve编号"`
+ UpdateType string `orm:"size(32);column(update_type);"description:"数据上传类型:insert, update, delete"`
+ CvePackName string `orm:"size(512);column(cve_packname);index;null"description:"Cve在上游对应的包名"`
+ PackName string `orm:"size(512);column(git_packname);index;null"description:"Cve对应的openEuler包名称(或者影响的包名)"`
+ Title string `orm:"size(1024);column(cve_title);null"description:"标题"`
+ AffectProduct string `orm:"size(512);column(affect_porduct);null"description:"Cve影响的组件, 对应"`
+ CnnvdID string `orm:"size(256);column(cnnvd_id);null"description:"Cnnvd_id"`
+ CnvdID string `orm:"size(256);column(cnvd_id);null"description:"Cnvd_id"`
+ PublishedDate string `orm:"size(32);column(published_date);null"description:"漏洞发布日期"`
+ VulStatus string `orm:"size(64);column(vul_status);null"description:"漏洞状态,REJECT, DISPUTED"`
+ Status int8 `orm:"default(0);column(cve_status)"description:"0:cve新增;1:数据已变化;2:数据已处理"`
+ AffectedScope string `orm:"size(512);column(affected_scope);null"description:"影响范围推理"`
+ Version string `orm:"size(64);column(version);index" description:"包对应的版本号"`
+ AttackLink string `orm:"size(512);column(attack_link);null"description:"攻击链路推理"`
+ IsExit int8 `orm:"default(1);column(is_exit)"description:"1: 当前包对应在src-openEuler有对应仓库; 0: 无;2:临时值"`
+ CreateTime string `orm:"size(32);column(create_time)"`
+ UpdateTime string `orm:"size(32);column(update_time);null"`
+ DeleteTime string `orm:"size(32);column(delete_time);null"`
+}
+
+type OriginUpstreamDesc struct {
+ DescId int64 `orm:"pk;auto;column(desc_id)"`
+ CveId int64 `orm:"index;column(cve_id)"description:"OriginUpstream 外键"`
+ EnDescription string `orm:"size(8192);column(en_desc);null"description:"cve英文描述"`
+ ZhDescription string `orm:"size(8192);column(zh_desc);null"description:"cve中文描述"`
+}
+
+type OriginUpstreamConfig struct {
+ ConfId int64 `orm:"pk;auto;column(conf_id)"`
+ CveId int64 `orm:"index;column(cve_id)"description:"OriginUpstream 外键"`
+ Nodes string `orm:"size(32);column(nodes);null"description:"nodes数组"`
+}
+
+type OriginUpstreamConfigNode struct {
+ NodeId int64 `orm:"pk;auto;column(node_id)"`
+ ConfId int64 `orm:"index;column(conf_id)"description:"OriginUpstreamConfig 外键"`
+ Operator string `orm:"size(256);column(operator);null"description:"operator"`
+}
+
+type SecurityReviewer struct {
+ Id int64 `orm:"pk;auto"`
+ NameSpace string `orm:"unique" description:"码云空间地址"`
+}
+type OriginUpstreamConfigNodeCpe struct {
+ CpeId int64 `orm:"pk;auto;column(cpe_id)"`
+ NodeId int64 `orm:"index;column(node_id)"description:"OriginUpstreamConfigNode 外键"`
+ Cpe23Uri string `orm:"size(1024);column(cpe_uri);null"description:"cpe"`
+ CpeMatchString string `orm:"size(1024);column(cpe_match);null"description:"过滤字符串"`
+ Vulnerable string `orm:"size(64);column(vulner_able);null"description:"易受攻击"`
+}
+
+type OriginUpstreamImpact struct {
+ ImpactId int64 `orm:"pk;auto;column(impact_id)"`
+ CveId int64 `orm:"index;column(cve_id)"description:"OriginUpstream 外键"`
+ Impact string `orm:"size(32);column(impact);null"description:"包含v2,v3评分数据"`
+}
+
+type OriginUpstreamImpactScore struct {
+ ScoreId int64 `orm:"pk;auto;column(score_id)"`
+ ImpactId int64 `orm:"index;column(impact_id)" description:"OriginUpstreamImpact 外键"`
+ BaseMetricV3 int8 `orm:"column(base_met_v3);null" description:"v3评分存在为:1; 0:不存在"`
+ BaseMetricV2 int8 `orm:"column(base_met_v2);null" description:"v2评分存在为:1; 0:不存在"`
+ CvssV3 int8 `orm:"column(cvss_v3);null" description:"v3评分存在为:1; 0:不存在"`
+ CvssV2 int8 `orm:"column(cvss_v2);null" description:"v2评分存在为:1; 0:不存在"`
+ Status int8 `orm:"default(1);column(score_status);null" description:"1:未处理;2:已处理;3:已修改"`
+}
+
+type OriginUpstreamImpactScoreV3 struct {
+ V3Id int64 `orm:"pk;auto;column(v3_id)"`
+ ScoreId int64 `orm:"index;column(score_id)" description:"OriginUpstreamImpactScore 外键"`
+ BaseScore float64 `orm:"digits(10);decimals(1);column(base_score);null" description:"nvd 基准分"`
+ VectorString string `orm:"size(256);column(vector_value);null" description:"nvd vector 评分向量值"`
+ AttackComplexity string `orm:"size(64);column(attack_complexity);null"description:"攻击复杂性"`
+ AttackVector string `orm:"size(64);column(attack_vector);null"description:"攻击目标"`
+ AvailabilityImpact string `orm:"size(64);column(availability_impact);null"description:"可用性影响"`
+ BaseSeverity string `orm:"size(64);column(base_severity);null"description:"严重程度"`
+ UserInteraction string `orm:"size(64);column(user_interaction);null"description:"用户交互"`
+ PrivilegesRequired string `orm:"size(64);column(privilege_required);null"description:"所需特权"`
+ Version string `orm:"size(64);column(version);null"description:"Cvss版本"`
+ ConfidentialityImpact string `orm:"size(64);column(confidentiality_impact);null"description:"可信性影响"`
+ IntegrityImpact string `orm:"size(64);column(integrity_impact);null"description:"完整性影响"`
+ Scope string `orm:"size(64);column(scope);null"description:"范围"`
+ ImpactScore float64 `orm:"digits(10);decimals(1);column(impact_score);null" description:"nvd 影响评分"`
+ ExploitabilityScore float64 `orm:"digits(10);decimals(1);column(exploitability_score);null" description:"nvd 可利用性评分"`
+ CveLevel string `orm:"size(32);column(cve_level);null"description:"致命(Critical) >= 9.0;严重(High)>=7.0&&<=8.9;中等(Medium)>4.0 && <=6.9;一般(Low)<=4.0;其他"`
+}
+
+type OriginUpstreamImpactScoreV2 struct {
+ V2Id int64 `orm:"pk;auto;column(v2_id)"`
+ ScoreId int64 `orm:"index;column(score_id)" description:"OriginUpstreamImpactScore 外键"`
+ AcInsufInfo string `orm:"size(64);column(acinsuf_info);null" description:"nvd vector 原始值"`
+ BaseScore float64 `orm:"digits(10);decimals(1);column(base_score);null" description:"nvd 基准分"`
+ VectorString string `orm:"size(256);column(vector_value);null" description:"nvd vector 评分向量值"`
+ AccessComplexity string `orm:"size(64);column(access_complexity);null"description:"攻击复杂性"`
+ Authentication string `orm:"size(64);column(authentication);null"description:"身份认证"`
+ AvailabilityImpact string `orm:"size(64);column(availability_impact);null"description:"可用性影响"`
+ Version string `orm:"size(64);column(version);null"description:"Cvss版本"`
+ ConfidentialityImpact string `orm:"size(64);column(confidentiality_impact);null"description:"可信性影响"`
+ IntegrityImpact string `orm:"size(64);column(integrity_impact);null"description:"完整性影响"`
+ AccessVector string `orm:"size(64);column(access_vector);null"description:"攻击目标"`
+ UserInteractionRequired string `orm:"size(64);column(user_interaction_required);null"description:"需要用户交互"`
+ Severity string `orm:"size(64);column(severity);null"description:"严重程度"`
+ ObtainUserPrivilege string `orm:"size(64);column(obtain_user_privilege);null"description:"获取用户特权"`
+ ObtainAllPrivilege string `orm:"size(64);column(obtain_all_privilege);null"description:"获取所有特权"`
+ ObtainOtherPrivilege string `orm:"size(64);column(obtain_other_privilege);null"description:"获取其他特权"`
+ ImpactScore float64 `orm:"digits(10);decimals(1);column(impact_score);null" description:"nvd 影响评分"`
+ ExploitabilityScore float64 `orm:"digits(10);decimals(1);column(exploitability_score);null" description:"nvd 可利用性评分"`
+ CveLevel string `orm:"size(32);column(cve_level);null"description:"致命(Critical) >= 9.0;严重(High)>=7.0&&<=8.9;中等(Medium)>4.0 && <=6.9;一般(Low)<=4.0;其他"`
+}
+
+type OriginUpstreamPoc struct {
+ PocId int64 `orm:"pk;auto;column(poc_id)"`
+ CveId int64 `orm:"index;column(cve_id)"description:"OriginUpstream 外键"`
+ Source string `orm:"size(512);column(source);null"description:"来源"`
+ Date string `orm:"size(32);column(date);null"description:"日期"`
+ Path string `orm:"size(512);column(path);null"description:"文件路径"`
+ Dbindex string `orm:"size(512);column(dbindex);null"description:"数据库索引"`
+ Url string `orm:"size(512);column(url);null"description:"下载链接"`
+ Desc string `orm:"size(2048);column(desc);null"description:"说明"`
+}
+
+type OriginUpstreamEvent struct {
+ EventId int64 `orm:"pk;auto;column(event_id)"`
+ CveId int64 `orm:"index;column(cve_id)"description:"OriginUpstream 外键"`
+ Title string `orm:"size(512);column(title);null"description:"标题"`
+ Date string `orm:"size(32);column(date);null"description:"日期"`
+ Url string `orm:"size(512);column(url);null"description:"连接"`
+ Description string `orm:"size(2048);column(description);null"description:"说明"`
+}
+
+type OriginUpstreamReference struct {
+ RefId int64 `orm:"pk;auto;column(ref_id)"`
+ CveId int64 `orm:"index;column(cve_id)"description:"OriginUpstream 外键"`
+ Name string `orm:"size(512);column(name);null"description:"名称"`
+ Refsource string `orm:"size(512);column(refsource);null"description:"参考来源"`
+ Url string `orm:"size(512);column(url);null"description:"链接"`
+ Tags string `orm:"size(2048);column(tags);null"description:"tags"`
+}
+
+type OriginUpstreamVulType struct {
+ VulId int64 `orm:"pk;auto;column(vul_id)"`
+ CveId int64 `orm:"index;column(cve_id)"description:"OriginUpstream 外键"`
+ Cwe string `orm:"size(256);column(cwe);null"description:"Cwe编号"`
+ EnDesc string `orm:"size(2048);column(en_desc);null"description:"英文描述"`
+ ZhDesc string `orm:"size(2048);column(zh_desc);null"description:"中文描述"`
+}
+
+type OriginUpstreamFixSuggest struct {
+ FixId int64 `orm:"pk;auto;column(fix_id)"`
+ CveId int64 `orm:"index;column(cve_id)"description:"OriginUpstream 外键"`
+ Detail string `orm:"size(1024);column(detail);null"description:"细节"`
+}
+
+type OriginUpstreamFixSuggestRef struct {
+ FixRefId int64 `orm:"pk;auto;column(fix_ref_id)"`
+ FixId int64 `orm:"index;column(fix_id)"description:"OriginUpstreamFixSuggest 外键"`
+ Refsource string `orm:"size(512);column(refsource);null"description:"参考文献,包含以下内容"`
+ Url string `orm:"size(1024);column(url);null"description:"链接"`
+ Name string `orm:"size(1024);column(name);null"description:"名称"`
+}
+
+type OriginUpstreamFixSuggestRefTag struct {
+ TagId int64 `orm:"pk;auto;column(tag_id)"`
+ FixRefId int64 `orm:"index;column(fix_ref_id)"description:"OriginUpstreamFixSuggestRef 外键"`
+ Name string `orm:"size(512);column(name);null"description:"名称"`
+}
+
+func CreateDb() bool {
+ BConfig, err := config.NewConfig("ini", "conf/app.conf")
+ if err != nil{
+ logs.Error("config init error:", err)
+ return false
+ }
+ prefix := BConfig.String("mysql::dbprefix")
+ InitdbType,_ := beego.AppConfig.Int("initdb")
+ if InitdbType == 1 {
+ orm.RegisterModelWithPrefix(prefix, new(OtherUser), new(AdminUser), new(VulnCenter),
+ new(OpenEulerSA), new(Score), new(SecurityNotice), new(Package),
+ new(IssueTemplate), new(ScoreRecord), new(IssueHooks),
+ new(GitPackageTable), new(GitOpenEuler), new(GitPackageInfo), new(GitSubPack),
+ new(SecurityReviewer),new(GitSubPackRequire), new(GitSubPackProvides), new(GitSubPackRequiredby),
+ new(IpWhite), new(OriginUpstream), new(OriginUpstreamDesc),
+ new(OriginUpstreamConfig), new(OriginUpstreamConfigNode),
+ new(OriginUpstreamConfigNodeCpe), new(OriginUpstreamImpact), new(OriginUpstreamImpactScore),
+ new(OriginUpstreamImpactScoreV3), new(OriginUpstreamImpactScoreV2),
+ new(OriginUpstreamPoc), new(OriginUpstreamEvent), new(OriginUpstreamReference), new(OriginUpstreamVulType),
+ new(OriginUpstreamFixSuggest),new(OriginUpstreamFixSuggestRefTag) ,new(OriginUpstreamFixSuggestRef))
+ logs.Info("table create success!")
+ errosyn := orm.RunSyncdb("default", false, true)
+ if errosyn != nil {
+ logs.Error(errosyn)
+ }
+ }
+ return true
+}
\ No newline at end of file
diff --git a/models/object.go b/models/object.go
new file mode 100644
index 0000000000000000000000000000000000000000..3ffb60850f104eabf7ca3d29fda97cf49c258d16
--- /dev/null
+++ b/models/object.go
@@ -0,0 +1,53 @@
+package models
+
+import (
+ "errors"
+ "strconv"
+ "time"
+)
+
+var (
+ Objects map[string]*Object
+)
+
+type Object struct {
+ ObjectId string
+ Score int64
+ PlayerName string
+}
+
+func init() {
+ Objects = make(map[string]*Object)
+ Objects["hjkhsbnmn123"] = &Object{"hjkhsbnmn123", 100, "astaxie"}
+ Objects["mjjkxsxsaa23"] = &Object{"mjjkxsxsaa23", 101, "someone"}
+}
+
+func AddOne(object Object) (ObjectId string) {
+ object.ObjectId = "astaxie" + strconv.FormatInt(time.Now().UnixNano(), 10)
+ Objects[object.ObjectId] = &object
+ return object.ObjectId
+}
+
+func GetOne(ObjectId string) (object *Object, err error) {
+ if v, ok := Objects[ObjectId]; ok {
+ return v, nil
+ }
+ return nil, errors.New("ObjectId Not Exist")
+}
+
+func GetAll() map[string]*Object {
+ return Objects
+}
+
+func Update(ObjectId string, Score int64) (err error) {
+ if v, ok := Objects[ObjectId]; ok {
+ v.Score = Score
+ return nil
+ }
+ return errors.New("ObjectId Not Exist")
+}
+
+func Delete(ObjectId string) {
+ delete(Objects, ObjectId)
+}
+
diff --git a/models/oricvecheck.go b/models/oricvecheck.go
new file mode 100644
index 0000000000000000000000000000000000000000..4cc773a85f13ceb7e49ed92f6bb6734c13f3ae5e
--- /dev/null
+++ b/models/oricvecheck.go
@@ -0,0 +1,56 @@
+package models
+
+import (
+ "cvevulner/common"
+ "github.com/astaxie/beego/logs"
+ "github.com/astaxie/beego/orm"
+)
+
+func QueryOriginCveE(prcnum int) ([]OriginUpstream, int64, error) {
+ o := orm.NewOrm()
+ var os []OriginUpstream
+ num, err := o.Raw("select cve_id,cve_un_ids,cve_num, update_type,cve_packname," +
+ "git_packname,cve_title,affect_porduct,cnnvd_id,cnvd_id,published_date,vul_status,cve_status,version"+
+ " from cve_origin_upstream where cve_status in (?, ?) and is_exit = ? "+
+ "order by cve_id asc limit ?", 0, 1, 2, prcnum).QueryRows(&os)
+ if err == nil && num > 0 {
+ logs.Info("cve_origin_upstream 查询结果: ", num)
+ } else {
+ logs.Info("当前无新增或者更新的cve, cur_time:", common.GetCurTime(), "err: ", err)
+ }
+ return os, num, err
+}
+
+func UpdateOriginExist(updatetime, pakName, version string, cveId int64, isExit int) (bool){
+ o := orm.NewOrm()
+ res, err := o.Raw("UPDATE cve_origin_upstream SET " +
+ "is_exit = ?, update_time = ? where cve_id = ? and git_packname = ? and version = ?", isExit, updatetime, cveId, pakName, version).Exec()
+ if err == nil {
+ num, _ := res.RowsAffected()
+ if num > 0 {
+ logs.Info("cve_origin_upstream row affected nums: ", num, ",cveId: ", cveId, ",", updatetime, pakName, version)
+ return true
+ }
+ return false
+ } else {
+ logs.Error("更新失败, cve_origin_upstream, ", ",cveId: ", cveId, ",", updatetime, pakName, version, ", err: ", err)
+ return false
+ }
+}
+
+func UpdateOriginExistTemp() (bool){
+ o := orm.NewOrm()
+ res, err := o.Raw("UPDATE cve_origin_upstream SET " +
+ "is_exit = ? where is_exit = ?", 2, 0).Exec()
+ if err == nil {
+ num, _ := res.RowsAffected()
+ if num > 0 {
+ logs.Info("cve_origin_upstream row affected nums: ", num, ", 数据被更新")
+ return true
+ }
+ return false
+ } else {
+ logs.Error("更新失败, cve_origin_upstream, err: ", err)
+ return false
+ }
+}
\ No newline at end of file
diff --git a/models/packages.go b/models/packages.go
new file mode 100644
index 0000000000000000000000000000000000000000..414b433028a09c9e2ca5195db789d34e60f8d666
--- /dev/null
+++ b/models/packages.go
@@ -0,0 +1,131 @@
+package models
+
+import (
+ "github.com/astaxie/beego/logs"
+ "github.com/astaxie/beego/orm"
+)
+
+func GetIpWhite(ip string, iw *IpWhite) (err error) {
+ o := orm.NewOrm()
+ err = o.Raw("select * FROM cve_ip_white WHERE machine_ip=?", ip).QueryRow(iw)
+ if err == nil {
+ logs.Info("ip:", ip, " 在白名单中")
+ return nil
+ } else {
+ logs.Error("ip:", ip, " 访问受限")
+ }
+ return err
+}
+
+
+func GetPackageInfo(packageName string, gi *GitPackageInfo) (err error) {
+ o := orm.NewOrm()
+ err = o.Raw("select * FROM cve_git_package_info WHERE package_name=?", packageName).QueryRow(gi)
+ if err == nil {
+ logs.Info("packageName: ", packageName, " 查询成功")
+ return nil
+ } else {
+ logs.Error("packageName: ", packageName, " 不存在")
+ }
+ return err
+}
+
+func GetSubPackage(packageInfoId int64) (gg []GitSubPack, num int64, err error) {
+ o := orm.NewOrm()
+ var gs []GitSubPack
+ num, err = o.Raw("select sub_id,ids,sub_pack_name FROM cve_git_sub_pack WHERE detail_id=?", packageInfoId).QueryRows(&gs)
+ if num > 0 && err == nil {
+ logs.Info("cve_git_sub_pack packageInfoId: ", packageInfoId, " 查询成功")
+ return gs, num, nil
+ } else {
+ logs.Error("cve_git_sub_pack packageInfoId: ", packageInfoId, " 不存在")
+ }
+ return gs, 0, err
+}
+
+func GetSubPackProvide(subId int64) (gg []GitSubPackProvides, num int64, err error) {
+ o := orm.NewOrm()
+ var gs []GitSubPackProvides
+ num, err = o.Raw("select provide_id,ids,provide_name, requiredb FROM cve_git_sub_pack_provides WHERE sub_id=?", subId).QueryRows(&gs)
+ if num > 0 && err == nil {
+ logs.Info("cve_git_sub_pack_provides subId: ", subId, " 查询成功")
+ return gs, num, nil
+ } else {
+ logs.Error("cve_git_sub_pack_provides subId: ", subId, " 不存在")
+ }
+ return gs, 0, err
+}
+
+func GetSubPackrequiredby(provideId int64) (gg []GitSubPackRequiredby, num int64, err error) {
+ o := orm.NewOrm()
+ var gs []GitSubPackRequiredby
+ num, err = o.Raw("select id,requiredb FROM cve_git_sub_pack_requiredby WHERE provide_id=?", provideId).QueryRows(&gs)
+ if num > 0 && err == nil {
+ logs.Info("cve_git_sub_pack_requiredby provideId: ", provideId, " 查询成功")
+ return gs, num, nil
+ } else {
+ logs.Error("cve_git_sub_pack_requiredby provideId: ", provideId, " 不存在")
+ }
+ return gs, 0, err
+}
+
+func GetSubPackRequire(subId int64) (gg []GitSubPackRequire, num int64, err error) {
+ o := orm.NewOrm()
+ var gs []GitSubPackRequire
+ num, err = o.Raw("select require_id,ids,require_name, providedb FROM cve_git_sub_pack_require WHERE sub_id=?", subId).QueryRows(&gs)
+ if num > 0 && err == nil {
+ logs.Info("cve_git_sub_pack_require subId: ", subId, " 查询成功")
+ return gs, num, nil
+ } else {
+ logs.Error("cve_git_sub_pack_require subId: ", subId, " 不存在")
+ }
+ return gs, 0, err
+}
+
+func GetPackageList(pagesize int64,pagenum int64, QueryPkgName string) (ge []GitOpenEuler, num int64, err error) {
+ o := orm.NewOrm()
+ qs := o.QueryTable("cve_git_open_euler")
+ var us []GitOpenEuler
+ if QueryPkgName != "" {
+ cnt, err := qs.Filter("package_name__icontains", QueryPkgName).Limit(pagesize, (pagenum-1)*pagesize).All(&us)
+ if err == nil {
+ logs.Info("cve_git_open_euler, count: ", cnt, "pagesize ", pagesize, ",pagenum ", pagenum, ", QueryPkgName ", QueryPkgName)
+ } else {
+ logs.Error("cve_git_open_euler, err: ", err, "pagesize ", pagesize, ",pagenum ", pagenum, ", QueryPkgName ", QueryPkgName)
+ }
+ return us, cnt, err
+ } else {
+ cnt, err := qs.Limit(pagesize, (pagenum-1)*pagesize).All(&us)
+ if err == nil {
+ logs.Info("cve_git_open_euler, count: ", cnt, "pagesize ", pagesize, ",pagenum ", pagenum, ", QueryPkgName ", QueryPkgName)
+ } else {
+ logs.Error("cve_git_open_euler, err: ", err, "pagesize ", pagesize, ",pagenum ", pagenum, ", QueryPkgName ", QueryPkgName)
+ }
+ return us, cnt, err
+ }
+}
+
+//获取package 总数
+func GetPackageNum(QueryPkgName string) int64 {
+ o := orm.NewOrm()
+ cg := o.QueryTable("cve_git_open_euler")
+
+ var ge []GitOpenEuler
+ if QueryPkgName != "" {
+ num, err := cg.Filter("package_name__icontains", QueryPkgName).All(&ge)
+ if err == nil {
+ return num
+ }else{
+ return 0
+ }
+ }else {
+ num, err := cg.Filter("git_id__gt", 0).All(&ge)
+ if err == nil {
+ return num
+ }else{
+ return 0
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/models/reviewer.go b/models/reviewer.go
new file mode 100644
index 0000000000000000000000000000000000000000..f26d447df938edb2bee82bfdfe6822049a846ae5
--- /dev/null
+++ b/models/reviewer.go
@@ -0,0 +1,23 @@
+package models
+
+import (
+ "github.com/astaxie/beego/logs"
+ "github.com/astaxie/beego/orm"
+)
+
+func (s *SecurityReviewer) Read(filed ...string) (ok bool) {
+ o := orm.NewOrm()
+ err := o.Read(s, filed...)
+ if err != nil {
+ logs.Error(err)
+ return false
+ }
+ return true
+}
+
+func GetSecurityReviewerList()(sr []SecurityReviewer,err error) {
+ var list []SecurityReviewer
+ o := orm.NewOrm()
+ _, err = o.QueryTable("cve_security_reviewer").All(&list)
+ return list,err
+}
diff --git a/models/uploadcve.go b/models/uploadcve.go
new file mode 100644
index 0000000000000000000000000000000000000000..dcc2431424a112d8e1ad0f132f9119f2ea578759
--- /dev/null
+++ b/models/uploadcve.go
@@ -0,0 +1,737 @@
+package models
+
+import (
+ "cvevulner/common"
+ "github.com/astaxie/beego/logs"
+ "github.com/astaxie/beego/orm"
+)
+
+type OpenSaId struct {
+ Id int64
+}
+
+func QueryCveOpeneulerdata(pkgName string, version string) (GitOpenEuler, bool){
+ o := orm.NewOrm()
+ var goe GitOpenEuler
+ err := o.Raw("select * from cve_git_open_euler where package_name = ? and version = ?", pkgName, version).QueryRow(&goe)
+ if err != nil {
+ logs.Info("pkgName", pkgName, "version", version, ", cve_git_open_euler 无对应数据")
+ return goe,false
+ } else {
+ logs.Info("pkgName", pkgName, "version", version, ", cve_git_open_euler 查询成功")
+ return goe,true
+ }
+}
+
+
+func QueryCveOriginByIds(ids string) (OriginUpstream, bool){
+ o := orm.NewOrm()
+ var orcve OriginUpstream
+ err := o.Raw("select * from cve_origin_upstream where cve_un_ids = ?", ids).QueryRow(&orcve)
+ if err != nil {
+ logs.Info("ids", ids, ", cve_origin_upstream 新增数据")
+ return orcve,false
+ } else {
+ return orcve,true
+ }
+}
+
+func CreateOriginCve(CveData common.CveOriginData, ou *OriginUpstream, od *OriginUpstreamDesc,
+ ous *OriginUpstreamConfig, osi *OriginUpstreamImpact, osp *OriginUpstreamPoc, ose *OriginUpstreamEvent,
+ osv *OriginUpstreamVulType, osf *OriginUpstreamFixSuggest) (Id int64, err error){
+ o := orm.NewOrm()
+ errs := o.Begin()
+ if errs == nil {
+ ouse := OriginUpstream{Ids: ou.Ids}
+ err := o.Read(&ouse, "Ids")
+ if err == orm.ErrNoRows || err == orm.ErrMissPK{
+ logs.Info("新增数据: ", ou)
+ var num int64
+ if num, err = o.Insert(ou); err == nil {
+ logs.Info("insert cve_origin_upstream success, num:, cveNum", num, ou.Ids)
+ }else {
+ logs.Error("insert cve_origin_upstream failed, ou:", ou, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ od.CveId = num
+ lod := OriginUpstreamDesc{CveId: num}
+ o.Delete(&lod, "CveId")
+ if odnum, err := o.Insert(od); err == nil {
+ logs.Info("insert cve_origin_upstream_desc success, num:", odnum, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert cve_origin_upstream_desc failed, ou:", ou, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ ous.CveId = num
+ lous := OriginUpstreamConfig{CveId: num}
+ err := o.Read(&lous, "CveId")
+ if err == orm.ErrNoRows || err == orm.ErrMissPK{
+ logs.Info("cve_origin_upstream_config 不存在, cveId: ", num)
+ } else {
+ var lousc []OriginUpstreamConfigNode
+ louscNum, err := o.Raw("select * from cve_origin_upstream_config_node where conf_id = ?", lous.ConfId).QueryRows(&lousc)
+ if err != nil {
+ logs.Info("cve_origin_upstream_config_node 不存在, louscNum: ", louscNum)
+ } else {
+ for _, lsc := range lousc {
+ ousnc := OriginUpstreamConfigNodeCpe{NodeId: lsc.NodeId}
+ o.Delete(&ousnc, "NodeId")
+ }
+ ousn := OriginUpstreamConfigNode{ConfId: lous.ConfId}
+ o.Delete(&ousn, "ConfId")
+ }
+ lousn := OriginUpstreamConfig{CveId: num}
+ o.Delete(&lousn, "CveId")
+ }
+ if ousnum, err := o.Insert(ous); err == nil {
+ logs.Info("insert cve_origin_upstream_config success, ousnum:", ousnum, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert cve_origin_upstream_config failed, ou:", ous, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ if CveData.Configurations.Nodes != nil && len(CveData.Configurations.Nodes) > 0 {
+ for _, nodes := range CveData.Configurations.Nodes {
+ var Lnode OriginUpstreamConfigNode
+ Lnode.Operator = nodes.Operator
+ Lnode.ConfId = ous.ConfId
+ if lousnum, err := o.Insert(&Lnode); err == nil {
+ logs.Info("insert cve_origin_upstream_config_node success, lousnum:", lousnum, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert cve_origin_upstream_config_node failed, Lnode:", Lnode, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ if nodes.Cpe != nil && len(nodes.Cpe) > 0 {
+ for _, nodCpe := range nodes.Cpe {
+ var ouscnc OriginUpstreamConfigNodeCpe
+ ouscnc.Cpe23Uri = nodCpe.Cpe23Uri
+ ouscnc.NodeId = Lnode.NodeId
+ ouscnc.CpeMatchString = nodCpe.CpeMatchString
+ ouscnc.Vulnerable = nodCpe.Vulnerable
+ if lousnumc, err := o.Insert(&ouscnc); err == nil {
+ logs.Info("insert cve_origin_upstream_config_node_cpe success, lousnumc:", lousnumc, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert cve_origin_upstream_config_node_cpe failed, ouscnc:", ouscnc, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ }
+ }
+ }
+ }
+ osi.CveId = num
+ losi := OriginUpstreamImpact{CveId: num}
+ errxx := o.Read(&losi, "CveId")
+ if errxx == orm.ErrNoRows || errxx == orm.ErrMissPK{
+ logs.Info("cve_origin_upstream_impact 不存在, cveId: ", num)
+ }else {
+ var losis []OriginUpstreamImpactScore
+ losisNum, err := o.Raw("select * from cve_origin_upstream_impact_score where impact_id = ?", losi.ImpactId).QueryRows(&losis)
+ if err != nil {
+ logs.Info("cve_origin_upstream_impact_score 不存在, losi.ImpactId: ", losi.ImpactId, "err: ", err, ",losisNum: ", losisNum)
+ } else {
+ for _, sis := range losis {
+ if sis.CvssV3 == 1 && sis.BaseMetricV3 == 1 {
+ lousisv3 := OriginUpstreamImpactScoreV3{ScoreId: sis.ScoreId}
+ o.Delete(&lousisv3, "ScoreId")
+ }
+ if sis.CvssV2 == 1 && sis.BaseMetricV2 == 1 {
+ lousisv2 := OriginUpstreamImpactScoreV2{ScoreId: sis.ScoreId}
+ o.Delete(&lousisv2, "ScoreId")
+ }
+ }
+ losisx := OriginUpstreamImpactScore{ImpactId: losi.ImpactId}
+ o.Delete(&losisx, "ImpactId")
+ }
+ losix := OriginUpstreamImpact{CveId: num}
+ o.Delete(&losix, "CveId")
+ }
+
+ if losinum, err := o.Insert(osi); err == nil {
+ logs.Info("insert cve_origin_upstream_impact success, lousnum:", losinum, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert cve_origin_upstream_impact failed, Lnode:", osi, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ var lousist OriginUpstreamImpactScore
+ lousist.ImpactId = osi.ImpactId
+ lousist.BaseMetricV3 = 1
+ lousist.BaseMetricV2 = 0
+ lousist.CvssV3 = 1
+ lousist.CvssV2 = 0
+ lousist.Status = 1
+ if lousistnum, err := o.Insert(&lousist); err == nil {
+ logs.Info("insert cve_origin_upstream_impact_score success, lousistnum:", lousistnum, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert cve_origin_upstream_impact_score failed, lousist:", lousist, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ var lousisv3 OriginUpstreamImpactScoreV3
+ lousisv3.ScoreId = lousist.ScoreId
+ lousisv3.BaseScore = CveData.Impact.BaseMetricV3.CvssV3.BaseScore
+ lousisv3.VectorString = CveData.Impact.BaseMetricV3.CvssV3.VectorString
+ lousisv3.AttackComplexity = CveData.Impact.BaseMetricV3.CvssV3.AttackComplexity
+ lousisv3.AttackVector = CveData.Impact.BaseMetricV3.CvssV3.AttackVector
+ lousisv3.AvailabilityImpact = CveData.Impact.BaseMetricV3.CvssV3.AvailabilityImpact
+ lousisv3.BaseSeverity = CveData.Impact.BaseMetricV3.CvssV3.BaseSeverity
+ lousisv3.UserInteraction = CveData.Impact.BaseMetricV3.CvssV3.UserInteraction
+ lousisv3.PrivilegesRequired = CveData.Impact.BaseMetricV3.CvssV3.PrivilegesRequired
+ lousisv3.Version = CveData.Impact.BaseMetricV3.CvssV3.Version
+ lousisv3.ConfidentialityImpact = CveData.Impact.BaseMetricV3.CvssV3.ConfidentialityImpact
+ lousisv3.IntegrityImpact = CveData.Impact.BaseMetricV3.CvssV3.IntegrityImpact
+ lousisv3.Scope = CveData.Impact.BaseMetricV3.CvssV3.Scope
+ lousisv3.ImpactScore = CveData.Impact.BaseMetricV3.ImpactScore
+ lousisv3.ExploitabilityScore = CveData.Impact.BaseMetricV3.ExploitabilityScore
+ if CveData.Impact.BaseMetricV3.CvssV3.BaseScore >= 9.0 {
+ lousisv3.CveLevel = "Critical"
+ } else if CveData.Impact.BaseMetricV3.CvssV3.BaseScore >= 7.0 && CveData.Impact.BaseMetricV3.CvssV3.BaseScore <= 8.9 {
+ lousisv3.CveLevel = "High"
+ } else if CveData.Impact.BaseMetricV3.CvssV3.BaseScore > 4.0 && CveData.Impact.BaseMetricV3.CvssV3.BaseScore <= 6.9 {
+ lousisv3.CveLevel = "Medium"
+ } else if CveData.Impact.BaseMetricV3.CvssV3.BaseScore <= 4.0 {
+ lousisv3.CveLevel = "Low"
+ }
+ if lousistnumv3, err := o.Insert(&lousisv3); err == nil {
+ logs.Info("insert cve_origin_upstream_impact_score_v3 success, lousistnumv3:", lousistnumv3, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert cve_origin_upstream_impact_score_v3 failed, lousisv3:", lousisv3, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ var lousistv2 OriginUpstreamImpactScore
+ lousistv2.ImpactId = osi.ImpactId
+ lousistv2.BaseMetricV3 = 0
+ lousistv2.BaseMetricV2 = 1
+ lousistv2.CvssV3 = 0
+ lousistv2.CvssV2 = 1
+ lousistv2.Status = 1
+ if lousistnum, err := o.Insert(&lousistv2); err == nil {
+ logs.Info("insert cve_origin_upstream_impact_score success, lousistnum:", lousistnum, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert cve_origin_upstream_impact_score failed, lousistv2:", lousistv2, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ var lousisv2 OriginUpstreamImpactScoreV2
+ lousisv2.ScoreId = lousistv2.ScoreId
+ lousisv2.BaseScore = CveData.Impact.BaseMetricV2.CvssV2.BaseScore
+ lousisv2.AcInsufInfo = CveData.Impact.BaseMetricV2.AcInsufInfo
+ lousisv2.BaseScore = CveData.Impact.BaseMetricV2.CvssV2.BaseScore
+ lousisv2.VectorString = CveData.Impact.BaseMetricV2.CvssV2.VectorString
+ lousisv2.AccessComplexity = CveData.Impact.BaseMetricV2.CvssV2.AccessComplexity
+ lousisv2.Authentication = CveData.Impact.BaseMetricV2.CvssV2.Authentication
+ lousisv2.AvailabilityImpact = CveData.Impact.BaseMetricV2.CvssV2.AvailabilityImpact
+ lousisv2.Version = CveData.Impact.BaseMetricV2.CvssV2.Version
+ lousisv2.ConfidentialityImpact = CveData.Impact.BaseMetricV2.CvssV2.ConfidentialityImpact
+ lousisv2.IntegrityImpact = CveData.Impact.BaseMetricV2.CvssV2.IntegrityImpact
+ lousisv2.AccessVector = CveData.Impact.BaseMetricV2.CvssV2.AccessVector
+ lousisv2.UserInteractionRequired = CveData.Impact.BaseMetricV2.UserInteractionRequired
+ lousisv2.Severity = CveData.Impact.BaseMetricV2.Severity
+ lousisv2.ObtainUserPrivilege = CveData.Impact.BaseMetricV2.ObtainUserPrivilege
+ lousisv2.ObtainAllPrivilege = CveData.Impact.BaseMetricV2.ObtainAllPrivilege
+ lousisv2.ObtainOtherPrivilege = CveData.Impact.BaseMetricV2.ObtainOtherPrivilege
+ lousisv2.ImpactScore = CveData.Impact.BaseMetricV2.ImpactScore
+ lousisv2.ExploitabilityScore = CveData.Impact.BaseMetricV2.ExploitabilityScore
+ if CveData.Impact.BaseMetricV2.CvssV2.BaseScore >= 9.0 {
+ lousisv2.CveLevel = "Critical"
+ } else if CveData.Impact.BaseMetricV2.CvssV2.BaseScore >= 7.0 && CveData.Impact.BaseMetricV2.CvssV2.BaseScore <= 8.9 {
+ lousisv2.CveLevel = "High"
+ } else if CveData.Impact.BaseMetricV2.CvssV2.BaseScore > 4.0 && CveData.Impact.BaseMetricV2.CvssV2.BaseScore <= 6.9 {
+ lousisv2.CveLevel = "Medium"
+ } else if CveData.Impact.BaseMetricV2.CvssV2.BaseScore <= 4.0 {
+ lousisv2.CveLevel = "Low"
+ }
+ if lousistnumv2, err := o.Insert(&lousisv2); err == nil {
+ logs.Info("insert cve_origin_upstream_impact_score_v2 success, lousistnumv2:", lousistnumv2, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert cve_origin_upstream_impact_score_v2 failed, lousisv2:", lousisv2, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+
+ osp.CveId = num
+ losp := OriginUpstreamPoc{CveId: num}
+ errxxx := o.Read(&losp, "CveId")
+ if errxxx == orm.ErrNoRows || errxxx == orm.ErrMissPK{
+ logs.Info("cve_origin_upstream_impact 不存在, cveId: ", num)
+ }else {
+ lospd := OriginUpstreamPoc{CveId: num}
+ o.Delete(&lospd, "CveId")
+ }
+ if ospnum, err := o.Insert(osp); err == nil {
+ logs.Info("insert Table: cve_origin_upstream_poc success, ospnum:", ospnum, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert Table: cve_origin_upstream_poc failed, osp:", osp, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+
+ ose.CveId = num
+ lose := OriginUpstreamEvent{CveId: num}
+ errx := o.Read(&lose, "CveId")
+ if errx == orm.ErrNoRows || errx == orm.ErrMissPK{
+ logs.Info("cve_origin_upstream_event 不存在, cveId: ", num)
+ }else {
+ losed := OriginUpstreamEvent{CveId: num}
+ o.Delete(&losed, "CveId")
+ }
+ if osenum, err := o.Insert(ose); err == nil {
+ logs.Info("insert Table: cve_origin_upstream_event success, osenum:", osenum, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert Table: cve_origin_upstream_event failed, ose:", ose, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+
+ lousr := OriginUpstreamReference{CveId: num}
+ o.Delete(&lousr, "CveId")
+ if CveData.ReferenceData != nil && len(CveData.ReferenceData) > 0 {
+ for _, ref := range CveData.ReferenceData {
+ var lousrd OriginUpstreamReference
+ lousrd.CveId = num
+ lousrd.Url = ref.Url
+ lousrd.Refsource = ref.Refsource
+ lousrd.Name = ref.Name
+ tags := ""
+ if ref.Tags != nil && len(ref.Tags) > 0 {
+ for _, ta := range ref.Tags {
+ tags = tags + string(ta) + ","
+ }
+ tags = tags[:len(tags) - 1]
+ }
+ lousrd.Tags = tags
+ if lousrdnum, err := o.Insert(&lousrd); err == nil {
+ logs.Info("insert Table: cve_origin_upstream_reference success, lousrdnum:", lousrdnum, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert Table: cve_origin_upstream_reference failed, lousrd:", lousrd, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ }
+ }
+ lousv := OriginUpstreamVulType{CveId: num}
+ o.Delete(&lousv, "CveId")
+ osv.CveId = num
+ if osvnum, err := o.Insert(osv); err == nil {
+ logs.Info("insert Table: cve_origin_upstream_vul_type success, osvnum:", osvnum, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert Table: cve_origin_upstream_vul_type failed, osv:", osv, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ ose.CveId = num
+ lousfs := OriginUpstreamFixSuggest{CveId: num}
+ errxxsx := o.Read(&lousfs, "CveId")
+ if errxxsx == orm.ErrNoRows || errxxsx == orm.ErrMissPK{
+ logs.Info("cve_origin_upstream_fix_suggest 不存在, cveId: ", num)
+ }else {
+ var lousfst []OriginUpstreamFixSuggestRef
+ louscNum, err := o.Raw("select * from cve_origin_upstream_fix_suggest_ref where fix_id = ?", lousfs.FixId).QueryRows(&lousfst)
+ if err != nil {
+ logs.Info("cve_origin_upstream_fix_suggest_ref 不存在, louscNum: ", louscNum, "err: ", err)
+ } else {
+ for _, sc := range lousfst {
+ lorfrt := OriginUpstreamFixSuggestRefTag{FixRefId: sc.FixRefId}
+ o.Delete(&lorfrt, "FixRefId")
+ }
+ lo := OriginUpstreamFixSuggestRef{FixId: lousfs.FixId}
+ o.Delete(&lo, "FixId")
+ }
+ lousfsx := OriginUpstreamFixSuggest{CveId: num}
+ o.Delete(&lousfsx, "CveId")
+ }
+ osf.CveId = num
+ if osfnum, err := o.Insert(osf); err == nil {
+ logs.Info("insert Table: cve_origin_upstream_fix_suggest success, osfnum:", osfnum, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert Table: cve_origin_upstream_fix_suggest failed, osf:", osf, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ if CveData.FixSuggest.References != nil && len(CveData.FixSuggest.References) > 0 {
+ for _, refer := range CveData.FixSuggest.References {
+ var lousfstr OriginUpstreamFixSuggestRef
+ lousfstr.FixId = osf.FixId
+ lousfstr.Name = refer.Name
+ lousfstr.Refsource = refer.Refsource
+ lousfstr.Url = refer.Url
+ if osfstrnum, err := o.Insert(&lousfstr); err == nil {
+ logs.Info("insert Table: cve_origin_upstream_fix_suggest_ref success, osfstrnum:", osfstrnum, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert Table: cve_origin_upstream_fix_suggest_ref failed, lousfstr:", lousfstr, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ if refer.Tags != nil && len(refer.Tags) > 0 {
+ for _, refertag := range refer.Tags {
+ var loufsrtg OriginUpstreamFixSuggestRefTag
+ loufsrtg.FixRefId = lousfstr.FixRefId
+ loufsrtg.Name = refertag
+ if osfstgrnum, err := o.Insert(&loufsrtg); err == nil {
+ logs.Info("insert Table: cve_origin_upstream_fix_suggest_ref_tag success, osfstgrnum:", osfstgrnum, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert Table: cve_origin_upstream_fix_suggest_ref_tag failed, loufsrtg:", loufsrtg, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ }
+ }
+ }
+ }
+ o.Commit()
+ } else {
+ logs.Info("更新数据: ", ou)
+ ou.CveId = ouse.CveId
+ ou.Ids = ouse.Ids
+ if num, err := o.Update(ou); err == nil {
+ logs.Info("Update cve_origin_upstream success, num:, cveNum", num, ou.Ids)
+ }else {
+ logs.Error("Update cve_origin_upstream failed, ou:", ou, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ num := ouse.CveId
+ od.CveId = num
+ lod := OriginUpstreamDesc{CveId: num}
+ o.Delete(&lod, "CveId")
+ if odnum, err := o.Insert(od); err == nil {
+ logs.Info("insert cve_origin_upstream_desc success, num:", odnum, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert cve_origin_upstream_desc failed, ou:", ou, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ ous.CveId = num
+ lous := OriginUpstreamConfig{CveId: num}
+ err := o.Read(&lous, "CveId")
+ if err == orm.ErrNoRows || err == orm.ErrMissPK{
+ logs.Info("cve_origin_upstream_config 不存在, cveId: ", num)
+ } else {
+ var lousc []OriginUpstreamConfigNode
+ louscNum, err := o.Raw("select * from cve_origin_upstream_config_node where conf_id = ?", lous.ConfId).QueryRows(&lousc)
+ if err != nil {
+ logs.Info("cve_origin_upstream_config_node 不存在, louscNum: ", louscNum)
+ } else {
+ for _, lsc := range lousc {
+ ousnc := OriginUpstreamConfigNodeCpe{NodeId: lsc.NodeId}
+ o.Delete(&ousnc, "NodeId")
+ }
+ ousn := OriginUpstreamConfigNode{ConfId: lous.ConfId}
+ o.Delete(&ousn, "ConfId")
+ }
+ lousn := OriginUpstreamConfig{CveId: num}
+ o.Delete(&lousn, "CveId")
+ }
+ if ousnum, err := o.Insert(ous); err == nil {
+ logs.Info("insert cve_origin_upstream_config success, ousnum:", ousnum, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert cve_origin_upstream_config failed, ou:", ous, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ if CveData.Configurations.Nodes != nil && len(CveData.Configurations.Nodes) > 0 {
+ for _, nodes := range CveData.Configurations.Nodes {
+ var Lnode OriginUpstreamConfigNode
+ Lnode.Operator = nodes.Operator
+ Lnode.ConfId = ous.ConfId
+ if lousnum, err := o.Insert(&Lnode); err == nil {
+ logs.Info("insert cve_origin_upstream_config_node success, lousnum:", lousnum, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert cve_origin_upstream_config_node failed, Lnode:", Lnode, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ if nodes.Cpe != nil && len(nodes.Cpe) > 0 {
+ for _, nodCpe := range nodes.Cpe {
+ var ouscnc OriginUpstreamConfigNodeCpe
+ ouscnc.Cpe23Uri = nodCpe.Cpe23Uri
+ ouscnc.NodeId = Lnode.NodeId
+ ouscnc.CpeMatchString = nodCpe.CpeMatchString
+ ouscnc.Vulnerable = nodCpe.Vulnerable
+ if lousnumc, err := o.Insert(&ouscnc); err == nil {
+ logs.Info("insert cve_origin_upstream_config_node_cpe success, lousnumc:", lousnumc, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert cve_origin_upstream_config_node_cpe failed, ouscnc:", ouscnc, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ }
+ }
+ }
+ }
+
+ osi.CveId = num
+ losi := OriginUpstreamImpact{CveId: num}
+ errxx := o.Read(&losi, "CveId")
+ if errxx == orm.ErrNoRows || errxx == orm.ErrMissPK{
+ logs.Info("cve_origin_upstream_impact 不存在, cveId: ", num)
+ }else {
+ var losis []OriginUpstreamImpactScore
+ losisNum, err := o.Raw("select * from cve_origin_upstream_impact_score where impact_id = ?", losi.ImpactId).QueryRows(&losis)
+ if err != nil {
+ logs.Info("cve_origin_upstream_impact_score 不存在, losi.ImpactId: ", losi.ImpactId, "err: ", err, ",losisNum: ", losisNum)
+ } else {
+ for _, sis := range losis {
+ if sis.CvssV3 == 1 && sis.BaseMetricV3 == 1 {
+ lousisv3 := OriginUpstreamImpactScoreV3{ScoreId: sis.ScoreId}
+ o.Delete(&lousisv3, "ScoreId")
+ }
+ if sis.CvssV2 == 1 && sis.BaseMetricV2 == 1 {
+ lousisv2 := OriginUpstreamImpactScoreV2{ScoreId: sis.ScoreId}
+ o.Delete(&lousisv2, "ScoreId")
+ }
+ }
+ losisx := OriginUpstreamImpactScore{ImpactId: losi.ImpactId}
+ o.Delete(&losisx, "ImpactId")
+ }
+ losix := OriginUpstreamImpact{CveId: num}
+ o.Delete(&losix, "CveId")
+ }
+
+ if losinum, err := o.Insert(osi); err == nil {
+ logs.Info("insert cve_origin_upstream_impact success, lousnum:", losinum, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert cve_origin_upstream_impact failed, Lnode:", osi, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ var lousist OriginUpstreamImpactScore
+ lousist.ImpactId = osi.ImpactId
+ lousist.BaseMetricV3 = 1
+ lousist.BaseMetricV2 = 0
+ lousist.CvssV3 = 1
+ lousist.CvssV2 = 0
+ lousist.Status = 1
+ if lousistnum, err := o.Insert(&lousist); err == nil {
+ logs.Info("insert cve_origin_upstream_impact_score success, lousistnum:", lousistnum, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert cve_origin_upstream_impact_score failed, lousist:", lousist, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ var lousisv3 OriginUpstreamImpactScoreV3
+ lousisv3.ScoreId = lousist.ScoreId
+ lousisv3.BaseScore = CveData.Impact.BaseMetricV3.CvssV3.BaseScore
+ lousisv3.VectorString = CveData.Impact.BaseMetricV3.CvssV3.VectorString
+ lousisv3.AttackComplexity = CveData.Impact.BaseMetricV3.CvssV3.AttackComplexity
+ lousisv3.AttackVector = CveData.Impact.BaseMetricV3.CvssV3.AttackVector
+ lousisv3.AvailabilityImpact = CveData.Impact.BaseMetricV3.CvssV3.AvailabilityImpact
+ lousisv3.BaseSeverity = CveData.Impact.BaseMetricV3.CvssV3.BaseSeverity
+ lousisv3.UserInteraction = CveData.Impact.BaseMetricV3.CvssV3.UserInteraction
+ lousisv3.PrivilegesRequired = CveData.Impact.BaseMetricV3.CvssV3.PrivilegesRequired
+ lousisv3.Version = CveData.Impact.BaseMetricV3.CvssV3.Version
+ lousisv3.ConfidentialityImpact = CveData.Impact.BaseMetricV3.CvssV3.ConfidentialityImpact
+ lousisv3.IntegrityImpact = CveData.Impact.BaseMetricV3.CvssV3.IntegrityImpact
+ lousisv3.Scope = CveData.Impact.BaseMetricV3.CvssV3.Scope
+ lousisv3.ImpactScore = CveData.Impact.BaseMetricV3.ImpactScore
+ lousisv3.ExploitabilityScore = CveData.Impact.BaseMetricV3.ExploitabilityScore
+ if CveData.Impact.BaseMetricV3.CvssV3.BaseScore >= 9.0 {
+ lousisv3.CveLevel = "Critical"
+ } else if CveData.Impact.BaseMetricV3.CvssV3.BaseScore >= 7.0 && CveData.Impact.BaseMetricV3.CvssV3.BaseScore <= 8.9 {
+ lousisv3.CveLevel = "High"
+ } else if CveData.Impact.BaseMetricV3.CvssV3.BaseScore > 4.0 && CveData.Impact.BaseMetricV3.CvssV3.BaseScore <= 6.9 {
+ lousisv3.CveLevel = "Medium"
+ } else if CveData.Impact.BaseMetricV3.CvssV3.BaseScore <= 4.0 {
+ lousisv3.CveLevel = "Low"
+ }
+ if lousistnumv3, err := o.Insert(&lousisv3); err == nil {
+ logs.Info("insert cve_origin_upstream_impact_score_v3 success, lousistnumv3:", lousistnumv3, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert cve_origin_upstream_impact_score_v3 failed, lousisv3:", lousisv3, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ var lousistv2 OriginUpstreamImpactScore
+ lousistv2.ImpactId = osi.ImpactId
+ lousistv2.BaseMetricV3 = 0
+ lousistv2.BaseMetricV2 = 1
+ lousistv2.CvssV3 = 0
+ lousistv2.CvssV2 = 1
+ lousistv2.Status = 1
+ if lousistnum, err := o.Insert(&lousistv2); err == nil {
+ logs.Info("insert cve_origin_upstream_impact_score success, lousistnum:", lousistnum, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert cve_origin_upstream_impact_score failed, lousistv2:", lousistv2, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ var lousisv2 OriginUpstreamImpactScoreV2
+ lousisv2.ScoreId = lousistv2.ScoreId
+ lousisv2.BaseScore = CveData.Impact.BaseMetricV2.CvssV2.BaseScore
+ lousisv2.AcInsufInfo = CveData.Impact.BaseMetricV2.AcInsufInfo
+ lousisv2.BaseScore = CveData.Impact.BaseMetricV2.CvssV2.BaseScore
+ lousisv2.VectorString = CveData.Impact.BaseMetricV2.CvssV2.VectorString
+ lousisv2.AccessComplexity = CveData.Impact.BaseMetricV2.CvssV2.AccessComplexity
+ lousisv2.Authentication = CveData.Impact.BaseMetricV2.CvssV2.Authentication
+ lousisv2.AvailabilityImpact = CveData.Impact.BaseMetricV2.CvssV2.AvailabilityImpact
+ lousisv2.Version = CveData.Impact.BaseMetricV2.CvssV2.Version
+ lousisv2.ConfidentialityImpact = CveData.Impact.BaseMetricV2.CvssV2.ConfidentialityImpact
+ lousisv2.IntegrityImpact = CveData.Impact.BaseMetricV2.CvssV2.IntegrityImpact
+ lousisv2.AccessVector = CveData.Impact.BaseMetricV2.CvssV2.AccessVector
+ lousisv2.UserInteractionRequired = CveData.Impact.BaseMetricV2.UserInteractionRequired
+ lousisv2.Severity = CveData.Impact.BaseMetricV2.Severity
+ lousisv2.ObtainUserPrivilege = CveData.Impact.BaseMetricV2.ObtainUserPrivilege
+ lousisv2.ObtainAllPrivilege = CveData.Impact.BaseMetricV2.ObtainAllPrivilege
+ lousisv2.ObtainOtherPrivilege = CveData.Impact.BaseMetricV2.ObtainOtherPrivilege
+ lousisv2.ImpactScore = CveData.Impact.BaseMetricV2.ImpactScore
+ lousisv2.ExploitabilityScore = CveData.Impact.BaseMetricV2.ExploitabilityScore
+ if CveData.Impact.BaseMetricV2.CvssV2.BaseScore >= 9.0 {
+ lousisv2.CveLevel = "Critical"
+ } else if CveData.Impact.BaseMetricV2.CvssV2.BaseScore >= 7.0 && CveData.Impact.BaseMetricV2.CvssV2.BaseScore <= 8.9 {
+ lousisv2.CveLevel = "High"
+ } else if CveData.Impact.BaseMetricV2.CvssV2.BaseScore > 4.0 && CveData.Impact.BaseMetricV2.CvssV2.BaseScore <= 6.9 {
+ lousisv2.CveLevel = "Medium"
+ } else if CveData.Impact.BaseMetricV2.CvssV2.BaseScore <= 4.0 {
+ lousisv2.CveLevel = "Low"
+ }
+ if lousistnumv2, err := o.Insert(&lousisv2); err == nil {
+ logs.Info("insert cve_origin_upstream_impact_score_v2 success, lousistnumv2:", lousistnumv2, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert cve_origin_upstream_impact_score_v2 failed, lousisv2:", lousisv2, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+
+ osp.CveId = num
+ losp := OriginUpstreamPoc{CveId: num}
+ errxxx := o.Read(&losp, "CveId")
+ if errxxx == orm.ErrNoRows || errxxx == orm.ErrMissPK{
+ logs.Info("cve_origin_upstream_impact 不存在, cveId: ", num)
+ }else {
+ lospd := OriginUpstreamPoc{CveId: num}
+ o.Delete(&lospd, "CveId")
+ }
+ if ospnum, err := o.Insert(osp); err == nil {
+ logs.Info("insert Table: cve_origin_upstream_poc success, ospnum:", ospnum, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert Table: cve_origin_upstream_poc failed, osp:", osp, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+
+ ose.CveId = num
+ lose := OriginUpstreamEvent{CveId: num}
+ errx := o.Read(&lose, "CveId")
+ if errx == orm.ErrNoRows || errx == orm.ErrMissPK{
+ logs.Info("cve_origin_upstream_event 不存在, cveId: ", num)
+ }else {
+ losed := OriginUpstreamEvent{CveId: num}
+ o.Delete(&losed, "CveId")
+ }
+ if osenum, err := o.Insert(ose); err == nil {
+ logs.Info("insert Table: cve_origin_upstream_event success, osenum:", osenum, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert Table: cve_origin_upstream_event failed, ose:", ose, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+
+ lousr := OriginUpstreamReference{CveId: num}
+ o.Delete(&lousr, "CveId")
+ if CveData.ReferenceData != nil && len(CveData.ReferenceData) > 0 {
+ for _, ref := range CveData.ReferenceData {
+ var lousrd OriginUpstreamReference
+ lousrd.CveId = num
+ lousrd.Url = ref.Url
+ lousrd.Refsource = ref.Refsource
+ lousrd.Name = ref.Name
+ tags := ""
+ if ref.Tags != nil && len(ref.Tags) > 0 {
+ for _, ta := range ref.Tags {
+ tags = tags + string(ta) + ","
+ }
+ tags = tags[:len(tags) - 1]
+ }
+ lousrd.Tags = tags
+ if lousrdnum, err := o.Insert(&lousrd); err == nil {
+ logs.Info("insert Table: cve_origin_upstream_reference success, lousrdnum:", lousrdnum, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert Table: cve_origin_upstream_reference failed, lousrd:", lousrd, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ }
+ }
+ lousv := OriginUpstreamVulType{CveId: num}
+ o.Delete(&lousv, "CveId")
+ osv.CveId = num
+ if osvnum, err := o.Insert(osv); err == nil {
+ logs.Info("insert Table: cve_origin_upstream_vul_type success, osvnum:", osvnum, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert Table: cve_origin_upstream_vul_type failed, osv:", osv, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ ose.CveId = num
+ lousfs := OriginUpstreamFixSuggest{CveId: num}
+ errxxsx := o.Read(&lousfs, "CveId")
+ if errxxsx == orm.ErrNoRows || errxxsx == orm.ErrMissPK{
+ logs.Info("cve_origin_upstream_fix_suggest 不存在, cveId: ", num)
+ }else {
+ var lousfst []OriginUpstreamFixSuggestRef
+ louscNum, err := o.Raw("select * from cve_origin_upstream_fix_suggest_ref where fix_id = ?", lousfs.FixId).QueryRows(&lousfst)
+ if err != nil {
+ logs.Info("cve_origin_upstream_fix_suggest_ref 不存在, louscNum: ", louscNum, "err: ", err)
+ } else {
+ for _, sc := range lousfst {
+ lorfrt := OriginUpstreamFixSuggestRefTag{FixRefId: sc.FixRefId}
+ o.Delete(&lorfrt, "FixRefId")
+ }
+ lo := OriginUpstreamFixSuggestRef{FixId: lousfs.FixId}
+ o.Delete(&lo, "FixId")
+ }
+ lousfsx := OriginUpstreamFixSuggest{CveId: num}
+ o.Delete(&lousfsx, "CveId")
+ }
+ osf.CveId = num
+ if osfnum, err := o.Insert(osf); err == nil {
+ logs.Info("insert Table: cve_origin_upstream_fix_suggest success, osfnum:", osfnum, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert Table: cve_origin_upstream_fix_suggest failed, osf:", osf, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ if CveData.FixSuggest.References != nil && len(CveData.FixSuggest.References) > 0 {
+ for _, refer := range CveData.FixSuggest.References {
+ var lousfstr OriginUpstreamFixSuggestRef
+ lousfstr.FixId = osf.FixId
+ lousfstr.Name = refer.Name
+ lousfstr.Refsource = refer.Refsource
+ lousfstr.Url = refer.Url
+ if osfstrnum, err := o.Insert(&lousfstr); err == nil {
+ logs.Info("insert Table: cve_origin_upstream_fix_suggest_ref success, osfstrnum:", osfstrnum, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert Table: cve_origin_upstream_fix_suggest_ref failed, lousfstr:", lousfstr, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ if refer.Tags != nil && len(refer.Tags) > 0 {
+ for _, refertag := range refer.Tags {
+ var loufsrtg OriginUpstreamFixSuggestRefTag
+ loufsrtg.FixRefId = lousfstr.FixRefId
+ loufsrtg.Name = refertag
+ if osfstgrnum, err := o.Insert(&loufsrtg); err == nil {
+ logs.Info("insert Table: cve_origin_upstream_fix_suggest_ref_tag success, osfstgrnum:", osfstgrnum, ", cveNum", ou.Ids)
+ }else {
+ logs.Error("insert Table: cve_origin_upstream_fix_suggest_ref_tag failed, loufsrtg:", loufsrtg, ", err: ", err)
+ o.Rollback()
+ return 0, err
+ }
+ }
+ }
+ }
+ }
+ o.Commit()
+ }
+ } else {
+ logs.Error("事务创建失败,cveNum:", ou.CveNum)
+ return 0, errs
+ }
+ return 0, nil
+}
+
diff --git a/models/user.go b/models/user.go
new file mode 100644
index 0000000000000000000000000000000000000000..d4bebb207c346beb63897d800b69dd6b5d223b3e
--- /dev/null
+++ b/models/user.go
@@ -0,0 +1,86 @@
+package models
+
+import (
+ "errors"
+ "strconv"
+ "time"
+)
+
+var (
+ UserList map[string]*User
+)
+
+func init() {
+ UserList = make(map[string]*User)
+ u := User{"user_11111", "astaxie", "11111", Profile{"male", 20, "Singapore", "astaxie@gmail.com"}}
+ UserList["user_11111"] = &u
+}
+
+type User struct {
+ Id string
+ Username string
+ Password string
+ Profile Profile
+}
+
+type Profile struct {
+ Gender string
+ Age int
+ Address string
+ Email string
+}
+
+func AddUser(u User) string {
+ u.Id = "user_" + strconv.FormatInt(time.Now().UnixNano(), 10)
+ UserList[u.Id] = &u
+ return u.Id
+}
+
+func GetUser(uid string) (u *User, err error) {
+ if u, ok := UserList[uid]; ok {
+ return u, nil
+ }
+ return nil, errors.New("User not exists")
+}
+
+func GetAllUsers() map[string]*User {
+ return UserList
+}
+
+func UpdateUser(uid string, uu *User) (a *User, err error) {
+ if u, ok := UserList[uid]; ok {
+ if uu.Username != "" {
+ u.Username = uu.Username
+ }
+ if uu.Password != "" {
+ u.Password = uu.Password
+ }
+ if uu.Profile.Age != 0 {
+ u.Profile.Age = uu.Profile.Age
+ }
+ if uu.Profile.Address != "" {
+ u.Profile.Address = uu.Profile.Address
+ }
+ if uu.Profile.Gender != "" {
+ u.Profile.Gender = uu.Profile.Gender
+ }
+ if uu.Profile.Email != "" {
+ u.Profile.Email = uu.Profile.Email
+ }
+ return u, nil
+ }
+ return nil, errors.New("User Not Exist")
+}
+
+func Login(username, password string) bool {
+ for _, u := range UserList {
+ if u.Username == username && u.Password == password {
+ return true
+ }
+ }
+ return false
+}
+
+func DeleteUser(uid string) {
+ delete(UserList, uid)
+}
diff --git a/models/ymal.go b/models/ymal.go
new file mode 100644
index 0000000000000000000000000000000000000000..c4411315c9323ae1c8b761be0e40d7e66e836724
--- /dev/null
+++ b/models/ymal.go
@@ -0,0 +1,220 @@
+package models
+
+import (
+ "github.com/astaxie/beego/logs"
+ "github.com/astaxie/beego/orm"
+)
+
+func GetYamlTable(gt *[]GitPackageTable) (int64, error) {
+ o := orm.NewOrm()
+ num, errx := o.Raw("select *"+
+ " from cve_git_package_table").QueryRows(gt)
+ if errx != nil {
+ logs.Error("获取数据失败或者不存在, err: ", errx)
+ }
+ return num, errx
+}
+
+func CreateYamlTable(gt *GitPackageTable) (TableId int64, err error) {
+ o := orm.NewOrm()
+ var localgt GitPackageTable
+ errx := o.Raw("select *"+
+ " from cve_git_package_table where table_name = ? ", gt.TableName).QueryRow(&localgt)
+ if errx != nil {
+ // 创建
+ var TableId int64
+ if TableId, err = o.Insert(gt); err == nil {
+ logs.Info("insert cve_git_package_table success, TableId: ", TableId, "tableName: ", gt.TableName)
+ } else {
+ logs.Error("insert cve_git_package_table failed, tableName:", gt.TableName, "err: ", err)
+ return 0, err
+ }
+ return TableId, nil
+ } else {
+ // 更新
+ gt.TableId = localgt.TableId
+ if num, err := o.Update(gt); err == nil {
+ logs.Info("update cve_git_package_table success, num: ", num, "TableName: ", gt.TableName)
+ } else {
+ logs.Error("update cve_git_package_table failed, TableName:", gt.TableName, "err: ", err)
+ return 0, err
+ }
+ return gt.TableId, nil
+ }
+}
+
+func GetSingleYaml(ge *GitOpenEuler) (bool, error){
+ o := orm.NewOrm()
+ if ge.Version != "" && ge.Release != "" {
+ localge := GitOpenEuler{PackageName: ge.PackageName, Version:ge.Version, Release:ge.Release}
+ err := o.Read(&localge, "PackageName", "Version", "Release")
+ logs.Info("查询yaml数据是否存在:", ge, ", localge: ", localge, ", err: ", err)
+ if err == orm.ErrNoRows {
+ return false, err
+ } else if err == orm.ErrMissPK {
+ return false, err
+ } else {
+ return true, err
+ }
+ } else {
+ localge := GitOpenEuler{PackageName: ge.PackageName}
+ err := o.Read(&localge, "PackageName")
+ logs.Info("查询yaml数据是否存在:", ge, ", localge: ", localge, ", err: ", err)
+ if err == orm.ErrNoRows {
+ return false, err
+ } else if err == orm.ErrMissPK {
+ return false, err
+ } else {
+ return true, err
+ }
+ }
+}
+
+
+func CreateYaml(ge *GitOpenEuler) (id int64, typex string, err error) {
+ o := orm.NewOrm()
+ var localge GitOpenEuler
+ errx := o.Raw("select *"+
+ " from cve_git_open_euler where package_name = ? and (version = ? or release = ?)",
+ ge.PackageName, ge.Version, ge.Release).QueryRow(&localge)
+ if errx != nil {
+ // 创建
+ logs.Info("createYaml: ", localge)
+ ge.Status = 0
+ var GitId int64
+ if GitId, err = o.Insert(ge); err == nil {
+ logs.Info("insert cve_git_open_euler success, GitId: ", GitId, "packName: ", ge.PackageName)
+ } else {
+ logs.Error("insert cve_git_open_euler failed, ", "packName: ", ge.PackageName, "err: ", err)
+ return 0, "insert", err
+ }
+ return GitId, "insert", nil
+ } else {
+ // 更新
+ logs.Info("createYaml: ", localge, "GitOpenEuler: ", ge)
+ ge.Status = 1
+ ge.GitId = localge.GitId
+ if _, err := o.Update(ge); err == nil {
+ logs.Info("update cve_git_open_euler success, GitId: ", ge.GitId, "packName: ", ge.PackageName)
+ } else {
+ logs.Error("update cve_git_open_euler failed, ", "packName: ", ge.PackageName, "err: ", err)
+ return ge.GitId, "update", err
+ }
+ return ge.GitId, "update", nil
+ }
+}
+
+
+func CreateYamlDetail(gp *GitPackageInfo, ge GitOpenEuler) (id int64, typex string, err error) {
+ o := orm.NewOrm()
+ var localgp GitPackageInfo
+ errx := o.Raw("select *"+
+ " from cve_git_package_info where git_id = ? and package_name = ? and version = ?",
+ ge.GitId, gp.PackageName, gp.Version).QueryRow(&localgp)
+ if errx != nil {
+ // 创建
+ gp.Status = 0
+ var DetailId int64
+ if DetailId, err = o.Insert(gp); err == nil {
+ logs.Info("insert cve_git_package_info success, DetailId: ", DetailId, ",PackageName: ", gp.PackageName)
+ } else {
+ logs.Error("insert cve_git_package_info failed, ", "PackageName: ", gp.PackageName, ",err: ", err)
+ return 0, "insert", err
+ }
+ return DetailId, "insert", nil
+ } else {
+ // 更新
+ gp.DetailId = localgp.DetailId
+ if _, err := o.Update(gp); err == nil {
+ logs.Info("update cve_git_package_info success, DetailId: ", DetailId, ",packName: ", gp.PackageName)
+ } else {
+ logs.Error("update cve_git_package_info failed, ", "packName: ", gp.PackageName, ",err: ", err)
+ return gp.DetailId, "update", err
+ }
+ return gp.DetailId, "update", nil
+ }
+}
+
+
+func CreateYamlSubPack(gb *GitSubPack) (SubId int64, typex string, err error) {
+ o := orm.NewOrm()
+ var localgb GitSubPack
+ errx := o.Raw("select *"+
+ " from cve_git_sub_pack where detail_id = ? and ids = ? and sub_pack_name = ?",
+ gb.DetailId, gb.Ids, gb.SubPackName).QueryRow(&localgb)
+ if errx != nil {
+ // 创建
+ var SubId int64
+ if SubId, err = o.Insert(gb); err == nil {
+ logs.Info("insert cve_git_sub_pack success, SubId: ", SubId, ",SubPackName: ", gb.SubPackName)
+ } else {
+ logs.Error("insert cve_git_sub_pack failed, ", "SubPackName: ", gb.SubPackName, ",err: ", err)
+ return 0, "insert", err
+ }
+ return SubId, "insert", nil
+ }
+ return localgb.SubId, "update", errx
+}
+
+
+func CreateYamlSubPackProvides(gs *GitSubPackProvides) (ProvideId int64, typex string, err error) {
+ o := orm.NewOrm()
+ var localgs GitSubPackProvides
+ errx := o.Raw("select *"+
+ " from cve_git_sub_pack_provides where sub_id = ? and ids = ? and provide_name = ?",
+ gs.SubId, gs.Ids, gs.ProvideName).QueryRow(&localgs)
+ if errx != nil {
+ // 创建
+ var ProvideId int64
+ if ProvideId, err = o.Insert(gs); err == nil {
+ logs.Info("insert cve_git_sub_pack_provides success, ProvideId: ", ProvideId, "ProvideName: ", gs.ProvideName)
+ } else {
+ logs.Error("insert cve_git_sub_pack_provides failed, ", "ProvideName: ", gs.ProvideName, "err: ", err)
+ return 0, "insert", err
+ }
+ return ProvideId, "insert", nil
+ }
+ return localgs.ProvideId, "update", errx
+}
+
+
+func CreateYamlSubPackRequiredb(gs *GitSubPackRequiredby) (Id int64, typex string, err error) {
+ o := orm.NewOrm()
+ var localgs GitSubPackRequiredby
+ errx := o.Raw("select *"+
+ " from cve_git_sub_pack_requiredby where provide_id = ? and requiredb = ?",
+ gs.ProvideId, gs.Requiredby).QueryRow(&localgs)
+ if errx != nil {
+ // 创建
+ var Id int64
+ if Id, err = o.Insert(gs); err == nil {
+ logs.Info("insert cve_git_sub_pack_requiredby success, Id: ", Id, "requiredb: ", gs.Requiredby)
+ } else {
+ logs.Error("insert cve_git_sub_pack_requiredby failed, ", "requiredb: ", gs.Requiredby, "err: ", err)
+ return 0, "insert", err
+ }
+ return Id, "insert", nil
+ }
+ return localgs.Id, "update", errx
+}
+
+
+func CreateYamlSubPackRequires(gs *GitSubPackRequire) (RequireId int64, typex string, err error) {
+ o := orm.NewOrm()
+ var localgs GitSubPackRequire
+ errx := o.Raw("select *"+
+ " from cve_git_sub_pack_require where sub_id = ? and ids = ? and require_name = ?",
+ gs.SubId, gs.Ids, gs.RequireName).QueryRow(&localgs)
+ if errx != nil {
+ // 创建
+ var RequireId int64
+ if RequireId, err = o.Insert(gs); err == nil {
+ logs.Info("insert cve_git_sub_pack_require success, RequireId: ", RequireId, "RequireName: ", gs.RequireName)
+ } else {
+ logs.Error("insert cve_git_sub_pack_require failed, ", "RequireName: ", gs.RequireName, "err: ", err)
+ return 0, "insert", err
+ }
+ return RequireId, "insert", nil
+ }
+ return localgs.RequireId, "update", errx
+}
\ No newline at end of file
diff --git a/routers/router.go b/routers/router.go
new file mode 100644
index 0000000000000000000000000000000000000000..08d8949d20dc82cd2b4a4cbb30099f85b99cd0f8
--- /dev/null
+++ b/routers/router.go
@@ -0,0 +1,59 @@
+// @APIVersion 1.0.0
+// @Title beego Test API
+// @Description beego has a very cool tools to autogenerate documents for your API
+// @Contact astaxie@gmail.com
+// @TermsOfServiceUrl http://beego.me/
+// @License Apache 2.0
+// @LicenseUrl http://www.apache.org/licenses/LICENSE-2.0.html
+package routers
+
+import (
+ "cvevulner/controllers"
+
+ "github.com/astaxie/beego"
+)
+
+func init() {
+ ns := beego.NewNamespace("/v1",
+ beego.NSNamespace("/object",
+ beego.NSInclude(
+ &controllers.ObjectController{},
+ ),
+ ),
+ beego.NSNamespace("/packages",
+ beego.NSInclude(
+ &controllers.PackagesController{},
+ ),
+ ),
+ beego.NSNamespace("/packages/packageinfo",
+ beego.NSInclude(
+ &controllers.PackagesInfoController{},
+ ),
+ ),
+ beego.NSNamespace("/user",
+ beego.NSInclude(
+ &controllers.UserController{},
+ ),
+ ),
+ beego.NSNamespace("/user/login",
+ beego.NSInclude(
+ &controllers.UserLoginController{},
+ ),
+ ),
+ beego.NSNamespace("/cve/upload",
+ beego.NSInclude(
+ &controllers.UserUploadController{},
+ ),
+ ),
+ beego.NSNamespace("/issue/oauth/callback",
+ beego.NSInclude(
+ &controllers.IssueOathCallbackController{},
+ ),
+ ),
+ beego.NSNamespace("/issue/hook/event",
+ beego.NSInclude(&controllers.HookEventControllers{},
+ ),
+ ),
+ )
+ beego.AddNamespace(ns)
+}
diff --git a/swagger.zip b/swagger.zip
new file mode 100644
index 0000000000000000000000000000000000000000..a38cc9e5dfe1623ff2df150cead85f8452ae415d
Binary files /dev/null and b/swagger.zip differ
diff --git a/task/cve.go b/task/cve.go
new file mode 100644
index 0000000000000000000000000000000000000000..55a334f8568051a7c3ab377dc6db18057d8f4525
--- /dev/null
+++ b/task/cve.go
@@ -0,0 +1,41 @@
+package task
+
+import (
+ "cvevulner/common"
+ "cvevulner/taskhandler"
+ "errors"
+ "github.com/astaxie/beego/config"
+ "github.com/astaxie/beego/logs"
+)
+
+func ParamsCveOriginData() error{
+ defer common.Catchs()
+ // 查询需要处理的cve, 1:新增;2:修改
+ BConfig, err := config.NewConfig("ini", "conf/app.conf")
+ if err != nil{
+ logs.Error("config init error:", err)
+ return err
+ }
+ // 单次处理的数据量
+ prcnum, err := BConfig.Int("crontab::prcnum")
+ if err != nil {
+ logs.Error("config crontab::prcnum error: invalid value is ",prcnum)
+ return errors.New("value is nil")
+ }
+ // 处理多少天到现在的数据
+ days, ok := BConfig.Int("crontab::days")
+ if ok != nil {
+ logs.Error("config crontab::days error:", err)
+ return ok
+ }
+ // openeuler 编号开始值
+ cveRef := BConfig.String("cve::cveref")
+ openeulernum, ok := BConfig.Int("cve::openeulernum")
+ if ok != nil {
+ logs.Error("config cve::openeulernum error:", err)
+ return ok
+ }
+ // 获取表的数据源
+ _, errx := taskhandler.GetCveOriginData(prcnum, days, openeulernum, cveRef)
+ return errx
+}
diff --git a/task/inittask.go b/task/inittask.go
new file mode 100644
index 0000000000000000000000000000000000000000..585de9fe4ea2cc223c7a63ce934317a7bd7d8694
--- /dev/null
+++ b/task/inittask.go
@@ -0,0 +1,139 @@
+package task
+
+import (
+ "github.com/astaxie/beego/config"
+ "github.com/astaxie/beego/logs"
+ "github.com/astaxie/beego/toolbox"
+)
+
+func CheckOriCveTask(oricvecheck string, ch *chan bool) {
+ logs.Info("校验原始cve数据 task start")
+ CheckTask := toolbox.NewTask("CheckOriCve", oricvecheck, CheckOriCve)
+ err := CheckTask.Run()
+ if err != nil{
+ logs.Error("创建校验原始cve数据失败 ,err:", err)
+ return
+ }
+ toolbox.AddTask("CheckOriCve", CheckTask)
+ toolbox.StartTask()
+ //time.Sleep(time.Minute * 1)
+ logs.Info("校验原始cve数据 task end")
+ *ch <- true
+ defer toolbox.StopTask()
+}
+
+func InitYamlTask(getymal string, ch *chan bool) {
+ logs.Info("获取yaml数据源 task start")
+ YamlTask := toolbox.NewTask("GetYamlData", getymal, GetYamlData)
+ err := YamlTask.Run()
+ if err != nil{
+ logs.Error("创建获取yaml数据源任务失败 ,err:", err)
+ return
+ }
+ toolbox.AddTask("GetYamlData", YamlTask)
+ toolbox.StartTask()
+ //time.Sleep(time.Minute * 1)
+ logs.Info("获取yaml数据源 task end")
+ *ch <- true
+ defer toolbox.StopTask()
+}
+
+func InitCveTask(getcve string, ch *chan bool) {
+ logs.Info("将cve原始数据生成cve库 task start")
+ CveTask := toolbox.NewTask("ParamsCveOriginData", getcve, ParamsCveOriginData)
+ err := CveTask.Run()
+ if err != nil{
+ logs.Error("创建Cve任务失败 ,err:", err)
+ return
+ }
+ toolbox.AddTask("ParamsCveOriginData", CveTask)
+ toolbox.StartTask()
+ //time.Sleep(time.Minute * 1)
+ logs.Info("将cve原始数据生成cve库 task end")
+ *ch <- true
+ defer toolbox.StopTask()
+}
+
+func InitIssueToken(issueoath string) {
+ logs.Info("执行获取token任务开始")
+ TokenTask := toolbox.NewTask("GetGiteeToken", issueoath, GetGiteeToken)
+ err := TokenTask.Run()
+ if err != nil{
+ logs.Error("create Issue token task failed ,err:", err)
+ return
+ }
+ toolbox.AddTask("GetGiteeToken", TokenTask)
+ toolbox.StartTask()
+ //time.Sleep(time.Minute * 1)
+ logs.Info("执行获取token任务结束")
+ defer toolbox.StopTask()
+}
+
+func CreatTask(createIssue string, ch *chan bool) {
+ logs.Info("执行创建issue任务开始")
+ cIssueTask := toolbox.NewTask("CreateIssue", createIssue, CreateIssue)
+ err := cIssueTask.Run()
+ if err != nil{
+ logs.Error("create Issue task failed ,err:", err)
+ return
+ }
+ toolbox.AddTask("CreateIssue", cIssueTask)
+ toolbox.StartTask()
+ //time.Sleep(time.Minute * 1)
+ logs.Info("执行创建issue任务结束")
+ *ch <- true
+ defer toolbox.StopTask()
+}
+
+func InitTask() {
+ BConfig, err := config.NewConfig("ini", "conf/app.conf")
+ if err != nil{
+ logs.Error("config init error: file:conf/app.conf: ", err)
+ return
+ }
+ // 获取原始的yaml数据
+ ymalflag, errxs := BConfig.Int("crontab::ymalflag")
+ if ymalflag == 1 && errxs == nil {
+ getymal := BConfig.String("crontab::getymal")
+ var yamch = make(chan bool)
+ go InitYamlTask(getymal, &yamch)
+ <-yamch
+ close(yamch)
+ }
+ // 校验原始cve数据
+ oricveflag, errxs := BConfig.Int("crontab::oricveflag")
+ if oricveflag == 1 && errxs == nil {
+ oricvecheck := BConfig.String("crontab::oricvecheck")
+ var checkch = make(chan bool)
+ go CheckOriCveTask(oricvecheck, &checkch)
+ <-checkch
+ close(checkch)
+ }
+ // 生成cve漏洞库
+ cveflag, errxs := BConfig.Int("crontab::cveflag")
+ if cveflag == 1 && errxs == nil {
+ getcve := BConfig.String("crontab::getcve")
+ var cvech = make(chan bool)
+ go InitCveTask(getcve, &cvech)
+ <-cvech
+ close(cvech)
+ }
+ // 添加issue
+ taskFlag, errx := BConfig.Int("crontab::issueflag")
+ if taskFlag == 1 && errx == nil{
+ issueoath := BConfig.String("crontab::issueoath")
+ gitToken := BConfig.String("gitee::git_token")
+ if gitToken == "xxx" {
+ InitIssueToken(issueoath)
+ }
+ var ch = make(chan bool)
+ //go InitIssueToken(issueoath, &ch)
+ createIssue := BConfig.String("crontab::createissue")
+ go CreatTask(createIssue, &ch)
+ <- ch
+ close(ch)
+ } else {
+ logs.Info("no task")
+ }
+}
+
diff --git a/task/issuetask.go b/task/issuetask.go
new file mode 100644
index 0000000000000000000000000000000000000000..99ba761f042a50401d9db292283e3f75826c74b0
--- /dev/null
+++ b/task/issuetask.go
@@ -0,0 +1,207 @@
+package task
+
+import (
+ "cvevulner/common"
+ "cvevulner/models"
+ "cvevulner/taskhandler"
+ "errors"
+ "github.com/astaxie/beego"
+ "github.com/astaxie/beego/config"
+ "github.com/astaxie/beego/logs"
+ "os"
+)
+
+
+func GetGiteeToken() error{
+ defer common.Catchs()
+ // 查询需要处理的cve, 1:新增;2:修改
+ BConfig, err := config.NewConfig("ini", "conf/app.conf")
+ if err != nil{
+ logs.Error("config init error:", err)
+ return err
+ }
+ clientId := BConfig.String("gitee::client_id")
+ if clientId == "" {
+ logs.Error("config gitee::clientId error: invalid value is ",clientId)
+ return errors.New("value is nil")
+ }
+ clientSecret := beego.AppConfig.String("gitee::client_secret")
+ if clientSecret == "" {
+ logs.Error("config gitee::clientSecret error: invalid value is ",clientSecret)
+ return errors.New("value is nil")
+ }
+
+ Email := BConfig.String("gitee::email")
+ if Email == "" {
+ logs.Error("config gitee::email error: value is nil")
+ return errors.New("value is nil")
+ }
+
+ password := BConfig.String("gitee::password")
+ if password == "" {
+ logs.Error("config gitee::password error: value is nil")
+ return errors.New("value is nil")
+ }
+ Scope := BConfig.String("gitee::scope")
+ if Scope == "" {
+ logs.Error("config gitee::scope error: value is nil")
+ return errors.New("value is nil")
+ }
+ logs.Info(clientId,clientSecret,password)
+ var gt taskhandler.GiteeToken
+ gt.GrantType = "password"
+ gt.UserName = Email
+ gt.Password = password
+ gt.ClientId = clientId
+ gt.ClientSecret = clientSecret
+ gt.Scope = Scope
+ taskhandler.GetOautToken(gt)
+ return nil
+}
+
+
+func CreateIssue() error{
+ defer common.Catchs()
+ // 查询需要处理的cve, 1:新增;2:修改
+ BConfig, err := config.NewConfig("ini", "conf/app.conf")
+ if err != nil{
+ logs.Error("config init error:", err)
+ return err
+ }
+ days, ok := BConfig.Int("crontab::days")
+ if ok != nil {
+ logs.Error("config crontab::days error:", err)
+ return ok
+ }
+ prcnum, ok := BConfig.Int("crontab::prcnum")
+ if ok != nil {
+ logs.Error("config crontab::prcnum error:", err)
+ return ok
+ }
+ beforeTime := common.GetBeforeTime(days)
+ cveData, err := models.QueryIssue(beforeTime, prcnum)
+ if err == nil && len(cveData) > 0{
+ logs.Info(cveData)
+ } else {
+ logs.Info("无cve数据可以使用, 当前时间: ", common.GetCurTime())
+ return err
+ }
+ accessToken := os.Getenv("issueaccesstoken")
+ if accessToken == "" || len(accessToken) < 1 {
+ logs.Error("issue token 获取失败, 当前时间: ", common.GetCurTime())
+ return err
+ }
+ owner := BConfig.String("gitee::owner")
+ path := BConfig.String("gitee::path")
+ for index, issueValue := range cveData {
+ logs.Info("当前正在处理第:", index, "条cve数据, cveNum: ", issueValue.CveNum)
+ // 处理每一条cve数据
+ if issueValue.Status == 0 {
+ err := ProcIssue(issueValue , accessToken, owner, path)
+ if err != nil {
+ logs.Error("创建issue失败, cvenum: ", issueValue.CveNum, "err,err: ", err)
+ continue
+ }
+ } else {
+ err := ProcUpdateIssue(issueValue, accessToken, owner, path)
+ if err != nil {
+ logs.Error("修改issue失败, cvenum: ", issueValue.CveNum, "err,err: ", err)
+ continue
+ }
+ }
+ }
+ return nil
+}
+
+func ProcUpdateIssue(issueValue models.VulnCenter, accessToken, owner, path string) error{
+ // 查询修改评分
+ sr, err := models.QueryIssueScoreRecord(issueValue.CveId, 0)
+ if err != nil {
+ logs.Error("查询 评分记录失败, cveId: ", issueValue.CveId, "err: ", err)
+ return err
+ }
+ // 查询issue模板
+ var it models.IssueTemplate
+ it.CveId = issueValue.CveId
+ lit, bools := models.GetIssueTemplet(&it)
+ if bools {
+ lit.NVDScore = sr.NVDScore
+ lit.NVDVector = sr.NvectorVule
+ lit.CveBrief = issueValue.Description
+ lit.CveLevel = issueValue.CveLevel
+ _, err := taskhandler.UpdateIssueToGit(accessToken, owner, path,
+ issueValue, lit)
+ if err != nil {
+ logs.Error("更新issue 模板失败, cveId: ", issueValue.CveId, "err: ", err)
+ return err
+ }
+ // 更新issue状态
+ models.UpdateIssueStatus(issueValue, 2)
+ // 更新分数状态
+ models.UpdateIssueScore(issueValue, 2)
+ templetId, err := models.CreateIssueTemplet(&lit)
+ if err != nil {
+ logs.Error("修改issue模板失败, cveId: ", issueValue.CveId, "err: ", err)
+ return err
+ }
+ models.UpdateIssueScoreRe(issueValue, 1)
+ logs.Info("更新issue模板成功,cveId: ", issueValue.CveId, "templetId: ", templetId)
+ }
+ return nil
+}
+
+func ProcIssue(issueValue models.VulnCenter, accessToken, owner, path string) error{
+ assignee := ""
+ sn, err := models.QueryIssueSecurity(issueValue.CveId)
+ if err == nil {
+ path = sn.InfluenceComponent
+ logs.Info("查询安全信息:sn: ", sn)
+ // 获取issue处理人
+ gitYaml, ok := models.QueryCveOpeneulerdata(issueValue.PackName, issueValue.CveVersion)
+ if !ok || gitYaml.MainTainer == "" || len(gitYaml.MainTainer) < 1{
+ assignee, err = taskhandler.GetCollaboratorInfo(accessToken, owner, path)
+ if assignee == "" {
+ logs.Error("获取仓库: owner:", owner, "path:", path, "分析人失败", "err:", err, "cveid: ", issueValue.CveId)
+ return err
+ }
+ } else {
+ assignee = gitYaml.MainTainer
+ }
+ } else {
+ logs.Error("获取security 失败, err: ", err, "cveId: ", issueValue.CveId)
+ return err
+ }
+ sc, err := models.QueryIssueScore(issueValue.CveId)
+ if err != nil {
+ logs.Error("获取Score 失败, err: ", err, "cveId: ", issueValue.CveId)
+ return err
+ }
+ resp, err := taskhandler.CreateIssueToGit(accessToken, owner, path, assignee, issueValue, sc)
+ if err != nil {
+ logs.Error("创建issue失败, err: ", err, "resp: ", resp, "cveId: ", issueValue.CveId)
+ return err
+ }
+ // 获取分支信息
+ branchs, err := taskhandler.GetBranchesInfo(accessToken, owner, path)
+ if branchs == "" {
+ logs.Error("获取分支信息失败,CveNum: ", issueValue.CveNum, "path: ", path)
+ }
+ // 存储安全公告相关信息
+ var sec models.SecurityNotice
+ taskhandler.CreateSecNoticeData(&sec, issueValue, path, branchs)
+ secId, err := models.UpdateSecNotice(&sec)
+ if err != nil {
+ logs.Error("更新安全信息失败,CveNum: ", issueValue.CveNum, "path: ", path, "err: ", err)
+ return err
+ } else {
+ logs.Info("更新安全信息成功, secId: ", secId, "cveNum: ", issueValue.CveNum)
+ }
+ return nil
+}
+
+
+
+
+
+
+
diff --git a/task/oricvecheck.go b/task/oricvecheck.go
new file mode 100644
index 0000000000000000000000000000000000000000..a229341b001230169e6033aff2abf5afef468dd4
--- /dev/null
+++ b/task/oricvecheck.go
@@ -0,0 +1,28 @@
+package task
+
+import (
+ "cvevulner/common"
+ "cvevulner/taskhandler"
+ "errors"
+ "github.com/astaxie/beego/config"
+ "github.com/astaxie/beego/logs"
+)
+
+func CheckOriCve() error{
+ defer common.Catchs()
+ // 查询需要处理的cve, 1:新增;2:修改
+ BConfig, err := config.NewConfig("ini", "conf/app.conf")
+ if err != nil{
+ logs.Error("config init error:", err)
+ return err
+ }
+ // 单次处理的数据量
+ prcnum, err := BConfig.Int("crontab::prcnum")
+ if err != nil {
+ logs.Error("config crontab::prcnum error: invalid value is ",prcnum)
+ return errors.New("value is nil")
+ }
+ // 获取表的数据源
+ _, errx := taskhandler.CheckCveOriginData(prcnum)
+ return errx
+}
\ No newline at end of file
diff --git a/task/yaml.go b/task/yaml.go
new file mode 100644
index 0000000000000000000000000000000000000000..cc2951cce4ed4f04e7d2ed30a01518e9b53246b3
--- /dev/null
+++ b/task/yaml.go
@@ -0,0 +1,31 @@
+package task
+
+import (
+ "cvevulner/common"
+ "cvevulner/taskhandler"
+ "errors"
+ "github.com/astaxie/beego/config"
+ "github.com/astaxie/beego/logs"
+)
+
+func GetYamlData() error{
+ defer common.Catchs()
+ // 查询需要处理的cve, 1:新增;2:修改
+ BConfig, err := config.NewConfig("ini", "conf/app.conf")
+ if err != nil{
+ logs.Error("config init error:", err)
+ return err
+ }
+ apiUrl := BConfig.String("yaml::apiurl")
+ if apiUrl == "" {
+ logs.Error("config yaml::apiurl error: invalid value is ",apiUrl)
+ return errors.New("value is nil")
+ }
+ // 获取表的数据源
+ _, errx := taskhandler.GetYamlTables(apiUrl)
+ // 获取yaml
+ if errx == nil {
+ _, errx = taskhandler.GetYamlByGit(apiUrl)
+ }
+ return errx
+}
diff --git a/taskhandler/assist.go b/taskhandler/assist.go
new file mode 100644
index 0000000000000000000000000000000000000000..6afdc08a1780267035b499d7aa32beb997b1f668
--- /dev/null
+++ b/taskhandler/assist.go
@@ -0,0 +1,107 @@
+package taskhandler
+
+import (
+ "cvevulner/util"
+ "encoding/json"
+ "errors"
+ "github.com/astaxie/beego/logs"
+ "os"
+ "strings"
+)
+
+
+func GetOautToken(gt GiteeToken) {
+ url := "https://gitee.com/oauth/token"
+ var req util.RequestInfo
+ req.Url = url
+ req.Data = make(map[string]string)
+ req.Data["grant_type"] = gt.GrantType
+ req.Data["username"] = gt.UserName
+ req.Data["password"] = gt.Password
+ req.Data["client_id"] = gt.ClientId
+ req.Data["client_secret"] = gt.ClientSecret
+ req.Data["scope"] = gt.Scope
+ resp, err := util.PostUrlEncoded(req)
+ if err != nil {
+ logs.Error("获取 token 失败,url: ", url, "请求参数:", gt, "err:", err)
+ return
+ }
+ var respDict map[string]interface{}
+ err =json.Unmarshal(resp, &respDict)
+ if err != nil {
+ logs.Error(err)
+ return
+ }
+ if _, ok := respDict["access_token"]; !ok {
+ logs.Error("获取token失败, err: ", ok, "url: ", url)
+ return
+ }
+ GitToken := respDict["access_token"].(string)
+ os.Setenv("issueaccesstoken", GitToken)
+}
+
+
+func GetCollaboratorInfo(accessToken string, owner string, path string) (string, error){
+ if accessToken != "" && owner != "" && path !="" {
+ url := "https://gitee.com/api/v5/repos/" + owner + "/" + path + "/collaborators?access_token=" + accessToken
+ collabor, err:= util.HttpGet(url)
+ if err == nil && collabor != nil {
+ for _, value := range collabor {
+ if _, ok := value["id"]; !ok {
+ logs.Error("collaborators, err: ", ok, "url: ", url)
+ continue
+ }
+ assignee := ""
+ flag := false
+ for mapKey, mapValue := range value {
+ if mapKey == "login" {
+ assignee = mapValue.(string)
+ }
+ if mapKey == "permissions" {
+ mapValuex := mapValue.(map[string]interface{})
+ for perKey, perValue := range mapValuex {
+ if perKey == "admin" && perValue.(bool) == true{
+ flag = true
+ }
+ }
+ }
+ }
+ if assignee != "" && flag {
+ return assignee, nil
+ }
+ }
+ } else {
+ logs.Error("获取仓库责任人失败, owner:", owner, "path:", path, "err: ", err)
+ return "", err
+ }
+ }
+ return "", errors.New("参数错误")
+}
+
+func GetBranchesInfo(accessToken string, owner string, path string) (string, error){
+ branchName := ""
+ if accessToken != "" && owner != "" && path != "" {
+ url := "https://gitee.com/api/v5/repos/"+ owner +"/"+ path +"/branches?access_token=" + accessToken
+ branch, err:= util.HttpGet(url)
+ if err == nil && branch != nil {
+ for _, value := range(branch) {
+ if _, ok := value["name"]; !ok {
+ logs.Error("branches, err: ", ok, "url: ", url)
+ continue
+ }
+ mapValue := value["name"].(string)
+ if mapValue != "" && len(mapValue) > 3 {
+ subStr := mapValue[len(mapValue) - 3:]
+ if strings.ToUpper(subStr) == "LTS" {
+ branchName = mapValue
+ break
+ }
+ }
+ }
+ } else {
+ logs.Error("获取分支名称失败, err: ", err, "owner: ", owner, "path: ", path)
+ return branchName, err
+ }
+ }
+ return branchName, nil
+}
diff --git a/taskhandler/comment.go b/taskhandler/comment.go
new file mode 100644
index 0000000000000000000000000000000000000000..4f61df65c5191dbc4dd7033b4a761b4465a7b5ad
--- /dev/null
+++ b/taskhandler/comment.go
@@ -0,0 +1,27 @@
+package taskhandler
+
+import (
+ "cvevulner/util"
+ "fmt"
+ "github.com/astaxie/beego/logs"
+)
+
+func AddCommentToIssue(msg,issueNum,owner,repo ,access string) {
+ url := fmt.Sprintf(`https://gitee.com/api/v5/repos/%v/%v/issues/%v/comments`,owner,repo,issueNum)
+ param := fmt.Sprintf(`{"access_token": "%s","body":"%s"}`,access,msg)
+ res, err := util.HttpPost(url, param)
+ if err != nil {
+ logs.Error(err)
+ }
+ logs.Info("添加评论返回:",res)
+}
+
+func SendPrivateLetters(access,content,useName string) {
+ url := "https://gitee.com/api/v5/notifications/messages"
+ param := fmt.Sprintf(`{"access_token":"%s","username":"%s","content":"%s"}`,access,useName,content)
+ res,err := util.HttpPost(url,param)
+ if err != nil {
+ logs.Error(err)
+ }
+ logs.Info("发送私信:",res)
+}
diff --git a/taskhandler/common.go b/taskhandler/common.go
new file mode 100644
index 0000000000000000000000000000000000000000..baafb6b614c3ed9063e1420329f440557c8de51b
--- /dev/null
+++ b/taskhandler/common.go
@@ -0,0 +1,311 @@
+package taskhandler
+
+import (
+ "cvevulner/common"
+ "cvevulner/models"
+ "fmt"
+ "strconv"
+)
+
+type GiteeToken struct {
+ GrantType string
+ UserName string
+ Password string
+ ClientId string
+ ClientSecret string
+ Scope string
+}
+
+func GitOpenEulerData(values map[string]interface{}, ge *models.GitOpenEuler, tb models.GitPackageTable) {
+ defer common.Catchs()
+ ge.TableName = tb.TableName
+ ge.TableId = tb.TableId
+ ge.Status = 0
+ if values["feature"] == nil {
+ ge.Feature = ""
+ } else {
+ switch values["feature"].(type) {
+ case string:
+ ge.Feature = values["feature"].(string)
+ case int:
+ ge.Feature = strconv.Itoa(values["feature"].(int))
+ case int64:
+ ge.Feature = strconv.FormatInt(values["feature"].(int64),10)
+ case float64:
+ ge.Feature = strconv.FormatInt(int64(values["feature"].(float64)),10)
+ default:
+ ge.Feature = ""
+ }
+ }
+ if values["url"] == nil {
+ ge.OriginUrl = ""
+ } else {
+ ge.OriginUrl = values["url"].(string)
+ }
+ switch values["id"].(type) {
+ case string:
+ ge.PackageId, _ = strconv.ParseInt(values["id"].(string), 10, 64)
+ case int:
+ ge.PackageId = values["id"].(int64)
+ case int64:
+ ge.PackageId = values["id"].(int64)
+ case float64:
+ ge.PackageId = int64(values["id"].(float64))
+ default:
+ ge.PackageId = 0
+ }
+ if values["name"] == nil {
+ ge.PackageName = ""
+ } else {
+ packName := values["name"].(string)
+ if packName != "" {
+ packName = common.DeletePreAndSufSpace(packName)
+ }
+ ge.PackageName = packName
+ }
+ if values["version"] == nil {
+ ge.Version = ""
+ } else {
+ version := values["version"].(string)
+ if version != "" {
+ version = common.DeletePreAndSufSpace(version)
+ }
+ ge.Version = version
+ }
+ if values["release"] == nil {
+ ge.Release = ""
+ } else {
+ release := values["release"].(string)
+ if release != "" {
+ release = common.DeletePreAndSufSpace(release)
+ }
+ ge.Release = release
+ }
+ if values["rpm_license"] == nil {
+ ge.License = ""
+ } else {
+ ge.License = values["rpm_license"].(string)
+ }
+ if values["maintainer"] == nil {
+ ge.MainTainer = ""
+ } else {
+ ge.MainTainer = values["maintainer"].(string)
+ }
+ if values["maintainlevel"] == nil {
+ ge.MainTainLevel = 0
+ } else {
+ ge.MainTainLevel = values["maintainlevel"].(int8)
+ }
+ if values["release_time"] == nil {
+ ge.ReleaseTime = ""
+ } else {
+ ge.ReleaseTime = values["release_time"].(string)
+ }
+ switch values["used_time"].(type) {
+ case string:
+ ge.UsedTime = values["used_time"].(string)
+ case int:
+ ge.UsedTime = strconv.Itoa(values["used_time"].(int))
+ case int64:
+ ge.UsedTime = strconv.FormatInt(values["used_time"].(int64),10)
+ case float64:
+ ge.UsedTime = strconv.FormatInt(int64(values["used_time"].(float64)),10)
+ default:
+ ge.UsedTime = ""
+ }
+ if values["latest_version"] == nil {
+ ge.LatestVersion = ""
+ } else {
+ ge.LatestVersion = values["latest_version"].(string)
+ }
+ if values["latest_version_time"] == nil {
+ ge.LatestVersionTime = ""
+ } else {
+ ge.LatestVersionTime = values["latest_version_time"].(string)
+ }
+ switch values["issue"].(type) {
+ case string:
+ ge.IssueCount, _ = strconv.ParseInt(values["issue"].(string), 10, 64)
+ case int:
+ ge.IssueCount = values["issue"].(int64)
+ case int64:
+ ge.IssueCount = values["issue"].(int64)
+ case float64:
+ ge.IssueCount = int64(values["issue"].(float64))
+ default:
+ ge.IssueCount = 0
+ }
+}
+
+
+func GitOpenEulerInfoData(values map[string]interface{}, gp *models.GitPackageInfo, ge models.GitOpenEuler) {
+ defer common.Catchs()
+ gp.GitId = ge.GitId
+ gp.Ids = 0
+ if values["pkg_name"] == nil {
+ gp.PackageName = ""
+ }else {
+ PackageName := values["pkg_name"].(string)
+ if PackageName != "" {
+ PackageName = common.DeletePreAndSufSpace(PackageName)
+ }
+ gp.PackageName = PackageName
+ }
+ if values["version"] == nil {
+ gp.Version = ""
+ } else {
+ Version := values["version"].(string)
+ if Version != "" {
+ Version = common.DeletePreAndSufSpace(Version)
+ }
+ gp.Version = Version
+ }
+ if values["release"] == nil {
+ gp.Release = ""
+ } else {
+ Release := values["release"].(string)
+ if Release != "" {
+ Release = common.DeletePreAndSufSpace(Release)
+ }
+ gp.Release = Release
+ }
+ if values["url"] == nil {
+ gp.OriginUrl = ""
+ }else {
+ gp.OriginUrl = values["url"].(string)
+ }
+ if values["license"] == nil {
+ gp.License = ""
+ } else {
+ gp.License = values["license"].(string)
+ }
+ switch values["feature"].(type) {
+ case string:
+ gp.Feature = values["feature"].(string)
+ case int:
+ gp.Feature = strconv.Itoa(values["feature"].(int))
+ case int64:
+ gp.Feature = strconv.FormatInt(values["feature"].(int64),10)
+ case float64:
+ gp.Feature = strconv.FormatInt(int64(values["feature"].(float64)),10)
+ default:
+ gp.Feature = ""
+ }
+ if values["maintainer"] == nil {
+ gp.MainTainer = ""
+ } else {
+ gp.MainTainer = values["maintainer"].(string)
+ }
+ if values["maintainlevel"] == nil {
+ gp.MainTainLevel = 0
+ } else {
+ gp.MainTainLevel = values["maintainlevel"].(int8)
+ }
+ if values["gitee_url"] == nil {
+ gp.GitUrl = ""
+ } else {
+ gp.GitUrl = values["gitee_url"].(string)
+ }
+ if values["summary"] == nil {
+ gp.Summary = ""
+ } else {
+ gp.Summary = values["summary"].(string)
+ }
+ if values["description"] == nil {
+ gp.Decription = ""
+ } else {
+ gp.Decription = values["description"].(string)
+ }
+ BuildRequired := ""
+ if values["buildrequired"].([]interface{}) != nil && len(values["buildrequired"].([]interface{})) > 0{
+ for _, vx := range values["buildrequired"].([]interface{}) {
+ BuildRequired = BuildRequired + vx.(string) + ","
+ }
+ gp.BuildRequired = BuildRequired[:len(BuildRequired) - 1]
+ } else {
+ gp.BuildRequired = BuildRequired
+ }
+ gp.Status = 0
+}
+
+
+type GitTablePackCount struct {
+ Page int
+ Size int
+ TableName string
+ Count int64
+}
+
+func CreateIssueBody(accessToken string, owner string, path string, assignee string,
+ cve models.VulnCenter, sc models.Score, OpenEulerScore, score, labels string,
+ its models.IssueTemplate, flag int, issueType, pkgLink string) string{
+ requestBody := ""
+ if flag == 1 {
+ body := "漏洞编号: " + "
[" + cve.CveNum + "](https://nvd.nist.gov/vuln/detail/"+ cve.CveNum + ")" + "" +
+ "
漏洞归属组件: " + "
"+ path +""+
+ "
漏洞归属的版本: " + "
" +cve.CveVersion +"" + "
CVSS V3.0分值: " +
+ "
BaseScore: " + score + " " + cve.CveLevel + "" +
+ "
Vector: " + sc.NvectorVule + "" + "
漏洞描述: " +
+ "
" + cve.Description +"" + "
影响性分析说明: " +
+ "
"+its.CveAnalysis +" " + "
原理分析: " + "
" + its.PrincipleAnalysis+"" +
+ "
openEuler评分: " + "
"+ OpenEulerScore + "" +
+ "
Vector: " + "
" +its.OpenEulerVector + "" +
+ "
受影响版本: " + "
"+its.AffectedVersion+"" +
+ "
规避方案或消减措施:
"+ its.Solution +"" +
+ "
受影响的包:
"+ " " +"
" + "@" + assignee + "
"
+ requestBody = fmt.Sprintf(`{
+ "access_token": "%s",
+ "repo": "%s",
+ "title": "%s",
+ "state": "%s",
+ "body": "%s",
+ "assignee": "%s",
+ "labels": "%s",
+ "security_hole": "false"
+ }`, accessToken, path, cve.CveNum, its.StatusName, body, assignee, labels)
+ } else if flag == 2 {
+ body := "漏洞编号: " + "
[" + cve.CveNum + "](https://nvd.nist.gov/vuln/detail/"+ cve.CveNum + ")" + "" +
+ "
漏洞归属组件: " + "
"+ path +""+
+ "
漏洞归属的版本: " + "
" +cve.CveVersion +"" + "
CVSS V3.0分值: " +
+ "
BaseScore: " + score + " " + cve.CveLevel + "" +
+ "
Vector: " + sc.NvectorVule + "" + "
漏洞描述: " +
+ "
" + cve.Description +"" + "
影响性分析说明: " +
+ "
" + "
原理分析: " + "
" + "
openEuler评分: " + "
" +
+ "
Vector: " + "
" + "
受影响版本: " + "
" +
+ "
规避方案或消减措施:
" + "
受影响的包:
" + " " +"
" + "@" + assignee + "
"
+ requestBody = fmt.Sprintf(`{
+ "access_token": "%s",
+ "repo": "%s",
+ "title": "%s",
+ "issue_type": "%s",
+ "body": "%s",
+ "assignee": "%s",
+ "labels": "%s",
+ "security_hole": "false"
+ }`, accessToken, path, cve.CveNum, issueType, body, assignee, labels)
+ } else {
+ body := "漏洞编号: " + "
[" + cve.CveNum + "](https://nvd.nist.gov/vuln/detail/"+ cve.CveNum + ")" + "" +
+ "
漏洞归属组件: " + "
"+ path +""+
+ "
漏洞归属的版本: " + "
" +cve.CveVersion +"" + "
CVSS V3.0分值: " +
+ "
BaseScore: " + score + " " + cve.CveLevel + "" +
+ "
Vector: " + its.NVDVector + "" + "
漏洞描述: " +
+ "
" + cve.Description +"" + "
影响性分析说明: " +
+ "
"+its.CveAnalysis +" " + "
原理分析: " + "
" + its.PrincipleAnalysis+"" +
+ "
openEuler评分: " + "
"+ OpenEulerScore + "" +
+ "
Vector: " + "
" +its.OpenEulerVector + "" +
+ "
受影响版本: " + "
"+its.AffectedVersion+"" +
+ "
规避方案或消减措施:
"+ its.Solution +"" + "
受影响的包:
"+
+ pkgLink +"
" + "@" + its.Assignee + "
"
+ requestBody = fmt.Sprintf(`{
+ "access_token": "%s",
+ "repo": "%s",
+ "title": "%s",
+ "state": "%s",
+ "body": "%s",
+ "assignee": "%s",
+ "labels": "%s",
+ "security_hole": "false"
+ }`, accessToken, path, cve.CveNum, its.StatusName, body, its.Assignee, labels)
+ }
+ return requestBody
+}
\ No newline at end of file
diff --git a/taskhandler/createissue.go b/taskhandler/createissue.go
new file mode 100644
index 0000000000000000000000000000000000000000..0f1cf424ec52638ce851e39984ab4993997e476b
--- /dev/null
+++ b/taskhandler/createissue.go
@@ -0,0 +1,419 @@
+package taskhandler
+
+import (
+ "cvevulner/common"
+ "cvevulner/models"
+ "cvevulner/util"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "github.com/astaxie/beego/config"
+ "github.com/astaxie/beego/logs"
+ "os"
+ "strconv"
+)
+
+func CreateIssueData(issueTemp *models.IssueTemplate, cve models.VulnCenter, sc models.Score, resp map[string]interface{},
+ path, assignee, issueType, labels, owner string) *models.IssueTemplate {
+ issueTemp.CveId = cve.CveId
+ issueTemp.CveNum = cve.CveNum
+ issueTemp.OwnedComponent = path
+ issueTemp.OwnedVersion = cve.CveVersion
+ issueTemp.NVDScore = sc.NVDScore
+ issueTemp.NVDVector = sc.NvectorVule
+ issueTemp.CveBrief = cve.Description
+ issueTemp.CveLevel = cve.CveLevel
+ issueTemp.IssueId = int64(resp["id"].(float64))
+ issueTemp.IssueNum = resp["number"].(string)
+ issueTemp.Assignee = assignee
+ issueTemp.StatusName = resp["state"].(string)
+ if resp["state"].(string) == "Open" {
+ issueTemp.Status = 1
+ } else if resp["state"].(string) == "Started" {
+ issueTemp.Status = 2
+ } else if resp["state"].(string) == "Closed" {
+ issueTemp.Status = 3
+ } else {
+ issueTemp.Status = 4
+ }
+ issueTemp.IssueStatus = 1
+ issueTemp.IssueLabel = labels
+ issueTemp.Owner = owner
+ issueTemp.Repo = path
+ issueTemp.Title = cve.CveNum
+ issueTemp.IssueType = issueType
+ issueTemp.Collaborators = ""
+ issueTemp.Milestone = ""
+ issueTemp.Program = ""
+ issueTemp.SecurityHole = 0
+ logs.Info("组装issue,模板数据存入db: ", issueTemp)
+ return issueTemp
+}
+
+func CreateIssueToGit(accessToken string, owner string, path string, assignee string,
+ cve models.VulnCenter, sc models.Score) (string, error) {
+ defer common.Catchs()
+ var it models.IssueTemplate
+ it.CveId = cve.CveId
+ its, err := models.GetIssueTemplet(&it)
+ if err && its.IssueNum != "" && len(its.IssueNum) > 0 {
+ if its.Assignee == "" || len(its.Assignee) == 0 {
+ its.Assignee = assignee
+ }
+ issueType := its.IssueType
+ labels := its.IssueLabel
+ if accessToken != "" && owner != "" && path != "" {
+ url := "https://gitee.com/api/v5/repos/" + owner + "/issues/" + its.IssueNum
+ score := strconv.FormatFloat(sc.NVDScore, 'f', 1, 64)
+ OpenEulerScore := strconv.FormatFloat(its.OpenEulerScore, 'f', 1, 64)
+ requestBody := CreateIssueBody(accessToken, owner, path, its.Assignee,
+ cve, sc, OpenEulerScore, score, labels, its, 1, its.IssueType, "")
+ logs.Info("isssue_body: ", requestBody)
+ resp, err := util.HttpPatch(url, requestBody)
+ if err != nil {
+ logs.Error("创建issue失败, cveNum: ", cve.CveNum, "err: ", err)
+ return "", err
+ }
+ if _, ok := resp["id"]; !ok {
+ logs.Error("创建issue 失败, err: ", ok, "url: ", url)
+ return "", errors.New("创建issue失败")
+ }
+ logs.Info("issue 创建成功,cveNum: ", cve.CveNum, "issueNum: ", resp["number"].(string))
+ // 构建数据
+ var issueTemp models.IssueTemplate
+ CreateIssueData(&issueTemp, cve, sc, resp, path, its.Assignee, issueType, labels, owner)
+ // 存储issue数据
+ issTempId, err := models.CreateIssueTemplet(&issueTemp)
+ if err != nil {
+ logs.Error("创建issue 模板的数据失败, cveNum: ", cve.CveNum, "err: ", err)
+ return "", err
+ } else {
+ logs.Info("创建issue 模板的数据成功, issTempId: ", issTempId, "cveNum: ", cve.CveNum)
+ }
+ // 构建回调
+ //err = CreateIssueHooks(accessToken, owner, path, cve, resp)
+ //if err != nil {
+ // logs.Error("创建hooks 失败, cveNum: ", cve.CveNum, "err: ", err)
+ // return "", err
+ //} else {
+ // logs.Info("创建hooks 成功, cveNum: ", cve.CveNum)
+ //}
+ //CreateIssueLabel(accessToken, owner, path, resp["number"].(string))
+ // 更新issue状态
+ models.UpdateIssueStatus(cve, 2)
+ // 更新分数状态
+ models.UpdateIssueScore(cve, 2)
+ // 更新分数记录状态
+ models.UpdateIssueScoreRe(cve, 1)
+ }
+ } else {
+ issueType := "CVE和安全问题"
+ //labels := "CVE/Bug,CVE/Undisclosed,CVE/Disclosed"
+ labels := "CVE/Undisclosed"
+ if accessToken != "" && owner != "" && path != "" {
+ url := "https://gitee.com/api/v5/repos/" + owner + "/issues"
+ score := strconv.FormatFloat(sc.NVDScore, 'f', 1, 64)
+ requestBody := CreateIssueBody(accessToken, owner, path, assignee,
+ cve, sc, "", score, labels, its, 2, issueType, "")
+ logs.Info("isssue_body: ", requestBody)
+ resp, err := util.HttpPost(url, requestBody)
+ if err != nil {
+ logs.Error("创建issue失败, cveNum: ", cve.CveNum, "err: ", err)
+ return "", err
+ }
+ if _, ok := resp["id"]; !ok {
+ logs.Error("创建issue 失败, err: ", ok, "url: ", url)
+ return "", errors.New("创建issue失败")
+ }
+ // 构建数据
+ var issueTemp models.IssueTemplate
+ CreateIssueData(&issueTemp, cve, sc, resp, path, assignee, issueType, labels, owner)
+ // 存储issue数据
+ issTempId, err := models.CreateIssueTemplet(&issueTemp)
+ if err != nil {
+ logs.Error("创建issue 模板的数据失败, cveNum: ", cve.CveNum, "err: ", err)
+ return "", err
+ } else {
+ logs.Info("创建issue 模板的数据成功, issTempId: ", issTempId, "cveNum: ", cve.CveNum)
+ }
+ // 创建issue评论
+ errx := CreateIssueComment(accessToken, owner, path, assignee, cve, resp)
+ logs.Info("issue评论创建结果, err: ", errx)
+ // 构建回调
+ err = CreateDepositHooks(accessToken, owner, path, cve, resp)
+ if err != nil {
+ logs.Error("创建hooks 失败, cveNum: ", cve.CveNum, "err: ", err)
+ return "", err
+ } else {
+ logs.Info("创建hooks 成功, cveNum: ", cve.CveNum)
+ }
+ // 创建issue标签
+ //CreateIssueLabel(accessToken, owner, path, resp["number"].(string))
+ // 更新issue状态
+ models.UpdateIssueStatus(cve, 2)
+ // 更新分数状态
+ models.UpdateIssueScore(cve, 2)
+ // 更新分数记录状态
+ models.UpdateIssueScoreRe(cve, 1)
+ }
+ }
+ return "", nil
+}
+
+func UpdateIssueToGit(accessToken string, owner string, path string,
+ cve models.VulnCenter, its models.IssueTemplate) (string, error) {
+ //issueType := its.IssueType
+ labels := its.IssueLabel
+ pkgList, err := models.QueryPackageByCveId(its.CveId)
+ pkgLink := ""
+ if err == nil && len(pkgList) > 0 {
+ for _, p := range pkgList {
+ pkgLink = pkgLink + fmt.Sprintf(`[%v](%v)\r\n`, p.PackName, p.PackUrl)
+ }
+ }
+ if accessToken != "" && owner != "" && path != "" {
+ url := "https://gitee.com/api/v5/repos/" + owner + "/issues/" + its.IssueNum
+ score := strconv.FormatFloat(its.NVDScore, 'f', 1, 64)
+ OpenEulerScore := strconv.FormatFloat(its.OpenEulerScore, 'f', 1, 64)
+ var sc models.Score
+ requestBody := CreateIssueBody(accessToken, owner, path, its.Assignee,
+ cve, sc, OpenEulerScore, score, labels, its, 3, its.IssueType, pkgLink)
+ logs.Info("isssue_body: ", requestBody)
+ resp, err := util.HttpPatch(url, requestBody)
+ if err != nil {
+ logs.Error("更新issue失败, cveNum: ", cve.CveNum, "err: ", err)
+ return "", err
+ }
+ if _, ok := resp["id"]; !ok {
+ logs.Error("创建issue 失败, err: ", ok, "url: ", url)
+ return "", errors.New("创建issue失败")
+ }
+ }
+ return "", nil
+}
+
+func CreateIssueHookData(issHook *models.IssueHooks, cve models.VulnCenter, resp map[string]interface{},
+ path, owner string, issresp map[string]interface{}) *models.IssueHooks {
+ issHook.CveId = cve.CveId
+ issHook.IssueId = int64(issresp["id"].(float64))
+ issHook.IssueNum = issresp["number"].(string)
+ issHook.HookId = int64(resp["id"].(float64))
+ issHook.Owner = owner
+ issHook.Repo = path
+ issHook.HookUrl = resp["url"].(string)
+ if resp["push_events"].(bool) == true {
+ issHook.PushEvent = 1
+ } else {
+ issHook.PushEvent = 0
+ }
+ if resp["tag_push_events"].(bool) == true {
+ issHook.TagPushEvent = 1
+ } else {
+ issHook.TagPushEvent = 0
+ }
+ if resp["issues_events"].(bool) == true {
+ issHook.IssueEvent = 1
+ } else {
+ issHook.IssueEvent = 0
+ }
+ if resp["note_events"].(bool) == true {
+ issHook.NoteEvent = 1
+ } else {
+ issHook.NoteEvent = 0
+ }
+ if resp["merge_requests_events"].(bool) == true {
+ issHook.MergeRequestEvent = 1
+ } else {
+ issHook.MergeRequestEvent = 0
+ }
+ return issHook
+}
+
+func CreateDepositHooks(accessToken string, owner string, path string,
+ cve models.VulnCenter, issResp map[string]interface{}) error {
+ var ih models.IssueHooks
+ ih.CveId = cve.CveId
+ ih.IssueNum = issResp["number"].(string)
+ ihs, err := models.GetIssueHook(&ih)
+ if err {
+ if accessToken != "" && owner != "" && path != "" {
+ url := "https://gitee.com/api/v5/repos/" + owner + "/" + path + "/hooks/" + strconv.Itoa(int(ihs.HookId))
+ BConfig, err := config.NewConfig("ini", "conf/app.conf")
+ if err != nil {
+ logs.Error("config init error:", err)
+ return err
+ }
+ pwd := os.Getenv("hookpwd")
+ hookurl := BConfig.String("hook::hookurl")
+ push_events := "true"
+ tag_push_events := "true"
+ issues_events := "true"
+ note_events := "true"
+ merge_requests_events := "true"
+ requestBody := fmt.Sprintf(`{
+ "access_token": "%s",
+ "url": "%s",
+ "password": "%s",
+ "push_events": "%s",
+ "tag_push_events": "%s",
+ "issues_events": "%s",
+ "note_events": "%s",
+ "merge_requests_events": "%s"
+ }`, accessToken, hookurl, pwd, push_events, tag_push_events, issues_events, note_events, merge_requests_events)
+ logs.Info("hook_body: ", requestBody)
+ resp, err := util.HttpPatch(url, requestBody)
+ if err != nil {
+ logs.Error("创建钩子失败, url: ", url, "cveId", cve.CveId, "err: ", err)
+ return err
+ }
+ if _, ok := resp["id"]; !ok {
+ logs.Error("创建仓库 hook失败, err: ", ok, "url: ", url)
+ return errors.New("创建仓库 hook失败")
+ }
+ // 构建数据
+ if resp["password"].(string) == pwd {
+ var issHook models.IssueHooks
+ CreateIssueHookData(&issHook, cve, resp,
+ path, owner, issResp)
+ // 存储issue数据
+ hookId, err := models.CreateDepositHooks(&issHook)
+ if err != nil {
+ logs.Error("创建仓库 hook数据失败, cveNum: ", cve.CveNum, "err: ", err)
+ return err
+ } else {
+ logs.Info("创建仓库 hook数据成功, hookId: ", hookId, "cveNum: ", cve.CveNum)
+ }
+ }
+ }
+ } else {
+ if accessToken != "" && owner != "" && path != "" {
+ url := "https://gitee.com/api/v5/repos/" + owner + "/" + path + "/hooks"
+ BConfig, err := config.NewConfig("ini", "conf/app.conf")
+ if err != nil {
+ logs.Error("config init error:", err)
+ return err
+ }
+ pwd := BConfig.String("hook::pwd")
+ hookurl := BConfig.String("hook::hookurl")
+ push_events := "true"
+ tag_push_events := "true"
+ issues_events := "true"
+ note_events := "true"
+ merge_requests_events := "true"
+ requestBody := fmt.Sprintf(`{
+ "access_token": "%s",
+ "url": "%s",
+ "password": "%s",
+ "push_events": "%s",
+ "tag_push_events": "%s",
+ "issues_events": "%s",
+ "note_events": "%s",
+ "merge_requests_events": "%s"
+ }`, accessToken, hookurl, pwd, push_events, tag_push_events, issues_events, note_events, merge_requests_events)
+ logs.Info("hook_body: ", requestBody)
+ resp, err := util.HttpPost(url, requestBody)
+ if err != nil {
+ logs.Error("创建钩子失败, url: ", url, "cveId", cve.CveId, "err: ", err)
+ return err
+ }
+ if _, ok := resp["id"]; !ok {
+ logs.Error("创建仓库hook失败, err: ", ok, "url: ", url)
+ return errors.New("创建仓库hook失败")
+ }
+ // 构建数据
+ if resp["password"].(string) == pwd {
+ var issHook models.IssueHooks
+ CreateIssueHookData(&issHook, cve, resp,
+ path, owner, issResp)
+ // 存储issue数据
+ hookId, err := models.CreateDepositHooks(&issHook)
+ if err != nil {
+ logs.Error("创建仓库hook失败, cveNum: ", cve.CveNum, "err: ", err)
+ return err
+ } else {
+ logs.Info("创建仓库 hook数据成功, hookId: ", hookId, "cveNum: ", cve.CveNum)
+ }
+ }
+ }
+ }
+ return nil
+}
+
+func CreateIssueComment(accessToken, owner, path, Assignee string,
+ cve models.VulnCenter, issResp map[string]interface{}) error {
+ issueNum := issResp["number"].(string)
+ if accessToken != "" && owner != "" && path != "" {
+ url := "https://gitee.com/api/v5/repos/" + owner + "/" + path + "/issues/" + issueNum + "/comments"
+ BConfig, err := config.NewConfig("ini", "conf/app.conf")
+ if err != nil {
+ logs.Error("config init error:", err)
+ return err
+ }
+ commentCmd := BConfig.String("reflink::comment_cmd")
+ commentBody := "Hey @" + Assignee + " , Please complete the content of the issue template in the issue comment. Please refer to the format:" +
+ commentCmd
+ requestBody := fmt.Sprintf(`{
+ "access_token": "%s",
+ "body": "%s"
+ }`, accessToken, commentBody)
+ logs.Info("create issue comment body: ", requestBody)
+ resp, err := util.HttpPost(url, requestBody)
+ if err != nil {
+ logs.Error("创建issue评论失败, url: ", url, "cveId", cve.CveId, ",issueNum: ", issueNum, ",err: ", err)
+ return err
+ }
+ if _, ok := resp["id"]; !ok {
+ logs.Error("创建issue评论失败, err: ", ok, "url: ", url)
+ return errors.New("创建issue评论失败")
+ }
+ commentId := int64(resp["id"].(float64))
+ models.UpdateIssueCommentId(issueNum, cve.CveNum, commentId)
+ }
+ return nil
+}
+
+func CreateSecNoticeData(sec *models.SecurityNotice, iss models.VulnCenter, path, branchs string) {
+ sec.CveId = iss.CveId
+ sec.CveNum = iss.CveNum
+ sec.Introduction = "An update for " + path + " is now available for " + branchs
+ sec.Summary = "An update for " + path + " is now available for " + branchs
+ sec.Theme = sec.Introduction + ";\n\n" + "openEuler Security has rated this" +
+ " update as having a security impact of medium. A Common Vunlnerability" +
+ " Scoring System(CVSS)base score,which gives a detailed severity rating," +
+ " is available for each vulnerability from the CVElink(s) in the References section."
+ sec.AffectProduct = branchs
+}
+
+func CreateIssueLabel(accessToken string, owner string, path string,
+ issNum string) error {
+ if accessToken != "" && owner != "" && path != "" {
+ url := "https://gitee.com/api/v5/repos/" + owner + "/" + path + "/issues/" + issNum + "/labels"
+ //label := []string{"CVE/Undisclosed","CVE/Disclosed"}
+ //reqs ,err:= json.Marshal(&requestBody)
+ //if err != nil {
+ // return err
+ //}
+ //requestBody := fmt.Sprintf(`{
+ // "access_token": "%s",
+ // "body": ["CVE/Undisclosed","CVE/Disclosed"]
+ // }`, accessToken)
+ body := make(map[string]interface{})
+ body["access_token"] = accessToken
+ body["body"] = "[\"CVE/Undisclosed\",\"CVE/Disclosed\"]"
+ requestBody, _ := json.Marshal(body)
+ logs.Info("create issue label: ", string(requestBody))
+ resp, err := util.HttpPost1(url, string(requestBody))
+ if err != nil {
+ logs.Error("cve标签创建失败, url: ", url, "requestBody: ", requestBody, "err: ", err)
+ return err
+ }
+ for _, value := range resp {
+ if _, ok := value["id"]; !ok {
+ logs.Error("创建issue 标签失败, err: ", ok, "url: ", url)
+ return errors.New("创建issue标签失败")
+ }
+ }
+ logs.Info("issue 标签创建成功, resp: ", resp)
+ }
+ return nil
+}
diff --git a/taskhandler/cve.go b/taskhandler/cve.go
new file mode 100644
index 0000000000000000000000000000000000000000..85d52510ea3cf84043e5074faedc8d913d1f3bb3
--- /dev/null
+++ b/taskhandler/cve.go
@@ -0,0 +1,320 @@
+package taskhandler
+
+import (
+ "cvevulner/common"
+ "cvevulner/models"
+ "errors"
+ "github.com/astaxie/beego/logs"
+ "strconv"
+ "strings"
+ "sync"
+ "time"
+)
+
+func UpdateCveGroups(cveData models.OriginUpstream, cveRef string, openeulernum int, CveRes models.VulnCenter, cveDesc models.OriginUpstreamDesc, cveScV3 models.OriginUpstreamImpactScoreV3) (bool, error){
+ var OpenEulId int64
+ CveRes.Description = cveDesc.EnDescription
+ CveRes.CveVersion = cveData.Version
+ CveRes.RepairTime = cveData.PublishedDate
+ CveRes.PackName = cveData.PackName
+ CveRes.CveUrl = cveRef + cveData.CveNum
+ CveRes.CveLevel = cveScV3.CveLevel
+ if CveRes.Status != 0 && CveRes.Status != 1 {
+ CveRes.Status = 1
+ }
+ //CveRes.Status = 1
+ openEusa, operr := models.QueryOpenEulerSAByCveId(CveRes.CveId)
+ if operr == false {
+ var opensa models.OpenEulerSA
+ os, operr := models.QueryOpenSaLastId()
+ var OpenNumData int
+ if operr == nil {
+ OpenNumList := strings.Split(os.OpenEulerSANum, "-")
+ OpenNum, err := strconv.Atoi(OpenNumList[len(OpenNumList) - 1])
+ if err == nil {
+ OpenNum += 100
+ } else {
+ OpenNum = openeulernum
+ }
+ OpenNumData = OpenNum
+ } else {
+ OpenNumData = openeulernum
+ }
+ OpenEulerSANum := "openEuler-SA-" + strconv.Itoa(time.Now().Year()) + "-" + strconv.Itoa(OpenNumData)
+ opensa.OpenEulerSANum = OpenEulerSANum
+ opensa.CveId = CveRes.CveId
+ OpenEulerId, OpEerr := models.CreateOpenEulerSA(&opensa)
+ if OpEerr == nil {
+ OpenEulId = OpenEulerId
+ } else {
+ logs.Error("更新openEulerSa数据表失败")
+ return false, errors.New("openEulerSA数据错误,暂时不处理")
+ }
+ } else {
+ OpenEulId = openEusa.OpenId
+ }
+ scoreRes,scoreerr := models.QueryScoreByCveId(CveRes.CveId)
+ if scoreerr {
+ if scoreRes.NVDScore != cveScV3.BaseScore {
+ var scorecode models.ScoreRecord
+ scorecode.NVDScore = cveScV3.BaseScore
+ scorecode.NvectorVule = cveScV3.VectorString
+ scorecode.Status = 0
+ scorecode.CveId = CveRes.CveId
+ scoreid, err :=models.CreateScoreRecord(&scorecode)
+ if scoreid > 0 && err == nil {
+ logs.Info("insert score_record success, id:",scoreid)
+ } else {
+ return false, errors.New("评分记录数据错误,暂时不处理")
+ }
+ }
+ scoreRes.NVDScore = cveScV3.BaseScore
+ scoreRes.NvectorVule = cveScV3.VectorString
+ scoreRes.OpenId = OpenEulId
+ scoreRes.Nstatus = 1
+ scoreRes.NattackVector = cveScV3.AttackVector
+ scoreRes.NattackComplexity = cveScV3.AttackComplexity
+ scoreRes.NprivilegeRequired = cveScV3.PrivilegesRequired
+ scoreRes.NuserInteraction = cveScV3.UserInteraction
+ scoreRes.Nscope = cveScV3.Scope
+ scoreRes.Nconfidentiality = cveScV3.ConfidentialityImpact
+ scoreRes.Nintegrity = cveScV3.IntegrityImpact
+ scoreRes.Navailability = cveScV3.AvailabilityImpact
+
+ }else {
+ var sc models.Score
+ sc.CveNum = cveData.CveNum
+ sc.NVDScore = cveScV3.BaseScore
+ sc.OpenEulerScore = cveScV3.BaseScore
+ sc.OpenId = OpenEulId
+ sc.NvectorVule = cveScV3.VectorString
+ sc.OvectorVule = cveScV3.VectorString
+ sc.CveId = CveRes.CveId
+ sc.Nstatus = 0
+ sc.Ostatus = 0
+ sc.ScoreType = "v3"
+ sc.NattackVector = cveScV3.AttackVector
+ sc.OattackVector = cveScV3.AttackVector
+ sc.NattackComplexity = cveScV3.AttackComplexity
+ sc.OattackComplexity = cveScV3.AttackComplexity
+ sc.NprivilegeRequired = cveScV3.PrivilegesRequired
+ sc.OprivilegeRequired = cveScV3.PrivilegesRequired
+ sc.NuserInteraction = cveScV3.UserInteraction
+ sc.OuserInteraction = cveScV3.UserInteraction
+ sc.Nscope = cveScV3.Scope
+ sc.Oscope = cveScV3.Scope
+ sc.Nconfidentiality = cveScV3.ConfidentialityImpact
+ sc.Oconfidentiality = cveScV3.ConfidentialityImpact
+ sc.Nintegrity = cveScV3.IntegrityImpact
+ sc.Ointegrity = cveScV3.IntegrityImpact
+ sc.Navailability = cveScV3.AvailabilityImpact
+ sc.Oavailability = cveScV3.AvailabilityImpact
+
+ scid, scerr := models.CreateScore(&sc)
+ if scerr != nil {
+ logs.Error("insert cve_score failed cveScV3:", cveScV3)
+ return false, errors.New("记录评分失败,暂时不处理")
+ } else {
+ logs.Info("insert cve_score success scid: ", scid, "CveNum:", cveData.CveNum)
+ }
+ }
+ SecNOtice, secerrx := models.QuerySecNoticeByCveId(CveRes.CveId)
+ if secerrx {
+ SecNOtice.InfluenceComponent = cveData.AffectProduct
+ SecNOtice.OpenId = OpenEulId
+ SecNOtice.Summary = cveData.AffectProduct + " security update"
+ SecNOtice.ReferenceLink = cveRef + cveData.CveNum
+ } else {
+ var sec models.SecurityNotice
+ sec.CveNum = cveData.CveNum
+ sec.OpenId = OpenEulId
+ sec.InfluenceComponent = cveData.AffectProduct
+ sec.Status = 0
+ sec.AffectStatus = "UnFixed"
+ sec.CveId = CveRes.CveId
+ sec.Summary = cveData.AffectProduct + " security update"
+ sec.ReferenceLink = cveRef + cveData.CveNum
+ secid, secerr := models.CreateSecurityNotice(&sec)
+ if secerr != nil {
+ logs.Error("insert cve_security_notice failed CveNum:", cveData.CveNum)
+ return false, errors.New("记录SA失败,暂时不处理")
+ } else {
+ logs.Info("insert cve_security_notice success secid: , cveNum: ", secid, cveData.CveNum)
+ }
+ }
+ if scoreerr && secerrx {
+ errx := models.UpdateCveRelat(&CveRes, &SecNOtice, &scoreRes)
+ if errx != nil {
+ logs.Error("update (&CveRes, &SecNOtice, &scoreRes) failed CveNum:", cveData.CveNum)
+ return false, errors.New("数据更新失败, 暂时不处理")
+ }
+ } else if scoreerr {
+ errx := models.UpdateCveRelat1(&CveRes, &SecNOtice)
+ if errx != nil {
+ logs.Error("update (&CveRes, &SecNOtice)failed CveNum:", cveData.CveNum)
+ return false, errors.New("数据更新失败, 暂时不处理")
+ }
+ } else {
+ errx := models.UpdateCveRelat2(&CveRes, &scoreRes)
+ if errx != nil {
+ logs.Error("update (&CveRes, &scoreRes) failed CveNum:", cveData.CveNum)
+ return false, errors.New("数据更新失败, 暂时不处理")
+ }
+ }
+ return true, nil
+}
+
+func InsertCveGroups(cveData models.OriginUpstream, cveRef string, openeulernum int, cveDesc models.OriginUpstreamDesc, cveScV3 models.OriginUpstreamImpactScoreV3) (bool, error) {
+ var vul models.VulnCenter
+ vul.CveNum = cveData.CveNum
+ vul.Description = cveDesc.EnDescription
+ vul.Status = 0
+ vul.CveVersion = cveData.Version
+ vul.RepairTime = cveData.PublishedDate
+ vul.PackName = cveData.PackName
+ vul.CveUrl = cveRef + cveData.CveNum
+ vul.CveLevel = cveScV3.CveLevel
+ var sec models.SecurityNotice
+ sec.CveNum = cveData.CveNum
+ sec.InfluenceComponent = cveData.AffectProduct
+ sec.Status = 0
+ sec.AffectStatus = "UnFixed"
+ sec.Summary = cveData.AffectProduct + " security update"
+ sec.ReferenceLink = cveRef + cveData.CveNum
+ var sc models.Score
+ sc.CveNum = cveData.CveNum
+ sc.NVDScore = cveScV3.BaseScore
+ sc.OpenEulerScore = cveScV3.BaseScore
+ sc.NvectorVule = cveScV3.VectorString
+ sc.OvectorVule = cveScV3.VectorString
+ sc.Nstatus = 0
+ sc.Ostatus = 0
+ sc.ScoreType = "v3"
+ sc.NattackVector = cveScV3.AttackVector
+ sc.OattackVector = cveScV3.AttackVector
+ sc.NattackComplexity = cveScV3.AttackComplexity
+ sc.OattackComplexity = cveScV3.AttackComplexity
+ sc.NprivilegeRequired = cveScV3.PrivilegesRequired
+ sc.OprivilegeRequired = cveScV3.PrivilegesRequired
+ sc.NuserInteraction = cveScV3.UserInteraction
+ sc.OuserInteraction = cveScV3.UserInteraction
+ sc.Nscope = cveScV3.Scope
+ sc.Oscope = cveScV3.Scope
+ sc.Nconfidentiality = cveScV3.ConfidentialityImpact
+ sc.Oconfidentiality = cveScV3.ConfidentialityImpact
+ sc.Nintegrity = cveScV3.IntegrityImpact
+ sc.Ointegrity = cveScV3.IntegrityImpact
+ sc.Navailability = cveScV3.AvailabilityImpact
+ sc.Oavailability = cveScV3.AvailabilityImpact
+ var opensa models.OpenEulerSA
+ //var os models.OpenSaId
+ os, operr := models.QueryOpenSaLastId()
+ var OpenNumData int
+ if operr == nil {
+ OpenNumList := strings.Split(os.OpenEulerSANum, "-")
+ OpenNum, err := strconv.Atoi(OpenNumList[len(OpenNumList) - 1])
+ if err == nil {
+ OpenNum += 100
+ } else {
+ OpenNum = openeulernum
+ }
+ OpenNumData = OpenNum
+ } else {
+ OpenNumData = openeulernum
+ }
+ OpenEulerSANum := "openEuler-SA-" + strconv.Itoa(time.Now().Year()) + "-" + strconv.Itoa(int(OpenNumData))
+ opensa.OpenEulerSANum = OpenEulerSANum
+ var scorecode models.ScoreRecord
+ scorecode.NVDScore = cveScV3.BaseScore
+ scorecode.NvectorVule = cveScV3.VectorString
+ scorecode.Status = 0
+ cveid, cveerr := models.CreateCveRelat(&vul, &sec, &sc, &opensa, &scorecode)
+ if cveerr != nil || cveid <= 0 {
+ logs.Error("insert (&CveRes, &scoreRes, &sec) failed CveNum:", cveData.CveNum)
+ return false, errors.New("数据插入失败,暂时不处理")
+ }
+ return true, nil
+}
+
+var lockx sync.Mutex
+
+func GenCveVuler(cveData models.OriginUpstream, cveRef string, openeulernum int) (bool, error){
+ if cveData.Ids == "" || cveData.CveNum == ""{
+ logs.Error("当前数据cveNum 为空暂不处理,data: ", cveData)
+ return false, errors.New("数据错误,暂时不处理")
+ }
+ cveDesc, ok := models.QueryCveDesc(cveData.CveId)
+ if !ok {
+ logs.Error("当前数据描述为空暂不处理, data: ", cveData)
+ return false, errors.New("数据错误,暂时不处理")
+ }
+ cveImpact, ok := models.QueryCveImpact(cveData.CveId)
+ if !ok {
+ logs.Error("cveImpact查询失败, data: ", cveData)
+ return false, errors.New("数据错误,暂时不处理")
+ }
+ cveScore, ok := models.QueryCveScore(cveImpact.ImpactId, "v3")
+ if !ok {
+ logs.Error("cveScore, data: ", cveData, ",cveImpact: ", cveImpact)
+ return false, errors.New("数据错误,暂时不处理")
+ }
+ cveScV3, ok := models.QueryCveCvssV3(cveScore.ScoreId)
+ if !ok {
+ logs.Error("cveScore, data: ", cveData, ",cveScore: ", cveScore)
+ return false, errors.New("数据错误,暂时不处理")
+ }
+ CveRes, err := models.QueryCveByNum(cveData.CveNum)
+ if err {
+ lockx.Lock()
+ ok, err := UpdateCveGroups(cveData, cveRef, openeulernum, CveRes, cveDesc, cveScV3)
+ lockx.Unlock()
+ if !ok {
+ logs.Error("更新cve数据失败, cveData: ", cveData, ", err: ", err)
+ return false, errors.New("数据错误,暂时不处理")
+ }
+ } else {
+ lockx.Lock()
+ ok, err := InsertCveGroups(cveData, cveRef, openeulernum, cveDesc, cveScV3)
+ lockx.Unlock()
+ if !ok {
+ logs.Error("插入cve数据失败, cveData: ", cveData, ", err: ", err)
+ return false, errors.New("数据错误,暂时不处理")
+ }
+ }
+ models.UpdateOriginStatus(common.GetCurTime(), cveData.PackName, cveData.Version, cveData.CveId)
+ return true, nil
+}
+
+func GetCveOriginData(prcnum, days , openeulernum int, cveRef string) (bool, error) {
+ defer common.Catchs()
+ //var os []models.OriginUpstream
+ count := 0
+ beforeTime := common.GetBeforeTime(days)
+ for {
+ os, num, err := models.QueryOriginCve(beforeTime, prcnum)
+ if err != nil || num == 0{
+ logs.Info("当前无cve原始数据处理, err: ", err,
+ ", 处理时间范围: beforetime: ", beforeTime,
+ "curtime: ", common.GetCurTime())
+ break
+ }
+ logs.Info("总共有: ", num, "条的数据需要处理, ", os)
+ ch := make(chan int, len(os))
+ for i, cveData := range os {
+ count = count + 1
+ logs.Info("当前正常解析第: ", count, "条数据,i:", i, ", cvenum: ", cveData.Ids)
+ go func () {
+ ok, err := GenCveVuler(cveData, cveRef, openeulernum)
+ if !ok {
+ logs.Error("cveData: ", cveData, "处理失败, err: ", err)
+ }
+ ch <- i
+ }()
+ }
+ for i := 0; i < cap(ch); i++ {
+ <-ch
+ }
+ close(ch)
+ }
+ return true, nil
+}
diff --git a/taskhandler/grabissue.go b/taskhandler/grabissue.go
new file mode 100644
index 0000000000000000000000000000000000000000..bfb6154160667c3e8530a8077bfba1699b01bb68
--- /dev/null
+++ b/taskhandler/grabissue.go
@@ -0,0 +1,83 @@
+package taskhandler
+
+import (
+ "encoding/json"
+ "fmt"
+ "github.com/astaxie/beego/logs"
+ "io/ioutil"
+ "net/http"
+ "sync"
+)
+
+const (
+ GiteOrgInfoUrl = `https://gitee.com/api/v5/orgs/%v?access_token=%v` //get gitee org info
+ GiteOrgReposUrl = `https://gitee.com/api/v5/orgs/%v/repos?access_token=%v&type=all&page=%v&per_page=%v`//get all repository
+ GiteRepoIssuesUrl = `https://gitee.com/api/v5/repos/{owner}/{repo}/issues`
+ perPage =50
+)
+
+var wg sync.WaitGroup
+
+type OrgInfo struct {
+ Id int32 `json:"id,omitempty"`
+ Login string `json:"login,omitempty"`
+ Url string `json:"url,omitempty"`
+ AvatarUrl string `json:"avatar_url,omitempty"`
+ ReposUrl string `json:"repos_url,omitempty"`
+ EventsUrl string `json:"events_url,omitempty"`
+ MembersUrl string `json:"members_url,omitempty"`
+ Description string `json:"description,omitempty"`
+ Name string `json:"name,omitempty"`
+ Enterprise string `json:"enterprise,omitempty"`
+ Members int64 `json:"members,omitempty"`
+ PublicRepos int64 `json:"public_repos,omitempty"`
+ PrivateRepos int64 `json:"private_repos,omitempty"`
+}
+
+//GrabIssueByOrg grab issue by org name
+func GrabIssueByOrg(accToken, org string) {
+ orgInfo, err := GetOrgInfo(accToken, org)
+ if err != nil {
+ logs.Error(err)
+ return
+ }
+ reposNum := orgInfo.PublicRepos + orgInfo.PrivateRepos
+ if reposNum <= 0 {
+ logs.Info(fmt.Sprintf("%v cantain %v repository,grab issue finish!",org,reposNum))
+ return
+ }
+ pageSize := reposNum / int64(perPage)
+ if reposNum%int64(perPage) > 0 {
+ pageSize = pageSize + 1
+ }
+ var i int64
+ for i = 1; i <= pageSize; i++ {
+ wg.Add(1)
+ //load org repository list
+ }
+ wg.Wait()
+}
+
+//GrabIssueByRepo grab issue by repository
+func GrabIssueByRepo(accToken, owner, repo, state string, page int) {
+
+}
+
+func GetOrgInfo(accToken, org string) (OrgInfo, error) {
+ oi := OrgInfo{}
+ resp, err := http.Get(fmt.Sprintf(GiteOrgInfoUrl, org, accToken))
+ if err != nil {
+ return oi, err
+ }
+ defer resp.Body.Close()
+ body, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return oi, err
+ }
+ err = json.Unmarshal(body, &oi)
+ return oi, err
+}
+
+func GetOrgRepos(accToken,org string) {
+
+}
diff --git a/taskhandler/oricvecheck.go b/taskhandler/oricvecheck.go
new file mode 100644
index 0000000000000000000000000000000000000000..8fae63598e10fb7968303952061f72393281f4bd
--- /dev/null
+++ b/taskhandler/oricvecheck.go
@@ -0,0 +1,49 @@
+package taskhandler
+
+import (
+ "cvevulner/common"
+ "cvevulner/models"
+ "github.com/astaxie/beego/logs"
+)
+
+func CheckCveOriginData(prcnum int) (string, error) {
+ defer common.Catchs()
+ //var os []models.OriginUpstream
+ count := 0
+ ok := models.UpdateOriginExistTemp()
+ if !ok {
+ logs.Info("UpdateOriginExistTemp, 没有数据需要处理")
+ return "", nil
+ }
+ for {
+ os, num, err := models.QueryOriginCveE(prcnum)
+ if err != nil || num == 0{
+ logs.Info("当前无异常cve原始数据处理, err: ", err,
+ ", 处理时间范围: beforetime: ",
+ "curtime: ", common.GetCurTime())
+ break
+ }
+ logs.Info("总共有: ", num, "条数据需要处理, ", os)
+ ch := make(chan int, len(os))
+ for i, cveData := range os {
+ count = count + 1
+ logs.Info("当前正常解析第: ", count, "条数据,i:", i, ", cvenum: ", cveData.Ids)
+ go func() {
+ gits, ok := models.QueryCveOpeneulerdata(cveData.PackName, cveData.Version)
+ if !ok {
+ models.UpdateOriginExist(common.GetCurTime(), cveData.PackName, cveData.Version, cveData.CveId, 0)
+ logs.Info("不存在,还原: ", cveData, ", gits: ", gits)
+ } else {
+ models.UpdateOriginExist(common.GetCurTime(), cveData.PackName, cveData.Version, cveData.CveId, 1)
+ logs.Info("加入到cve漏洞中: ", cveData, ", gits: ", gits)
+ }
+ ch <- i
+ }()
+ }
+ for i :=0; i < cap(ch); i++ {
+ <- ch
+ }
+ close(ch)
+ }
+ return "", nil
+}
diff --git a/taskhandler/yaml.go b/taskhandler/yaml.go
new file mode 100644
index 0000000000000000000000000000000000000000..e46b65d5b95d184dd8e3aa5fbf8dd29da3696ba5
--- /dev/null
+++ b/taskhandler/yaml.go
@@ -0,0 +1,355 @@
+package taskhandler
+
+import (
+ "cvevulner/common"
+ "cvevulner/models"
+ "cvevulner/util"
+ "encoding/json"
+ "errors"
+ "github.com/astaxie/beego/logs"
+ "strconv"
+ "sync"
+)
+
+func GetYamlTables(url string) (string, error){
+ compUrl := url + "/lifeCycle/tables"
+ body, err:= util.HttpGetCom(compUrl)
+ if err == nil && body != nil {
+ var respBody map[string]interface{}
+ err =json.Unmarshal(body, &respBody)
+ if err != nil {
+ logs.Error(err)
+ return "", err
+ }
+ logs.Info(respBody)
+ if respBody["code"].(string) == "2001"{
+ for i, values := range respBody["data"].([]interface{}) {
+ var gt models.GitPackageTable
+ gt.TableName = values.(string)
+ table_id, err := models.CreateYamlTable(>)
+ if table_id > 0 {
+ logs.Info("第 ", i, "条数据, table: ", values, "插入成功, table_id: ", table_id)
+ } else {
+ logs.Error("第 ", i, "条数据, table: ", values, "插入失败, err: ", err)
+ return "", err
+ }
+ }
+ } else {
+ return "", errors.New("数据格式错误")
+ }
+ }
+ return "", nil
+}
+
+var lock sync.Mutex
+//var wg sync.WaitGroup
+
+func GetYamlByGit(url string) (string, error) {
+ defer common.Catchs()
+ var gt []models.GitPackageTable
+ page := 1
+ size := 20
+ num, err := models.GetYamlTable(>)
+ if err != nil {
+ logs.Error("查询表失败,无法获取yaml, err: ", err)
+ return "", err
+ }
+ logs.Info("总共有: ", num, "表的数据需要获取, ", gt)
+ compUrl1 := url + "/packages"
+ var ch = make(chan int, len(gt))
+ for i, tableValue := range gt {
+ logs.Info("查询第 ", i, "tableName: ", tableValue.TableName, "开始...")
+ //wg.Add(1)
+ go func() {
+ ok, err := GetYaml(url, compUrl1, page, size, tableValue, &ch)
+ if err == nil {
+ logs.Info("当前数据处理成功,i: ", i)
+ } else {
+ logs.Error("当前数据处理失败, ok: ", ok, ",i: ", i, ", err: ", err)
+ }
+ }()
+ //<- ch
+ }
+ for i:=0; i< len(gt); i++ {
+ <-ch
+ }
+ close(ch)
+ //wg.Wait()
+ return "", nil
+}
+
+func GetYaml(url, compUrl1 string, page, size int, tableValue models.GitPackageTable, ch *chan int) (string, error){
+ //defer wg.Done()
+ defer common.Catchs()
+ var tc GitTablePackCount
+ tc.TableName = tableValue.TableName
+ tc.Page = 0
+ tc.Size = 0
+ tc.Page = page
+ tc.Size = size
+ compUrl2 := compUrl1 + "?table_name=" + tableValue.TableName
+ for ;; {
+ compUrl := compUrl2 +
+ "&page_num=" + strconv.Itoa(tc.Page) + "&page_size=" + strconv.Itoa(size)
+ body, err:= util.HttpGetCom(compUrl)
+ var respBody map[string]interface{}
+ if err == nil && body != nil {
+ err =json.Unmarshal(body, &respBody)
+ if err != nil {
+ logs.Error(err)
+ return "", err
+ }
+ } else {
+ logs.Error( "http 请求失败, url: ", compUrl)
+ return "", err
+ }
+ logs.Info("start: ", tc)
+ if respBody["code"].(string) == "2001"{
+ //chx := make(chan int)
+ cur_count := 0
+ if respBody == nil || respBody["data"] == nil || len(respBody["data"].([]interface{})) == 0{
+ logs.Error("数据为空, url: ", compUrl)
+ return "", err
+ }
+ for i, values := range respBody["data"].([]interface{}) {
+ tc.Count = tc.Count + 1
+ logs.Info("第:",tc.Page,"页, 到: ", tc.Size, "条, tableName: ",tc.TableName,
+ ",已处理到第count: ", tc.Count, "条, yaml values: ", values)
+ if values == nil || values == "" || len(values.(map[string]interface{})) == 0{
+ logs.Error("第:",tc.Page,"页, 到: ", tc.Size, "条, tableName: ",tc.TableName,
+ ",已处理到第count: ", tc.Count, "条, yaml values: ", values, ", 处理失败")
+ cur_count = cur_count + 1
+ continue
+ }
+ valuesx := values.(map[string]interface{})
+ ok, err := ProcPackDetail(url, valuesx, tableValue, i)
+ logs.Info("ok: ", ok, ", err: ", err)
+ //<- chx
+ cur_count = cur_count + 1
+ }
+ //close(chx)
+ totalPage := 0
+ switch respBody["total_page"].(type) {
+ case string:
+ totalPage, _ = strconv.Atoi(respBody["total_page"].(string))
+ case int:
+ totalPage = respBody["total_page"].(int)
+ case int64:
+ totalPage = int(respBody["total_page"].(int64))
+ case float64:
+ totalPage = int(int64(respBody["total_page"].(float64)))
+ default:
+ totalPage = 1
+ }
+ totalCount := 0
+ switch respBody["total_count"].(type) {
+ case string:
+ totalCount, _ = strconv.Atoi(respBody["total_count"].(string))
+ case int:
+ totalCount = respBody["total_count"].(int)
+ case int64:
+ totalCount = int(respBody["total_count"].(int64))
+ case float64:
+ totalCount = int(int64(respBody["total_count"].(float64)))
+ default:
+ totalCount = 1
+ }
+ if tc.Page > totalPage || tc.Size >= totalCount{
+ logs.Info("已处理完成:tableName: ", tc.TableName, "数据获取完成, " +
+ "总页数(page_num):", totalPage, ", 总条数(page_size):", totalCount, "\n",
+ ",当前页数Page:", tc.Page, ",当前条数size: ", tc.Size, ",url: ", compUrl)
+ break
+ } else {
+ logs.Info("当前: tableName: ", tc.TableName, "数据获取完成, " +
+ "总页数(page_num):", totalPage, ", 总条数(page_size):", totalCount, "\n",
+ ",当前页数Page:", tc.Page, ",当前条数size: ", tc.Size, ",url: ", compUrl)
+ lock.Lock()
+ tc.Page = tc.Page + page
+ tc.Size = tc.Size + cur_count
+ lock.Unlock()
+ logs.Info("增加后: tableName: ", tc.TableName, "数据获取完成, " +
+ "总页数(page_num):", totalPage, ", 总条数(page_size):", totalCount, "\n",
+ ",当前页数Page:", tc.Page, ",当前条数size: ", tc.Size, ",url: ", compUrl)
+ }
+ logs.Info("start: ", tc)
+ } else {
+ logs.Error("网络请求失败,url:", compUrl)
+ continue
+ }
+ }
+ *ch <- 1
+ return "", nil
+}
+
+
+func ProcPackDetail(url string, values map[string]interface{}, tableValue models.GitPackageTable, i int) (string, error){
+ var ge models.GitOpenEuler
+ GitOpenEulerData(values, &ge, tableValue)
+ ok, _ := models.GetSingleYaml(&ge)
+ if ok {
+ logs.Info("第 ", i, "条数据, PackageName: ", ge.PackageName, "已经存在,不需要再次插入")
+ return ge.PackageName, nil
+ }
+ git_id, typex, err := models.CreateYaml(&ge)
+ if git_id > 0 && err == nil {
+ logs.Info("第 ", i, "条数据, PackageName: ", ge.PackageName, typex, "成功, git_id: ", git_id)
+ } else {
+ logs.Error("第 ", i, "条数据, PackageName: ", ge.PackageName, typex, "失败, err: ", err)
+ return "", err
+ }
+ if typex == "insert" && git_id > 0 {
+ subcompUrl := url + "/packages/packageInfo" + "?table_name=" + tableValue.TableName + "&pkg_name=" + ge.PackageName
+ body, err:= util.HttpGetCom(subcompUrl)
+ var respBody map[string]interface{}
+ if err == nil && body != nil {
+ err =json.Unmarshal(body, &respBody)
+ if err != nil {
+ logs.Error(err)
+ return "", err
+ }
+ } else {
+ logs.Error( "http 请求失败, subcompUrl: ", subcompUrl)
+ return "", err
+ }
+ logs.Info(respBody)
+ if respBody["code"].(string) == "2001"{
+ if respBody["data"] == nil || respBody["data"] == "" {
+ logs.Error("获取包详情失败, subcompUrl: ", subcompUrl)
+ return "", errors.New("数据错误")
+ }
+ var gp models.GitPackageInfo
+ GitOpenEulerInfoData(respBody["data"].(map[string]interface{}), &gp, ge)
+ detailid, typex, err := models.CreateYamlDetail(&gp, ge)
+ if detailid >0 && typex == "insert" && err == nil {
+ subdata := respBody["data"].(map[string]interface{})
+ if subdata["subpack"] == nil {
+ return "", err
+ }
+ if subdata == nil || subdata["subpack"] == nil || len(subdata["subpack"].([]interface{})) == 0 {
+ return "", errors.New("数据错误")
+ }
+ subpack := subdata["subpack"].([]interface{})
+ for _, packValuex := range subpack {
+ logs.Info("yaml packValuex: ", packValuex)
+ if packValuex == nil || packValuex == "" || len(packValuex.(map[string]interface{})) == 0 {
+ continue
+ }
+ packValue := packValuex.(map[string]interface{})
+ var gb models.GitSubPack
+ gb.DetailId = gp.DetailId
+ switch packValue["id"].(type) {
+ case string:
+ gb.Ids, _ = strconv.ParseInt(packValue["id"].(string), 10, 64)
+ case int:
+ gb.Ids = packValue["id"].(int64)
+ case int64:
+ gb.Ids = packValue["id"].(int64)
+ case float64:
+ gb.Ids = int64(packValue["id"].(float64))
+ default:
+ gb.Ids = 0
+ }
+ if packValue["name"] == nil {
+ gb.SubPackName = ""
+ } else {
+ gb.SubPackName = packValue["name"].(string)
+ }
+ SubId, typex, err := models.CreateYamlSubPack(&gb)
+ if SubId > 0 && typex == "insert" && err == nil {
+ if packValue["provides"] != nil && len(packValue["provides"].([]interface{})) > 0{
+ provides := packValue["provides"].([]interface{})
+ for _, provValuex := range provides {
+ logs.Info("yaml provValuex: ", provValuex)
+ if provValuex == nil || provValuex == "" || len(provValuex.(map[string]interface{})) == 0 {
+ continue
+ }
+ provValue := provValuex.(map[string]interface{})
+ var gs models.GitSubPackProvides
+ gs.SubId = SubId
+ switch provValue["id"].(type) {
+ case string:
+ gs.Ids, _ = strconv.ParseInt(provValue["id"].(string), 10, 64)
+ case int:
+ gs.Ids = provValue["id"].(int64)
+ case int64:
+ gs.Ids = provValue["id"].(int64)
+ case float64:
+ gs.Ids = int64(provValue["id"].(float64))
+ default:
+ gs.Ids = 0
+ }
+ if provValue["name"] == nil {
+ gs.ProvideName = ""
+ } else {
+ gs.ProvideName = provValue["name"].(string)
+ }
+
+ gs.Requiredby = ""
+ ProvideId, typexx, err := models.CreateYamlSubPackProvides(&gs)
+ if ProvideId > 0 && typexx == "insert" && err == nil {
+ if provValue["requiredby"] != nil && len(provValue["requiredby"].([]interface{})) > 0{
+ requiredby := provValue["requiredby"].([]interface{})
+ for _, reqValue := range requiredby {
+ if reqValue != nil && reqValue.(string) != "" {
+ var gr models.GitSubPackRequiredby
+ gr.ProvideId = gs.ProvideId
+ gr.Requiredby = reqValue.(string)
+ Id, typexy, err := models.CreateYamlSubPackRequiredb(&gr)
+ logs.Info("CreateYamlSubPackRequiredb", Id, typexy, err)
+ }
+ }
+ }
+ }
+ }
+ }
+ if packValue["requires"] != nil && len(packValue["requires"].([]interface{})) > 0{
+ requires := packValue["requires"].([]interface{})
+ for _, reqValuexx := range requires {
+ logs.Info("reqValuexx: ", reqValuexx)
+ if reqValuexx == nil || reqValuexx == "" || len(reqValuexx.(map[string]interface{})) == 0 {
+ continue
+ }
+ reqValuex := reqValuexx.(map[string]interface{})
+ reqStr := ""
+ if reqValuex["providedby"] != nil && len(reqValuex["providedby"].([]interface{})) > 0{
+ providedby := reqValuex["providedby"].([]interface{})
+ for _, reqValue := range providedby {
+ if reqValue != nil && reqValue.(string) != "" {
+ reqStr = reqStr + reqValue.(string) + ","
+ }
+ }
+ }
+ if reqStr != "" {
+ reqStr = reqStr[:len(reqStr) -1]
+ }
+ var gs models.GitSubPackRequire
+ gs.SubId = SubId
+ switch reqValuex["id"].(type) {
+ case string:
+ gs.Ids, _ = strconv.ParseInt(reqValuex["id"].(string), 10, 64)
+ case int:
+ gs.Ids = reqValuex["id"].(int64)
+ case int64:
+ gs.Ids = reqValuex["id"].(int64)
+ case float64:
+ gs.Ids = int64(reqValuex["id"].(float64))
+ default:
+ gs.Ids = 0
+ }
+ if reqValuex["name"] == nil {
+ gs.RequireName = ""
+ } else {
+ gs.RequireName = reqValuex["name"].(string)
+ }
+ gs.Providedby = reqStr
+ RequireId, typexx, err := models.CreateYamlSubPackRequires(&gs)
+ logs.Info("CreateYamlSubPackRequires", RequireId, typexx, err)
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return "", nil
+}
\ No newline at end of file
diff --git a/tests/aes_test.go b/tests/aes_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..aa06bb9917a37a3dbc81c8e003196d9a3fc90a71
--- /dev/null
+++ b/tests/aes_test.go
@@ -0,0 +1,18 @@
+package test
+
+import (
+ "cvevulner/common"
+ "github.com/astaxie/beego"
+ "testing"
+)
+
+func TestEnPwdCode(t *testing.T) {
+ pwd := []byte("159xwz@Qmxx")
+ key := []byte(beego.AppConfig.String("key"))
+ code, err := common.EnPwdCode(pwd, key)
+ if err != nil {
+ t.Error(err)
+ }else {
+ t.Log(code)
+ }
+}
diff --git a/tests/default_test.go b/tests/default_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..ebff2df1af1de6215676b8e2d3f73ac919cc4381
--- /dev/null
+++ b/tests/default_test.go
@@ -0,0 +1,38 @@
+package test
+
+import (
+ "net/http"
+ "net/http/httptest"
+ "testing"
+ "runtime"
+ "path/filepath"
+ _ "cvevulner/routers"
+
+ "github.com/astaxie/beego"
+ . "github.com/smartystreets/goconvey/convey"
+)
+
+func init() {
+ _, file, _, _ := runtime.Caller(0)
+ apppath, _ := filepath.Abs(filepath.Dir(filepath.Join(file, ".." + string(filepath.Separator))))
+ beego.TestBeegoInit(apppath)
+}
+
+// TestGet is a sample to run an endpoint test
+func TestGet(t *testing.T) {
+ r, _ := http.NewRequest("GET", "/v1/object", nil)
+ w := httptest.NewRecorder()
+ beego.BeeApp.Handlers.ServeHTTP(w, r)
+
+ beego.Trace("testing", "TestGet", "Code[%d]\n%s", w.Code, w.Body.String())
+
+ Convey("Subject: Test Station Endpoint\n", t, func() {
+ Convey("Status Code Should Be 200", func() {
+ So(w.Code, ShouldEqual, 200)
+ })
+ Convey("The Result Should Not Be Empty", func() {
+ So(w.Body.Len(), ShouldBeGreaterThan, 0)
+ })
+ })
+}
+
diff --git a/util/http.go b/util/http.go
new file mode 100644
index 0000000000000000000000000000000000000000..527153a9aad3cd627c74ba850b1ab7cf95995d6e
--- /dev/null
+++ b/util/http.go
@@ -0,0 +1,196 @@
+package util
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "github.com/astaxie/beego/logs"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "strconv"
+ "strings"
+)
+
+type RequestInfo struct {
+ Url string
+ Data map[string]string //post要传输的数据,必须key value必须都是string
+ DataInterface map[string]interface{}
+}
+
+
+func HttpPatch(url string, requestBody string) (map[string]interface{}, error){
+ req, err := http.NewRequest("PATCH", url, bytes.NewBuffer([]byte(requestBody)))
+ req.Header.Set("Content-Type", "application/json")
+ client := &http.Client{}
+ resp, err := client.Do(req)
+ if err != nil {
+ logs.Error("Post request 失败, err: ", err, "body: ", requestBody, "url:", url)
+ return nil, err
+ }
+ defer resp.Body.Close()
+ logs.Info("response Status:", resp.Status, "url: ", url)
+ logs.Info("response Headers:", resp.Header, "url: ", url)
+ status, _ := strconv.Atoi(resp.Status)
+ if status > 300 {
+ logs.Error("Patch request 失败, err: ", err, "body: ", requestBody, "url:", url)
+ return nil, err
+ }
+ body, err := ioutil.ReadAll(resp.Body)
+ fmt.Println("response Body:", string(body))
+ if err != nil {
+ logs.Error("post 返回失败, err: ", err, "body: ", requestBody)
+ return nil, err
+ }
+ logs.Info("post 返回成功!, body: ", string(body))
+ var iss map[string]interface{}
+ err =json.Unmarshal(body, &iss)
+ if err != nil {
+ logs.Error(err, string(body))
+ return nil, err
+ }
+ logs.Info(iss)
+ return iss, nil
+}
+
+
+func HttpPost(url string, requestBody string) (map[string]interface{}, error){
+ req, err := http.NewRequest("POST", url, bytes.NewBuffer([]byte(requestBody)))
+ req.Header.Set("Content-Type", "application/json")
+ client := &http.Client{}
+ resp, err := client.Do(req)
+ if err != nil {
+ logs.Error("Post request 失败, err: ", err, "body: ", requestBody, "url:", url)
+ return nil, err
+ }
+ defer resp.Body.Close()
+ logs.Info("response Status:", resp.Status, "url: ", url)
+ logs.Info("response Headers:", resp.Header, "url: ", url)
+ status, _ := strconv.Atoi(resp.Status)
+ if status > 300 {
+ logs.Error("Post request 失败, err: ", err, "body: ", requestBody, "url:", url)
+ return nil, err
+ }
+ body, err := ioutil.ReadAll(resp.Body)
+ fmt.Println("response Body:", string(body))
+ if err != nil {
+ logs.Error("post 返回失败, err: ", err, "body: ", requestBody)
+ return nil, err
+ }
+ logs.Info("post 返回成功!, body: ", string(body))
+ var iss map[string]interface{}
+ err =json.Unmarshal(body, &iss)
+ if err != nil {
+ logs.Error(err, string(body))
+ return nil, err
+ }
+ logs.Info(iss)
+ return iss, nil
+}
+
+func HttpPost1(url string, requestBody string) ([]map[string]interface{}, error){
+ req, err := http.NewRequest("POST", url, bytes.NewBuffer([]byte(requestBody)))
+ req.Header.Set("Content-Type", "application/json")
+ client := &http.Client{}
+ resp, err := client.Do(req)
+ if err != nil {
+ logs.Error("Post request 失败, err: ", err, "body: ", requestBody, "url:", url)
+ return nil, err
+ }
+ defer resp.Body.Close()
+ logs.Info("response Status:", resp.Status, "url: ", url)
+ logs.Info("response Headers:", resp.Header, "url: ", url)
+ status, _ := strconv.Atoi(resp.Status)
+ if status > 300 {
+ logs.Error("Post request 失败, err: ", err, "body: ", requestBody, "url:", url)
+ return nil, err
+ }
+ body, err := ioutil.ReadAll(resp.Body)
+ fmt.Println("response Body:", string(body))
+ if err != nil {
+ logs.Error("post 返回失败, err: ", err, "body: ", requestBody)
+ return nil, err
+ }
+ logs.Info("post 返回成功!, body: ", string(body))
+ var iss []map[string]interface{}
+ err =json.Unmarshal(body, &iss)
+ if err != nil {
+ logs.Error(err, string(body))
+ return nil, err
+ }
+ logs.Info(iss)
+ return iss, nil
+}
+
+func PostUrlEncoded(this RequestInfo)([]byte,error){
+ client := &http.Client{}
+ //post要提交的数据
+ DataUrlVal := url.Values{}
+ for key,val := range this.Data{
+ DataUrlVal.Add(key,val)
+ }
+ req,err := http.NewRequest("POST",this.Url,strings.NewReader(DataUrlVal.Encode()))
+ if err != nil{
+ logs.Error(err)
+ return nil,err
+ }
+ //伪装头部
+ req.Header.Set("Accept","application/json")
+ req.Header.Add("Content-Type","application/x-www-form-urlencoded")
+
+ //提交请求
+ resp,err := client.Do(req)
+ defer resp.Body.Close()
+ if err != nil{
+ logs.Error(err)
+ return nil,err
+ }
+ //读取返回值
+ result,err := ioutil.ReadAll(resp.Body)
+ if err != nil{
+ logs.Error(err)
+ return nil,err
+ }
+ logs.Info(string(result))
+ return result,nil
+}
+
+
+func HttpGet(url string) ([]map[string]interface{}, error){
+ resp, err := http.Get(url)
+ if err != nil {
+ logs.Error("get error, url:", url, "error: ", err)
+ return nil, err
+ }
+ defer resp.Body.Close()
+ body, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ logs.Error("url:", url, ",err: ", err)
+ return nil, err
+ }else {
+ logs.Info("body: \n", string(body), "url: ", url)
+ }
+ var col []map[string]interface{}
+ err =json.Unmarshal(body, &col)
+ if err != nil {
+ logs.Error(err)
+ }
+ return col, nil
+}
+
+func HttpGetCom(url string) ([]byte, error){
+ resp, err := http.Get(url)
+ if err != nil {
+ logs.Error("get error, url:", url, "error: ", err)
+ return nil, err
+ }
+ defer resp.Body.Close()
+ body, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ logs.Error(err)
+ return nil, err
+ }else {
+ logs.Info("body: \n", string(body), "url: ", url)
+ }
+ return body, nil
+}
\ No newline at end of file
diff --git a/util/parsepayload.go b/util/parsepayload.go
new file mode 100644
index 0000000000000000000000000000000000000000..174789aac273e95406f669cef048383366565924
--- /dev/null
+++ b/util/parsepayload.go
@@ -0,0 +1,173 @@
+package util
+
+import (
+ "fmt"
+ "regexp"
+ "strings"
+ "sync"
+)
+
+var (
+ LAC = "LAC" //漏洞组件标签
+ LN = "LN" //漏洞编号标签
+ LAV = "LAV" //漏洞版本标签
+ CVS = "CVS" //cvss 3.0分值标签
+ CVV = "CVV" //cvss 3.1向量标签
+ LD = "LD" //漏洞描述标签
+ IAD = "IAD" //影响分析说明标签
+ PA = "PA" //原理分析标签
+ OES = "OES" //openEuler评分标签
+ OEV = "OEV" //openEuler向量标签
+ IV = "IV" //影响的版本标签
+ CPMM = "CPMM" //规避方案措施
+ IW = "IW" //影响的包
+)
+
+var VectorMap map[string]map[string]string
+var mutex sync.Mutex
+
+func init() {
+ //pattenStr := `/AV:[NL]/AC:[HL]/PR:[NH]/UI:N/S:U/C:[LH]/I:[HN]/A:[LNH]`
+ VectorMap = make(map[string]map[string]string)
+ mAv := make(map[string]string)
+ mAv["N"] = "Network"
+ mAv["L"] = "Local"
+ VectorMap["AV"] = mAv
+ mAc := make(map[string]string)
+ mAc["H"] = "High"
+ mAc["L"] = "Low"
+ VectorMap["AC"] = mAc
+ mPr := make(map[string]string)
+ mPr["H"] = "High"
+ mPr["N"] = "None"
+ VectorMap["PR"] = mPr
+ mUi := make(map[string]string)
+ mUi["N"] = "None"
+ VectorMap["UI"] = mUi
+ mS := make(map[string]string)
+ mS["U"] = "Unchanged"
+ VectorMap["S"] = mS
+ mC := make(map[string]string)
+ mC["H"] = "High"
+ mC["L"] = "Low"
+ VectorMap["C"] = mC
+ mI := make(map[string]string)
+ mI["H"] = "High"
+ mI["N"] = "None"
+ VectorMap["I"] = mC
+ mA := make(map[string]string)
+ mA["H"] = "High"
+ mA["L"] = "Low"
+ mI["N"] = "None"
+ VectorMap["A"] = mA
+}
+
+//ParseCommentContent extract comment content based on tags.
+func ParseCommentContent(content string, label string) (res string, ok bool) {
+ ret := regexp.MustCompile(genCommentRegexpStr(label))
+ sm := ret.FindAllStringSubmatch(content, 1)
+ if len(sm) > 0 {
+ res = sm[0][1]
+ ok = true
+ }
+ return
+}
+
+func ParseCommentVector(content string) string {
+ pattenStr := `/AV:[NL]/AC:[HL]/PR:[NH]/UI:N/S:U/C:[LH]/I:[HN]/A:[LNH]`
+ ret := regexp.MustCompile(pattenStr)
+ sm := ret.Find([]byte(content))
+ return string(sm)
+
+}
+
+func ReadVmValue(kstr string) (value string) {
+ if kstr == "" {
+ return ""
+ }
+ if !strings.Contains(kstr, ":") {
+ return ""
+ }
+ kstr = TrimString(kstr)
+ sKs := strings.Split(kstr, ":")
+ if len(sKs) != 2 {
+ return ""
+ }
+ mutex.Lock()
+ defer mutex.Unlock()
+ if _, ok := VectorMap[sKs[0]]; ok {
+ value = VectorMap[sKs[0]][sKs[1]]
+ }
+ return
+}
+
+func VctToMap(vct string) (vctMap map[string]string, ok bool) {
+ if vct == "" {
+ return nil, false
+ }
+ sp := strings.Split(vct, "/")
+ if len(sp) < 1 {
+ return nil, false
+ }
+ vMap := make(map[string]string)
+ for _, v := range sp {
+ spv := strings.Split(v, ":")
+ if len(spv) != 2 {
+ continue
+ }
+ vMap[spv[0]] = v
+ }
+ if len(vMap) > 0 {
+ return vMap, true
+ } else {
+ return nil, false
+ }
+}
+
+func ParseCommentWithAllLabel(content string) map[string]string {
+ res := make(map[string]string, 0)
+ s, ok := ParseCommentContent(content, IAD)
+ if ok {
+ res["cve_analysis"] = s
+ }
+ s, ok = ParseCommentContent(content, PA)
+ if ok {
+ res["principle_analysis"] = s
+ }
+ s, ok = ParseCommentContent(content, OES)
+ if ok {
+ res["openeuler_score"] = TrimString(s)
+ }
+ s, ok = ParseCommentContent(content, OEV)
+ if ok {
+ vector := ParseCommentVector(s)
+ if vector != "" {
+ res["openeuler_vector"] = s
+ }
+ }
+ s, ok = ParseCommentContent(content, IV)
+ if ok {
+ res["affected_version"] = s
+ }
+ s, ok = ParseCommentContent(content, CPMM)
+ if ok {
+ res["solution"] = s
+ }
+ s,ok =ParseCommentContent(content,IW)
+ if ok {
+ res["issue_package"]=s
+ }
+
+ return res
+}
+
+func genCommentRegexpStr(label string) string {
+ return fmt.Sprintf(`\[%s\](?s:(.*?))\[/%s\]`, label, label)
+}
+
+func TrimString(str string) string {
+ str = strings.Replace(str, " ", "", -1)
+ str = strings.Replace(str, "\n", "", -1)
+ str = strings.Replace(str, "\r", "", -1)
+ return str
+}