diff --git a/common/common.go b/common/common.go index bef2454359c175fd2b7b3e48670105ab0e418b36..415f0c3afac92b743d112bf9e08bd3f1a577a35a 100644 --- a/common/common.go +++ b/common/common.go @@ -75,7 +75,7 @@ func GetSpecifiedTime(startTime time.Time, days int, localFlag bool) string { if !localFlag { h, _ := time.ParseDuration("1h") resTime = getTime.Add(8 * h).Format(DATE_FORMAT) - }else { + } else { resTime = getTime.Format(DATE_FORMAT) // The format of the obtained time } logs.Info("Get the number of days:", days, ",Time:", resTime) diff --git a/conf/app.conf b/conf/app.conf index cf97c74120a6ef75e472326bd79e775751457331..7e520d581fd481a61751ac5a63e27a9721b255a6 100644 --- a/conf/app.conf +++ b/conf/app.conf @@ -50,6 +50,8 @@ maxsize=204800 [crontab] ymalflag = 2 getymal = 0 0 1 * * 1 +eulerymalflag = 1 +eulergetymal = 0 49 16 * * * cveflag = 2 getcve = 0 14 11 * * * oricveflag = 2 @@ -58,6 +60,8 @@ getissueflag = 2 getissue = 0 50 10 * * * issueflag = 2 createissue = 0 18 10 * * * +emergissueflag = 2 +emergcreateissue = 0 */3 * * * * test = 0/10 * * * * * gittokenflag = 2 issueoath = * * */20 * * * @@ -124,6 +128,7 @@ delete_hook = 1 [yaml] apiurl = https://api.openeuler.org/pkgmanage +eulerurl = http://159.138.0.250:8081/v1/versions [cve] cveref = https://nvd.nist.gov/vuln/detail/ @@ -179,8 +184,12 @@ email_host = smtp.gmail.com email_port = 587 [opengauss] -gauss_owner = opengauss -#gauss_owner = cve-gauss +#gauss_owner = opengauss +gauss_owner = cve-gauss # git token git_gauss_token = "${GITEE_GAUSS_TOKEN||xxx}" -gauss_version = 1.1.0,1.0.1,1.0.0 \ No newline at end of file +gauss_version = 1.1.0,1.0.1,1.0.0 +gauss_issue_path = security +sa_init_value = 1001 +pr_repo = "openGauss-server,openGauss-connector-jdbc,openGauss-connector-odbc,openGauss-OM,openGauss-third_party" +nvd_relink = https://nvd.nist.gov/vuln/detail/ \ No newline at end of file diff --git a/conf/product_app.conf b/conf/product_app.conf index cbcf296f449c712a050dabcad86f87d59723c666..be9e42ea86fd98db0bff9dc792a7ba647fc20d89 100644 --- a/conf/product_app.conf +++ b/conf/product_app.conf @@ -50,7 +50,9 @@ maxsize=204800 [crontab] ymalflag = 1 -getymal = 0 0 1 * * * +getymal = 0 40 1 * * * +eulerymalflag = 1 +eulergetymal = 0 0 1 * * * cveflag = 1 getcve = 0 0 3 * * * oricveflag = 1 @@ -59,6 +61,8 @@ getissueflag = 1 getissue = 0 20 1,12 * * * issueflag = 1 createissue = 0 0 6 * * * +emergissueflag = 1 +emergcreateissue = 0 */5 * * * * test = 0/10 * * * * * gittokenflag = 2 issueoath = * * */20 * * * @@ -119,6 +123,7 @@ delete_hook = 2 [yaml] apiurl = https://api.openeuler.org/pkgmanage +eulerurl = http://omapi.osinfra.cn/v1/versions [cve] cveref = https://nvd.nist.gov/vuln/detail/ @@ -133,8 +138,8 @@ cve_number_t = 2018 issue_whitelist = 2 # List of affected branches affected_branchs = openEuler-20.03-LTS,openEuler-20.03-LTS-SP1 -# Close the highest privilege of issue -close_issue_privilege = 1 +# Close the highest privilege of issue:1:open;2:close +close_issue_privilege = 2 # abnormal cve status ,Use "," to separate multiple states abn_cve_status =3 # SA number, The remaining amount @@ -146,6 +151,7 @@ credibility_level = 3 # Date before adding the security bulletin link task sec_link_date = -100 + [reflink] comment_cmd = https://gitee.com/openeuler/cve-manager/blob/master/doc/md/manual.md @@ -176,4 +182,8 @@ email_port = 587 gauss_owner = opengauss # git token git_gauss_token = "${GITEE_GAUSS_TOKEN||xxx}" -gauss_version = 1.1.0,1.0.1,1.0.0 \ No newline at end of file +gauss_version = 1.1.0,1.0.1,1.0.0 +gauss_issue_path = security +sa_init_value = 1001 +pr_repo = "openGauss-server,openGauss-connector-jdbc,openGauss-connector-odbc,openGauss-OM,openGauss-third_party" +nvd_relink = https://nvd.nist.gov/vuln/detail/ diff --git a/controllers/gauss.go b/controllers/gauss.go new file mode 100644 index 0000000000000000000000000000000000000000..7df849363d960b0aba5a6389510ac866522d55a8 --- /dev/null +++ b/controllers/gauss.go @@ -0,0 +1,713 @@ +package controllers + +import ( + "cvevulner/common" + "cvevulner/errcode" + "cvevulner/models" + "cvevulner/taskhandler" + "fmt" + "github.com/astaxie/beego" + "github.com/astaxie/beego/logs" + "os" + "regexp" + "strings" +) + +// openGauss generates a summary of Sa data and provides an api interface for obtaining data +type GenSaController struct { + beego.Controller +} + +// Manually trigger, generate sa data, and then store the data in the database, a total of api calls +//@router / [get] +func (g *GenSaController) TriggerCveData() { + var gi taskhandler.GitInfo + startTime := g.GetString("startTime") + if startTime == "" { + g.Ctx.WriteString("Error: startTime cannot be empty") + return + } + gi.StartTime = startTime + releaseFlag, reErr := g.GetInt("releaseFlag", 1) + if reErr != nil { + g.Ctx.WriteString("Error: releaseFlag cannot be empty") + return + } + // Get configuration information + accessToken := os.Getenv("GITEE_GAUSS_TOKEN") + if accessToken == "" || len(accessToken) < 1 { + logs.Error("TriggerCveData, Issue token acquisition failed, "+ + "current time: ", common.GetCurTime()) + g.Ctx.WriteString("Error: Failed to obtain gauss token") + return + } + gi.Token = accessToken + owner := beego.AppConfig.String("opengauss::gauss_owner") + gi.Owner = owner + // Check if the file is being processed + fileData, fileErr := models.QueryDownloadFile(2) + if len(fileData) > 0 { + logs.Info("There are currently files being processed, "+ + "please finish processing before triggering a new sa generation, file: ", fileData) + g.Ctx.WriteString("processing, There are currently files being processed, " + + "please finish processing before triggering a new sa generation") + return + } + // Query the file to be downloaded + fileData, fileErr = models.QueryDownloadFile(1) + if len(fileData) == 0 { + logs.Error("QueryDownloadFile, err: ", fileErr) + g.Ctx.WriteString("Error: There is currently no downloadable file path") + return + } + // Get file storage path + gaussDir := beego.AppConfig.DefaultString("gaussFileDir", "download/gauss") + common.CreateAllDir(gaussDir) + rt := regexp.MustCompile(`^(\d{4})-\d{2}-(\d{2})$`) + find := rt.Match([]byte(startTime)) + if !find { + g.Ctx.WriteString(`Error: please enter the correct start time in a format like this "yyyy-MM-dd".`) + return + } + // Define global variables to store cve information + cveComponent := taskhandler.CveComponent{} + branchVersion := make([]string, 0) + for _, fp := range fileData { + branchVersion = append(branchVersion, fp.RepoVersion) + } + // Clear unaffected historical data + taskhandler.ClearHisDataSa(1) + // Generate unaffected cve data + if len(branchVersion) > 0 { + taskhandler.GaussUnaffectIssue(branchVersion, gi) + } + // Clear historical data + taskhandler.ClearHisDataSa(2) + saInitValue := int64(0) + // Get sa initialization variable + ogs := models.OpenGaussSiteList{} + qgErr := models.QueryGaussSaMaxValue(&ogs) + if ogs.GaussId == 0 { + logs.Info("QueryGaussSaMaxValue, qgErr: ", qgErr) + saInitValue = beego.AppConfig.DefaultInt64("opengauss::sa_init_value", 1001) + } else { + saInitValue = ogs.SaNum + 1 + } + for _, fExcel := range fileData { + if releaseFlag == 1 { + g.Ctx.WriteString(fmt.Sprintf("start:The SA pre-release generation of openGauss has been triggered. "+ + "Please wait patiently for the completion of the data generation. "+ + "It is estimated that it will take a few minutes.", startTime, fExcel.FilePath)) + } else { + g.Ctx.WriteString(fmt.Sprintf("start:Currently, openGauss SA has been officially released and generated. "+ + "Please wait patiently for the completion of the data generation. "+ + "It is estimated that it will take a few minutes.", startTime, fExcel.FilePath)) + } + models.UpdateDownloadFile(fExcel.FileId, 2) + taskhandler.DownloadFileAndParse(fExcel, startTime, gaussDir, &cveComponent) + models.UpdateDownloadFile(fExcel.FileId, 1) + // Return the result first, continue processing the data + if releaseFlag == 1 { + g.Ctx.WriteString(fmt.Sprintf("Success:The SA pre-release generation of openGauss has been triggered. "+ + "Please wait patiently for the completion of the data generation. "+ + "It is estimated that it will take a few minutes.", startTime, fExcel.FilePath)) + } else { + g.Ctx.WriteString(fmt.Sprintf("Success:Currently, openGauss SA has been officially released and generated. "+ + "Please wait patiently for the completion of the data generation. "+ + "It is estimated that it will take a few minutes.", startTime, fExcel.FilePath)) + } + } + // Merging of multi-branch data + MergMultiBranchData(branchVersion, cveComponent, &saInitValue) + // Upgrade pre-release data to official data + if releaseFlag == 2 { + models.UpdateGaussPreTRelease() + } +} + +func MergMultiBranchData(branchVersion []string, cveComponent taskhandler.CveComponent, saInitValue *int64) { + bVersionSlice := make([]string, 0) + if cveComponent.PackMap != nil && len(cveComponent.PackMap) > 0 { + for k, v := range cveComponent.PackMap { + isEque := true + iFlag := 0 + for i, bv := range branchVersion { + _, ok1 := v.BranchMap[bv] + if ok1 { + iFlag = i + break + } + } + bv1 := v.BranchMap[branchVersion[iFlag]] + if (iFlag + 1) <= (len(branchVersion) - 1) { + for _, branchInfo := range branchVersion[iFlag+1:] { + bv2, ok2 := v.BranchMap[branchInfo] + if ok2 { + if !common.CompareSlice(bv1, bv2) { + isEque = false + break + } + } + + } + } + for _, bv := range branchVersion { + _, ok1 := v.BranchMap[bv] + if ok1 { + addBs := false + for _, vj := range bVersionSlice { + if vj == bv { + addBs = true + break + } + } + if !addBs { + bVersionSlice = append(bVersionSlice, bv) + } + } + } + taskhandler.PreGeneratedSaData(k, bVersionSlice, isEque, saInitValue) + } + } +} + +type GaussSaController struct { + beego.Controller +} + +func (c *GaussSaController) RetSaData(resp map[string]interface{}) { + c.Data["json"] = resp + c.ServeJSON() +} + +type GaussSaData struct { + SaId int64 `json:"saId"` + GaussSaNum string `json:"gaussSaNum"` + Summary string `json:"summary"` + CveLevel string `json:"cveLevel"` + CveLevelValue int `json:"cveLevelValue"` + AffectProduct string `json:"affectProduct"` + InfluenceComponent string `json:"influenceComponent"` + ReleaseDate string `json:"releaseDate"` +} + +// @Get the information of the SA that has been generated +// @Description get gauss sa +// @router / [get] +func (u *GaussSaController) Get() { + req := u.Ctx.Request + addr := req.RemoteAddr + logs.Info("Method: ", req.Method, "Client request ip address: ", addr, + ", Header: ", req.Header, ", body: ", req.Body) + resp := make(map[string]interface{}) + var gs []GaussSaData + resp["code"] = errcode.RecodeNodata + resp["errmsg"] = errcode.RecodeText(errcode.RecodeNodata) + resp["body"] = []GaussSaData{} + resp["totalCount"] = 0 + resp["totalPage"] = 0 + defer u.RetSaData(resp) + cveLevel, cErr := u.GetInt("cveLevel", 0) + if cErr != nil { + cveLevel = 0 + } + years, yErr := u.GetInt("years", 0) + if yErr != nil { + years = 0 + } + releaseFlag, rErr := u.GetInt("releaseFlag", 1) + if rErr != nil { + releaseFlag = 1 + } + searchName := u.GetString("searchName", "") + count := models.QueryGaussSaCount(cveLevel, years, releaseFlag, searchName) + if count > 0 { + resp["totalCount"] = count + resp["code"] = errcode.RecodeOk + resp["errmsg"] = errcode.RecodeText(errcode.RecodeOk) + pageNum, err := u.GetInt("pageNum", 1) + if err != nil { + logs.Error("err: ", err, ", pageNum: ", pageNum) + resp["errno"] = errcode.RecodeParamErr + resp["errmsg"] = errcode.RecodeText(errcode.RecodeParamErr) + return + } + pageSize, err := u.GetInt("pageSize", 100) + if err != nil { + logs.Error("err: ", err, ", pageSize: ", pageSize) + resp["errno"] = errcode.RecodeParamErr + resp["errmsg"] = errcode.RecodeText(errcode.RecodeParamErr) + return + } + if int(count) % pageSize == 0 { + resp["totalPage"] = int(count) / pageSize + } else { + resp["totalPage"] = int(count) / pageSize + 1 + } + saData, saErr := models.QueryOpenGaussSiteList(pageNum, pageSize, cveLevel, years, releaseFlag, searchName) + if len(saData) > 0 { + for _, sa := range saData { + var irda GaussSaData + irda.SaId = sa.GaussId + irda.GaussSaNum = sa.GaussSaNum + irda.Summary = sa.Summary + irda.CveLevel = sa.CveLevel + irda.CveLevelValue = sa.CveLevelValue + irda.InfluenceComponent = sa.InfluenceComponent + if len(sa.CreateTime) > 10 { + irda.ReleaseDate = sa.CreateTime[:10] + } else { + irda.ReleaseDate = sa.CreateTime + } + irda.AffectProduct = sa.AffectProduct + gs = append(gs, irda) + } + resp["body"] = gs + resp["code"] = errcode.RecodeOk + resp["errmsg"] = errcode.RecodeText(errcode.RecodeOk) + } else { + logs.Error("QueryOpenGaussSiteList, saErr: ", saErr) + resp["code"] = errcode.RecodeNodata + resp["errmsg"] = errcode.RecodeText(errcode.RecodeNodata) + return + } + } +} + +type GaussTag struct { + PackageName string `json:"packageName"` + AffectedPlatform []string `json:"affectedPlatform"` +} + +type GaussPackage struct { + GroupName string `json:"groupName"` + GaussTag []GaussTag `json:"tagBody"` +} + +type GaussVersions struct { + Versions string `json:"versions"` + GaussPackage []GaussPackage `json:"packageBody"` +} + +type GaussSaDetailData struct { + GaussSaNum string `json:"gaussSaNum"` + Summary string `json:"summary"` + CveLevel string `json:"cveLevel"` + CveLevelValue int `json:"cveLevelValue"` + AffectProduct string `json:"affectProduct"` + InfluenceComponent string `json:"influenceComponent"` + ReleaseDate string `json:"releaseDate"` + Introduction string `json:"introduction"` + Theme string `json:"theme"` + Description string `json:"description"` + CveNumbers string `json:"cveNumbers"` + ReferenceLink string `json:"referenceLink"` + GaussVersions []GaussVersions `json:"versionsBody"` +} + +type GaussSaDetailController struct { + beego.Controller +} + +func (c *GaussSaDetailController) RetSaDetailData(resp map[string]interface{}) { + c.Data["json"] = resp + c.ServeJSON() +} + +// @Title Get GaussSaDetailController +// @Description get sa detail +// @router / [get] +func (u *GaussSaDetailController) Get() { + req := u.Ctx.Request + addr := req.RemoteAddr + logs.Info("Method: ", req.Method, "Client request ip address: ", addr, + ", Header: ", req.Header, ", body: ", req.Body) + resp := make(map[string]interface{}) + var ird GaussSaDetailData + resp["errno"] = errcode.RecodeUnknowErr + resp["errmsg"] = errcode.RecodeText(errcode.RecodeUnknowErr) + resp["body"] = GaussSaDetailData{} + defer u.RetSaDetailData(resp) + gaussSaNum := u.GetString("gaussSaNum", "") + if gaussSaNum == "" { + resp["errno"] = errcode.RecodeParamErr + resp["errmsg"] = errcode.RecodeText(errcode.RecodeParamErr) + return + } + osl := models.OpenGaussSiteList{GaussSaNum: gaussSaNum} + oslErr := models.QueryOpenGaussSaByNum(&osl, "GaussSaNum") + if osl.GaussId > 0 { + CreateSaDetailData(&ird, osl) + resp["body"] = ird + resp["errno"] = errcode.RecodeOk + resp["errmsg"] = errcode.RecodeText(errcode.RecodeOk) + } else { + logs.Error("QueryOpenGaussSaByNum, oslErr: ", oslErr) + resp["errno"] = errcode.RecodeNodata + resp["errmsg"] = errcode.RecodeText(errcode.RecodeNodata) + return + } +} + +func CreateSaDetailData(ird *GaussSaDetailData, osl models.OpenGaussSiteList) { + nvdRelink := beego.AppConfig.String("opengauss::nvd_relink") + ird.GaussSaNum = osl.GaussSaNum + ird.AffectProduct = osl.AffectProduct + ird.Summary = osl.Summary + ird.Introduction = osl.Introduction + ird.CveLevel = osl.CveLevel + ird.CveLevelValue = osl.CveLevelValue + ird.InfluenceComponent = osl.InfluenceComponent + if len(osl.CreateTime) > 10 { + ird.ReleaseDate = osl.CreateTime[:10] + } else { + ird.ReleaseDate = osl.CreateTime + } + ird.Theme = osl.Theme + ird.Description = osl.Description + ird.Description = strings.ReplaceAll(ird.Description, "\n\n", "
") + ird.CveNumbers = osl.CveNums + cveLinkSlice := make([]string, 0) + if len(osl.CveNums) > 1 { + cveNumSlice := strings.Split(osl.CveNums, ";") + if len(cveNumSlice) > 0 { + for _, cve := range cveNumSlice { + cveLinkSlice = append(cveLinkSlice, nvdRelink+cve) + } + } + } + if len(cveLinkSlice) > 0 { + ird.ReferenceLink = strings.Join(cveLinkSlice, ";") + } + gv := make([]GaussVersions, 0) + // Query the associated version information + if len(osl.AffectProduct) > 0 { + affectSlice := strings.Split(osl.AffectProduct, "/") + if len(affectSlice) > 0 { + for _, affect := range affectSlice { + var lgv GaussVersions + lgv.Versions = affect + ogp, pErr := models.QueryGaussPackageByGid(osl.GaussId, affect) + if len(ogp) > 0 { + groupMap := make(map[int64]map[string][]int64) + for _, gp := range ogp { + groupV, ok := groupMap[gp.GroupId] + if !ok { + platMap := make(map[string][]int64) + paltSlice := make([]int64, 0) + paltSlice = append(paltSlice, gp.PlatId) + platMap[gp.RpmName] = paltSlice + groupMap[gp.GroupId] = platMap + } else { + platV, ok := groupV[gp.RpmName] + if !ok { + paltSlice := make([]int64, 0) + paltSlice = append(paltSlice, gp.PlatId) + groupV[gp.RpmName] = paltSlice + } else { + vIsExit := false + for _, pv := range platV { + if pv == gp.PlatId { + vIsExit = true + break + } + } + if !vIsExit { + platV = append(platV, gp.PlatId) + groupV[gp.RpmName] = platV + } + } + } + } + if len(groupMap) > 0 { + gp := make([]GaussPackage, 0) + for kg, vg := range groupMap { + ogg := models.OpenGaussGroup{GroupId: kg} + gErr := models.QueryOpenGaussGroup(&ogg, "GroupId") + if gErr == nil { + var ge GaussPackage + ge.GroupName = ogg.GroupName + tag := make([]GaussTag, 0) + for pgk, pgv := range vg { + var tagv GaussTag + tagv.PackageName = pgk + ogl, opErr := models.QueryGaussPlatByPids(pgv) + if len(ogl) > 0 { + plSlice := make([]string, 0) + for _, pl := range ogl { + plSlice = append(plSlice, pl.PlatName) + } + tagv.AffectedPlatform = plSlice + } else { + logs.Error("QueryGaussPlatByPids, opErr: ", opErr) + } + tag = append(tag, tagv) + } + ge.GaussTag = tag + gp = append(gp, ge) + } + } + lgv.GaussPackage = gp + } + } else { + logs.Error("QueryGaussPackageByGid, pErr: ", pErr) + } + gv = append(gv, lgv) + } + } + } + ird.GaussVersions = gv +} + +type GaussCveController struct { + beego.Controller +} + +func (c *GaussCveController) RetGaussCveData(resp map[string]interface{}) { + c.Data["json"] = resp + c.ServeJSON() +} + +type GaussCveData struct { + CveId int64 `json:"cveId"` + CveNum string `json:"cveNum"` + Description string `json:"description"` + NvdScore float64 `json:"NVDScore"` + UpdateTime string `json:"updateTime"` + ReleaseDate string `json:"releaseDate"` +} + +// @Get the cve information of gauss +// @Description get gauss cve +// @router / [get] +func (u *GaussCveController) Get() { + req := u.Ctx.Request + addr := req.RemoteAddr + logs.Info("Method: ", req.Method, "Client request ip address: ", addr, + ", Header: ", req.Header, ", body: ", req.Body) + resp := make(map[string]interface{}) + var gs []GaussCveData + resp["code"] = errcode.RecodeNodata + resp["errmsg"] = errcode.RecodeText(errcode.RecodeNodata) + resp["body"] = []GaussCveData{} + resp["totalCount"] = 0 + resp["totalPage"] = 0 + defer u.RetGaussCveData(resp) + releaseFlag, rErr := u.GetInt("releaseFlag", 1) + if rErr != nil { + releaseFlag = 1 + } + isAffectFlag, rErr := u.GetInt("isAffectFlag", 1) + if rErr != nil { + isAffectFlag = 1 + } + searchName := u.GetString("searchName", "") + count := models.QueryGaussCveCount(releaseFlag, isAffectFlag, searchName) + if count > 0 { + resp["totalCount"] = count + resp["code"] = errcode.RecodeOk + resp["errmsg"] = errcode.RecodeText(errcode.RecodeOk) + pageNum, err := u.GetInt("pageNum", 1) + if err != nil { + logs.Error("err: ", err, ", pageNum: ", pageNum) + resp["errno"] = errcode.RecodeParamErr + resp["errmsg"] = errcode.RecodeText(errcode.RecodeParamErr) + return + } + pageSize, err := u.GetInt("pageSize", 100) + if err != nil { + logs.Error("err: ", err, ", pageSize: ", pageSize) + resp["errno"] = errcode.RecodeParamErr + resp["errmsg"] = errcode.RecodeText(errcode.RecodeParamErr) + return + } + if int(count) % pageSize == 0 { + resp["totalPage"] = int(count) / pageSize + } else { + resp["totalPage"] = int(count) / pageSize + 1 + } + saData, saErr := models.QueryOpenGaussCveList(pageNum, pageSize, releaseFlag, isAffectFlag, searchName) + if len(saData) > 0 { + for _, sa := range saData { + var irda GaussCveData + irda.CveId = sa.Id + irda.CveNum = sa.CveNum + irda.Description = sa.Description + irda.NvdScore = sa.NVDScore + irda.UpdateTime = sa.UpdateTime + if len(sa.CreateTime) > 10 { + irda.ReleaseDate = sa.CreateTime[:10] + } else { + irda.ReleaseDate = sa.CreateTime + } + gs = append(gs, irda) + } + resp["body"] = gs + resp["code"] = errcode.RecodeOk + resp["errmsg"] = errcode.RecodeText(errcode.RecodeOk) + } else { + logs.Error("QueryOpenGaussCveList, saErr: ", saErr) + resp["code"] = errcode.RecodeNodata + resp["errmsg"] = errcode.RecodeText(errcode.RecodeNodata) + return + } + } +} + +type GaussCveAffectProduct struct { + AffectProduct string `json:"affectProduct"` + PackName string `json:"packName"` + FixLabel string `json:"fixLabel"` +} + +type GaussCveSa struct { + GaussSaNum string `json:"gaussSaNum"` + SaId int64 `json:"saId"` + Summary string `json:"summary"` + ReleaseDate string `json:"releaseDate"` +} + +type GaussCveCvssV3 struct { + NvdScore float64 `json:"NVDScore"` + OpenGaussScore float64 `json:"openGaussScore"` + NAttackVector string `json:"nAttackVector"` + OAttackVector string `json:"oAttackVector"` + NAttackComplexity string `json:"nAttackComplexity"` + OAttackComplexity string `json:"oAttackComplexity"` + NPrivilegeRequired string `json:"nPrivilegeRequired"` + OPrivilegeRequired string `json:"oPrivilegeRequired"` + NUserInteraction string `json:"nUserInteraction"` + OUserInteraction string `json:"oUserInteraction"` + NScope string `json:"nScope"` + OScope string `json:"oScope"` + NConfidentiality string `json:"nConfidentiality"` + OConfidentiality string `json:"oConfidentiality"` + NIntegrity string `json:"nIntegrity"` + OIntegrity string `json:"oIntegrity"` + NAvailability string `json:"nAvailability"` + OAvailability string `json:"oAvailability"` + ScoreType string `json:"scoreType"` +} + +type GaussCveDetailData struct { + CveId int64 `json:"cveId"` + CveNum string `json:"cveNum"` + Description string `json:"description"` + NvdScore float64 `json:"NVDScore"` + UpdateTime string `json:"updateTime"` + ReleaseDate string `json:"releaseDate"` + CVSSV3 GaussCveCvssV3 `json:"CVSSV3"` + SaBody GaussCveSa `json:"saBody"` + AffectBody []GaussCveAffectProduct `json:"affectBody"` +} + +type GaussCveDetailController struct { + beego.Controller +} + +func (c *GaussCveDetailController) RetCveDetailData(resp map[string]interface{}) { + c.Data["json"] = resp + c.ServeJSON() +} + +// @Title Get GaussSaDetailController +// @Description get sa detail +// @router / [get] +func (u *GaussCveDetailController) Get() { + req := u.Ctx.Request + addr := req.RemoteAddr + logs.Info("Method: ", req.Method, "Client request ip address: ", addr, + ", Header: ", req.Header, ", body: ", req.Body) + resp := make(map[string]interface{}) + var ird GaussCveDetailData + resp["errno"] = errcode.RecodeUnknowErr + resp["errmsg"] = errcode.RecodeText(errcode.RecodeUnknowErr) + resp["body"] = GaussCveDetailData{} + defer u.RetCveDetailData(resp) + cveNum := u.GetString("cveNum", "") + if cveNum == "" { + resp["errno"] = errcode.RecodeParamErr + resp["errmsg"] = errcode.RecodeText(errcode.RecodeParamErr) + return + } + osl := models.OpenGaussCveList{CveNum: cveNum} + oslErr := models.QueryOpenGaussCveByNum(&osl, "CveNum") + if osl.Id > 0 { + CreateCveDetailData(&ird, osl) + resp["body"] = ird + resp["errno"] = errcode.RecodeOk + resp["errmsg"] = errcode.RecodeText(errcode.RecodeOk) + } else { + logs.Error("QueryOpenGaussCveByNum, oslErr: ", oslErr) + resp["errno"] = errcode.RecodeNodata + resp["errmsg"] = errcode.RecodeText(errcode.RecodeNodata) + return + } +} + +func CreateCveDetailData(gdd *GaussCveDetailData, ocl models.OpenGaussCveList) { + gdd.CveId = ocl.Id + gdd.CveNum = ocl.CveNum + gdd.Description = ocl.Description + gdd.Description = strings.ReplaceAll(gdd.Description, "\n\n", "
") + gdd.NvdScore = ocl.NVDScore + gdd.UpdateTime = ocl.UpdateTime + if len(ocl.CreateTime) > 10 { + gdd.ReleaseDate = ocl.CreateTime[:10] + } else { + gdd.ReleaseDate = ocl.CreateTime + } + var gcv GaussCveCvssV3 + gcv.NvdScore = ocl.NVDScore + gcv.OpenGaussScore = ocl.OpenEulerScore + gcv.NAttackVector = ocl.NattackVector + gcv.OAttackVector = ocl.OattackVector + gcv.NAttackComplexity = ocl.NattackComplexity + gcv.OAttackComplexity = ocl.OattackComplexity + gcv.NPrivilegeRequired = ocl.NprivilegeRequired + gcv.OPrivilegeRequired = ocl.OprivilegeRequired + gcv.NUserInteraction = ocl.NuserInteraction + gcv.OUserInteraction = ocl.OuserInteraction + gcv.NScope = ocl.Nscope + gcv.OScope = ocl.Oscope + gcv.NConfidentiality = ocl.Nconfidentiality + gcv.OConfidentiality = ocl.Oconfidentiality + gcv.NIntegrity = ocl.Nintegrity + gcv.OIntegrity = ocl.Ointegrity + gcv.NAvailability = ocl.Navailability + gcv.OAvailability = ocl.Oavailability + gcv.ScoreType = ocl.ScoreType + gdd.CVSSV3 = gcv + if ocl.GaussId > 0 { + ost := models.OpenGaussSiteList{GaussId: ocl.GaussId} + ostErr := models.QueryOpenGaussSaByNum(&ost, "GaussId") + if ostErr == nil { + var gs GaussCveSa + gs.SaId = ost.GaussId + gs.Summary = ost.Summary + gs.GaussSaNum = ost.GaussSaNum + if len(ost.CreateTime) > 10 { + gs.ReleaseDate = ost.CreateTime[:10] + } else { + gs.ReleaseDate = ost.CreateTime + } + gdd.SaBody = gs + } + } else { + gdd.SaBody = GaussCveSa{} + } + ogv, ogvErr := models.QueryGaussVersionByCid(gdd.CveId) + if len(ogv) > 0 { + gcp := make([]GaussCveAffectProduct, 0) + for _, gv := range ogv { + var gp GaussCveAffectProduct + gp.AffectProduct = gv.RepoVersion + gp.PackName = ocl.PackName + gp.FixLabel = gv.AffectStatusName + gcp = append(gcp, gp) + } + gdd.AffectBody = gcp + } else { + logs.Error("QueryGaussVersionByCid, ogvErr: ", ogvErr) + } +} diff --git a/controllers/hook.go b/controllers/hook.go index d1af141dc3892470f52a2c54984a316c416c65a2..cfb935337c9d8fe4563439bcb9f05c4b6f1e6579 100644 --- a/controllers/hook.go +++ b/controllers/hook.go @@ -121,7 +121,11 @@ func (c *HookEventControllers) isLegitimateHookEvent() (ok bool) { } //judge hook password xToken := c.Ctx.Request.Header.Get(XGiteeToken) - logs.Info(xToken) + //logs.Info(xToken) + hookPwd := beego.AppConfig.String("hook::hookpwd") + if xToken != hookPwd { + logs.Error("hookPwd Err, xToken: ", xToken) + } return } @@ -170,6 +174,7 @@ func (c *HookEventControllers) handleIssue() { err := models.GetIssueTemplateByColName(&issueTmp, "issue_num", "issue_id") if err != nil { logs.Error(err) + return } issueTmp.Assignee = issueHook.Assignee.Login err = models.UpdateIssueTemplate(&issueTmp, "issue_assignee") @@ -182,18 +187,27 @@ func (c *HookEventControllers) handleIssue() { err = handleIssueStateChange(&issueHook) if err != nil { logs.Error(err) + return } } if issueHook.Action == "open" { + issueTmp := models.IssueTemplate{IssueNum: issueHook.Iid, IssueId: issueHook.Issue.Id} + err := models.GetIssueTemplateByColName(&issueTmp, "issue_num", "issue_id") + if err == nil { + logs.Error(err) + return + } err = gitAddIssueProc(&issueHook) if err != nil { logs.Error(err) + return } } if issueHook.Action == "delete" { err = gitDelIssueProc(&issueHook) if err != nil { logs.Error(err) + return } } } @@ -415,13 +429,14 @@ func handleIssueStateChange(issueHook *models.IssuePayload) error { unFix := beego.AppConfig.String("labelUnFix") fixed := beego.AppConfig.String("labelFixed") uNaffected := beego.AppConfig.String("labeUnaffected") + gaussIssuePath := beego.AppConfig.String("opengauss::gauss_issue_path") issueId := issueHook.Issue.Id issueTmp := models.IssueTemplate{} issueTmp.IssueId = issueId issueTmp.IssueNum = issueHook.Iid if issueHook.Issue.Repository.Path != "" && len(issueHook.Issue.Repository.Path) > 1 && - issueHook.Issue.Repository.Path != "security" { + issueHook.Issue.Repository.Path != gaussIssuePath { issueTmp.OwnedComponent = issueHook.Issue.Repository.Path issueErr := models.GetIssueTemplateByColName(&issueTmp, "issue_num", "owned_component", "issue_id") if issueErr != nil { @@ -446,7 +461,8 @@ func handleIssueStateChange(issueHook *models.IssuePayload) error { if cveCenter.OrganizationID == 2 { owner = gaussOwner token = gitGaussToken - path = "security" + gaussIssuePath := beego.AppConfig.String("opengauss::gauss_issue_path") + path = gaussIssuePath } issueTmp.StatusName = issueHook.Issue.StateName logs.Info("Initiating issue status modification, sponsor: @", issueHook.Sender.UserName, ", Modify status: ", @@ -795,6 +811,7 @@ func getRepoIssueAllPR(affectBranch, token, owner, repo string, isTemp models.Is logs.Error("Unmarshal, url: ", url, ",err: ", err) return } + logs.Info("issuePr: ", issuePr) for _, v := range issuePr { if _, ok := v["id"]; !ok { continue @@ -908,7 +925,8 @@ func updateTempAndCenter(issueTmp models.IssueTemplate, cveCenter models.VulnCen } path := "" if cveCenter.OrganizationID == 2 { - path = "security" + gaussIssuePath := beego.AppConfig.String("opengauss::gauss_issue_path") + path = gaussIssuePath if issueTmp.Status == 3 { issueTmp.IssueLabel = labelFixed } else { @@ -989,7 +1007,8 @@ func gaussMaintainerApprove(issueTmp *models.IssueTemplate, cuAccount, owner, to issueTmp.IssueStatus = 6 cveCenter.IsExport = 2 } - issueTmp.Repo = "security" + gaussIssuePath := beego.AppConfig.String("opengauss::gauss_issue_path") + issueTmp.Repo = gaussIssuePath updateBool := updateTempAndCenter(*issueTmp, cveCenter, token, owner) if !updateBool { return @@ -1143,7 +1162,8 @@ func handleIssueComment(payload models.CommentPayload) { if vcErr == nil && vc.OrganizationID == 2 { owner = gaussOwner accessToken = gitGaussToken - path = "security" + gaussIssuePath := beego.AppConfig.String("opengauss::gauss_issue_path") + path = gaussIssuePath cBody = strings.ReplaceAll(cBody, util.KwOpenGaussScore, util.KwOpenEulerScore) } @@ -2181,6 +2201,7 @@ func gitAddIssueProc(issueHook *models.IssuePayload) error { logs.Error("cve::openeulernum, err:", err) return ok } + // Determine whether the issue has been created product, err := taskhandler.GetInfProduct(token, owner, path) if err != nil { logs.Error("GetInfProduct, err: ", err) diff --git a/controllers/upload.go b/controllers/upload.go index 220a0983c63c9a05288ff41ef9ba880baca0dbfd..46053e3b0bebdc4f29344a849084bb2b8ed637b5 100644 --- a/controllers/upload.go +++ b/controllers/upload.go @@ -23,6 +23,13 @@ type ResultData struct { func (c *UserUploadController) RetData(resp map[string]interface{}) { c.Data["json"] = resp c.ServeJSON() + // sysnc cve and create issue + synErr := task.SyncCveAndIssue() + if synErr != nil { + logs.Error("SyncCveAndIssue, Sync cve data error, err: ", synErr) + } else { + logs.Info("SyncCveAndIssue, cve data has been synchronized") + } } func (c *CveErrorFeedBackController) RetData(resp map[string]interface{}) { @@ -315,15 +322,6 @@ func (u *UserUploadController) Post() { ResData.CveNum = CveDataDict.Ids ResData.Status = 0 ResDataList = append(ResDataList, ResData) - // sysnc cve and create issue - if orCve.Status == 0 || orCve.Status == 1 { - synErr := task.SyncCveAndIssue() - if synErr != nil { - logs.Error("SyncCveAndIssue, Sync cve data error, err: ", synErr) - } else { - logs.Info("SyncCveAndIssue, cve data has been synchronized") - } - } } else { logs.Info("cve creation failed CveNum: ", CveDataDict.Ids) ResData.CveNum = CveDataDict.Ids diff --git a/cve-py/controller/taskcontroller.py b/cve-py/controller/taskcontroller.py index 3e5959b40bac6b272761b8d81bc9e782798ca336..f279129d2ea24cc4401bbfd8004a974f643ca9b3 100644 --- a/cve-py/controller/taskcontroller.py +++ b/cve-py/controller/taskcontroller.py @@ -52,7 +52,7 @@ def runtabletask(): spec_error_task.add_error_details() runtask.handle_data() repeattask.repeat_task() - repeattask.get_published_date_task() + # repeattask.get_published_date_task() print("Analyze the manual data table, " "crawl the CVE official website data task completed") @@ -159,3 +159,14 @@ def supplement_cve_task(): print("Supplemental cve information task starts") supplement_cve.supplement_cve() print("Supplement cve information task is over") + + +def long_supplement_cve_task(): + """ + Complete the template information of the + issue with the data on the CVE official website + return None + """ + print("long Supplemental cve information task starts") + supplement_cve.long_supplement_cve() + print("long Supplement cve information task is over") diff --git a/cve-py/controller/timertaskcontroller.py b/cve-py/controller/timertaskcontroller.py index d991eaaab802d4324792c7c345c71877b5a56728..b21b73e4aef264de2c92864ae23c13400fb7a608 100644 --- a/cve-py/controller/timertaskcontroller.py +++ b/cve-py/controller/timertaskcontroller.py @@ -46,7 +46,8 @@ def timertask(): # Parse the issue statistics recipient list scheduler.add_job(taskcontroller.issue_statistics_email_task, 'cron', day_of_week='0-6', hour=5, minute=30) # Complete the template information of the issue with the data on the CVE official website - scheduler.add_job(taskcontroller.supplement_cve_task, 'cron', day_of_week='0-6', hour=1, minute=30) + scheduler.add_job(taskcontroller.supplement_cve_task, 'interval', minutes=3) + scheduler.add_job(taskcontroller.long_supplement_cve_task, 'cron', day_of_week='0-6', hour=1, minute=30) scheduler.start() except SystemExit as err: print("Err:", err) diff --git a/cve-py/tabletask/crawltask.py b/cve-py/tabletask/crawltask.py index c289f1136c2ecf236a324a1cbb56e60c2aa21849..f546cb9cf73227836689f9f08f91c880b9bb2d77 100644 --- a/cve-py/tabletask/crawltask.py +++ b/cve-py/tabletask/crawltask.py @@ -25,6 +25,9 @@ def crawling(url): :return xpth_list: list """ xpth_list = [] + if url is None or url == "" or url.find("http") == -1: + print("crawling, url:", url) + return try: content = requests.get(url).content except requests.exceptions.ConnectionError: @@ -36,89 +39,159 @@ def crawling(url): if content and len(content) > 1: html = etree.HTML(content) try: - if html.xpath( - '/html/body/div[2]/div[2]/div/table/tr/td/div/div[1]/div[3]/div[2]/div[1]' - '/div[2]/span/span/a/text()') == [ - "N/A"] or \ - html.xpath( - '/html/body/div[2]/div[2]/div/table/tr/td/div/div[1]/div[2]/div[2]/div[1]' - '/div[2]/span/span/a/text()') == [ - "N/A"] or \ - html.xpath( - '/html/body/div[2]/div[2]/div[2]/table/tr/td/div/div[1]/div[4]/div[2]/div[1]/div[2]' - '/span/span/a/text()') == ['N/A']: - if html.xpath( - "/html/body/div[2]/div[2]/div/table/tr/td/div/div[1]/div[2]/div[3]/div[1]/div[2]" - "/span/span/a/text()") == [ - "N/A"] or \ - html.xpath( - "/html/body/div[2]/div[2]/div/table/tbody/tr/td/div/div[1]/div[2]/div[2]/div[1]" - "/div[2]/span/span/a/text()") == ["N/A"]: - nvd_score = cve_level = cve_desc = repair_time = vector_value = attack_vector = \ - access_vector = attack_complexity = access_complexity = \ - privilege_required = user_interaction = scope = confidentiality = \ - integrity = availability = authentication = None - print("No data on this vulnerability link, ", url) - score_type = "" - cve_desc = str(html.xpath('//*[@id="vulnDetailTableView"]/tr/td/div/div[1]/p[1]/text()')[0]) - if cve_desc: - score_type = "v3.0" - else: - score_type = "v2.0" - element = html.xpath('//*[@id="nistV2MetricHidden"]/@value') - cve_desc = str(html.xpath('//*[@id="vulnDetailTableView"]/tr/td/div/div[1]/p[1]/text()')[0]) - repair_time = str( - html.xpath('//*[@id="vulnDetailTableView"]/tr/td/div/div[2]/div/span[1]/text()')[0]) - repair_time = datetime.strptime(repair_time, '%m/%d/%Y') - html1 = etree.HTML(element[0]) - cve_level = str(html1.xpath('//*[@data-testid="vuln-cvssv2-base-score-severity"]/text()') - [0].strip()).capitalize() - nvd_score = str(html1.xpath('//*[@data-testid="vuln-cvssv2-base-score"]/text()')[0].strip()) - vector_value = str(html1.xpath('//*[@data-testid="vuln-cvssv2-vector"]/text()')[0]). \ - replace("(", "").replace(")", "").strip() - access_vector = str(html1.xpath('//*[@data-testid="vuln-cvssv2-av"]/text()')[0].strip()) - access_complexity = str(html1.xpath('//*[@data-testid="vuln-cvssv2-ac"]/text()')[0].strip()) - authentication = str(html1.xpath('//*[@data-testid="vuln-cvssv2-au"]/text()')[0].strip()) - confidentiality = str(html1.xpath('//*[@data-testid="vuln-cvssv3-c"]/text()')[0].strip()) - integrity = str(html1.xpath('//*[@data-testid="vuln-cvssv2-i"]/text()')[0].strip()) - availability = str(html1.xpath('//*[@data-testid="vuln-cvssv2-a"]/text()')[0].strip()) - attack_vector = attack_complexity = privilege_required = user_interaction = scope = None - elif html.xpath( - '/html/body/div[2]/div[2]/div/table/tr/td/div/div[1]/div[3]/div[2]/div[1]/div[2]' - '/span/span/a/text()') == [] and \ - html.xpath( - '/html/body/div[2]/div[2]/div/table/tr/td/div/div[1]/div[2]/div[2]/div[1]' - '/div[2]/span/span/a/text()') == []: - nvd_score = cve_level = cve_desc = repair_time = vector_value = attack_vector = \ - access_vector = attack_complexity = access_complexity = \ - privilege_required = user_interaction = scope = confidentiality = integrity = \ - availability = authentication = None - score_type = "v3.0" - print("This vulnerability link not found, ", url) + # if html.xpath( + # '/html/body/div[2]/div[2]/div/table/tr/td/div/div[1]/div[3]/div[2]/div[1]' + # '/div[2]/span/span/a/text()') == [ + # "N/A"] or \ + # html.xpath( + # '/html/body/div[2]/div[2]/div/table/tr/td/div/div[1]/div[2]/div[2]/div[1]' + # '/div[2]/span/span/a/text()') == [ + # "N/A"] or \ + # html.xpath( + # '/html/body/div[2]/div[2]/div[2]/table/tr/td/div/div[1]/div[4]/div[2]/div[1]/div[2]' + # '/span/span/a/text()') == ['N/A']: + # if html.xpath( + # "/html/body/div[2]/div[2]/div/table/tr/td/div/div[1]/div[2]/div[3]/div[1]/div[2]" + # "/span/span/a/text()") == [ + # "N/A"] or \ + # html.xpath( + # "/html/body/div[2]/div[2]/div/table/tbody/tr/td/div/div[1]/div[2]/div[2]/div[1]" + # "/div[2]/span/span/a/text()") == ["N/A"]: + # nvd_score = cve_level = cve_desc = repair_time = vector_value = attack_vector = \ + # access_vector = attack_complexity = access_complexity = \ + # privilege_required = user_interaction = scope = confidentiality = \ + # integrity = availability = authentication = None + # print("No data on this vulnerability link, ", url) + # score_type = "" + # cve_desc = str(html.xpath('//*[@id="vulnDetailTableView"]/tr/td/div/div[1]/p[1]/text()')[0]) + # if cve_desc: + # score_type = "v3.0" + # else: + # score_type = "v2.0" + # element = html.xpath('//*[@id="nistV2MetricHidden"]/@value') + # cve_desc = str(html.xpath('//*[@id="vulnDetailTableView"]/tr/td/div/div[1]/p[1]/text()')[0]) + # repair_time = str( + # html.xpath('//*[@id="vulnDetailTableView"]/tr/td/div/div[2]/div/span[1]/text()')[0]) + # if repair_time is not None: + # repair_time = datetime.strptime(repair_time, '%m/%d/%Y') + # html1 = etree.HTML(element[0]) + # cve_level = str(html1.xpath('//*[@data-testid="vuln-cvssv2-base-score-severity"]/text()') + # [0].strip()).capitalize() + # nvd_score = str(html1.xpath('//*[@data-testid="vuln-cvssv2-base-score"]/text()')[0].strip()) + # vector_value = str(html1.xpath('//*[@data-testid="vuln-cvssv2-vector"]/text()')[0]). \ + # replace("(", "").replace(")", "").strip() + # access_vector = str(html1.xpath('//*[@data-testid="vuln-cvssv2-av"]/text()')[0].strip()) + # access_complexity = str(html1.xpath('//*[@data-testid="vuln-cvssv2-ac"]/text()')[0].strip()) + # authentication = str(html1.xpath('//*[@data-testid="vuln-cvssv2-au"]/text()')[0].strip()) + # confidentiality = str(html1.xpath('//*[@data-testid="vuln-cvssv3-c"]/text()')[0].strip()) + # integrity = str(html1.xpath('//*[@data-testid="vuln-cvssv2-i"]/text()')[0].strip()) + # availability = str(html1.xpath('//*[@data-testid="vuln-cvssv2-a"]/text()')[0].strip()) + # attack_vector = attack_complexity = privilege_required = user_interaction = scope = None + # elif html.xpath( + # '/html/body/div[2]/div[2]/div/table/tr/td/div/div[1]/div[3]/div[2]/div[1]/div[2]' + # '/span/span/a/text()') == [] and \ + # html.xpath( + # '/html/body/div[2]/div[2]/div/table/tr/td/div/div[1]/div[2]/div[2]/div[1]' + # '/div[2]/span/span/a/text()') == []: + # nvd_score = cve_level = cve_desc = repair_time = vector_value = attack_vector = \ + # access_vector = attack_complexity = access_complexity = \ + # privilege_required = user_interaction = scope = confidentiality = integrity = \ + # availability = authentication = None + # score_type = "v3.0" + # print("This vulnerability link not found, ", url) + # else: + # score_type = "v3.0" + # cve_desc = str(html.xpath('//*[@id="vulnDetailTableView"]/tr/td/div/div[1]/p[1]/text()')[0]) + # repair_time = html.xpath('//*[@id="vulnDetailTableView"]/tr/td/div/div[2]/div/span[1]/text()')[0] + # if repair_time is not None: + # repair_time = datetime.strptime(repair_time, '%m/%d/%Y') + # if html.xpath('//*[@id="nistV3MetricHidden"]/@value'): + # element = html.xpath('//*[@id="nistV3MetricHidden"]/@value') + # else: + # element = html.xpath('//*[@id="cnaV3MetricHidden"]/@value') + # html1 = etree.HTML(element[0]) + # cve_level = str(html1.xpath('//*[@data-testid="vuln-cvssv3-base-score-severity"]/text()')[0] + # .strip()).capitalize() + # nvd_score = str(html1.xpath('//*[@data-testid="vuln-cvssv3-base-score"]/text()')[0].strip()) + # vector_value = str(html1.xpath('//*[@data-testid="vuln-cvssv3-vector"]/text()')[0]).replace("(", ''). \ + # replace(')', '').strip() + # attack_vector = str(html1.xpath('//*[@data-testid="vuln-cvssv3-av"]/text()')[0].strip()) + # attack_complexity = str(html1.xpath('//*[@data-testid="vuln-cvssv3-ac"]/text()')[0].strip()) + # privilege_required = str(html1.xpath('//*[@data-testid="vuln-cvssv3-pr"]/text()')[0].strip()) + # user_interaction = str(html1.xpath('//*[@data-testid="vuln-cvssv3-ui"]/text()')[0].strip()) + # scope = str(html1.xpath('//*[@data-testid="vuln-cvssv3-s"]/text()')[0].strip()) + # confidentiality = str(html1.xpath('//*[@data-testid="vuln-cvssv3-c"]/text()')[0].strip()) + # integrity = str(html1.xpath('//*[@data-testid="vuln-cvssv3-i"]/text()')[0].strip()) + # availability = str(html1.xpath('//*[@data-testid="vuln-cvssv3-a"]/text()')[0].strip()) + # access_vector = access_complexity = authentication = None + nvd_score = cve_level = cve_desc = repair_time = vector_value = attack_vector = \ + access_vector = attack_complexity = access_complexity = \ + privilege_required = user_interaction = scope = confidentiality = integrity = \ + availability = authentication = None + cve_descx = html.xpath('//*[@id="vulnDetailTableView"]/tr/td/div/div[1]/p[1]/text()') + if cve_descx is not None and len(cve_descx) > 0: + cve_desc = str(cve_descx[0]) + # repair_timex = html.xpath('//*[@id="vulnDetailTableView"]/tr/td/div/div[2]/div/span[1]/text()') + repair_timex = html.xpath('//*[@data-testid="vuln-published-on"]/text()') + if repair_timex is not None and len(repair_timex) > 0: + repair_time = str(repair_timex[0]) + if repair_time is not None and repair_time != "": + repair_time = str(datetime.strptime(repair_time, '%m/%d/%Y')) + score_type = "v3.0" + if html.xpath('//*[@id="nistV3MetricHidden"]/@value'): + element = html.xpath('//*[@id="nistV3MetricHidden"]/@value') else: - score_type = "v3.0" - cve_desc = str(html.xpath('//*[@id="vulnDetailTableView"]/tr/td/div/div[1]/p[1]/text()')[0]) - repair_time = html.xpath('//*[@id="vulnDetailTableView"]/tr/td/div/div[2]/div/span[1]/text()')[0] - repair_time = datetime.strptime(repair_time, '%m/%d/%Y') - if html.xpath('//*[@id="nistV3MetricHidden"]/@value'): - element = html.xpath('//*[@id="nistV3MetricHidden"]/@value') - else: - element = html.xpath('//*[@id="cnaV3MetricHidden"]/@value') + element = html.xpath('//*[@id="cnaV3MetricHidden"]/@value') + if element and len(element) > 0: html1 = etree.HTML(element[0]) - cve_level = str(html1.xpath('//*[@data-testid="vuln-cvssv3-base-score-severity"]/text()')[0] - .strip()).capitalize() - nvd_score = str(html1.xpath('//*[@data-testid="vuln-cvssv3-base-score"]/text()')[0].strip()) - vector_value = str(html1.xpath('//*[@data-testid="vuln-cvssv3-vector"]/text()')[0]).replace("(", ''). \ - replace(')', '').strip() - attack_vector = str(html1.xpath('//*[@data-testid="vuln-cvssv3-av"]/text()')[0].strip()) - attack_complexity = str(html1.xpath('//*[@data-testid="vuln-cvssv3-ac"]/text()')[0].strip()) - privilege_required = str(html1.xpath('//*[@data-testid="vuln-cvssv3-pr"]/text()')[0].strip()) - user_interaction = str(html1.xpath('//*[@data-testid="vuln-cvssv3-ui"]/text()')[0].strip()) - scope = str(html1.xpath('//*[@data-testid="vuln-cvssv3-s"]/text()')[0].strip()) - confidentiality = str(html1.xpath('//*[@data-testid="vuln-cvssv3-c"]/text()')[0].strip()) - integrity = str(html1.xpath('//*[@data-testid="vuln-cvssv3-i"]/text()')[0].strip()) - availability = str(html1.xpath('//*[@data-testid="vuln-cvssv3-a"]/text()')[0].strip()) - access_vector = access_complexity = authentication = None + if html1 is not None: + cve_level = str(html1.xpath('//*[@data-testid="vuln-cvssv3-base-score-severity"]/text()')[0] + .strip()).capitalize() + nvd_score = str(html1.xpath('//*[@data-testid="vuln-cvssv3-base-score"]/text()')[0].strip()) + vector_value = str(html1.xpath('//*[@data-testid="vuln-cvssv3-vector"]/text()')[0]).replace("(", + ''). \ + replace(')', '').strip() + attack_vector = str(html1.xpath('//*[@data-testid="vuln-cvssv3-av"]/text()')[0].strip()) + attack_complexity = str(html1.xpath('//*[@data-testid="vuln-cvssv3-ac"]/text()')[0].strip()) + privilege_required = str(html1.xpath('//*[@data-testid="vuln-cvssv3-pr"]/text()')[0].strip()) + user_interaction = str(html1.xpath('//*[@data-testid="vuln-cvssv3-ui"]/text()')[0].strip()) + scope = str(html1.xpath('//*[@data-testid="vuln-cvssv3-s"]/text()')[0].strip()) + confidentiality = str(html1.xpath('//*[@data-testid="vuln-cvssv3-c"]/text()')[0].strip()) + integrity = str(html1.xpath('//*[@data-testid="vuln-cvssv3-i"]/text()')[0].strip()) + availability = str(html1.xpath('//*[@data-testid="vuln-cvssv3-a"]/text()')[0].strip()) + access_vector = access_complexity = authentication = None + else: + element = html.xpath('//*[@id="nistV2MetricHidden"]/@value') + if element and len(element) > 0: + html1 = etree.HTML(element[0]) + if html1 is not None: + score_type = "v2.0" + cve_level = str(html1.xpath('//*[@data-testid="vuln-cvssv2-base-score-severity"]/text()') + [0].strip()).capitalize() + nvd_score = str(html1.xpath('//*[@data-testid="vuln-cvssv2-base-score"]/text()')[0].strip()) + vector_value = str(html1.xpath('//*[@data-testid="vuln-cvssv2-vector"]/text()')[0]). \ + replace("(", "").replace(")", "").strip() + access_vector = str(html1.xpath('//*[@data-testid="vuln-cvssv2-av"]/text()')[0].strip()) + access_complexity = str(html1.xpath('//*[@data-testid="vuln-cvssv2-ac"]/text()')[0].strip()) + authentication = str(html1.xpath('//*[@data-testid="vuln-cvssv2-au"]/text()')[0].strip()) + confidentiality = str(html1.xpath('//*[@data-testid="vuln-cvssv3-c"]/text()')[0].strip()) + integrity = str(html1.xpath('//*[@data-testid="vuln-cvssv2-i"]/text()')[0].strip()) + availability = str(html1.xpath('//*[@data-testid="vuln-cvssv2-a"]/text()')[0].strip()) + attack_vector = attack_complexity = privilege_required = user_interaction = scope = None + if cve_desc == 'N/A': + cve_desc = None + if repair_time == 'N/A': + repair_time = None + if nvd_score is None or nvd_score == "" or nvd_score == 'N/A': + nvd_score = None + print("nvd_score:", nvd_score, "\n", "cve_level:", cve_level, "\n", + "repair_time:", repair_time, "\n", "score_type:", score_type, "\n", + "vector_value, attack_vector, access_vector,attack_complexity, \n" + "access_complexity, privilege_required, user_interaction, scope,\n" + "confidentiality, integrity, availability, authentication:\n", + vector_value, attack_vector, access_vector, + attack_complexity, access_complexity, privilege_required, user_interaction, scope, + confidentiality, integrity, availability, authentication, "\n", "cve_desc:", cve_desc) xpth_list = [nvd_score, cve_level, cve_desc, repair_time, vector_value, attack_vector, access_vector, attack_complexity, access_complexity, privilege_required, user_interaction, scope, confidentiality, integrity, availability, authentication, score_type] diff --git a/cve-py/tabletask/gauss_yaml.py b/cve-py/tabletask/gauss_yaml.py index 9b977f91b5ef86af928991d33bcef036834c9698..b349e125e5f7de5955ce02a94498affadb865aa1 100644 --- a/cve-py/tabletask/gauss_yaml.py +++ b/cve-py/tabletask/gauss_yaml.py @@ -110,8 +110,8 @@ def store_yaml_data(yaml_data): mysql.end() except pymysql.err.IntegrityError: print(pymysql.err.IntegrityError) - # except Exception as e: - # print(e) + # except Exception as e: + # print(e) mysql.dispose(2) mysql.close() diff --git a/cve-py/tabletask/supplement_cve.py b/cve-py/tabletask/supplement_cve.py index aa681acf7c8b967368898e7ad56dc427ac0130ac..a1f2b685c5c836f7464438fe76855986f9a08d08 100644 --- a/cve-py/tabletask/supplement_cve.py +++ b/cve-py/tabletask/supplement_cve.py @@ -19,33 +19,72 @@ import time import datetime +def query_cve_all_data(mysql): + """ + Find cve with missing necessary fields + """ + before_date = (datetime.date.today() - + datetime.timedelta(days=100)).strftime("%Y-%m-%d %H:%M:%S") + score_sql = "select cve_id,cve_num from cve_score " \ + "where nvd_score = 0 and create_time >= %s order by create_time desc" + val = (before_date,) + cve_list = [] + score_result = mysql.getMany(score_sql, val) + if score_result and len(score_result) > 0: + for sc in score_result: + center_sql = "select cve_num, pack_name, cve_version," \ + "cve_desc,repair_time,cve_status,cve_id from " \ + "cve_vuln_center where cve_id = %s and " \ + "cve_num = %s order by cve_id desc" + center_val = (sc["cve_id"], sc["cve_num"]) + center_result = mysql.getOne(center_sql, center_val) + if center_result: + cve_list.append(center_result) + cve_desc_sql = "select cve_num, pack_name, cve_version," \ + "cve_desc,repair_time,cve_status,cve_id from " \ + "cve_vuln_center where (cve_desc = %s or " \ + "repair_time = %s) and create_time >= %s " \ + "order by cve_id desc" + center_val = ("", "", before_date) + center_result = mysql.getMany(cve_desc_sql, center_val) + if center_result and len(center_result) > 0: + for ce in center_result: + cve_list.append(ce) + return cve_list + + def query_cve_data(mysql): """ Find cve with missing necessary fields """ before_date = (datetime.date.today() - - datetime.timedelta(days=90)).strftime("%Y-%m-%d %H:%M:%S") + datetime.timedelta(days=3)).strftime("%Y-%m-%d %H:%M:%S") score_sql = "select cve_id,cve_num from cve_score " \ - "where nvd_score = 0 and create_time >= %s" + "where nvd_score = 0 and create_time >= %s " \ + "order by create_time desc" val = (before_date,) cve_list = [] score_result = mysql.getMany(score_sql, val) if score_result and len(score_result) > 0: for sc in score_result: - center_sql = "select cve_num, pack_name, cve_version from " \ - "cve_vuln_center where cve_id = %s and cve_num = %s" + center_sql = "select cve_num, pack_name, cve_version," \ + "cve_desc,repair_time,cve_status,cve_id from " \ + "cve_vuln_center where cve_id = %s and " \ + "cve_num = %s order by cve_id desc" center_val = (sc["cve_id"], sc["cve_num"]) center_result = mysql.getOne(center_sql, center_val) if center_result: cve_list.append(center_result) - cve_desc_sql = "select cve_num, pack_name, cve_version from " \ - "cve_vuln_center where cve_desc = %s and create_time >= %s" - center_val = ("", before_date) + cve_desc_sql = "select cve_num, pack_name, cve_version," \ + "cve_desc,repair_time,cve_status,cve_id from " \ + "cve_vuln_center where (cve_desc = %s or " \ + "repair_time = %s) and create_time >= %s " \ + "order by cve_id desc" + center_val = ("", "", before_date) center_result = mysql.getMany(cve_desc_sql, center_val) if center_result and len(center_result) > 0: for ce in center_result: cve_list.append(ce) - print(cve_list) return cve_list @@ -112,40 +151,66 @@ def update_cve(url, result_dict, cve, mysql): print("error: ", result_dict) -def insert_cve(url, cve, mysql): +def update_cve_vuln(url, cve, mysql): """ - insert data + update data """ cve_num = str(cve["cve_num"]).strip() - cve_version = str(cve["cve_version"]).strip() - pack_name = str(cve["pack_name"]).strip() - create_time = update_time = str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) - delete_time = None + cve_id = cve["cve_id"] + cve_status = cve["cve_status"] + cve_desc = str(cve["cve_desc"]).strip() + repair_time = str(cve["repair_time"]).strip() + update_time = str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) # State 0 means new, 1 means modified - cve_status = 1 + if cve_status in (0, 3, 4, 5, 6): + cve_statux = 0 + elif cve_status in (1, 2): + cve_statux = 1 + else: + cve_statux = cve_status try: listx = crawltask.crawling(url) - if listx[2] is None or \ - len(listx[2]) < 2 or \ - listx[0] is None or \ - listx[0] == 0: + if (listx[2] is None or listx[2] == "" or len(listx[2]) < 2) and \ + (listx[0] is None or listx[0] == 0) and \ + (listx[3] is None or listx[3] == "" or len(listx[3]) < 2): print("The data does not exist and will not be processed temporarily", listx) return - sql = "INSERT INTO cve_origin_excel (cve_num, cve_url, cve_version, pack_name, score_type, " \ - "nvd_score, cve_level, cve_desc, repair_time, vector_value, attack_vector, " \ - "access_vector, attack_complexity, access_complexity, privilege_required, " \ - "user_interaction, scope, confidentiality, integrity, availability, " \ - "authentication, cve_status, " \ - "create_time, update_time, delete_time) " \ - "VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, " \ - "%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)" - val = ( - cve_num, url, cve_version, pack_name, listx[16], listx[0], listx[1], listx[2], listx[3], - listx[4], - listx[5], listx[6], listx[7], listx[8], listx[9], listx[10], listx[11], listx[12], - listx[13], - listx[14], listx[15], cve_status, create_time, update_time, delete_time) - mysql.insertOne(sql, val) + if repair_time == "" and listx[3] is not None and len(listx[3]) > 2: + if len(listx[3]) > 10: + repair_times = listx[3][:10] + else: + repair_times = listx[3] + sql = "update cve_vuln_center set repair_time = %s,update_time=%s," \ + "cve_status=%s where cve_id=%s and cve_status=%s" + val = (repair_times, update_time, cve_statux, cve_id, cve_status) + mysql.insertOne(sql, val) + if listx[2] is not None and len(listx[2]) > 2 and cve_desc == "": + sql = "update cve_vuln_center set cve_desc = %s,update_time=%s," \ + "cve_status=%s where cve_id=%s and cve_status=%s" + val = (listx[2], update_time, cve_statux, cve_id, cve_status) + mysql.insertOne(sql, val) + if listx[0] is not None and float(listx[0]) > 0: + if listx[16] == "v3.0": + score_type = "v3" + else: + score_type = "v2" + sql = "select id,nvd_score from cve_score where cve_id = %s and " \ + "cve_num = %s and score_type = %s" + val = (cve_id, cve_num, score_type) + nvd_result = mysql.getOne(sql, val) + if nvd_result and len(nvd_result) > 0 and nvd_result["nvd_score"] == 0: + sql = "update cve_score set nvd_score=%s, " \ + "n_vector_value=%s, n_attack_vector=%s, n_access_vector=%s, " \ + "n_attack_complexity=%s, n_access_complexity=%s, n_privilege_required=%s, " \ + "n_user_interaction=%s, n_scope=%s, n_confidentiality=%s, n_integrity=%s, " \ + "n_availability=%s, n_authentication=%s, update_time=%s " \ + "where id = %s" + val = ( + listx[0], listx[4], + listx[5], listx[6], listx[7], listx[8], listx[9], + listx[10], listx[11], listx[12], listx[13], listx[14], + listx[15], update_time, nvd_result["id"]) + mysql.update(sql, val) mysql.dispose() except IndexError as e: print("Subscript out of bounds", e) @@ -163,30 +228,43 @@ def supplement_cve(): cve_list = query_cve_data(mysql) if cve_list is not None and len(cve_list) > 0: for cve in cve_list: + print(cve) cve_num = str(cve["cve_num"]).strip() cve_version = str(cve["cve_version"]).strip() pack_name = str(cve["pack_name"]).strip() url = "https://nvd.nist.gov/vuln/detail/" + cve_num - sql = "select * from cve_origin_excel where " \ - "cve_num= %s and pack_name = %s and cve_version = %s" - val = (cve_num, pack_name, cve_version) - result_dict = mysql.getOne(sql, val) - # Determine whether CVE exists in the database - if result_dict: - if result_dict["cve_desc"] is None or \ - len(result_dict["cve_desc"]) < 2 or \ - result_dict["nvd_score"] is None or \ - result_dict["nvd_score"] == 0: - pass - # update_cve(url, result_dict, cve, mysql) - else: - sql = "update cve_origin_excel set cve_status = %s " \ - "where cve_num= %s and pack_name = %s and cve_version = %s" - val = (1, cve_num, pack_name, cve_version) - mysql.update(sql, val) - mysql.dispose() - else: - insert_cve(url, cve, mysql) + update_cve_vuln(url, cve, mysql) + sql = "select * from cve_spec_error where cve_num = %s and " \ + "cve_owner = %s and pack_name = %s" + val = (cve_num, "src-openEuler", pack_name) + result_spec_error = mysql.getOne(sql, val) + if result_spec_error: + print("过滤,修改status为6:{}".format(cve_num)) + sql = "update cve_origin_excel set cve_desc = %s, cve_status = %s " \ + "where cve_num= %s and pack_name = %s and cve_version = %s" + val = (result_spec_error["cve_desc"], 6, cve_num, pack_name, cve_version) + mysql.update(sql, val) + mysql.dispose() + mysql.close() + + +def long_supplement_cve(): + """ + 1. Find cve with missing necessary fields; + 2. Go to the CVE official website to find the CVE information; + 3. Fill in the corresponding table again; + return None + """ + mysql = Mysql() + cve_list = query_cve_all_data(mysql) + if cve_list is not None and len(cve_list) > 0: + for cve in cve_list: + print(cve) + cve_num = str(cve["cve_num"]).strip() + cve_version = str(cve["cve_version"]).strip() + pack_name = str(cve["pack_name"]).strip() + url = "https://nvd.nist.gov/vuln/detail/" + cve_num + update_cve_vuln(url, cve, mysql) sql = "select * from cve_spec_error where cve_num = %s and " \ "cve_owner = %s and pack_name = %s" val = (cve_num, "src-openEuler", pack_name) diff --git a/models/common.go b/models/common.go index b407564f57699da4f1de927a3474ed46be5baa3c..458c935fe8d726d056404336b0efc24a6e2d8d07 100644 --- a/models/common.go +++ b/models/common.go @@ -1,6 +1,7 @@ package models import ( + "fmt" "github.com/astaxie/beego/logs" "time" ) @@ -41,3 +42,75 @@ func openEulerScoreProc(openEulerScore float64) (CveLevel string) { } return CveLevel } + +func SearchGaussCondSa(cveLevel, years, releaseFlag int, searchName string) string { + conditStr := "" + if cveLevel > 0 { + conditStr = fmt.Sprintf(`cve_level_value = %d`, cveLevel) + } + if years > 0 { + if len(conditStr) > 1 { + conditStr = conditStr + " and " + fmt.Sprintf(`sa_years = %d`, years) + } else { + conditStr = fmt.Sprintf(`sa_years = %d`, years) + } + } + if releaseFlag == 2 { + if len(conditStr) > 1 { + conditStr = conditStr + " and " + fmt.Sprintf(`status = 3`) + } else { + conditStr = fmt.Sprintf(`status = 3`) + } + } else { + if len(conditStr) > 1 { + conditStr = conditStr + " and " + fmt.Sprintf(`status = 1`) + } else { + conditStr = fmt.Sprintf(`status = 1`) + } + } + if len(searchName) > 1 { + searchName = "%" + searchName + "%" + if len(conditStr) > 1 { + conditStr = conditStr + " and " + fmt.Sprintf(`(gauss_sa_num like '%v' or influence_component like '%v')`, + searchName, searchName) + } else { + conditStr = fmt.Sprintf(`gauss_sa_num like '%v' or influence_component like '%v'`, searchName, searchName) + } + } + return conditStr +} + +func SearchGaussCondCve(releaseFlag, isAffectFlag int, searchName string) string { + conditStr := "" + if len(searchName) > 1 { + searchName = "%" + searchName + "%" + conditStr = fmt.Sprintf(`cve_num like '%v'`, searchName) + } + if releaseFlag == 2 { + if len(conditStr) > 1 { + conditStr = conditStr + " and " + fmt.Sprintf(`status = 3`) + } else { + conditStr = fmt.Sprintf(`status = 3`) + } + } else { + if len(conditStr) > 1 { + conditStr = conditStr + " and " + fmt.Sprintf(`status = 1`) + } else { + conditStr = fmt.Sprintf(`status = 1`) + } + } + if isAffectFlag == 3 { + if len(conditStr) > 1 { + conditStr = conditStr + " and " + fmt.Sprintf(`gauss_id = 0`) + } else { + conditStr = fmt.Sprintf(`gauss_id = 0`) + } + } else if isAffectFlag == 2 { + if len(conditStr) > 1 { + conditStr = conditStr + " and " + fmt.Sprintf(`gauss_id > 0`) + } else { + conditStr = fmt.Sprintf(`gauss_id > 0`) + } + } + return conditStr +} diff --git a/models/gauss.go b/models/gauss.go new file mode 100644 index 0000000000000000000000000000000000000000..dfe241e205b709b214dcf43ad0f3c7e7049b55ba --- /dev/null +++ b/models/gauss.go @@ -0,0 +1,526 @@ +package models + +import ( + "cvevulner/common" + "errors" + "fmt" + "github.com/astaxie/beego/logs" + "github.com/astaxie/beego/orm" + "strconv" + "strings" +) + +//ExcelPackage Released packages +type GaussExcelTag struct { + PubTime string + Repo string + Packages string +} + +// Provide gauss related data and mysql interface layer processing logic +func QueryDownloadFile(status int) (FileData []OpenGaussDownloadFile, err error) { + o := orm.NewOrm() + sql := fmt.Sprintf(`SELECT * from cve_open_gauss_download_file WHERE status = %d`, status) + _, err = o.Raw(sql).QueryRows(&FileData) + logs.Info("QueryDownloadFile, err: ", err) + return +} + +func UpdateDownloadFile(fileId int64, status int) { + o := orm.NewOrm() + err := o.Raw("update cve_open_gauss_download_file set status = ?,"+ + "update_time = ? where file_id = ?", status, common.GetCurTime(), fileId).QueryRow() + logs.Info("UpdateDownloadFile", err) +} + +// Query all processed issues and filter out the unaffected data that needs to be processed +func QueryGaussIssueData(startTime string) (issueTemp []IssueTemplate, err error) { + sql := `SELECT * FROM cve_issue_template WHERE status = 3 AND issue_status in (2,6) AND +cve_id IN (SELECT DISTINCT cve_id FROM cve_vuln_center WHERE cve_status = 2 and +organizate_id = 2 and is_export != 1) AND create_time >= '%s'` + sql = fmt.Sprintf(sql, startTime) + o := orm.NewOrm() + _, err = o.Raw(sql).QueryRows(&issueTemp) + return +} + +// Get published CVE data +func QueryReleaseGaussIssue(ogv *OpenGaussVersion, field ...string) error { + o := orm.NewOrm() + err := o.Read(ogv, field...) + return err +} + +//GetCanExportExcelData Get exportable data +func QueryGaussExportSaData(cveNum, issueNum, repo string, issueId int64) (list []ExcelExport, err error) { + if cveNum == "" { + return list, errors.New("cve number can not empty") + } + sql := `SELECT b.num,c.*,a.issue_num,a.owned_component,a.cve_brief, +d.sec_id,d.introduction,d.summary,d.theme,d.description,d.influence_component, +d.affect_product,d.reference_link,d.affect_status, +e.public_date,e.openeuler_sa_num,a.cve_level,b.organizate_id,a.affected_version,a.issue_label +FROM cve_issue_template a +RIGHT JOIN +(SELECT (SELECT COUNT(*) FROM cve_vuln_center WHERE cve_num = ? AND +is_export != 1 AND pack_name = ? AND organizate_id = 2) num , +bc.cve_id,bc.cve_num,bc.organizate_id +FROM cve_vuln_center bc WHERE bc.cve_num = ? AND bc.is_export != 1 AND +bc.pack_name = ? AND bc.organizate_id = 2) b +ON a.cve_id = b.cve_id +LEFT JOIN cve_score c +ON b.cve_id = c.cve_id +LEFT JOIN cve_security_notice d +ON b.cve_id = d.cve_id +LEFT JOIN cve_open_euler_s_a e +ON b.cve_id = e.cve_id +WHERE a.issue_num = ? and a.issue_id = ? and b.organizate_id = 2 +` + o := orm.NewOrm() + _, err = o.Raw(sql, cveNum, repo, cveNum, repo, issueNum, issueId).QueryRows(&list) + return +} + +func QueryReleaseCve(ogc *OpenGaussCveList, field ...string) error { + o := orm.NewOrm() + err := o.Read(ogc, field...) + return err +} + +// update data +func UpdateReleaseCve(ogc *OpenGaussCveList, fields ...string) error { + o := orm.NewOrm() + _, err := o.Update(ogc, fields...) + return err +} + +// insert data +func InsertReleaseCve(ogc *OpenGaussCveList) (int64, error) { + o := orm.NewOrm() + id, err := o.Insert(ogc) + return id, err +} + +func QueryGaussVersion(ogv *OpenGaussVersion, field ...string) error { + o := orm.NewOrm() + err := o.Read(ogv, field...) + return err +} + +func UpdateGaussVersion(ogv *OpenGaussVersion, fields ...string) error { + o := orm.NewOrm() + _, err := o.Update(ogv, fields...) + return err +} + +// insert data +func InsertGaussVersion(ogv *OpenGaussVersion) (int64, error) { + o := orm.NewOrm() + id, err := o.Insert(ogv) + return id, err +} + +func GetGaussIssueNumber(packName string) (issueTemp []IssueTemplate, err error) { + sql := `select * from cve_issue_template where status = 3 and issue_status = 2 and +cve_id in (select cve_id from cve_vuln_center where cve_status = 2 and +is_export in (0,3) and pack_name in ('%s') and organizate_id = 2)` + sql = fmt.Sprintf(sql, packName) + o := orm.NewOrm() + _, err = o.Raw(sql).QueryRows(&issueTemp) + return +} + +func QuerySaDataByPackName(ogl *OpenGaussListTemp) error { + sql := `select * from cve_open_gauss_list_temp where influence_component = '%s' and affect_product = '%s'` + sql = fmt.Sprintf(sql, ogl.InfluenceComponent, ogl.AffectProduct) + o := orm.NewOrm() + err := o.Raw(sql).QueryRow(ogl) + if ogl.GaussTempId > 0 { + return nil + } else { + return err + } +} + +func UpdateSaData(ogl *OpenGaussListTemp, fields ...string) error { + o := orm.NewOrm() + _, err := o.Update(ogl, fields...) + return err +} + +// insert data +func InsertSaData(ogl *OpenGaussListTemp) (int64, error) { + o := orm.NewOrm() + id, err := o.Insert(ogl) + return id, err +} + +func GetGaussExportThem(cveNums, component, affectBranch string) (string, error) { + if cveNums == "" || component == "" { + return "", errors.New("param is empty") + } + s := strings.Split(cveNums, ";") + for k, v := range s { + s[k] = "'" + v + "'" + } + cveNums = strings.Join(s, ",") + type tmp = struct { + OpenEulerScore float64 `orm:"column(openeuler_score)"` + Theme string `orm:"column(theme)"` + AffectProduct string `orm:"column(affect_product)"` + } + res := make([]tmp, 0) + sql := fmt.Sprintf(`SELECT b.openeuler_score,a.theme,a.affect_product FROM cve_issue_template b +JOIN cve_security_notice a ON a.cve_id = b.cve_id +WHERE b.cve_num IN (%s) +AND b.owned_component = '%s'`, cveNums, component) + o := orm.NewOrm() + _, err := o.Raw(sql).QueryRows(&res) + if err != nil { + return "", err + } + max := float64(0) + resStr := "" + for _, v := range res { + if v.AffectProduct == "" || len(v.AffectProduct) < 2 { + continue + } + if max < v.OpenEulerScore { + max = v.OpenEulerScore + if affectBranch != "" && len(affectBranch) > 1 { + resStr = strings.ReplaceAll(v.Theme, v.AffectProduct, affectBranch) + } else { + resStr = v.Theme + } + } + } + return resStr, nil +} + +func QueryOpenGaussGroup(ogg *OpenGaussGroup, field ...string) error { + o := orm.NewOrm() + err := o.Read(ogg, field...) + return err +} + +// insert data +func InsertOpenGaussGroup(ogg *OpenGaussGroup) (int64, error) { + o := orm.NewOrm() + id, err := o.Insert(ogg) + return id, err +} + +func QueryOpenGaussPlatform(ogp *OpenGaussPlatform, field ...string) error { + o := orm.NewOrm() + err := o.Read(ogp, field...) + return err +} + +// insert data +func InsertOpenGaussPlatform(ogp *OpenGaussPlatform) (int64, error) { + o := orm.NewOrm() + id, err := o.Insert(ogp) + return id, err +} + +func QueryOpenGaussPackage(ogk *OpenGaussPackage, field ...string) error { + o := orm.NewOrm() + err := o.Read(ogk, field...) + return err +} + +// insert data +func InsertOpenGaussPackage(ogk *OpenGaussPackage) (int64, error) { + o := orm.NewOrm() + id, err := o.Insert(ogk) + return id, err +} + +func UpdateOpenGaussPackage(ogk *OpenGaussPackage, fields ...string) error { + o := orm.NewOrm() + _, err := o.Update(ogk, fields...) + return err +} + +func QueryGaussSaMaxValue(ogs *OpenGaussSiteList) (err error) { + sql := `select * from cve_open_gauss_site_list where status = 3 order by gauss_id desc limit 1` + o := orm.NewOrm() + err = o.Raw(sql).QueryRow(ogs) + return +} + +func QueryOpenGaussSitePreAll() (ogl []OpenGaussSiteList, err error) { + sql := `select * from cve_open_gauss_site_list where status != 3` + o := orm.NewOrm() + num, err := o.Raw(sql).QueryRows(&ogl) + logs.Info("QueryOpenGaussSitePreAll, err: ", err, num) + return +} + +func QuerySaTempByPackName(packName string) (ogl []OpenGaussListTemp, err error) { + sql := `select * from cve_open_gauss_list_temp where influence_component = '%s' and status = 1` + sql = fmt.Sprintf(sql, packName) + o := orm.NewOrm() + num, err := o.Raw(sql).QueryRows(&ogl) + logs.Info("QuerySaTempByPackName, err: ", err, num) + return +} + +func DeleteSaTempByPackName(packName string) { + o := orm.NewOrm() + err := o.Raw("delete from cve_open_gauss_list_temp where influence_component = ?", packName).QueryRow() + logs.Info("DeleteSaTempByPackName", err) +} + +func QueryOpenGaussCveByGid(gaussId int64) (ogl []OpenGaussCveList, err error) { + sql := "" + if gaussId == 0 { + sql = `select * from cve_open_gauss_cve_list where status != 3` + } else { + sql = `select * from cve_open_gauss_cve_list where gauss_id = %d and status != 3` + } + sql = fmt.Sprintf(sql, gaussId) + o := orm.NewOrm() + num, err := o.Raw(sql).QueryRows(&ogl) + logs.Info("QueryOpenGaussCveByGid, err: ", err, num) + return +} + +func DeleteOpenGaussVersionById(cveId int64) { + o := orm.NewOrm() + err := o.Raw("delete from cve_open_gauss_version where cve_id = ?", cveId).QueryRow() + logs.Info("DeleteOpenGaussVersionById", err) +} + +func DeleteGaussVersionByIdStatus(cveId int64) { + o := orm.NewOrm() + err := o.Raw("delete from cve_open_gauss_version where cve_id = ? and release_flag = 1", cveId).QueryRow() + logs.Info("DeleteGaussVersionByIdStatus", err) +} + +func DeleteOpenGaussCveByGid(gaussId int64) { + o := orm.NewOrm() + err := o.Raw("delete from cve_open_gauss_cve_list where gauss_id = ?", gaussId).QueryRow() + logs.Info("DeleteOpenGaussCveById", err) +} + +func DeleteOpenGaussCveByCid(cveId int64) { + o := orm.NewOrm() + err := o.Raw("delete from cve_open_gauss_cve_list where id = ?", cveId).QueryRow() + logs.Info("DeleteOpenGaussCveByCid", err) +} + +func DeleteOpenGaussPackByGid(gaussId int64) { + o := orm.NewOrm() + err := o.Raw("delete from cve_open_gauss_package where gauss_id = ?", gaussId).QueryRow() + logs.Info("DeleteOpenGaussPackByGid", err) +} + +func DeleteOpenGaussSitePreAll() { + o := orm.NewOrm() + err := o.Raw("delete from cve_open_gauss_site_list where status != 3").QueryRow() + logs.Info("DeleteOpenGaussSitePreAll", err) +} + +// insert data +func InsertOpenGaussSiteList(osl *OpenGaussSiteList) (int64, error) { + o := orm.NewOrm() + id, err := o.Insert(osl) + return id, err +} + +func UpdateOpenGaussCveByGid(gaussId, sGaussId int64) { + o := orm.NewOrm() + err := o.Raw("update cve_open_gauss_cve_list set gauss_id =?,update_time = ? where gauss_id = ?", + sGaussId, common.GetCurTime(), gaussId).QueryRow() + logs.Info("UpdateOpenGaussCveByGid", err) +} + +func UpdateOpenGaussVersionByCid(tempCveId, cveId int64, cveNum string) { + o := orm.NewOrm() + err := o.Raw("update cve_open_gauss_version set cve_id =?,update_time = ? where cve_id = ? and cve_num = ?", + cveId, common.GetCurTime(), tempCveId, cveNum).QueryRow() + logs.Info("UpdateOpenGaussVersionByCid", err) +} + +func UpdateOpenGaussPackByGid(gaussId, sGaussId int64) { + o := orm.NewOrm() + err := o.Raw("update cve_open_gauss_package set gauss_id = ?,update_time = ? where gauss_id = ?", + sGaussId, common.GetCurTime(), gaussId).QueryRow() + logs.Info("UpdateOpenGaussPackByGid", err) +} + +// Upgrade pre-release data to official data +func UpdateGaussPreTRelease() { + o := orm.NewOrm() + errs := o.Begin() + if errs == nil { + siteErr := o.Raw("update cve_open_gauss_site_list set status = 3,update_time = ? where status = 1", + common.GetCurTime()).QueryRow() + if siteErr != nil { + logs.Error("UpdateGaussPreTRelease, update cve_open_gauss_site_list failed ,err: ", siteErr) + o.Rollback() + } + cveErr := o.Raw("update cve_open_gauss_cve_list set status = 3,update_time = ? where status = 1", + common.GetCurTime()).QueryRow() + if cveErr != nil { + logs.Error("UpdateGaussPreTRelease, update cve_open_gauss_cve_list failed ,err: ", cveErr) + o.Rollback() + } + o.Commit() + } else { + logs.Error("UpdateGaussPreTRelease, Transaction creation failed, errs: ", errs) + } +} + +func QueryGaussSaCount(cveLevel, years, releaseFlag int, searchName string) (count int64) { + conditStr := SearchGaussCondSa(cveLevel, years, releaseFlag, searchName) + sql := "" + if len(conditStr) > 2 { + sql = fmt.Sprintf(`SELECT COUNT(gauss_id) total FROM cve_open_gauss_site_list where %v`, conditStr) + } else { + sql = fmt.Sprintf(`SELECT COUNT(gauss_id) total FROM cve_open_gauss_site_list`) + } + + res := struct { + Total int64 + }{} + o := orm.NewOrm() + err := o.Raw(sql).QueryRow(&res) + if err != nil { + logs.Error("QueryGaussSaCount, err: ", err) + return 0 + } + return res.Total +} + +//QueryIssue query QueryOpenGaussSiteList +func QueryOpenGaussSiteList(pageNum, pageSize, cveLevel, years, + releaseFlag int, searchName string) ([]OpenGaussSiteList, error) { + conditStr := SearchGaussCondSa(cveLevel, years, releaseFlag, searchName) + startSize := (pageNum - 1) * pageSize + o := orm.NewOrm() + var psl []OpenGaussSiteList + if len(conditStr) > 2 { + sql := fmt.Sprintf(`SELECT * from cve_open_gauss_site_list where %s +order by gauss_id desc limit %d offset %d`, conditStr, pageSize, startSize) + logs.Info("sql===> ", sql) + num, err := o.Raw(sql).QueryRows(&psl) + if err == nil && num > 0 { + logs.Info("QueryOpenGaussSiteList, search num: ", num) + } else { + logs.Info("QueryOpenGaussSiteList, cur_time:", + common.GetCurTime(), ",err: ", err) + } + return psl, err + } else { + sql := fmt.Sprintf(`SELECT * from cve_open_gauss_site_list +order by gauss_id desc limit %d offset %d`, pageSize, startSize) + num, err := o.Raw(sql).QueryRows(&psl) + if err == nil && num > 0 { + logs.Info("QueryOpenGaussSiteList, search num: ", num) + } else { + logs.Info("QueryOpenGaussSiteList, cur_time:", + common.GetCurTime(), ",err: ", err) + } + return psl, err + } +} + +func QueryOpenGaussSaByNum(osl *OpenGaussSiteList, field ...string) error { + o := orm.NewOrm() + err := o.Read(osl, field...) + return err +} + +func QueryGaussPackageByGid(gaussId int64, repoVersion string) (ogl []OpenGaussPackage, err error) { + sql := `select * from cve_open_gauss_package where gauss_id = %d and repo_version = '%s' and status = 1` + sql = fmt.Sprintf(sql, gaussId, repoVersion) + o := orm.NewOrm() + num, err := o.Raw(sql).QueryRows(&ogl) + logs.Info("QueryGaussPackageByGid, err: ", err, num) + return +} + +func QueryGaussPlatByPids(platIds []int64) (ogl []OpenGaussPlatform, err error) { + platStr := "(" + if len(platIds) > 0 { + for _, pid := range platIds { + platStr = platStr + strconv.FormatInt(pid, 10) + "," + } + platStr = platStr[:len(platStr)-1] + ")" + sql := fmt.Sprintf(`select * from cve_open_gauss_platform where plat_id in %s and status = 1`, platStr) + o := orm.NewOrm() + num, err := o.Raw(sql).QueryRows(&ogl) + logs.Info("QueryGaussPackageByGid, err: ", err, num) + } + return +} + +func QueryGaussCveCount(releaseFlag, isAffectFlag int, searchName string) (count int64) { + conditStr := SearchGaussCondCve(releaseFlag, isAffectFlag, searchName) + sql := "" + if len(conditStr) > 2 { + sql = fmt.Sprintf(`SELECT COUNT(id) total FROM cve_open_gauss_cve_list where %v`, conditStr) + } else { + sql = fmt.Sprintf(`SELECT COUNT(id) total FROM cve_open_gauss_cve_list`) + } + + res := struct { + Total int64 + }{} + o := orm.NewOrm() + err := o.Raw(sql).QueryRow(&res) + if err != nil { + logs.Error("QueryGaussCveCount, err: ", err) + return 0 + } + return res.Total +} + +// query QueryOpenGaussCveList +func QueryOpenGaussCveList(pageNum, pageSize, releaseFlag, + isAffectFlag int, searchName string) ([]OpenGaussCveList, error) { + conditStr := SearchGaussCondCve(releaseFlag, isAffectFlag, searchName) + startSize := (pageNum - 1) * pageSize + o := orm.NewOrm() + var psl []OpenGaussCveList + if len(conditStr) > 2 { + sql := fmt.Sprintf(`SELECT * from cve_open_gauss_cve_list +where %s order by id desc limit %d offset %d`, conditStr, pageSize, startSize) + num, err := o.Raw(sql).QueryRows(&psl) + if err == nil && num > 0 { + logs.Info("QueryOpenGaussCveList, search num: ", num) + } else { + logs.Info("QueryOpenGaussCveList, cur_time:", + common.GetCurTime(), ",err: ", err) + } + return psl, err + } else { + sql := fmt.Sprintf(`SELECT * from cve_open_gauss_cve_list order by id desc limit %d offset %d`, + pageSize, startSize) + num, err := o.Raw(sql).QueryRows(&psl) + if err == nil && num > 0 { + logs.Info("QueryOpenGaussCveList2, search num: ", num) + } else { + logs.Info("QueryOpenGaussCveList2, cur_time:", + common.GetCurTime(), ",err: ", err) + } + return psl, err + } +} + +func QueryOpenGaussCveByNum(osl *OpenGaussCveList, field ...string) error { + o := orm.NewOrm() + err := o.Read(osl, field...) + return err +} + +func QueryGaussVersionByCid(cveId int64) (ogv []OpenGaussVersion, err error) { + sql := `select * from cve_open_gauss_version where cve_id = %d` + sql = fmt.Sprintf(sql, cveId) + o := orm.NewOrm() + num, err := o.Raw(sql).QueryRows(&ogv) + logs.Info("QueryGaussVersionByCid, err: ", err, num) + return +} diff --git a/models/modeldb.go b/models/modeldb.go index 0e6e0ec9d32726a8cf7d97d79300a94da5404354..1b3c4f2a37005c54861afbc195e82cd824a8c3a9 100644 --- a/models/modeldb.go +++ b/models/modeldb.go @@ -718,6 +718,7 @@ type SaFileRecord struct { type OpenGaussSiteList struct { GaussId int64 `orm:"pk;auto;column(gauss_id)"` GaussSaNum string `orm:"size(64);column(gauss_sa_num);unique" description:"opengauss的sa编号"` + SaNum int64 `orm:"null;column(sa_num)" description:"sa对应的数据值"` Introduction string `orm:"size(256);null;column(introduction)" description:"简介"` CveLevel string `orm:"size(32);column(cve_level)" description:"致命(Critical);严重(High);中等(Medium);一般(Low);其他"` CveLevelValue int `orm:"default(0);column(cve_level_value)" desription:"Critical: 1, High: 2, Medium: 3,low: 4"` @@ -728,7 +729,8 @@ type OpenGaussSiteList struct { AffectProduct string `orm:"size(256);null;column(affect_product)" description:"影响产品"` CveNums string `orm:"size(2048);column(cve_nums)" description:"cve编号汇总"` ReferenceLink string `orm:"size(1024);null;column(reference_link)" description:"参考链接"` - Status int8 `orm:"default(1);column(status)" description:"1:正常可用;2:已删除"` + PublicDate string `orm:"size(32);null;column(public_date)" description:"sa发布日期"` + Status int8 `orm:"default(1);column(status)" description:"1:正常可用;2:已删除;3:已发布"` Years int `orm:"null;column(sa_years)" description:"sa 发布年份"` CreateTime string `orm:"size(32);column(create_time)"` UpdateTime string `orm:"size(32);column(update_time);null"` @@ -769,7 +771,7 @@ type OpenGaussCveList struct { Oauthentication string `orm:"size(64);column(o_authentication);null"` ScoreType string `orm:"size(16);column(score_type)"` FixLabel string `orm:"size(32);column(fix_label)" description:"issue标签, Fixed, Unaffected"` - Status int8 `orm:"default(1);column(status)" description:"1:正常可用;2:已删除"` + Status int8 `orm:"default(1);column(status)" description:"1:正常可用(预发布);2:已删除;3:正常发布,数据在官网展示"` Years int `orm:"null;column(cve_years)" description:"cve 发布年份"` CreateTime string `orm:"size(32);column(create_time)"` UpdateTime string `orm:"size(32);column(update_time);null"` @@ -778,7 +780,7 @@ type OpenGaussCveList struct { type OpenGaussGroup struct { GroupId int64 `orm:"pk;auto;column(group_id)"` - GroupName string `orm:"size(64);column(group_name)" description:"软件包分类组名称"` + GroupName string `orm:"size(64);column(group_name);unique" description:"软件包分类组名称"` Status int8 `orm:"default(1);column(status)" description:"1:正常可用;2:已删除"` CreateTime string `orm:"size(32);column(create_time)"` } @@ -786,16 +788,89 @@ type OpenGaussGroup struct { type OpenGaussPackage struct { PackId int64 `orm:"pk;auto;column(pack_id)"` GroupId int64 `orm:"index;column(group_id)"` + PlatId int64 `orm:"index;column(plat_id)"` GaussId int64 `orm:"index;column(gauss_id);default(0)" description:"对应sa的表id"` - PackName string `orm:"size(512);column(pack_name)" description:"cve对应得包名称"` - PackageName string `orm:"size(1024);column(package_name)" description:"软件包名称"` + PackageName string `orm:"size(512);column(package_name)" description:"cve对应得包名称"` + RpmName string `orm:"size(1024);column(rpm_name)" description:"tag包名称"` ReleaseDate string `orm:"size(32);column(release_date)" description:"版本发布日期"` + RepoVersion string `orm:"size(32);column(repo_version);" description:"分支版本信息"` Status int8 `orm:"default(1);column(status)" description:"1:正常可用;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 OpenGaussReleaseNum struct { +// SaId int64 `orm:"pk;auto;column(sa_id)"` +// GaussSaNum string `orm:"size(128);column(gauss_sa_num);unique" description:"安全公告完整编号"` +// SaYears string `orm:"size(16);column(sa_years);" description:"sa对应的年份"` +// SaNum int64 `orm:"default(0);column(sa_num)" description:"sa编号"` +// Status int8 `orm:"default(1);column(status)" description:"1:已发布;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 OpenGaussDownloadFile struct { + FileId int64 `orm:"pk;auto;column(file_id)"` + FilePath string `orm:"size(512);column(file_path);unique" description:"文件下载路径"` + RepoVersion string `orm:"size(32);column(repo_version);" description:"分支版本信息"` + Status int8 `orm:"default(1);column(status)" description:"1:文件待使用;2:文件解析中;3:文件已废弃"` + 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 OpenGaussVersion struct { + VersionId int64 `orm:"pk;auto;column(version_id)"` + CveId int64 `orm:"index;column(cve_id)"` + CveNum string `orm:"size(256);column(cve_num);index" description:"cve编号"` + AffectStatus int8 `orm:"default(1);column(affect_status)" description:"1:受影响,Fixed;2:不受影响,Unaffected"` + AffectStatusName string `orm:"size(32);column(affect_status_name);" description:"是否受影响名称, Fixed, Unaffected"` + RepoVersion string `orm:"size(32);column(repo_version);" description:"分支版本信息"` + ReleaseFlag int8 `orm:"default(1);column(release_flag)" description:"1: 受影响标识;2:不受影响标识;3:丢弃"` + CreateTime string `orm:"size(32);column(create_time)"` + UpdateTime string `orm:"size(32);column(update_time);null"` +} + +type OpenGaussPlatform struct { + PlatId int64 `orm:"pk;auto;column(plat_id)"` + PlatName string `orm:"size(64);column(plat_name);unique" description:"软件包平台名称"` + Status int8 `orm:"default(1);column(status)" description:"1:正常可用;2:已删除"` + CreateTime string `orm:"size(32);column(create_time)"` +} + +type OpenGaussListTemp struct { + GaussTempId int64 `orm:"pk;auto;column(gauss_temp_id)"` + Introduction string `orm:"size(256);null;column(introduction)" description:"简介"` + CveLevel string `orm:"size(32);column(cve_level)" description:"致命(Critical);严重(High);中等(Medium);一般(Low);其他"` + CveLevelValue int `orm:"default(0);column(cve_level_value)" desription:"Critical: 1, High: 2, Medium: 3,low: 4"` + 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:"影响产品"` + PublicDate string `orm:"size(32);null;column(public_date)" description:"sa发布日期"` + CveNums string `orm:"size(2048);column(cve_nums)" description:"cve编号汇总"` + Status int8 `orm:"default(1);column(status)" description:"1:正常可用;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 OpenEulerRepoOrigin struct { + Id int64 `orm:"pk;auto;column(id)"` + PackageName string `orm:"column(package_name);size(256)" description:"包名称"` + Version string `orm:"size(64);column(version)" description:"版本号"` + Summary string `orm:"size(1024);column(summary)" description:"简介"` + Decription string `orm:"size(8092);column(decription)" description:"描述"` + Branchs string `orm:"size(256);column(branch)" description:"分支信息"` + Status int8 `orm:"default(0);column(status)" description:"1:正常;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"` +} + func CreateDb() bool { BConfig, err := config.NewConfig("ini", "conf/app.conf") if err != nil { @@ -829,6 +904,9 @@ func CreateDb() bool { new(SaFileRecord), new(OpenGaussSiteList), new(OpenGaussCveList), new(OpenGaussGroup), new(OpenGaussPackage), new(IssueTemplateAssociation), + new(OpenGaussDownloadFile), new(OpenGaussVersion), + new(OpenGaussPlatform), new(OpenGaussListTemp), + new(OpenEulerRepoOrigin), ) logs.Info("table create success!") errosyn := orm.RunSyncdb("default", false, true) diff --git a/models/uploadcve.go b/models/uploadcve.go index 2fe5bf28568b5d4d06efd977d70bbbb5b279b2cf..16dc49c491c89e057ac5fbebf019d0b4e8348a75 100644 --- a/models/uploadcve.go +++ b/models/uploadcve.go @@ -552,6 +552,7 @@ func CreateOriginCve(CveData common.CveOriginData, ou *OriginUpstream, od *Origi logs.Info("update datas: ", ou) ou.CveId = ouse.CveId ou.Ids = ouse.Ids + ou.CreateTime = ouse.CreateTime if num, err := o.Update(ou); err == nil { logs.Info("CreateOriginCve, Update cve_origin_upstream success, num: ", num, ", cveNum: ", ou.Ids) } else { @@ -841,8 +842,8 @@ func CreateOriginCve(CveData common.CveOriginData, ou *OriginUpstream, od *Origi } ose.CveId = num lousfs := OriginUpstreamFixSuggest{CveId: num} - errxxsx := o.Read(&lousfs, "CveId") - if errxxsx == orm.ErrNoRows || errxxsx == orm.ErrMissPK { + osErr := o.Read(&lousfs, "CveId") + if osErr == orm.ErrNoRows || osErr == orm.ErrMissPK { logs.Info("CreateOriginCve, cve_origin_upstream_fix_suggest, Data does not exist, cveId: ", num) } else { var lousfst []OriginUpstreamFixSuggestRef diff --git a/models/ymal.go b/models/ymal.go index 1e9b463b7915d72bb77342b1d88b130ba93c85dd..5f02dd41f9ef491ac6cf2f5c03251e6a1ea8c395 100644 --- a/models/ymal.go +++ b/models/ymal.go @@ -275,3 +275,22 @@ func CreateYamlSubPackRequires(gs *GitSubPackRequire) (RequireId int64, typex st } return localgs.RequireId, "update", errx } + +func QueryEulerRepoOrigin(ogk *OpenEulerRepoOrigin, field ...string) error { + o := orm.NewOrm() + err := o.Read(ogk, field...) + return err +} + +// insert data +func InsertEulerRepoOrigin(ogk *OpenEulerRepoOrigin) (int64, error) { + o := orm.NewOrm() + id, err := o.Insert(ogk) + return id, err +} + +func UpdateEulerRepoOrigin(ogk *OpenEulerRepoOrigin, fields ...string) error { + o := orm.NewOrm() + _, err := o.Update(ogk, fields...) + return err +} \ No newline at end of file diff --git a/routers/commentsRouter_controllers.go b/routers/commentsRouter_controllers.go index 486385ddf1492bdac1ab3fecdc5cb15fb5021d02..5e8ced4a233d58294ff7e7a1f412169bc9e1780d 100644 --- a/routers/commentsRouter_controllers.go +++ b/routers/commentsRouter_controllers.go @@ -79,6 +79,51 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["cvevulner/controllers:GaussCveController"] = append(beego.GlobalControllerRouter["cvevulner/controllers:GaussCveController"], + beego.ControllerComments{ + Method: "Get", + Router: "/", + AllowHTTPMethods: []string{"get"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + + beego.GlobalControllerRouter["cvevulner/controllers:GaussCveDetailController"] = append(beego.GlobalControllerRouter["cvevulner/controllers:GaussCveDetailController"], + beego.ControllerComments{ + Method: "Get", + Router: "/", + AllowHTTPMethods: []string{"get"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + + beego.GlobalControllerRouter["cvevulner/controllers:GaussSaController"] = append(beego.GlobalControllerRouter["cvevulner/controllers:GaussSaController"], + beego.ControllerComments{ + Method: "Get", + Router: "/", + AllowHTTPMethods: []string{"get"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + + beego.GlobalControllerRouter["cvevulner/controllers:GaussSaDetailController"] = append(beego.GlobalControllerRouter["cvevulner/controllers:GaussSaDetailController"], + beego.ControllerComments{ + Method: "Get", + Router: "/", + AllowHTTPMethods: []string{"get"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + + beego.GlobalControllerRouter["cvevulner/controllers:GenSaController"] = append(beego.GlobalControllerRouter["cvevulner/controllers:GenSaController"], + beego.ControllerComments{ + Method: "TriggerCveData", + Router: "/", + AllowHTTPMethods: []string{"get"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["cvevulner/controllers:HookEventControllers"] = append(beego.GlobalControllerRouter["cvevulner/controllers:HookEventControllers"], beego.ControllerComments{ Method: "Post", diff --git a/routers/router.go b/routers/router.go index 1c8eacca15c65ec32683e0ad3eb9081a6de427a6..614ab8981ff48fc8f976ec55d0b52022cc625cb7 100644 --- a/routers/router.go +++ b/routers/router.go @@ -9,7 +9,6 @@ package routers import ( "cvevulner/controllers" - "github.com/astaxie/beego" ) @@ -54,9 +53,10 @@ func init() { beego.NSInclude(&controllers.HookEventControllers{}, ), ), - beego.NSNamespace("/download/excel", beego.NSInclude( - &controllers.FileController{}, - ), + beego.NSNamespace("/download/excel", + beego.NSInclude( + &controllers.FileController{}, + ), ), beego.NSNamespace("/cve/detail", beego.NSInclude( @@ -85,6 +85,36 @@ func init() { &controllers.CveAllIssueController{}, ), ), + // openGauss generates a summary of Sa data, and manually triggers the data at regular intervals + beego.NSNamespace("/gauss/triggerCveData", + beego.NSInclude( + &controllers.GenSaController{}, + ), + ), + // Get the information of the SA that has been generated + beego.NSNamespace("/gauss/sa", + beego.NSInclude( + &controllers.GaussSaController{}, + ), + ), + // Get the details of gauss' sa + beego.NSNamespace("/gauss/sa/detail", + beego.NSInclude( + &controllers.GaussSaDetailController{}, + ), + ), + // Get the cve information of gauss + beego.NSNamespace("/gauss/cve", + beego.NSInclude( + &controllers.GaussCveController{}, + ), + ), + // Get the cve details of gauss + beego.NSNamespace("/gauss/cve/detail", + beego.NSInclude( + &controllers.GaussCveDetailController{}, + ), + ), ) beego.AddNamespace(ns) } diff --git a/task/inittask.go b/task/inittask.go index a57ab6510a42cac7e5986020a8d8082b50d130d4..c40dc90ac77989f21bbfbf095c21d4794391cb33 100644 --- a/task/inittask.go +++ b/task/inittask.go @@ -17,11 +17,19 @@ func CheckOriCveTask(oriCveCheck string) { //InitYamlTask Get yaml data source func InitYamlTask(getYaml string) { logs.Info("Get the yaml data source task started...") - YamlTask := toolbox.NewTask("GetYamlData", getYaml, GetYamlData) - toolbox.AddTask("GetYamlData", YamlTask) + yamlTask := toolbox.NewTask("GetYamlData", getYaml, GetYamlData) + toolbox.AddTask("GetYamlData", yamlTask) logs.Info("End of the task of obtaining yaml data source...") } +//InitEulerYamlTask Get yaml data source +func InitEulerYamlTask(eulergetymal string) { + logs.Info("Get the euleryaml data source task started...") + eulerYamlTask := toolbox.NewTask("GetEulerYamlData", eulergetymal, GetEulerYamlData) + toolbox.AddTask("GetEulerYamlData", eulerYamlTask) + logs.Info("End of the task of obtaining euleryaml data source...") +} + //InitCveTask Generate cve original data into cve library func InitCveTask(getCve string) { logs.Info("The task of generating cve vulnerability library from cve raw data begins...") @@ -54,6 +62,14 @@ func CreatTask(createIssue string) { logs.Info("End of execution of the task of creating an issue...") } +// Handle the current emergency cve and create an issue +func EmgCreatTask(emergCreateIssue string) { + logs.Info("Handle the current emergency cve and create an issue task to start...") + cIssueTask := toolbox.NewTask("EmgCreateIssue", emergCreateIssue, EmgCreateIssue) + toolbox.AddTask("EmgCreateIssue", cIssueTask) + logs.Info("Handle the current emergency cve and create an issue to end...") +} + // unlock table func UnlockTask(unLockTable string) { logs.Info("Execute unlock table task start...") @@ -212,6 +228,12 @@ func InitTask() bool { createIssue := BConfig.String("crontab::createissue") CreatTask(createIssue) } + // Handle the current emergency cve and create an issue + emergissueflag, errx := BConfig.Int("crontab::emergissueflag") + if emergissueflag == 1 && errx == nil { + emergCreateIssue := BConfig.String("crontab::emergcreateissue") + EmgCreatTask(emergCreateIssue) + } // Generate excel data from issue genexcelflag, errx := BConfig.Int("crontab::genexcelflag") if genexcelflag == 1 && errx == nil { @@ -278,5 +300,11 @@ func InitTask() bool { checkissuedel := BConfig.String("crontab::checkissuedel") CheckIssueDel(checkissuedel) } + // Obtain openEuler data sources from other channels + eulerymalflag, errxs := BConfig.Int("crontab::eulerymalflag") + if eulerymalflag == 1 && errxs == nil { + eulergetymal := BConfig.String("crontab::eulergetymal") + InitEulerYamlTask(eulergetymal) + } return true } diff --git a/task/issuetask.go b/task/issuetask.go index e088bde5a324c6f79c4c28d277ed4b694ea15091..922c253c10042d96d9b06b7612a625e6c4e119b9 100644 --- a/task/issuetask.go +++ b/task/issuetask.go @@ -562,11 +562,20 @@ func ProcIssue(issueValue models.VulnCenter, } else { branchList := make([]string, 0) errBrands := errors.New("") + gaussIssuePath := beego.AppConfig.String("opengauss::gauss_issue_path") + path = gaussIssuePath // Get branch information branchList, errBrands = taskhandler.GetGaussBranchesInfo(gitGaussToken, gaussOwner, path) if branchList == nil || len(branchList) == 0 { logs.Error("ProcIssue, Failed to obtain branch information,CveNum: ", issueValue.CveNum, ", path: ", path, ", err: ", errBrands) + gaussVersion := beego.AppConfig.String("opengauss::gauss_version") + if len(gaussVersion) > 1 { + gaussVerSlice := strings.Split(gaussVersion, ",") + if len(gaussVerSlice) > 0 { + branchList = append(branchList, gaussVerSlice...) + } + } } sc, err := models.QueryIssueScore(issueValue.CveId) if err != nil { @@ -583,7 +592,6 @@ func ProcIssue(issueValue models.VulnCenter, models.UpdateIssueStatus(issueValue, 6) return errors.New("Field is empty") } - path = "security" resp, err := taskhandler.CreateIssueToGit(gitGaussToken, gaussOwner, path, assignee, issueValue, sc, branchList) if err != nil && err.Error() != "Recreate issue" { logs.Error("ProcIssue, Failed to create issue, err: ", err, @@ -595,3 +603,53 @@ func ProcIssue(issueValue models.VulnCenter, } return nil } + +func EmgCreateIssue() error { + defer common.Catchs() + // Query the cve to be processed, 1: add; 2: modify + BConfig, err := config.NewConfig("ini", "conf/app.conf") + if err != nil { + logs.Error("CreateIssue, config init, error:", err) + return err + } + years, ok := BConfig.Int("cve::cve_number") + if ok != nil { + logs.Error("CreateIssue, config cve::years, error:", ok) + return ok + } + manYears, ok := BConfig.Int("cve::cve_number_m") + if ok != nil { + logs.Error("CreateIssue, config cve::manYears, error:", ok) + return ok + } + toolYears, ok := BConfig.Int("cve::cve_number_t") + if ok != nil { + logs.Error("CreateIssue, config cve::toolYears, error:", ok) + return ok + } + prcnum, ok := BConfig.Int("crontab::prcnum") + if ok != nil { + logs.Error("CreateIssue, config crontab::prcnum, error:", ok) + return ok + } + issueWhitelist, ok := BConfig.Int("cve::issue_whitelist") + if ok != nil { + logs.Error("CreateIssue, config cve::issue_whitelist, error: ", ok) + return ok + } + beforeTime := time.Now().Add(-time.Minute * 60).String() + if len(beforeTime) > 19 { + beforeTime = beforeTime[:19] + } + if issueWhitelist == 1 { + limitErr := addLimitedIssue(beforeTime, prcnum, years, toolYears, manYears) + logs.Info("CreateIssue, addLimitedIssue, err: ", limitErr) + logs.Info("The execution of the issue task of creating cve ends. . .") + return limitErr + } else { + unlimitErr := addUnlimitedIssue(beforeTime, prcnum, years, toolYears, manYears) + logs.Info("CreateIssue, addUnlimitedIssue, err: ", unlimitErr) + logs.Info("The execution of the issue task of creating cve ends. . .") + return unlimitErr + } +} diff --git a/task/yaml.go b/task/yaml.go index 2c1ad1538260a1f0134948acd30aa3ba0cfe27dc..b976a1247b838474f7d3fc4de3531c1461224deb 100644 --- a/task/yaml.go +++ b/task/yaml.go @@ -4,6 +4,7 @@ import ( "cvevulner/common" "cvevulner/taskhandler" "errors" + "github.com/astaxie/beego" "github.com/astaxie/beego/config" "github.com/astaxie/beego/logs" ) @@ -32,3 +33,18 @@ func GetYamlData() error { logs.Info("End of the task of obtaining yaml data source") return err } + +// GetEulerYamlData Get yaml data source +func GetEulerYamlData() error { + defer common.Catchs() + logs.Info("Get the euleryaml data source task started") + // Query the cve to be processed, 1: add; 2: modify + eulerUrl := beego.AppConfig.String("yaml::eulerurl") + if eulerUrl == "" { + logs.Error("GetEulerYamlData, config yaml::eulerUrl, error: invalid value") + return errors.New("eulerUrl value is nil") + } + _, err := taskhandler.GetEulerYamlInfo(eulerUrl) + logs.Info("End of the task of obtaining euleryaml data source") + return err +} diff --git a/taskhandler/assist.go b/taskhandler/assist.go index b966ddf3c41102ed2f5b7c0dd84de40b6843a251..e41ad8059c496080af283d06684f2bc65aeea659 100644 --- a/taskhandler/assist.go +++ b/taskhandler/assist.go @@ -125,7 +125,6 @@ func GetGaussBranchesInfo(accessToken, owner, path string) ([]string, error) { continue } mapValue := value["name"].(string) - logs.Info(mapValue) if mapValue != "" && len(mapValue) > 1 { for _, gv := range gaussVerSlice { if gv == mapValue { diff --git a/taskhandler/common.go b/taskhandler/common.go index bff2f0d67229ea2c11957cffc2273194916b7429..ce1db8973611d8f918622036ceeaa8bdba6bf3e4 100644 --- a/taskhandler/common.go +++ b/taskhandler/common.go @@ -461,9 +461,12 @@ func CreateIssueBody(accessToken string, owner string, path string, assignee str } else { scoreType = "3.0" } - cve.Description = strings.ReplaceAll(cve.Description, "\"", "") - cve.Description = strings.ReplaceAll(cve.Description, "'", "") - cve.Description = strings.ReplaceAll(cve.Description, "\\", "") + if cve.Description != "" && len(cve.Description) > 1 { + cve.Description = strings.Replace(cve.Description, "\n", "", -1) + cve.Description = strings.ReplaceAll(cve.Description, "\"", " ") + cve.Description = strings.ReplaceAll(cve.Description, "'", " ") + cve.Description = strings.ReplaceAll(cve.Description, "\\", " ") + } BConfig, err := config.NewConfig("ini", "conf/app.conf") if err != nil { logs.Error("config init error:", err) @@ -477,6 +480,9 @@ func CreateIssueBody(accessToken string, owner string, path string, assignee str cveAnalysis := "" if its.CveAnalysis != "" && len(its.CveAnalysis) > 1 { cveAnalysis = strings.Replace(its.CveAnalysis, "\n", "", -1) + cveAnalysis = strings.ReplaceAll(cveAnalysis, "'", " ") + cveAnalysis = strings.ReplaceAll(cveAnalysis, "\"", " ") + cveAnalysis = strings.ReplaceAll(cveAnalysis, "\\", " ") } affectedVersion := "" if its.AffectedVersion != "" && len(its.AffectedVersion) > 0 { @@ -501,13 +507,17 @@ func CreateIssueBody(accessToken string, owner string, path string, assignee str affectedVersion = "\n" } } - updateTime := its.CreateTime.String() - updateTime = common.GetLocalCurTime() + logs.Info("its.CreateTime: ", its.CreateTime) + updateTime := its.CreateTime.Format(common.DATE_FORMAT) + if len(updateTime) >= 19 && its.TemplateId > 0 { + updateTime = common.TimeConverStr(updateTime[:19]) + } else { + updateTime = common.GetLocalCurTime() + } logs.Info("cve.UpdateTime.String(): ", updateTime, its.CreateTime, cve.CreateTime) if updateTime != "" && len(updateTime) > 19 { updateTime = updateTime[:19] } - StatusName := "" if its.StatusName != "" && len(its.StatusName) > 1 { if its.StatusName == "待办的" || its.StatusName == "开启的" || @@ -539,6 +549,7 @@ func CreateIssueBody(accessToken string, owner string, path string, assignee str if cve.OrganizationID == 2 { bodyUpTplx = gaussBodyUpTpl bodyTplx = gaussBodyTpl + commentCmd = " " } cveNumber := "[" + cve.CveNum + "](https://nvd.nist.gov/vuln/detail/" + cve.CveNum + ")" cve.CveDetailUrl = "https://nvd.nist.gov/vuln/detail/" + cve.CveNum @@ -791,4 +802,4 @@ func XmlSpecCharHand(xmlStr string) string { tempXmlStr = strings.ReplaceAll(tempXmlStr, "'", "'") tempXmlStr = strings.ReplaceAll(tempXmlStr, "\"", """) return tempXmlStr -} \ No newline at end of file +} diff --git a/taskhandler/createissue.go b/taskhandler/createissue.go index a5bdfa60d5ccfff2d707a919169ba436de25d382..43c6c5dd2b426398f94338083320681d56af1e2a 100644 --- a/taskhandler/createissue.go +++ b/taskhandler/createissue.go @@ -13,6 +13,7 @@ import ( "strconv" "strings" "sync" + "time" ) var updateLock sync.Mutex @@ -207,6 +208,7 @@ func CreateIssueToGit(accessToken, owner, path, assignee string, labels := beego.AppConfig.String("labelUnFix") if accessToken != "" && owner != "" && path != "" { var issueTemp models.IssueTemplate + issueTemp.CreateTime = time.Now() CreateIssueData(&issueTemp, cve, sc, nil, path, assignee, issueType, labels, owner) // Store issue data issTempID, templateErr := models.InsertIssueTemplate(&issueTemp) @@ -332,7 +334,8 @@ func UpdateIssueToGit(accessToken string, owner string, path string, if cve.OrganizationID == 2 { owner = gaussOwner accessToken = gitGaussToken - path = "security" + gaussIssuePath := beego.AppConfig.String("opengauss::gauss_issue_path") + path = gaussIssuePath } if its.IssueNum != "" && len(its.IssueNum) > 0 { issueErr, _ := GetGiteeIssue(accessToken, owner, path, its.IssueNum) @@ -606,6 +609,7 @@ func CreateIssueComment(accessToken, owner, path, assignee string, commentCmd := BConfig.String("reflink::comment_cmd") commentBody := "" if cve.OrganizationID == 2 { + commentCmd = " " commentBody = GaussCommentTemplate(assignee, commentCmd, affectedVersion) } else { commentBody = CommentTemplate(assignee, commentCmd, affectedVersion, path) @@ -672,10 +676,17 @@ func CreateSecNoticeData(sec *models.SecurityNotice, iss models.VulnCenter, sec.CveNum = iss.CveNum opScoreLeve := openEulerScoreProc(opScore) sec.Introduction = "An update for " + iss.PackName + " is now available for " + branchs + "." - sec.Theme = sec.Introduction[:len(sec.Introduction)-1] + ".\n\n" + "openEuler Security has rated this" + - " update as having a security impact of " + strings.ToLower(opScoreLeve) + ". 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." + if iss.OrganizationID == 2 { + sec.Theme = sec.Introduction[:len(sec.Introduction)-1] + ".\n\n" + "openGauss Security has rated this" + + " update as having a security impact of " + strings.ToLower(opScoreLeve) + ". 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." + } else { + sec.Theme = sec.Introduction[:len(sec.Introduction)-1] + ".\n\n" + "openEuler Security has rated this" + + " update as having a security impact of " + strings.ToLower(opScoreLeve) + ". 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 } diff --git a/taskhandler/excel.go b/taskhandler/excel.go index 77b690378743d59dcebc1e671eb6561968487d6e..d1124427def2a09347446d0bb2a2f0b7be1c9363 100644 --- a/taskhandler/excel.go +++ b/taskhandler/excel.go @@ -1125,7 +1125,7 @@ func getDateByGite(pkgList []models.ExcelPackage, startTime string, c chan<- []I for _, v := range pkgList { //logs.Info("excel, v===>", v) rt := util.TimeStrToInt(v.PubTime, "20060102 15-04-05") + saTimeStampZone - // 查询当前需要处理的issue + // Query the current issues that need to be dealt with issueTemp, err := models.GetIssueNumber(v.Repo) if err != nil || issueTemp == nil { logs.Info("No need to deal with ", v.Repo) diff --git a/taskhandler/gauss.go b/taskhandler/gauss.go new file mode 100644 index 0000000000000000000000000000000000000000..2d09d95d23d9f89e1b32682a630452987bde11a2 --- /dev/null +++ b/taskhandler/gauss.go @@ -0,0 +1,1038 @@ +package taskhandler + +import ( + "cvevulner/common" + "cvevulner/models" + "cvevulner/util" + "encoding/json" + "errors" + "fmt" + "github.com/360EntSecGroup-Skylar/excelize/v2" + "github.com/astaxie/beego" + "github.com/astaxie/beego/logs" + "io" + "io/ioutil" + "net/http" + "os" + "path" + "path/filepath" + "strconv" + "strings" + "sync" + "time" +) + +var localLock sync.Mutex + +type GitInfo struct { + StartTime string + Token string + Owner string +} + +type CveBranch struct { + CveNums []string + BranchMap map[string][]string +} + +type CveComponent struct { + PackMap map[string]CveBranch +} + +// Handling openGauss data types +func GaussUnaffectIssue(branchVersion []string, gi GitInfo) { + for _, bv := range branchVersion { + data, err := models.QueryGaussIssueData(gi.StartTime) + if len(data) > 0 { + for _, v := range data { + ogc := models.OpenGaussCveList{CveNum: v.CveNum, PackName: v.OwnedComponent, Status: 3} + ogcErr := models.QueryReleaseCve(&ogc, "CveNum", "PackName", "Status") + if ogc.Id > 0 { + var center models.VulnCenter + center.CveId = v.CveId + center.OrganizationID = 2 + centErr := models.GetVulnCenterByCid(¢er, "CveId", "OrganizationID") + if centErr == nil { + center.IsExport = 1 + models.UpdateVulnCenter(¢er, "is_export") + } + continue + } else { + logs.Info("Continue to execute data, ogcErr: ", ogcErr) + } + // Get specific business data + el, err := models.QueryGaussExportSaData(v.CveNum, v.IssueNum, v.OwnedComponent, v.IssueId) + if err != nil { + logs.Error("QueryGaussExportSaData, err: ", err, "tpl.CveNum, tpl.IssueNum: ", + v.CveNum, v.IssueNum, v.OwnedComponent) + return + } + for _, vx := range el { + affectBool := GaussFindUnaffVersion(&vx, bv, gi) + if affectBool { + logs.Info("Unaffected version, data: ", vx.CveNum, vx.OwnedComponent, vx.AffectProduct) + // Generate unaffected cvrf files + localLock.Lock() + UnaffectCveStore(&vx, bv) + localLock.Unlock() + } + } + } + } else { + logs.Error(err) + } + } +} + +// Does not affect the storage and release of cve data +func UnaffectCveStore(xmlp *models.ExcelExport, versions string) { + ogc := models.OpenGaussCveList{CveNum: xmlp.CveNum, PackName: xmlp.OwnedComponent} + ogcErr := models.QueryReleaseCve(&ogc, "CveNum", "PackName") + if ogc.Id == 0 { + logs.Info("ogcErr: ", ogcErr, xmlp.CveNum, xmlp.OwnedComponent) + CreateReleaseCve(&ogc, xmlp, 1, 0) + ogcId, gocErr := models.InsertReleaseCve(&ogc) + if ogcId > 0 { + ogv := models.OpenGaussVersion{CveId: ogcId, CveNum: xmlp.CveNum, RepoVersion: versions} + verErr := models.QueryGaussVersion(&ogv, "CveId", "CveNum", "RepoVersion") + if ogv.VersionId == 0 { + logs.Info("QueryGaussVersion, verErr: ", verErr) + CreateGaussVersion(&ogv, 1, 2, 2, xmlp.CveNum, versions, + "Unaffected", ogcId) + versionId, vErr := models.InsertGaussVersion(&ogv) + if versionId > 0 { + logs.Info("InsertGaussVersion, Data inserted successfully, id: ", versionId) + } else { + logs.Error("InsertGaussVersion, Data insertion failed, err: ", vErr, ogv) + } + } else { + gv := CreateGaussVersion(&ogv, 2, 2, 2, xmlp.CveNum, versions, + "Unaffected", ogcId) + uvErr := models.UpdateGaussVersion(&ogv, gv...) + logs.Info("UpdateGaussVersion, uvErr: ", uvErr) + } + } else { + logs.Error("InsertReleaseCve, gocErr: ", gocErr) + return + } + } else { + updateSlice := CreateReleaseCve(&ogc, xmlp, 2, 0) + upErr := models.UpdateReleaseCve(&ogc, updateSlice...) + if upErr == nil { + ogv := models.OpenGaussVersion{CveId: ogc.Id, CveNum: xmlp.CveNum, RepoVersion: versions} + verErr := models.QueryGaussVersion(&ogv, "CveId", "CveNum", "RepoVersion") + if ogv.VersionId == 0 { + logs.Info("QueryGaussVersion2, verErr: ", verErr) + CreateGaussVersion(&ogv, 1, 2, 2, xmlp.CveNum, versions, + "Unaffected", ogc.Id) + versionId, vErr := models.InsertGaussVersion(&ogv) + if versionId > 0 { + logs.Info("InsertGaussVersion2, Data inserted successfully, id: ", versionId) + } else { + logs.Error("InsertGaussVersion2, Data insertion failed, err: ", vErr, ogv) + } + } else { + gv := CreateGaussVersion(&ogv, 2, 2, 2, xmlp.CveNum, versions, + "Unaffected", ogc.Id) + uvErr := models.UpdateGaussVersion(&ogv, gv...) + logs.Info("UpdateGaussVersion2, uvErr: ", uvErr) + } + } + } +} + +func CreateGaussVersion(ogv *models.OpenGaussVersion, flag, affectStatus, ReleaseFlag int8, + cveNum, versions, affectStatusName string, cveId int64) []string { + gv := make([]string, 0) + ogv.CveId = cveId + gv = append(gv, "CveId") + ogv.CveNum = cveNum + gv = append(gv, "CveNum") + ogv.RepoVersion = versions + gv = append(gv, "RepoVersion") + ogv.AffectStatusName = affectStatusName + gv = append(gv, "AffectStatusName") + ogv.AffectStatus = affectStatus + gv = append(gv, "AffectStatus") + ogv.ReleaseFlag = ReleaseFlag + gv = append(gv, "ReleaseFlag") + if flag == 2 { + ogv.UpdateTime = common.GetCurTime() + gv = append(gv, "UpdateTime") + } else { + ogv.CreateTime = common.GetCurTime() + } + return gv +} + +func CreateReleaseCve(ogc *models.OpenGaussCveList, xmlp *models.ExcelExport, flag int, gaussId int64) []string { + updateSlice := make([]string, 0) + cveNumSlice := make([]string, 0) + if len(xmlp.CveNum) > 1 { + cveNumSlice = strings.Split(xmlp.CveNum, "-") + } + years := time.Now().Year() + if len(cveNumSlice) > 2 { + years, _ = strconv.Atoi(cveNumSlice[1]) + } + ogc.GaussId = gaussId + ogc.CveNum = xmlp.CveNum + updateSlice = append(updateSlice, "CveNum") + ogc.Description = xmlp.Description + updateSlice = append(updateSlice, "Description") + ogc.PackName = xmlp.OwnedComponent + updateSlice = append(updateSlice, "PackName") + ogc.NVDScore = xmlp.NVDScore + updateSlice = append(updateSlice, "NVDScore") + ogc.OpenEulerScore = xmlp.OpenEulerScore + updateSlice = append(updateSlice, "OpenEulerScore") + ogc.NvectorVule = xmlp.NvectorVule + updateSlice = append(updateSlice, "NvectorVule") + ogc.OvectorVule = xmlp.OvectorVule + updateSlice = append(updateSlice, "OvectorVule") + ogc.NattackVector = xmlp.NattackVector + updateSlice = append(updateSlice, "NattackVector") + ogc.NaccessVector = xmlp.NaccessVector + updateSlice = append(updateSlice, "NaccessVector") + ogc.OattackVector = xmlp.OattackVector + updateSlice = append(updateSlice, "OattackVector") + ogc.OaccessVector = xmlp.OaccessVector + updateSlice = append(updateSlice, "OaccessVector") + ogc.NattackComplexity = xmlp.NattackComplexity + updateSlice = append(updateSlice, "NattackComplexity") + ogc.NaccessComplexity = xmlp.NaccessComplexity + updateSlice = append(updateSlice, "NaccessComplexity") + ogc.OattackComplexity = xmlp.OattackComplexity + updateSlice = append(updateSlice, "OattackComplexity") + ogc.OaccessComplexity = xmlp.OaccessComplexity + updateSlice = append(updateSlice, "OaccessComplexity") + ogc.NprivilegeRequired = xmlp.NprivilegeRequired + updateSlice = append(updateSlice, "NprivilegeRequired") + ogc.OprivilegeRequired = xmlp.OprivilegeRequired + updateSlice = append(updateSlice, "OprivilegeRequired") + ogc.NuserInteraction = xmlp.NuserInteraction + updateSlice = append(updateSlice, "NuserInteraction") + ogc.OuserInteraction = xmlp.OuserInteraction + updateSlice = append(updateSlice, "OuserInteraction") + ogc.Nscope = xmlp.Nscope + updateSlice = append(updateSlice, "Nscope") + ogc.Oscope = xmlp.Oscope + updateSlice = append(updateSlice, "Oscope") + ogc.Nconfidentiality = xmlp.Nconfidentiality + updateSlice = append(updateSlice, "Nconfidentiality") + ogc.Oconfidentiality = xmlp.Oconfidentiality + updateSlice = append(updateSlice, "Oconfidentiality") + ogc.Nintegrity = xmlp.Nintegrity + updateSlice = append(updateSlice, "Nintegrity") + ogc.Ointegrity = xmlp.Ointegrity + updateSlice = append(updateSlice, "Ointegrity") + ogc.Navailability = xmlp.Navailability + updateSlice = append(updateSlice, "Navailability") + ogc.Oavailability = xmlp.Oavailability + updateSlice = append(updateSlice, "Oavailability") + ogc.Nauthentication = xmlp.Nauthentication + updateSlice = append(updateSlice, "Nauthentication") + ogc.Oauthentication = xmlp.Oauthentication + updateSlice = append(updateSlice, "Oauthentication") + ogc.ScoreType = xmlp.ScoreType + updateSlice = append(updateSlice, "ScoreType") + ogc.FixLabel = xmlp.IssueLabel + updateSlice = append(updateSlice, "FixLabel") + ogc.Status = 1 + updateSlice = append(updateSlice, "Status") + ogc.Years = years + updateSlice = append(updateSlice, "Years") + if flag == 2 { + ogc.UpdateTime = common.GetCurTime() + updateSlice = append(updateSlice, "UpdateTime") + } else { + ogc.CreateTime = common.GetCurTime() + } + return updateSlice +} + +func GaussFindUnaffVersion(xmlp *models.ExcelExport, versions string, gi GitInfo) bool { + branchArry, _ := GetGaussBranchesInfo(gi.Token, gi.Owner, xmlp.OwnedComponent) + if len(branchArry) == 0 { + gaussVersion := beego.AppConfig.String("opengauss::gauss_version") + if len(gaussVersion) > 1 { + gaussVerSlice := strings.Split(gaussVersion, ",") + if len(gaussVerSlice) > 0 { + branchArry = append(branchArry, gaussVerSlice...) + } + } + } + affectBool := false + if xmlp.AffectedVersion != "" && len(xmlp.AffectedVersion) > 1 { + affSlice := strings.Split(xmlp.AffectedVersion, ",") + if len(affSlice) > 0 { + for _, aff := range affSlice { + if strings.Contains(aff, versions+":") || strings.Contains(aff, versions+":") { + branchSlice := make([]string, 0) + if strings.Contains(aff, ":") { + branchSlice = strings.Split(aff, ":") + } else if strings.Contains(aff, ":") { + branchSlice = strings.Split(aff, ":") + } + if len(branchSlice) == 2 { + if strings.TrimSpace(branchSlice[0]) == versions && + len(strings.TrimSpace(branchSlice[1])) > 1 && + strings.TrimSpace(branchSlice[1]) != "受影响" { + // Query branch information + for _, arr := range branchArry { + if arr == strings.TrimSpace(branchSlice[0]) { + affectBool = true + break + } + } + } + } + } + } + } + } + return affectBool +} + +// Download the excel file that needs to be processed and parse the data +func DownloadFileAndParse(fExcel models.OpenGaussDownloadFile, startTime, + gaussDir string, cveComponent *CveComponent) { + fileSlice := make([]string, 0) + if len(fExcel.FilePath) > 1 { + fileSlice = strings.Split(fExcel.FilePath, "/") + } + localPath := filepath.Join(gaussDir, fileSlice[len(fileSlice)-1]) + // Download files from the Internet + dErr := downloadGaussPackageFile(localPath, fExcel.FilePath) + if dErr != nil { + logs.Error(dErr) + return + } + pkgList, err := ReadExcelFile(localPath, fExcel.RepoVersion) + if err != nil { + logs.Error(err) + return + } else { + pErr := ParseExcelFile(pkgList, fExcel, startTime, cveComponent) + if pErr != nil { + logs.Error(pErr) + } + } +} + +func ParseExcelFile(pkgList []models.GaussExcelTag, fExcel models.OpenGaussDownloadFile, + startTime string, cveComponent *CveComponent) error { + pl := len(pkgList) + pageSize := 10 + pc := pl / 10 + if pl%10 > 0 { + pc++ + } + cd := make(chan []IssueAndPkg) + start := 0 + end := 0 + for i := 0; i < pc; i++ { + start = i * pageSize + end = (i + 1) * pageSize + if end > pl { + end = pl + } + wgTrigger.Add(1) + go GuassGetDateByGite(pkgList[start:end], cd, startTime, fExcel.RepoVersion) + } + for i := 0; i < pc; i++ { + wgTrigger.Add(1) + go GaussHandleGiteData(cd, fExcel, cveComponent) + } + wgTrigger.Wait() + return nil +} + +func GaussHandleGiteData(c <-chan []IssueAndPkg, fExcel models.OpenGaussDownloadFile, cveComponent *CveComponent) { + defer wgTrigger.Done() + data := <-c + var pkgList []string + for _, v := range data { + pkgList = strings.Split(v.IssuePkg, " ") + if len(pkgList) == 0 { + logs.Error("Data is filtered, v.IssuePkg: ", v.IssuePkg) + continue + } + GaussAffectIssue(v, pkgList, fExcel, cveComponent) + } +} + +func GaussAffectIssue(v IssueAndPkg, pkgList []string, fExcel models.OpenGaussDownloadFile, cveComponent *CveComponent) { + for _, iv := range v.IssueMap { + tpl := models.IssueTemplate{IssueNum: iv.Number, Repo: iv.Repo, IssueId: v.IssueId} + err := models.GetIssueTemplateByColName(&tpl, "issue_num", "repo", "issue_id") + if err != nil { + logs.Error("GetIssueTemplateByColName, ----", err, iv.Number, iv.Repo, v.IssueId) + continue + } + //save data to db + el, err := models.QueryGaussExportSaData(tpl.CveNum, tpl.IssueNum, tpl.OwnedComponent, tpl.IssueId) + if err != nil { + logs.Error("QueryGaussExportSaData, err: ", err, "tpl.CveNum, tpl.IssueNum: ", + tpl.CveNum, tpl.IssueNum, tpl.OwnedComponent) + continue + } + err = GaussHandleContentToDbSync(el, pkgList, fExcel, cveComponent) + if err != nil { + logs.Error("GaussHandleContentToDbSync, err: ", err) + } + } +} + +func GaussHandleContentToDbSync(list []models.ExcelExport, pkgList []string, + fExcel models.OpenGaussDownloadFile, cveComponent *CveComponent) (err error) { + lz := len(list) + if lz > 0 { + for _, v := range list { + if v.OrganizateId != 2 { + logs.Error("openEuler, data: ", v) + continue + } + //affectProduct := v.AffectProduct + affectBool := affectBrachRep(&v, fExcel.RepoVersion) + if !affectBool { + logs.Error("Unaffected version, data: ", v) + continue + } + localLock.Lock() + AddSaToDb(v, fExcel.RepoVersion, pkgList, cveComponent) + localLock.Unlock() + } + } + return nil +} + +func AddSaToDb(v models.ExcelExport, affectBranch string, pkgList []string, cveComponent *CveComponent) { + if v.PublicDate == "" { + v.PublicDate = time.Now().Format("2006-01-02") + } + gaussTempId := int64(0) + ogl := models.OpenGaussListTemp{InfluenceComponent: v.OwnedComponent, AffectProduct: affectBranch} + oErr := models.QuerySaDataByPackName(&ogl) + if ogl.GaussTempId > 0 { + gaussTempId = ogl.GaussTempId + oglSlice := CreateSaData(v, &ogl, affectBranch) + uErr := models.UpdateSaData(&ogl, oglSlice...) + if uErr != nil { + logs.Error("UpdateSaData, uErr: ", uErr) + } + } else { + logs.Info("QuerySaDataByPackName, err: ", oErr) + CreateSaData(v, &ogl, affectBranch) + id, iErr := models.InsertSaData(&ogl) + if id > 0 { + gaussTempId = id + prErr := ParseRpmPackage(pkgList, gaussTempId, v.OwnedComponent, v.PublicDate, affectBranch) + if prErr != nil { + logs.Error("ParseRpmPackage, prErr: ", prErr) + } + } else { + logs.Error("InsertSaData, iErr: ", iErr) + } + } + AffectCveStore(&v, affectBranch, gaussTempId) + // Global data store + GlobalStoreData(v, affectBranch, cveComponent) +} + +// store cve info +func GlobalStoreData(v models.ExcelExport, affectBranch string, cveComponent *CveComponent) { + if cveComponent.PackMap != nil && len(cveComponent.PackMap) > 0 { + cb, ok := cveComponent.PackMap[v.OwnedComponent] + if ok { + if len(cb.CveNums) > 0 { + cveFlag := false + for _, cn := range cb.CveNums { + if cn == v.CveNum { + cveFlag = true + break + } + } + if !cveFlag { + cb.CveNums = append(cb.CveNums, v.CveNum) + } + } else { + cb.CveNums = make([]string, 0) + cb.CveNums = append(cb.CveNums, v.CveNum) + } + if len(cb.BranchMap) > 0 { + af, afOk := cb.BranchMap[affectBranch] + if afOk { + if len(af) > 0 { + cfFlag := false + for _, ch := range af { + if ch == v.CveNum { + cfFlag = true + break + } + } + if !cfFlag { + af = append(af, v.CveNum) + cb.BranchMap[affectBranch] = af + } + } else { + af = make([]string, 0) + af = append(af, v.CveNum) + cb.BranchMap[affectBranch] = af + } + } else { + af = make([]string, 0) + af = append(af, v.CveNum) + cb.BranchMap[affectBranch] = af + } + } else { + cb.BranchMap = make(map[string][]string) + af := make([]string, 0) + af = append(af, v.CveNum) + cb.BranchMap[affectBranch] = af + } + cveComponent.PackMap[v.OwnedComponent] = cb + } else { + cveNums := make([]string, 0) + cveNums = append(cveNums, v.CveNum) + branchMap := make(map[string][]string) + branchMap[affectBranch] = cveNums + var cb CveBranch + cveNums1 := make([]string, 0) + cveNums1 = append(cveNums1, v.CveNum) + cb.CveNums = cveNums1 + cb.BranchMap = branchMap + cveComponent.PackMap[v.OwnedComponent] = cb + } + } else { + cveNums := make([]string, 0) + cveNums = append(cveNums, v.CveNum) + branchMap := make(map[string][]string) + branchMap[affectBranch] = cveNums + var cb CveBranch + cveNums1 := make([]string, 0) + cveNums1 = append(cveNums1, v.CveNum) + cb.CveNums = cveNums1 + cb.BranchMap = branchMap + packMap := make(map[string]CveBranch) + packMap[v.OwnedComponent] = cb + cveComponent.PackMap = packMap + } +} + +func AddCveAffectProduct(cveNum, versions string, cveId int64) { + models.DeleteGaussVersionByIdStatus(cveId) + ogv := models.OpenGaussVersion{CveId: cveId, CveNum: cveNum, RepoVersion: versions} + CreateGaussVersion(&ogv, 1, 1, 1, cveNum, versions, "Fixed", cveId) + versionId, vErr := models.InsertGaussVersion(&ogv) + if versionId > 0 { + logs.Info("AffectCveStore, InsertGaussVersion, Data inserted successfully, id: ", versionId) + } else { + logs.Error("AffectCveStore, InsertGaussVersion, Data insertion failed, err: ", vErr, ogv) + } +} + +// Does affect the storage and release of cve data +func AffectCveStore(xmlp *models.ExcelExport, versions string, gaussTempId int64) { + ogc := models.OpenGaussCveList{CveNum: xmlp.CveNum, PackName: xmlp.OwnedComponent} + ogcErr := models.QueryReleaseCve(&ogc) + if ogc.Id == 0 { + logs.Error(ogcErr) + CreateReleaseCve(&ogc, xmlp, 1, gaussTempId) + ogcId, gocErr := models.InsertReleaseCve(&ogc) + if ogcId > 0 { + AddCveAffectProduct(xmlp.CveNum, versions, ogcId) + } else { + logs.Error("AffectCveStore, InsertReleaseCve, gocErr: ", gocErr) + return + } + } else { + updateSlice := CreateReleaseCve(&ogc, xmlp, 2, gaussTempId) + upErr := models.UpdateReleaseCve(&ogc, updateSlice...) + if upErr == nil { + AddCveAffectProduct(xmlp.CveNum, versions, ogc.Id) + } + } +} + +func CreateSaData(v models.ExcelExport, ogl *models.OpenGaussListTemp, affectBranch string) []string { + oglSlice := make([]string, 0) + if !strings.Contains(ogl.CveNums, v.CveNum) { + ogl.CveNums = ogl.CveNums + ";" + v.CveNum + oglSlice = append(oglSlice, "CveNums") + } else { + return oglSlice + } + ogl.AffectProduct = affectBranch + ogl.InfluenceComponent = v.OwnedComponent + ogl.PublicDate = v.PublicDate + oglSlice = append(oglSlice, "PublicDate") + ogl.Status = 1 + oglSlice = append(oglSlice, "Status") + if ogl.GaussTempId > 0 { + ogl.UpdateTime = common.GetCurTime() + oglSlice = append(oglSlice, "UpdateTime") + dSplit := strings.Split(v.Description, "Security Fix(es):") + if len(dSplit) > 1 { + if !strings.Contains(ogl.Description, dSplit[0]) { + ogl.Description = dSplit[0] + ogl.Description + } + ogl.Description += dSplit[1] + } + oglSlice = append(oglSlice, "Description") + if ogl.CveLevelValue > 0 { + switch strings.ToLower(v.CveLevel) { + case "critical": + if ogl.CveLevelValue > 1 { + ogl.CveLevelValue = 1 + ogl.CveLevel = v.CveLevel + } + case "high": + if ogl.CveLevelValue > 2 { + ogl.CveLevelValue = 2 + ogl.CveLevel = v.CveLevel + } + case "medium": + if ogl.CveLevelValue > 3 { + ogl.CveLevelValue = 3 + ogl.CveLevel = v.CveLevel + } + default: + ogl.CveLevelValue = 4 + ogl.CveLevel = v.CveLevel + } + } else { + switch strings.ToLower(v.CveLevel) { + case "critical": + ogl.CveLevelValue = 1 + case "high": + ogl.CveLevelValue = 2 + case "medium": + ogl.CveLevelValue = 3 + default: + ogl.CveLevelValue = 4 + } + ogl.CveLevel = v.CveLevel + } + oglSlice = append(oglSlice, "CveLevelValue") + oglSlice = append(oglSlice, "CveLevel") + theme, err := models.GetGaussExportThem(ogl.CveNums, v.OwnedComponent, affectBranch) + if err == nil && len(theme) > 1 { + ogl.Theme = theme + } + oglSlice = append(oglSlice, "Theme") + } else { + ogl.CreateTime = common.GetCurTime() + ogl.Description = v.Description + ogl.CveLevel = v.CveLevel + switch strings.ToLower(v.CveLevel) { + case "critical": + ogl.CveLevelValue = 1 + case "high": + ogl.CveLevelValue = 2 + case "medium": + ogl.CveLevelValue = 3 + default: + ogl.CveLevelValue = 4 + } + ogl.Summary = v.Summary + oglSlice = append(oglSlice, "Summary") + ogl.Introduction = v.Introduction + oglSlice = append(oglSlice, "Introduction") + ogl.Theme = v.Theme + ogl.CveNums = v.CveNum + } + ogl.Theme = strings.ReplaceAll(ogl.Theme, "openEuler", "openGauss") + return oglSlice +} + +func ParseRpmPackage(pkgList []string, gaussTempId int64, packageName, publicDate, affectBranch string) error { + if len(pkgList) > 0 { + for _, pg := range pkgList { + pgSlice := strings.Split(pg, ".") + if len(pgSlice) < 3 { + logs.Error("ParseRpmPackage, rpm package structure error, pg: ", pg) + continue + } + groupId := int64(0) + ogg := models.OpenGaussGroup{GroupName: pgSlice[len(pgSlice)-2]} + gErr := models.QueryOpenGaussGroup(&ogg, "GroupName") + if ogg.GroupId == 0 { + ogg.GroupName = pgSlice[len(pgSlice)-2] + ogg.CreateTime = common.GetCurTime() + ogg.Status = 1 + id, iErr := models.InsertOpenGaussGroup(&ogg) + if iErr != nil { + logs.Error("InsertOpenGaussGroup, err:", iErr) + continue + } + groupId = id + } else { + groupId = ogg.GroupId + logs.Info(gErr) + } + platId := int64(0) + ogp := models.OpenGaussPlatform{PlatName: pgSlice[len(pgSlice)-1]} + pErr := models.QueryOpenGaussPlatform(&ogp, "PlatName") + if ogp.PlatId == 0 { + ogp.PlatName = pgSlice[len(pgSlice)-1] + ogp.Status = 1 + ogp.CreateTime = common.GetCurTime() + id, iErr := models.InsertOpenGaussPlatform(&ogp) + if iErr != nil { + logs.Error("InsertOpenGaussPlatform, err:", iErr) + continue + } + platId = id + } else { + platId = ogp.PlatId + logs.Info(pErr) + } + rpmName := strings.Join(pgSlice[:len(pgSlice)-2], ".") + ogk := models.OpenGaussPackage{GroupId: groupId, PlatId: platId, + GaussId: gaussTempId, PackageName: packageName, RpmName: rpmName, RepoVersion: affectBranch} + opErr := models.QueryOpenGaussPackage(&ogk, "GroupId", "PlatId", "GaussId", "PackageName", "RpmName", "RepoVersion") + if ogk.PackId > 0 { + ogk.Status = 1 + ogk.ReleaseDate = publicDate + ogk.UpdateTime = common.GetCurTime() + upErr := models.UpdateOpenGaussPackage(&ogk, "Status", "ReleaseDate", "UpdateTime") + if upErr != nil { + logs.Error("UpdateOpenGaussPackage, upErr: ", upErr) + } + } else { + logs.Info("QueryOpenGaussPackage, opErr: ", opErr) + ogk = models.OpenGaussPackage{GroupId: groupId, PlatId: platId, GaussId: gaussTempId, + PackageName: packageName, RpmName: rpmName, CreateTime: common.GetCurTime(), + ReleaseDate: publicDate, Status: 1, RepoVersion: affectBranch} + packId, ipErr := models.InsertOpenGaussPackage(&ogk) + if packId == 0 { + logs.Error("InsertOpenGaussPackage, packId, ipErr: ", packId, ipErr) + } + } + } + } + return nil +} + +func GuassGetDateByGite(pkgList []models.GaussExcelTag, c chan<- []IssueAndPkg, startTime, affectBranch string) { + defer wgTrigger.Done() + token := beego.AppConfig.String("opengauss::git_gauss_token") + owner := beego.AppConfig.String("opengauss::gauss_owner") + gaussIssuePath := beego.AppConfig.String("opengauss::gauss_issue_path") + prRepo := beego.AppConfig.String("opengauss::pr_repo") + prRepoSlice := strings.Split(prRepo, ",") + prRepoSlice = append(prRepoSlice, gaussIssuePath) + st := util.TimeStrToInt(startTime, "2006-01-02") + chData := make([]IssueAndPkg, 0) + for _, v := range pkgList { + rt := util.TimeStrToInt(v.PubTime, "20060102 15-04-05") + // Query the current issues that need to be dealt with + issueTemp, err := models.GetGaussIssueNumber(v.Repo) + if err != nil || issueTemp == nil { + logs.Info("No need to deal with ", v.Repo) + continue + } + for _, isTemp := range issueTemp { + //logs.Info("isTemp===>", isTemp) + var prList []models.PullRequestIssue + for _, rPath := range prRepoSlice { + prList = getGaussRepoIssueAllPR(affectBranch, token, owner, rPath, st, rt, isTemp) + if len(prList) > 0 { + break + } + } + //prList := getGaussRepoIssueAllPR(affectBranch, token, owner, gaussIssuePath, st, rt, isTemp) + //get pull request related issue + repoIssue := make(map[int64]models.PullRequestIssue, 0) + for _, p := range prList { + //getPRRelatedAllIssue(token, owner, v.Repo, st, rt, p.Number, repoIssue) + p.Repo = v.Repo + repoIssue[p.Id] = p + } + if len(repoIssue) > 0 { + chData = append(chData, IssueAndPkg{IssueMap: repoIssue, IssuePkg: v.Packages, + Repo: v.Repo, IssueId: isTemp.IssueId}) + } + } + } + c <- chData +} + +func getGaussRepoIssueAllPR(affectBranch, token, owner, repo string, startTime, + releaseTime int64, isTemp models.IssueTemplate) (prList []models.PullRequestIssue) { + url := fmt.Sprintf("https://gitee.com/api/v5/repos/%v/issues/%v/pull_requests", owner, isTemp.IssueNum) + req, err := http.NewRequest(http.MethodGet, url, nil) + if err != nil { + logs.Error("NewRequest, url: ", url, ",err: ", err) + return + } + q := req.URL.Query() + q.Add("access_token", token) + q.Add("repo", repo) + req.URL.RawQuery = q.Encode() + resp, err := http.DefaultClient.Do(req) + if err != nil { + logs.Error("DefaultClient, url: ", url, ",err: ", err) + return + } + if resp.StatusCode == http.StatusOK { + issuePr := make([]map[string]interface{}, 0) + read, err := ioutil.ReadAll(resp.Body) + if err != nil { + logs.Error("ReadAll, url: ", url, ",err: ", err) + return + } + logs.Info("getGaussRepoIssueAllPR, value: ", string(read)) + resp.Body.Close() + err = json.Unmarshal(read, &issuePr) + if err != nil { + logs.Error("Unmarshal, url: ", url, ",err: ", err) + return + } + for _, v := range issuePr { + if _, ok := v["id"]; !ok { + continue + } + pr := models.PullRequestIssue{} + if v["state"].(string) == "merged" && v["mergeable"].(bool) { + //mt := v["closed_at"].(string).(time.Time).Local().Unix() + closedAt := v["closed_at"].(string) + mt := util.TimeStrToInt(closedAt[:19], "2006-01-02T15:04:05") + mergedAt := v["merged_at"].(string) + ct := util.TimeStrToInt(mergedAt[:19], "2006-01-02T15:04:05") + //logs.Info("======>>mt: ", mt, ", startTime: ", startTime, ",releaseTime: ", releaseTime, ":ct:", ct, ",repo:", repo, ", pr: ", v) + //ct := v["merged_at"].(string).(time.Time).Local().Unix() + var pt int64 + if mt > 0 && ct > 0 { + if mt > ct { + pt = ct + } else { + pt = mt + } + if pt >= startTime && pt <= releaseTime { + if v["base"].(map[string]interface{})["label"].(string) == affectBranch { + if v["base"].(map[string]interface{})["repo"].(map[string]interface{})["path"] == repo { + if v["base"].(map[string]interface{})["repo"].(map[string]interface{})["namespace"].(map[string]interface{})["path"] == owner { + pr.Id = int64(v["id"].(float64)) + pr.Number = isTemp.IssueNum + pr.CveNumber = isTemp.CveNum + pr.Repo = repo + prList = append(prList, pr) + } + } + } + //if v["base"].(map[string]interface{})["repo"].(map[string]interface{})["path"] == repo { + // if v["base"].(map[string]interface{})["repo"].(map[string]interface{})["namespace"].(map[string]interface{})["path"] == owner { + // pr.Id = int64(v["id"].(float64)) + // pr.Number = isTemp.IssueNum + // pr.CveNumber = isTemp.CveNum + // pr.Repo = repo + // prList = append(prList, pr) + // } + //} + } + } + } + } + } else { + resp.Body.Close() + } + return +} + +func downloadGaussPackageFile(localPath, url string) error { + timeStamp := time.Now().Unix() + url = url + "?" + strconv.FormatInt(timeStamp, 10) + resp, err := http.Get(url) + if err != nil { + return err + } + defer resp.Body.Close() + if resp.StatusCode == http.StatusOK { + pkgLock.Lock() + defer pkgLock.Unlock() + if ex, _ := util.IsExistPath(localPath); ex { + err := os.Remove(localPath) + if err != nil { + logs.Error(err) + } + } + out, err := os.Create(localPath) + if err != nil { + return err + } + defer out.Close() + _, err = io.Copy(out, resp.Body) + return err + } else { + return errors.New("download file request fail") + } +} + +//ExtractPackageData extract the package data by excel file +func ReadExcelFile(lp string, versions string) (pkgList []models.GaussExcelTag, err error) { + pkgLock.Lock() + defer pkgLock.Unlock() + if lp == "" || path.Ext(lp) != ".xlsx" { + return pkgList, errors.New("the file path is error") + } + f, opErr := excelize.OpenFile(lp) + if opErr != nil { + logs.Error(opErr) + return pkgList, opErr + } + rows, rErr := f.GetRows(versions) + if rErr != nil { + logs.Error(rErr) + return pkgList, rErr + } + for _, row := range rows { + pkgList = append(pkgList, models.GaussExcelTag{PubTime: row[0], Repo: row[1], Packages: row[2]}) + } + return pkgList, nil +} + +// Complete data conversion +func TempCveToGaussCve(tempGaussId int64, ogl []models.OpenGaussCveList) { + if len(ogl) > 0 { + for _, ol := range ogl { + osl := models.OpenGaussCveList{GaussId: tempGaussId, CveNum: ol.CveNum} + cbErr := models.QueryOpenGaussCveByNum(&osl, "GaussId", "CveNum") + if cbErr == nil { + models.UpdateOpenGaussVersionByCid(osl.Id, ol.Id, ol.CveNum) + } + } + models.UpdateOpenGaussPackByGid(tempGaussId, ogl[0].GaussId) + } + models.DeleteOpenGaussCveByGid(tempGaussId) + //models.DeleteOpenGaussPackByGid(tempGaussId) +} + +func DeleteGaussCveVaildData(gaussId int64) { + ogg, oggErr := models.QueryOpenGaussCveByGid(gaussId) + if len(ogg) > 0 { + for _, og := range ogg { + models.DeleteOpenGaussVersionById(og.Id) + } + models.DeleteOpenGaussCveByGid(gaussId) + } else { + logs.Info("QueryOpenGaussCveByGid, oggErr: ", oggErr, ",GaussId: ", gaussId) + } + models.DeleteOpenGaussPackByGid(gaussId) +} + +func ClearHisDataSa(flag int) { + if flag == 2 { + ogl, oglErr := models.QueryOpenGaussSitePreAll() + if len(ogl) == 0 { + logs.Info("ClearHisDataSa, oglErr: ", oglErr) + } else { + for _, o := range ogl { + DeleteGaussCveVaildData(o.GaussId) + } + models.DeleteOpenGaussSitePreAll() + } + } else { + ogg, oggErr := models.QueryOpenGaussCveByGid(0) + if len(ogg) > 0 { + for _, og := range ogg { + models.DeleteOpenGaussVersionById(og.Id) + models.DeleteOpenGaussCveByCid(og.Id) + } + } else { + logs.Info("QueryOpenGaussCveByGid, oggErr: ", oggErr) + } + } + +} + +func PreGeneratedSaData(packName string, bVersionSlice []string, isEque bool, saInitValue *int64) { + if isEque { + ogl, ogErr := models.QuerySaTempByPackName(packName) + if len(ogl) > 0 { + openGaussNum := "openGauss-SA-" + strconv.Itoa(time.Now().Year()) + "-" + strconv.FormatInt(*saInitValue, 10) + var osl models.OpenGaussSiteList + CreateOpenGaussSite(&osl, ogl[0], bVersionSlice, openGaussNum, *saInitValue) + sitGaussId, gErr := models.InsertOpenGaussSiteList(&osl) + if sitGaussId > 0 { + models.UpdateOpenGaussCveByGid(ogl[0].GaussTempId, sitGaussId) + models.UpdateOpenGaussPackByGid(ogl[0].GaussTempId, sitGaussId) + } else { + logs.Error("InsertOpenGaussSiteList, gErr: ", gErr) + return + } + *saInitValue += 1 + // Delete duplicate data + if len(ogl) > 1 { + ogg, oggErr := models.QueryOpenGaussCveByGid(sitGaussId) + if oggErr != nil { + logs.Error("PreGeneratedSaData, QueryOpenGaussCveByGid, ogErr: ", oggErr) + return + } + for _, l := range ogl[1:] { + TempCveToGaussCve(l.GaussTempId, ogg) + } + } + } else { + logs.Error("PreGeneratedSaData, QuerySaTempByPackName, ogErr: ", ogErr) + return + } + } else { + ogl, ogErr := models.QuerySaTempByPackName(packName) + if len(ogl) > 0 { + for _, l := range ogl { + openGaussNum := "openGauss-SA-" + strconv.Itoa(time.Now().Year()) + "-" + strconv.FormatInt(*saInitValue, 10) + var osl models.OpenGaussSiteList + CreateOpenGaussSite(&osl, l, bVersionSlice, openGaussNum, *saInitValue) + sitGaussId, gErr := models.InsertOpenGaussSiteList(&osl) + if sitGaussId > 0 { + models.UpdateOpenGaussCveByGid(l.GaussTempId, sitGaussId) + models.UpdateOpenGaussPackByGid(l.GaussTempId, sitGaussId) + } else { + logs.Error("InsertOpenGaussSiteList, gErr: ", gErr) + return + } + *saInitValue += 1 + } + } else { + logs.Error("PreGeneratedSaData, QuerySaTempByPackName2, ogErr: ", ogErr) + return + } + } + models.DeleteSaTempByPackName(packName) +} + +// Reorganize the data +func CreateOpenGaussSite(osl *models.OpenGaussSiteList, olt models.OpenGaussListTemp, + bVersionSlice []string, openGaussNum string, saInitValue int64) { + osl.SaNum = saInitValue + osl.CveNums = olt.CveNums + osl.PublicDate = olt.PublicDate + osl.InfluenceComponent = olt.InfluenceComponent + osl.Status = 1 + osl.CreateTime = common.GetCurTime() + osl.CveLevelValue = olt.CveLevelValue + osl.CveLevel = olt.CveLevel + osl.Description = olt.Description + if len(bVersionSlice) < 2 { + osl.Theme = olt.Theme + osl.Introduction = olt.Introduction + } else if len(bVersionSlice) == 2 { + bVersionStr := strings.Join(bVersionSlice, " and ") + theme := strings.ReplaceAll(olt.Theme, olt.AffectProduct, bVersionStr) + osl.Theme = theme + introduction := strings.ReplaceAll(olt.Introduction, olt.AffectProduct, bVersionStr) + osl.Introduction = introduction + } else { + bVersionStr := strings.Join(bVersionSlice[:len(bVersionSlice)-1], ",") + " and " + bVersionSlice[len(bVersionSlice)-1] + theme := strings.ReplaceAll(olt.Theme, olt.AffectProduct, bVersionStr) + osl.Theme = theme + introduction := strings.ReplaceAll(olt.Introduction, olt.AffectProduct, bVersionStr) + osl.Introduction = introduction + } + osl.AffectProduct = strings.Join(bVersionSlice, "/") + osl.Summary = olt.Summary + osl.GaussSaNum = openGaussNum + osl.Years = time.Now().Year() +} diff --git a/taskhandler/issue.go b/taskhandler/issue.go index 99669915bd83aa43d4cdadd1ddaf7d83ffe95eac..3fc5219a9695516a634813b40f1bb91073360d08 100644 --- a/taskhandler/issue.go +++ b/taskhandler/issue.go @@ -32,7 +32,8 @@ func ProcIssueIsExists(prnum int, owner, gaussOwner, accessToken, gitGaussToken issueErr := error(nil) issueData := map[string]interface{}{} if v.OrganizationID == 2 { - issueErr, issueData = GetGiteeIssue(gitGaussToken, gaussOwner, "security", issueTmp.IssueNum) + gaussIssuePath := beego.AppConfig.String("opengauss::gauss_issue_path") + issueErr, issueData = GetGiteeIssue(gitGaussToken, gaussOwner, gaussIssuePath, issueTmp.IssueNum) } else { issueErr, issueData = GetGiteeIssue(accessToken, owner, issueTmp.OwnedComponent, issueTmp.IssueNum) } diff --git a/taskhandler/yaml.go b/taskhandler/yaml.go index 3206fafaddca8594be91f4397470e2298cf71d62..7679db2b69eceba962f639e930d51e665df47d80 100644 --- a/taskhandler/yaml.go +++ b/taskhandler/yaml.go @@ -6,6 +6,7 @@ import ( "cvevulner/util" "encoding/json" "errors" + "fmt" "github.com/astaxie/beego/logs" "net/http" "net/url" @@ -14,6 +15,7 @@ import ( "sync" ) +var lock sync.Mutex func GetYamlTables(url string) (string, error) { compURL := url + "/lifeCycle/tables" @@ -45,8 +47,6 @@ func GetYamlTables(url string) (string, error) { return "", nil } -var lock sync.Mutex - //GetYamlByGit func GetYamlByGit(url string) (string, error) { defer common.Catchs() @@ -405,3 +405,98 @@ func GetPackageInfo(urls string, tableValue models.GitPackageTable, ge models.Gi } return "", nil } + +func GetEulerYamlInfo(url string) (string, error) { + defer common.Catchs() + compUrl := url + "?community=openeuler" + 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 Request failed, url: ", compUrl) + return "", err + } + if respBody == nil || respBody["data"] == nil || len(respBody["data"].([]interface{})) == 0 { + logs.Error("Data is empty, url: ", compUrl) + return "", fmt.Errorf("Data is empty, url: %s", compUrl) + } + if respBody["code"].(float64) == 200 && respBody["total"].(float64) > 0 { + for _, values := range respBody["data"].([]interface{}) { + valuesX := values.(map[string]interface{}) + ProcYamlInfo(valuesX) + } + } + return "", nil +} + +// Parse the received json data +func ProcYamlInfo(valuesX map[string]interface{}) { + if valuesX != nil && len(valuesX) > 0 { + for repKey, repValue := range valuesX { + if repKey != "" && len(repKey) > 1 { + var er models.OpenEulerRepoOrigin + er.PackageName = repKey + value := repValue.(map[string]interface{}) + brValue, brOk := value["branches"] + if brOk { + brKey := brValue.([]interface{}) + if brKey != nil && len(brKey) > 0 { + for _, branchValue := range brKey { + v := branchValue.(map[string]interface{}) + for vKey, vu := range v { + switch vKey { + case "summary": + er.Summary = vu.(string) + case "version": + er.Version = vu.(string) + case "brname": + er.Branchs = vu.(string) + case "description": + er.Decription = vu.(string) + } + UpdateYamlToDb(er) + } + } + } + } + } + } + } + return +} + +// Update data to the database +func UpdateYamlToDb(er models.OpenEulerRepoOrigin) { + if len(er.PackageName) > 0 && len(er.Version) > 0 { + var oro models.OpenEulerRepoOrigin + oro.PackageName = er.PackageName + oro.Version = er.Version + repErr := models.QueryEulerRepoOrigin(&oro, "PackageName", "Version") + if oro.Id > 0 { + oro.Decription = er.Decription + oro.Branchs = er.Branchs + oro.Summary = er.Summary + oro.UpdateTime = er.UpdateTime + oro.Status = 1 + upErr := models.UpdateEulerRepoOrigin(&oro, "Decription", "Branchs", "Summary", "UpdateTime") + logs.Info("UpdateEulerRepoOrigin, upErr: ", upErr) + } else { + logs.Info(repErr) + oro.Decription = er.Decription + oro.Branchs = er.Branchs + oro.Summary = er.Summary + oro.UpdateTime = er.UpdateTime + oro.PackageName = er.PackageName + oro.Version = er.Version + oro.Status = 1 + oro.CreateTime = common.GetCurTime() + id, inErr := models.InsertEulerRepoOrigin(&oro) + logs.Info("InsertEulerRepoOrigin, id, inErr: ", id, inErr) + } + } +}