Chatwork support (#634)
This commit is contained in:
@@ -59,6 +59,7 @@ type ReportCmd struct {
|
||||
toSlack bool
|
||||
toStride bool
|
||||
toHipChat bool
|
||||
toChatWork bool
|
||||
toEMail bool
|
||||
toSyslog bool
|
||||
toLocalFile bool
|
||||
@@ -117,6 +118,7 @@ func (*ReportCmd) Usage() string {
|
||||
[-to-slack]
|
||||
[-to-stride]
|
||||
[-to-hipchat]
|
||||
[-to-chatwork]
|
||||
[-to-localfile]
|
||||
[-to-s3]
|
||||
[-to-azure-blob]
|
||||
@@ -269,6 +271,7 @@ func (p *ReportCmd) SetFlags(f *flag.FlagSet) {
|
||||
f.BoolVar(&p.toSlack, "to-slack", false, "Send report via Slack")
|
||||
f.BoolVar(&p.toStride, "to-stride", false, "Send report via Stride")
|
||||
f.BoolVar(&p.toHipChat, "to-hipchat", false, "Send report via hipchat")
|
||||
f.BoolVar(&p.toChatWork, "to-chatwork", false, "Send report via chatwork")
|
||||
f.BoolVar(&p.toEMail, "to-email", false, "Send report via Email")
|
||||
f.BoolVar(&p.toSyslog, "to-syslog", false, "Send report via Syslog")
|
||||
f.BoolVar(&p.toLocalFile,
|
||||
@@ -336,6 +339,7 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
|
||||
c.Conf.ToSlack = p.toSlack
|
||||
c.Conf.ToStride = p.toStride
|
||||
c.Conf.ToHipChat = p.toHipChat
|
||||
c.Conf.ToChatWork = p.toChatWork
|
||||
c.Conf.ToEmail = p.toEMail
|
||||
c.Conf.ToSyslog = p.toSyslog
|
||||
c.Conf.ToLocalFile = p.toLocalFile
|
||||
@@ -382,6 +386,10 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
|
||||
reports = append(reports, report.HipChatWriter{})
|
||||
}
|
||||
|
||||
if p.toChatWork {
|
||||
reports = append(reports, report.ChatWorkWriter{})
|
||||
}
|
||||
|
||||
if p.toEMail {
|
||||
reports = append(reports, report.EMailWriter{})
|
||||
}
|
||||
|
||||
@@ -94,13 +94,14 @@ type Config struct {
|
||||
DebugSQL bool
|
||||
Lang string
|
||||
|
||||
EMail SMTPConf
|
||||
Slack SlackConf
|
||||
Stride StrideConf
|
||||
HipChat HipChatConf
|
||||
Syslog SyslogConf
|
||||
Default ServerInfo
|
||||
Servers map[string]ServerInfo
|
||||
EMail SMTPConf
|
||||
Slack SlackConf
|
||||
Stride StrideConf
|
||||
HipChat HipChatConf
|
||||
ChatWork ChatWorkConf
|
||||
Syslog SyslogConf
|
||||
Default ServerInfo
|
||||
Servers map[string]ServerInfo
|
||||
|
||||
CvssScoreOver float64
|
||||
IgnoreUnscoredCves bool
|
||||
@@ -132,6 +133,7 @@ type Config struct {
|
||||
ToSlack bool
|
||||
ToStride bool
|
||||
ToHipChat bool
|
||||
ToChatWork bool
|
||||
ToEmail bool
|
||||
ToSyslog bool
|
||||
ToLocalFile bool
|
||||
@@ -279,6 +281,10 @@ func (c Config) ValidateOnReport() bool {
|
||||
errs = append(errs, hipchaterrs...)
|
||||
}
|
||||
|
||||
if chatworkerrs := c.ChatWork.Validate(); 0 < len(chatworkerrs) {
|
||||
errs = append(errs, chatworkerrs...)
|
||||
}
|
||||
|
||||
if strideerrs := c.Stride.Validate(); 0 < len(strideerrs) {
|
||||
errs = append(errs, strideerrs...)
|
||||
}
|
||||
@@ -519,6 +525,32 @@ func (c *HipChatConf) Validate() (errs []error) {
|
||||
return
|
||||
}
|
||||
|
||||
// ChatWorkConf is ChatWork config
|
||||
type ChatWorkConf struct {
|
||||
ApiToken string `json:"ApiToken"`
|
||||
Room string `json:"Room"`
|
||||
}
|
||||
|
||||
// Validate validates configuration
|
||||
func (c *ChatWorkConf) Validate() (errs []error) {
|
||||
if !Conf.ToChatWork {
|
||||
return
|
||||
}
|
||||
if len(c.Room) == 0 {
|
||||
errs = append(errs, fmt.Errorf("chatworkcaht.room must not be empty"))
|
||||
}
|
||||
|
||||
if len(c.ApiToken) == 0 {
|
||||
errs = append(errs, fmt.Errorf("chatworkcaht.ApiToken must not be empty"))
|
||||
}
|
||||
|
||||
_, err := valid.ValidateStruct(c)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// SyslogConf is syslog config
|
||||
type SyslogConf struct {
|
||||
Protocol string
|
||||
|
||||
@@ -46,6 +46,7 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) error {
|
||||
Conf.Slack = conf.Slack
|
||||
Conf.Stride = conf.Stride
|
||||
Conf.HipChat = conf.HipChat
|
||||
Conf.ChatWork = conf.ChatWork
|
||||
Conf.Syslog = conf.Syslog
|
||||
|
||||
d := conf.Default
|
||||
|
||||
73
report/chatwork.go
Normal file
73
report/chatwork.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package report
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/future-architect/vuls/config"
|
||||
"github.com/future-architect/vuls/models"
|
||||
)
|
||||
|
||||
// ChatWorkWriter send report to ChatWork
|
||||
type ChatWorkWriter struct{}
|
||||
|
||||
func (w ChatWorkWriter) Write(rs ...models.ScanResult) (err error) {
|
||||
conf := config.Conf.ChatWork
|
||||
|
||||
for _, r := range rs {
|
||||
serverInfo := fmt.Sprintf("%s", r.ServerInfo())
|
||||
if err = ChatWorkpostMessage(conf.Room, conf.ApiToken, serverInfo); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, vinfo := range r.ScannedCves {
|
||||
maxCvss := vinfo.MaxCvssScore()
|
||||
severity := strings.ToUpper(maxCvss.Value.Severity)
|
||||
if severity == "" {
|
||||
severity = "?"
|
||||
}
|
||||
|
||||
message := fmt.Sprintf(`%s[info][title]"https://nvd.nist.gov/vuln/detail/%s" %s %s[/title]%s[/info]`,
|
||||
serverInfo,
|
||||
vinfo.CveID,
|
||||
strconv.FormatFloat(maxCvss.Value.Score, 'f', 1, 64),
|
||||
severity,
|
||||
vinfo.Summaries(config.Conf.Lang, r.Family)[0].Value)
|
||||
|
||||
if err = ChatWorkpostMessage(conf.Room, conf.ApiToken, message); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ChatWorkpostMessage(room, token, message string) error {
|
||||
uri := fmt.Sprintf("https://api.chatwork.com/v2/rooms/%s/messages=%s", room, token)
|
||||
|
||||
payload := url.Values{
|
||||
"body": {message},
|
||||
}
|
||||
|
||||
reqs, err := http.NewRequest("POST", uri, strings.NewReader(payload.Encode()))
|
||||
|
||||
reqs.Header.Add("X-ChatWorkToken", token)
|
||||
reqs.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client := &http.Client{}
|
||||
|
||||
resp, err := client.Do(reqs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
1
report/chatwork_test.go
Normal file
1
report/chatwork_test.go
Normal file
@@ -0,0 +1 @@
|
||||
package report
|
||||
Reference in New Issue
Block a user