From 9cd2c6a1e2436023c204e3240d63ee8bfe10c2bb Mon Sep 17 00:00:00 2001 From: Sajad Date: Thu, 14 Jul 2022 15:51:38 +0530 Subject: [PATCH 01/10] add google chat (#155) --- pkg/providers/googlechat/googlechat.go | 51 ++++++++++++++++++++++++++ pkg/providers/providers.go | 24 ++++++++---- 2 files changed, 68 insertions(+), 7 deletions(-) create mode 100644 pkg/providers/googlechat/googlechat.go diff --git a/pkg/providers/googlechat/googlechat.go b/pkg/providers/googlechat/googlechat.go new file mode 100644 index 0000000..8412dc2 --- /dev/null +++ b/pkg/providers/googlechat/googlechat.go @@ -0,0 +1,51 @@ +package googlechat + +import ( + "fmt" + + "github.com/containrrr/shoutrrr" + "github.com/pkg/errors" + "github.com/projectdiscovery/gologger" + "github.com/projectdiscovery/notify/pkg/utils" + "go.uber.org/multierr" +) + +type Provider struct { + GoogleChat []*Options `yaml:"googleChat,omitempty"` +} + +type Options struct { + ID string `yaml:"id,omitempty"` + Space string `yaml:"space,omitempty"` + Key string `yaml:"key,omitempty"` + Token string `yaml:"token,omitempty"` + GoogleChatFormat string `yaml:"google_chat_format,omitempty"` +} + +func New(options []*Options, ids []string) (*Provider, error) { + provider := &Provider{} + + for _, o := range options { + if len(ids) == 0 || utils.Contains(ids, o.ID) { + provider.GoogleChat = append(provider.GoogleChat, o) + } + } + + return provider, nil +} + +func (p *Provider) Send(message, CliFormat string) error { + var GoogleChatErr error + for _, pr := range p.GoogleChat { + msg := utils.FormatMessage(message, utils.SelectFormat(CliFormat, pr.GoogleChatFormat)) + url := fmt.Sprintf("googlechat://chat.googleapis.com/v1/spaces/%s/messages?key=%s&token=%s", pr.Space, pr.Key, pr.Token) + err := shoutrrr.Send(url, msg) + if err != nil { + err = errors.Wrap(err, fmt.Sprintf("failed to send googleChat notification for id: %s ", pr.ID)) + GoogleChatErr = multierr.Append(GoogleChatErr, err) + continue + } + gologger.Verbose().Msgf("googleChat notification sent for id: %s", pr.ID) + } + return GoogleChatErr +} diff --git a/pkg/providers/providers.go b/pkg/providers/providers.go index 01ade2c..9ccfc44 100644 --- a/pkg/providers/providers.go +++ b/pkg/providers/providers.go @@ -6,6 +6,7 @@ import ( "github.com/projectdiscovery/gologger" "github.com/projectdiscovery/notify/pkg/providers/custom" "github.com/projectdiscovery/notify/pkg/providers/discord" + "github.com/projectdiscovery/notify/pkg/providers/googlechat" "github.com/projectdiscovery/notify/pkg/providers/pushover" "github.com/projectdiscovery/notify/pkg/providers/slack" "github.com/projectdiscovery/notify/pkg/providers/smtp" @@ -18,13 +19,14 @@ import ( // ProviderOptions is configuration for notify providers type ProviderOptions struct { - Slack []*slack.Options `yaml:"slack,omitempty"` - Discord []*discord.Options `yaml:"discord,omitempty"` - Pushover []*pushover.Options `yaml:"pushover,omitempty"` - SMTP []*smtp.Options `yaml:"smtp,omitempty"` - Teams []*teams.Options `yaml:"teams,omitempty"` - Telegram []*telegram.Options `yaml:"telegram,omitempty"` - Custom []*custom.Options `yaml:"custom,omitempty"` + Slack []*slack.Options `yaml:"slack,omitempty"` + Discord []*discord.Options `yaml:"discord,omitempty"` + Pushover []*pushover.Options `yaml:"pushover,omitempty"` + SMTP []*smtp.Options `yaml:"smtp,omitempty"` + Teams []*teams.Options `yaml:"teams,omitempty"` + Telegram []*telegram.Options `yaml:"telegram,omitempty"` + GoogleChat []*googlechat.Options `yaml:"googlechat,omitempty"` + Custom []*custom.Options `yaml:"custom,omitempty"` } // Provider is an interface implemented by providers @@ -67,6 +69,14 @@ func New(providerOptions *ProviderOptions, options *types.Options) (*Client, err } client.providers = append(client.providers, provider) } + if providerOptions.GoogleChat != nil && (len(options.Providers) == 0 || utils.Contains(options.Providers, "googlechat")) { + + provider, err := googlechat.New(providerOptions.GoogleChat, options.IDs) + if err != nil { + return nil, errors.Wrap(err, "could not create googlechat provider client") + } + client.providers = append(client.providers, provider) + } if providerOptions.SMTP != nil && (len(options.Providers) == 0 || utils.Contains(options.Providers, "smtp")) { provider, err := smtp.New(providerOptions.SMTP, options.IDs) From b10be4445c0a28126dd8bfa5fdb3b0a0db78096f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Jul 2022 15:58:15 +0530 Subject: [PATCH 02/10] chore(deps): bump github.com/projectdiscovery/goflags from 0.0.7 to 0.0.8 (#152) * chore(deps): bump github.com/projectdiscovery/goflags Bumps [github.com/projectdiscovery/goflags](https://github.com/projectdiscovery/goflags) from 0.0.7 to 0.0.8. - [Release notes](https://github.com/projectdiscovery/goflags/releases) - [Commits](https://github.com/projectdiscovery/goflags/compare/v0.0.7...v0.0.8) --- updated-dependencies: - dependency-name: github.com/projectdiscovery/goflags dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * update goflags stringSliceVar breaking changes Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Sajad Parra --- cmd/notify/notify.go | 4 ++-- go.mod | 4 ++-- go.sum | 12 ++++++++---- pkg/types/types.go | 18 +++++++++--------- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/cmd/notify/notify.go b/cmd/notify/notify.go index 27d512b..ed75e3b 100644 --- a/cmd/notify/notify.go +++ b/cmd/notify/notify.go @@ -52,8 +52,8 @@ func readConfig() { set.StringVar(&cfgFile, "config", "", "notify configuration file") set.StringVarP(&options.ProviderConfig, "provider-config", "pc", "", "provider config path (default: $HOME/.config/notify/provider-config.yaml)") set.StringVarP(&options.Data, "data", "i", "", "input file to send for notify") - set.NormalizedStringSliceVarP(&options.Providers, "provider", "p", []string{}, "provider to send the notification to (optional)") - set.NormalizedStringSliceVar(&options.IDs, "id", []string{}, "id to send the notification to (optional)") + set.StringSliceVarP(&options.Providers, "provider", "p", []string{}, "provider to send the notification to (optional)", goflags.NormalizedStringSliceOptions) + set.StringSliceVar(&options.IDs, "id", []string{}, "id to send the notification to (optional)", goflags.NormalizedStringSliceOptions) set.IntVarP(&options.RateLimit, "rate-limit", "rl", 1, "maximum number of HTTP requests to send per second") set.BoolVar(&options.Bulk, "bulk", false, "enable bulk processing") set.IntVarP(&options.CharLimit, "char-limit", "cl", 4000, "max character limit per message") diff --git a/go.mod b/go.mod index dc08802..6faa944 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/oriser/regroup v0.0.0-20210730155327-fca8d7531263 github.com/pkg/errors v0.9.1 github.com/projectdiscovery/fileutil v0.0.0-20220510111557-fba17e05663f - github.com/projectdiscovery/goflags v0.0.7 + github.com/projectdiscovery/goflags v0.0.8 github.com/projectdiscovery/gologger v1.1.4 go.uber.org/multierr v1.8.0 go.uber.org/ratelimit v0.2.0 @@ -31,5 +31,5 @@ require ( golang.org/x/net v0.0.0-20210614182718-04defd469f4e // indirect golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 // indirect google.golang.org/protobuf v1.25.0 // indirect - gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 178de23..29c1109 100644 --- a/go.sum +++ b/go.sum @@ -84,6 +84,7 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -133,10 +134,11 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/projectdiscovery/fileutil v0.0.0-20210928100737-cab279c5d4b5/go.mod h1:U+QCpQnX8o2N2w0VUGyAzjM3yBAe4BKedVElxiImsx0= github.com/projectdiscovery/fileutil v0.0.0-20220510111557-fba17e05663f h1:6SdZmaGf/XQGkBtOjN8I9HOnvjYufNxDk+9iPVHYMxw= github.com/projectdiscovery/fileutil v0.0.0-20220510111557-fba17e05663f/go.mod h1:qcx3tdBzVDlUvr5nMKrgzNkCNQpCV7kGbYlXBAtXz0o= -github.com/projectdiscovery/goflags v0.0.7 h1:aykmRkrOgDyRwcvGrK3qp+9aqcjGfAMs/+LtRmtyxwk= -github.com/projectdiscovery/goflags v0.0.7/go.mod h1:Jjwsf4eEBPXDSQI2Y+6fd3dBumJv/J1U0nmpM+hy2YY= +github.com/projectdiscovery/goflags v0.0.8 h1:IhTmnEGSKtBHfD23tSwpnzai5CRYfLKVOWlVq9ngYvY= +github.com/projectdiscovery/goflags v0.0.8/go.mod h1:GDSkWyXa6kfQjpJu10SO64DN8lXuKXVENlBMk8N7H80= github.com/projectdiscovery/gologger v1.1.4 h1:qWxGUq7ukHWT849uGPkagPKF3yBPYAsTtMKunQ8O2VI= github.com/projectdiscovery/gologger v1.1.4/go.mod h1:Bhb6Bdx2PV1nMaFLoXNBmHIU85iROS9y1tBuv7T5pMY= github.com/projectdiscovery/stringsutil v0.0.0-20210804142656-fd3c28dbaafe/go.mod h1:oTRc18WBv9t6BpaN9XBY+QmG28PUpsyDzRht56Qf49I= @@ -176,8 +178,9 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= @@ -289,7 +292,8 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/pkg/types/types.go b/pkg/types/types.go index 4f27285..233751b 100644 --- a/pkg/types/types.go +++ b/pkg/types/types.go @@ -3,15 +3,15 @@ package types import "github.com/projectdiscovery/goflags" type Options struct { - Verbose bool `yaml:"verbose,omitempty"` - NoColor bool `yaml:"no_color,omitempty"` - Silent bool `yaml:"silent,omitempty"` - Version bool `yaml:"version,omitempty"` - ProviderConfig string `yaml:"provider_config,omitempty"` - Providers goflags.NormalizedStringSlice `yaml:"providers,omitempty"` - IDs goflags.NormalizedStringSlice `yaml:"ids,omitempty"` - Proxy string `yaml:"proxy,omitempty"` - RateLimit int `yaml:"rate_limit,omitempty"` + Verbose bool `yaml:"verbose,omitempty"` + NoColor bool `yaml:"no_color,omitempty"` + Silent bool `yaml:"silent,omitempty"` + Version bool `yaml:"version,omitempty"` + ProviderConfig string `yaml:"provider_config,omitempty"` + Providers goflags.StringSlice `yaml:"providers,omitempty"` + IDs goflags.StringSlice `yaml:"ids,omitempty"` + Proxy string `yaml:"proxy,omitempty"` + RateLimit int `yaml:"rate_limit,omitempty"` MessageFormat string `yaml:"message_format,omitempty"` From 2c59eec1c1ef99812cccdded2ad8b9b098c458cc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Jul 2022 15:58:34 +0530 Subject: [PATCH 03/10] chore(deps): bump golang from 1.18.3-alpine to 1.18.4-alpine (#157) Bumps golang from 1.18.3-alpine to 1.18.4-alpine. --- updated-dependencies: - dependency-name: golang dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 88f6b04..d6b4684 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.18.3-alpine as build-env +FROM golang:1.18.4-alpine as build-env RUN go install -v github.com/projectdiscovery/notify/cmd/notify@latest FROM alpine:latest From 9513f412c2bee01e3ae58f2a8318201e7642cedf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Jul 2022 18:20:02 +0530 Subject: [PATCH 04/10] chore(deps): bump github.com/projectdiscovery/goflags (#158) Bumps [github.com/projectdiscovery/goflags](https://github.com/projectdiscovery/goflags) from 0.0.8 to 0.0.9. - [Release notes](https://github.com/projectdiscovery/goflags/releases) - [Commits](https://github.com/projectdiscovery/goflags/compare/v0.0.8...v0.0.9) --- updated-dependencies: - dependency-name: github.com/projectdiscovery/goflags dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 6faa944..3cf2a8c 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/oriser/regroup v0.0.0-20210730155327-fca8d7531263 github.com/pkg/errors v0.9.1 github.com/projectdiscovery/fileutil v0.0.0-20220510111557-fba17e05663f - github.com/projectdiscovery/goflags v0.0.8 + github.com/projectdiscovery/goflags v0.0.9 github.com/projectdiscovery/gologger v1.1.4 go.uber.org/multierr v1.8.0 go.uber.org/ratelimit v0.2.0 diff --git a/go.sum b/go.sum index 29c1109..6c9fd09 100644 --- a/go.sum +++ b/go.sum @@ -137,8 +137,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/projectdiscovery/fileutil v0.0.0-20210928100737-cab279c5d4b5/go.mod h1:U+QCpQnX8o2N2w0VUGyAzjM3yBAe4BKedVElxiImsx0= github.com/projectdiscovery/fileutil v0.0.0-20220510111557-fba17e05663f h1:6SdZmaGf/XQGkBtOjN8I9HOnvjYufNxDk+9iPVHYMxw= github.com/projectdiscovery/fileutil v0.0.0-20220510111557-fba17e05663f/go.mod h1:qcx3tdBzVDlUvr5nMKrgzNkCNQpCV7kGbYlXBAtXz0o= -github.com/projectdiscovery/goflags v0.0.8 h1:IhTmnEGSKtBHfD23tSwpnzai5CRYfLKVOWlVq9ngYvY= -github.com/projectdiscovery/goflags v0.0.8/go.mod h1:GDSkWyXa6kfQjpJu10SO64DN8lXuKXVENlBMk8N7H80= +github.com/projectdiscovery/goflags v0.0.9 h1:bPsYIPE1LvdgYaM3XNX0YmS68e6huv22W22rKh5IscI= +github.com/projectdiscovery/goflags v0.0.9/go.mod h1:t/dEhv2VDOzayugXZCkbkX8n+pPeVmRD+WgQRSgReeI= github.com/projectdiscovery/gologger v1.1.4 h1:qWxGUq7ukHWT849uGPkagPKF3yBPYAsTtMKunQ8O2VI= github.com/projectdiscovery/gologger v1.1.4/go.mod h1:Bhb6Bdx2PV1nMaFLoXNBmHIU85iROS9y1tBuv7T5pMY= github.com/projectdiscovery/stringsutil v0.0.0-20210804142656-fd3c28dbaafe/go.mod h1:oTRc18WBv9t6BpaN9XBY+QmG28PUpsyDzRht56Qf49I= @@ -173,14 +173,15 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.6.3/go.mod h1:jUMtyi0/lB5yZH/FjyGAoH7IMNrIhlBf6pXZmbMDvzw= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= -github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= From 3597ad1b7fdcd3b5bd7ee60d4439a038d67e813d Mon Sep 17 00:00:00 2001 From: Sajad Date: Wed, 10 Aug 2022 21:50:01 +0530 Subject: [PATCH 05/10] Msg Format conflict fix (#162) * fix SelectFormat * use sliceutil * remove debug instructions --- cmd/notify/notify.go | 2 +- go.mod | 1 + go.sum | 3 +++ pkg/providers/custom/custom.go | 3 ++- pkg/providers/discord/discord.go | 11 ++++++----- pkg/providers/googlechat/googlechat.go | 3 ++- pkg/providers/providers.go | 18 +++++++++--------- pkg/providers/pushover/pushover.go | 3 ++- pkg/providers/slack/slack.go | 3 ++- pkg/providers/smtp/smtp.go | 3 ++- pkg/providers/teams/teams.go | 3 ++- pkg/providers/telegram/telegram.go | 3 ++- pkg/utils/utils.go | 20 +++++++------------- 13 files changed, 41 insertions(+), 35 deletions(-) diff --git a/cmd/notify/notify.go b/cmd/notify/notify.go index ed75e3b..031fc29 100644 --- a/cmd/notify/notify.go +++ b/cmd/notify/notify.go @@ -57,7 +57,7 @@ func readConfig() { set.IntVarP(&options.RateLimit, "rate-limit", "rl", 1, "maximum number of HTTP requests to send per second") set.BoolVar(&options.Bulk, "bulk", false, "enable bulk processing") set.IntVarP(&options.CharLimit, "char-limit", "cl", 4000, "max character limit per message") - set.StringVarP(&options.MessageFormat, "msg-format", "mf", "{{data}}", "add custom formatting to message") + set.StringVarP(&options.MessageFormat, "msg-format", "mf", "", "add custom formatting to message") set.BoolVar(&options.Silent, "silent", false, "enable silent mode") set.BoolVarP(&options.Verbose, "verbose", "v", false, "enable verbose mode") set.BoolVar(&options.Version, "version", false, "display version") diff --git a/go.mod b/go.mod index 3cf2a8c..36a32be 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/projectdiscovery/fileutil v0.0.0-20220510111557-fba17e05663f github.com/projectdiscovery/goflags v0.0.9 github.com/projectdiscovery/gologger v1.1.4 + github.com/projectdiscovery/sliceutil v0.0.0-20220625085859-c3a4ecb669f4 go.uber.org/multierr v1.8.0 go.uber.org/ratelimit v0.2.0 gopkg.in/yaml.v2 v2.4.0 diff --git a/go.sum b/go.sum index 6c9fd09..5b64d26 100644 --- a/go.sum +++ b/go.sum @@ -141,6 +141,8 @@ github.com/projectdiscovery/goflags v0.0.9 h1:bPsYIPE1LvdgYaM3XNX0YmS68e6huv22W2 github.com/projectdiscovery/goflags v0.0.9/go.mod h1:t/dEhv2VDOzayugXZCkbkX8n+pPeVmRD+WgQRSgReeI= github.com/projectdiscovery/gologger v1.1.4 h1:qWxGUq7ukHWT849uGPkagPKF3yBPYAsTtMKunQ8O2VI= github.com/projectdiscovery/gologger v1.1.4/go.mod h1:Bhb6Bdx2PV1nMaFLoXNBmHIU85iROS9y1tBuv7T5pMY= +github.com/projectdiscovery/sliceutil v0.0.0-20220625085859-c3a4ecb669f4 h1:C04j5gVVMXqFyBIetAz92SyPRYCpkFgIwZw0L/pps9Q= +github.com/projectdiscovery/sliceutil v0.0.0-20220625085859-c3a4ecb669f4/go.mod h1:RxDaccMjPzIuF7F8XbdGl1yOcqxN4YPiHr9xHpfCkGI= github.com/projectdiscovery/stringsutil v0.0.0-20210804142656-fd3c28dbaafe/go.mod h1:oTRc18WBv9t6BpaN9XBY+QmG28PUpsyDzRht56Qf49I= github.com/projectdiscovery/stringsutil v0.0.0-20220422150559-b54fb5dc6833 h1:yo7hCL47BOHl8X/aMmPeRQwiqUrH6TZ2WjgqItaSPcc= github.com/projectdiscovery/stringsutil v0.0.0-20220422150559-b54fb5dc6833/go.mod h1:oTRc18WBv9t6BpaN9XBY+QmG28PUpsyDzRht56Qf49I= @@ -180,6 +182,7 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.3/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= diff --git a/pkg/providers/custom/custom.go b/pkg/providers/custom/custom.go index 890c61a..a39e3aa 100644 --- a/pkg/providers/custom/custom.go +++ b/pkg/providers/custom/custom.go @@ -9,6 +9,7 @@ import ( "github.com/projectdiscovery/gologger" "github.com/projectdiscovery/notify/pkg/utils" "github.com/projectdiscovery/notify/pkg/utils/httpreq" + "github.com/projectdiscovery/sliceutil" "go.uber.org/multierr" ) @@ -28,7 +29,7 @@ func New(options []*Options, ids []string) (*Provider, error) { provider := &Provider{} for _, o := range options { - if len(ids) == 0 || utils.Contains(ids, o.ID) { + if len(ids) == 0 || sliceutil.Contains(ids, o.ID) { provider.Custom = append(provider.Custom, o) } } diff --git a/pkg/providers/discord/discord.go b/pkg/providers/discord/discord.go index 880c6fd..cc59d8e 100644 --- a/pkg/providers/discord/discord.go +++ b/pkg/providers/discord/discord.go @@ -4,11 +4,12 @@ import ( "fmt" "github.com/containrrr/shoutrrr" + "github.com/oriser/regroup" "github.com/pkg/errors" "github.com/projectdiscovery/gologger" "github.com/projectdiscovery/notify/pkg/utils" + "github.com/projectdiscovery/sliceutil" "go.uber.org/multierr" - "github.com/oriser/regroup" ) type Provider struct { @@ -27,7 +28,7 @@ func New(options []*Options, ids []string) (*Provider, error) { provider := &Provider{} for _, o := range options { - if len(ids) == 0 || utils.Contains(ids, o.ID) { + if len(ids) == 0 || sliceutil.Contains(ids, o.ID) { provider.Discord = append(provider.Discord, o) } } @@ -39,16 +40,16 @@ func (p *Provider) Send(message, CliFormat string) error { for _, pr := range p.Discord { msg := utils.FormatMessage(message, utils.SelectFormat(CliFormat, pr.DiscordFormat)) - + discordWebhookRegex := regroup.MustCompile(`(?Phttps?):\/\/(?P(?:ptb\.|canary\.)?discord(?:app)?\.com)\/api(?:\/)?(?Pv\d{1,2})?\/webhooks\/(?P\d{17,19})\/(?P[\w\-]{68})`) matchedGroups, err := discordWebhookRegex.Groups(pr.DiscordWebHookURL) - + if err != nil { err := fmt.Errorf("incorrect discord configuration for id: %s ", pr.ID) DiscordErr = multierr.Append(DiscordErr, err) continue } - + webhookID, webhookToken := matchedGroups["webhook_identifier"], matchedGroups["webhook_token"] url := fmt.Sprintf("discord://%s@%s?splitlines=no", webhookToken, webhookID) sendErr := shoutrrr.Send(url, msg) diff --git a/pkg/providers/googlechat/googlechat.go b/pkg/providers/googlechat/googlechat.go index 8412dc2..085e75a 100644 --- a/pkg/providers/googlechat/googlechat.go +++ b/pkg/providers/googlechat/googlechat.go @@ -7,6 +7,7 @@ import ( "github.com/pkg/errors" "github.com/projectdiscovery/gologger" "github.com/projectdiscovery/notify/pkg/utils" + "github.com/projectdiscovery/sliceutil" "go.uber.org/multierr" ) @@ -26,7 +27,7 @@ func New(options []*Options, ids []string) (*Provider, error) { provider := &Provider{} for _, o := range options { - if len(ids) == 0 || utils.Contains(ids, o.ID) { + if len(ids) == 0 || sliceutil.Contains(ids, o.ID) { provider.GoogleChat = append(provider.GoogleChat, o) } } diff --git a/pkg/providers/providers.go b/pkg/providers/providers.go index 9ccfc44..3497483 100644 --- a/pkg/providers/providers.go +++ b/pkg/providers/providers.go @@ -13,7 +13,7 @@ import ( "github.com/projectdiscovery/notify/pkg/providers/teams" "github.com/projectdiscovery/notify/pkg/providers/telegram" "github.com/projectdiscovery/notify/pkg/types" - "github.com/projectdiscovery/notify/pkg/utils" + "github.com/projectdiscovery/sliceutil" "go.uber.org/multierr" ) @@ -44,7 +44,7 @@ func New(providerOptions *ProviderOptions, options *types.Options) (*Client, err client := &Client{providerOptions: providerOptions, options: options} - if providerOptions.Slack != nil && (len(options.Providers) == 0 || utils.Contains(options.Providers, "slack")) { + if providerOptions.Slack != nil && (len(options.Providers) == 0 || sliceutil.Contains(options.Providers, "slack")) { provider, err := slack.New(providerOptions.Slack, options.IDs) if err != nil { @@ -53,7 +53,7 @@ func New(providerOptions *ProviderOptions, options *types.Options) (*Client, err client.providers = append(client.providers, provider) } - if providerOptions.Discord != nil && (len(options.Providers) == 0 || utils.Contains(options.Providers, "discord")) { + if providerOptions.Discord != nil && (len(options.Providers) == 0 || sliceutil.Contains(options.Providers, "discord")) { provider, err := discord.New(providerOptions.Discord, options.IDs) if err != nil { @@ -61,7 +61,7 @@ func New(providerOptions *ProviderOptions, options *types.Options) (*Client, err } client.providers = append(client.providers, provider) } - if providerOptions.Pushover != nil && (len(options.Providers) == 0 || utils.Contains(options.Providers, "pushover")) { + if providerOptions.Pushover != nil && (len(options.Providers) == 0 || sliceutil.Contains(options.Providers, "pushover")) { provider, err := pushover.New(providerOptions.Pushover, options.IDs) if err != nil { @@ -69,7 +69,7 @@ func New(providerOptions *ProviderOptions, options *types.Options) (*Client, err } client.providers = append(client.providers, provider) } - if providerOptions.GoogleChat != nil && (len(options.Providers) == 0 || utils.Contains(options.Providers, "googlechat")) { + if providerOptions.GoogleChat != nil && (len(options.Providers) == 0 || sliceutil.Contains(options.Providers, "googlechat")) { provider, err := googlechat.New(providerOptions.GoogleChat, options.IDs) if err != nil { @@ -77,7 +77,7 @@ func New(providerOptions *ProviderOptions, options *types.Options) (*Client, err } client.providers = append(client.providers, provider) } - if providerOptions.SMTP != nil && (len(options.Providers) == 0 || utils.Contains(options.Providers, "smtp")) { + if providerOptions.SMTP != nil && (len(options.Providers) == 0 || sliceutil.Contains(options.Providers, "smtp")) { provider, err := smtp.New(providerOptions.SMTP, options.IDs) if err != nil { @@ -85,7 +85,7 @@ func New(providerOptions *ProviderOptions, options *types.Options) (*Client, err } client.providers = append(client.providers, provider) } - if providerOptions.Teams != nil && (len(options.Providers) == 0 || utils.Contains(options.Providers, "teams")) { + if providerOptions.Teams != nil && (len(options.Providers) == 0 || sliceutil.Contains(options.Providers, "teams")) { provider, err := teams.New(providerOptions.Teams, options.IDs) if err != nil { @@ -93,7 +93,7 @@ func New(providerOptions *ProviderOptions, options *types.Options) (*Client, err } client.providers = append(client.providers, provider) } - if providerOptions.Telegram != nil && (len(options.Providers) == 0 || utils.Contains(options.Providers, "telegram")) { + if providerOptions.Telegram != nil && (len(options.Providers) == 0 || sliceutil.Contains(options.Providers, "telegram")) { provider, err := telegram.New(providerOptions.Telegram, options.IDs) if err != nil { @@ -102,7 +102,7 @@ func New(providerOptions *ProviderOptions, options *types.Options) (*Client, err client.providers = append(client.providers, provider) } - if providerOptions.Custom != nil && (len(options.Providers) == 0 || utils.Contains(options.Providers, "custom")) { + if providerOptions.Custom != nil && (len(options.Providers) == 0 || sliceutil.Contains(options.Providers, "custom")) { provider, err := custom.New(providerOptions.Custom, options.IDs) if err != nil { diff --git a/pkg/providers/pushover/pushover.go b/pkg/providers/pushover/pushover.go index 5fdce66..e78d13c 100644 --- a/pkg/providers/pushover/pushover.go +++ b/pkg/providers/pushover/pushover.go @@ -8,6 +8,7 @@ import ( "github.com/pkg/errors" "github.com/projectdiscovery/gologger" "github.com/projectdiscovery/notify/pkg/utils" + "github.com/projectdiscovery/sliceutil" "go.uber.org/multierr" ) @@ -27,7 +28,7 @@ func New(options []*Options, ids []string) (*Provider, error) { provider := &Provider{} for _, o := range options { - if len(ids) == 0 || utils.Contains(ids, o.ID) { + if len(ids) == 0 || sliceutil.Contains(ids, o.ID) { provider.Pushover = append(provider.Pushover, o) } } diff --git a/pkg/providers/slack/slack.go b/pkg/providers/slack/slack.go index 43d5272..aa07cc9 100644 --- a/pkg/providers/slack/slack.go +++ b/pkg/providers/slack/slack.go @@ -9,6 +9,7 @@ import ( "github.com/pkg/errors" "github.com/projectdiscovery/gologger" "github.com/projectdiscovery/notify/pkg/utils" + "github.com/projectdiscovery/sliceutil" "go.uber.org/multierr" ) @@ -31,7 +32,7 @@ func New(options []*Options, ids []string) (*Provider, error) { provider := &Provider{} for _, o := range options { - if len(ids) == 0 || utils.Contains(ids, o.ID) { + if len(ids) == 0 || sliceutil.Contains(ids, o.ID) { provider.Slack = append(provider.Slack, o) } } diff --git a/pkg/providers/smtp/smtp.go b/pkg/providers/smtp/smtp.go index 72b1870..5d2033a 100644 --- a/pkg/providers/smtp/smtp.go +++ b/pkg/providers/smtp/smtp.go @@ -8,6 +8,7 @@ import ( "github.com/pkg/errors" "github.com/projectdiscovery/gologger" "github.com/projectdiscovery/notify/pkg/utils" + "github.com/projectdiscovery/sliceutil" "go.uber.org/multierr" ) @@ -30,7 +31,7 @@ func New(options []*Options, ids []string) (*Provider, error) { provider := &Provider{} for _, o := range options { - if len(ids) == 0 || utils.Contains(ids, o.ID) { + if len(ids) == 0 || sliceutil.Contains(ids, o.ID) { provider.SMTP = append(provider.SMTP, o) } } diff --git a/pkg/providers/teams/teams.go b/pkg/providers/teams/teams.go index 57c6c1c..1c75e0f 100644 --- a/pkg/providers/teams/teams.go +++ b/pkg/providers/teams/teams.go @@ -8,6 +8,7 @@ import ( "github.com/pkg/errors" "github.com/projectdiscovery/gologger" "github.com/projectdiscovery/notify/pkg/utils" + "github.com/projectdiscovery/sliceutil" "go.uber.org/multierr" ) @@ -25,7 +26,7 @@ func New(options []*Options, ids []string) (*Provider, error) { provider := &Provider{} for _, o := range options { - if len(ids) == 0 || utils.Contains(ids, o.ID) { + if len(ids) == 0 || sliceutil.Contains(ids, o.ID) { provider.Teams = append(provider.Teams, o) } } diff --git a/pkg/providers/telegram/telegram.go b/pkg/providers/telegram/telegram.go index 7c70043..c085529 100644 --- a/pkg/providers/telegram/telegram.go +++ b/pkg/providers/telegram/telegram.go @@ -7,6 +7,7 @@ import ( "github.com/pkg/errors" "github.com/projectdiscovery/gologger" "github.com/projectdiscovery/notify/pkg/utils" + "github.com/projectdiscovery/sliceutil" "go.uber.org/multierr" ) @@ -25,7 +26,7 @@ func New(options []*Options, ids []string) (*Provider, error) { provider := &Provider{} for _, o := range options { - if len(ids) == 0 || utils.Contains(ids, o.ID) { + if len(ids) == 0 || sliceutil.Contains(ids, o.ID) { provider.Telegram = append(provider.Telegram, o) } } diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 97e5737..71192f9 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -6,25 +6,19 @@ import ( const defaultFormat = "{{data}}" -func Contains(slice []string, item string) bool { - set := make(map[string]struct{}, len(slice)) - for _, s := range slice { - set[s] = struct{}{} - } - - _, ok := set[item] - return ok - -} - +// FormatMessage formats the message according to the format string func FormatMessage(msg, format string) string { return strings.Replace(format, defaultFormat, msg, -1) } +// SelectFormat returns the format string in the following order of precedence: +// 1. cliFormat +// 2. configFormat +// 3. defaulFormat func SelectFormat(cliFormat, configFormat string) string { - if cliFormat != "" && cliFormat != defaultFormat { + if cliFormat != "" { return cliFormat - } else if configFormat != "" && configFormat != defaultFormat { + } else if configFormat != "" { return configFormat } return defaultFormat From 24a06472c999489cecb33358ffabb2745747aac8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Aug 2022 02:49:04 +0400 Subject: [PATCH 06/10] chore(deps): bump golang from 1.18.4-alpine to 1.19.0-alpine (#163) Bumps golang from 1.18.4-alpine to 1.19.0-alpine. --- updated-dependencies: - dependency-name: golang dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index d6b4684..ae2bc04 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.18.4-alpine as build-env +FROM golang:1.19.0-alpine as build-env RUN go install -v github.com/projectdiscovery/notify/cmd/notify@latest FROM alpine:latest From e85b1a791405b879763fc7ca0a0f99b3dadb9b45 Mon Sep 17 00:00:00 2001 From: Sajad Date: Wed, 24 Aug 2022 16:32:00 +0530 Subject: [PATCH 07/10] Integration tests (#143) * add integration tests * add bash script to run integration test * update build-test workflow to run integration tests * temporally disabling few tests * misc update * variable name update * add env to integration test action * enable debug * edit slack success message Co-authored-by: sandeep --- .github/workflows/build-test.yml | 13 ++++- cmd/integration-test/action-run.sh | 20 ++++++++ cmd/integration-test/integration.go | 45 ++++++++++++++++ cmd/integration-test/providers.go | 74 +++++++++++++++++++++++++++ cmd/integration-test/run.sh | 14 +++++ cmd/integration-test/test-config.yaml | 42 +++++++++++++++ go.mod | 2 +- internal/testutils/integration.go | 41 +++++++++++++++ pkg/providers/slack/slack.go | 2 +- 9 files changed, 249 insertions(+), 4 deletions(-) create mode 100755 cmd/integration-test/action-run.sh create mode 100644 cmd/integration-test/integration.go create mode 100644 cmd/integration-test/providers.go create mode 100755 cmd/integration-test/run.sh create mode 100644 cmd/integration-test/test-config.yaml create mode 100644 internal/testutils/integration.go diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 4b4beae..5e2506d 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -1,6 +1,5 @@ name: 🔨 Build Test on: - push: pull_request: workflow_dispatch: @@ -24,4 +23,14 @@ jobs: - name: Build run: go build . - working-directory: cmd/notify/ \ No newline at end of file + working-directory: cmd/notify/ + + - name: Integration Tests + env: + DISCORD_WEBHOOK_URL: "${{ secrets.DISCORD_WEBHOOK_URL }}" + SLACK_WEBHOOK_URL: "${{ secrets.SLACK_WEBHOOK_URL }}" + CUSTOM_WEBOOK_URL: "${{ secrets.CUSTOM_WEBOOK_URL }}" + run: | + chmod +x action-run.sh + bash action-run.sh + working-directory: cmd/integration-test/ \ No newline at end of file diff --git a/cmd/integration-test/action-run.sh b/cmd/integration-test/action-run.sh new file mode 100755 index 0000000..53958c7 --- /dev/null +++ b/cmd/integration-test/action-run.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +rm -f final-config.yaml temp.yaml +( echo "cat <final-config.yaml"; + cat test-config.yaml; + echo "EOF"; +) >temp.yaml +. temp.yaml +rm integration-test notify 2>/dev/null + +go build ../notify +go build + +DEBUG=true ./integration-test --provider-config final-config.yaml +if [ $? -eq 0 ] +then + exit 0 +else + exit 1 +fi diff --git a/cmd/integration-test/integration.go b/cmd/integration-test/integration.go new file mode 100644 index 0000000..9aa55b9 --- /dev/null +++ b/cmd/integration-test/integration.go @@ -0,0 +1,45 @@ +package main + +import ( + "flag" + "fmt" + "os" + + "github.com/logrusorgru/aurora" + "github.com/projectdiscovery/notify/internal/testutils" +) + +var ( + providerConfig = flag.String("provider-config", "", "provider config to use for testing") + debug = os.Getenv("DEBUG") == "true" + errored = false + success = aurora.Green("[✓]").String() + failed = aurora.Red("[✘]").String() + testCases = map[string]testutils.TestCase{ + "discord": &discord{}, + "slack": &slack{}, + "custom": &custom{}, + // "telegram": &telegram{}, + // "teams": &teams{}, + // "smtp": &smtp{}, + // "pushover": &pushover{}, + } +) + +func main() { + flag.Parse() + + for name, test := range testCases { + fmt.Printf("Running test cases for \"%s\"\n", aurora.Blue(name)) + err := test.Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "%s Test \"%s\" failed: %s\n", failed, name, err) + errored = true + } else { + fmt.Printf("%s Test \"%s\" passed!\n", success, name) + } + } + if errored { + os.Exit(1) + } +} diff --git a/cmd/integration-test/providers.go b/cmd/integration-test/providers.go new file mode 100644 index 0000000..7cbef0a --- /dev/null +++ b/cmd/integration-test/providers.go @@ -0,0 +1,74 @@ +package main + +import ( + "fmt" + "strings" + + "github.com/projectdiscovery/notify/internal/testutils" +) + +func run(provider string) error { + args := []string{"--provider", provider} + if *providerConfig != "" { + args = append(args, "--provider-config", *providerConfig) + } + results, err := testutils.RunNotifyAndGetResults(debug, args...) + if err != nil { + return err + } + if len(results) < 1 { + return errIncorrectResultsCount(results) + } + for _, r := range results { + if !strings.Contains(r, provider) { + return fmt.Errorf("incorrect result %s", results[0]) + } + } + return nil +} + +type discord struct{} + +func (h *discord) Execute() error { + return run("discord") +} + +type custom struct{} + +func (h *custom) Execute() error { + return run("custom") +} + +type slack struct{} + +func (h *slack) Execute() error { + return run("slack") +} + +// type pushover struct{} +// +// func (h *pushover) Execute() error { +// return run("pushover") +// } +// +// type smtp struct{} +// +// func (h *smtp) Execute() error { +// return run("smtp") +// } +// +// type teams struct{} +// +// func (h *teams) Execute() error { +// return run("teams") +// } +// +// type telegram struct{} +// +// func (h *telegram) Execute() error { +// return run("telegram") +// } + +func errIncorrectResultsCount(results []string) error { + return fmt.Errorf("incorrect number of results %s", strings.Join(results, "\n\t")) +} diff --git a/cmd/integration-test/run.sh b/cmd/integration-test/run.sh new file mode 100755 index 0000000..15abb9f --- /dev/null +++ b/cmd/integration-test/run.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +rm integration-test notify 2>/dev/null + +go build ../notify +go build + +./integration-test +if [ $? -eq 0 ] +then + exit 0 +else + exit 1 +fi diff --git a/cmd/integration-test/test-config.yaml b/cmd/integration-test/test-config.yaml new file mode 100644 index 0000000..49db7f7 --- /dev/null +++ b/cmd/integration-test/test-config.yaml @@ -0,0 +1,42 @@ +discord: + - id: "disocord-integration-test" + discord_webhook_url: "${DISCORD_WEBHOOK_URL}" + discord_format: "{{data}}" +slack: + - id: "slack-integration-test" + slack_channel: "random" + slack_username: "test" + slack_webhook_url: "${SLACK_WEBHOOK_URL}" + slack_format: "{{data}}" +telegram: + - id: "telegram-integration-test" + telegram_api_key: "${telegram_api_key}" + telegram_chat_id: "${telegram_chat_id}" + telegram_format: "{{data}}" +custom: + - id: "custom-integration-test" + custom_webook_url: "${CUSTOM_WEBOOK_URL}" + custom_method: POST + custom_format: '{{data}}' + custom_headers: + Content-Type: application/json +pushover: + - id: "push" + pushover_user_key: "${pushover_user_key}" + pushover_api_token: "${pushover_api_token}" + pushover_format: "{{data}}" + pushover_devices: + - "iphone" +smtp: + - id: email + smtp_server: "${smtp_server}" + smtp_username: "${smtp_username}" + smtp_password: "${smtp_password}" + from_address: "${smtp_from_address}" + smtp_cc: + - "${smtp_cc}" + smtp_format: "{{data}}" +teams: + - id: teams-integration-test + teams_webhook_url: "${teams_webhook_url}" + teams_format: "{{data}}" diff --git a/go.mod b/go.mod index 36a32be..48b22b9 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d github.com/containrrr/shoutrrr v0.4.5-0.20220522113502-c91dc3cf1279 github.com/json-iterator/go v1.1.12 + github.com/logrusorgru/aurora v2.0.3+incompatible github.com/oriser/regroup v0.0.0-20210730155327-fca8d7531263 github.com/pkg/errors v0.9.1 github.com/projectdiscovery/fileutil v0.0.0-20220510111557-fba17e05663f @@ -22,7 +23,6 @@ require ( github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08 // indirect github.com/fatih/color v1.10.0 // indirect - github.com/logrusorgru/aurora v2.0.3+incompatible // indirect github.com/mattn/go-colorable v0.1.8 // indirect github.com/mattn/go-isatty v0.0.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect diff --git a/internal/testutils/integration.go b/internal/testutils/integration.go new file mode 100644 index 0000000..fa4887e --- /dev/null +++ b/internal/testutils/integration.go @@ -0,0 +1,41 @@ +package testutils + +import ( + "fmt" + "os/exec" + "strings" +) + +// RunNotifyAndGetResults returns a list of results for a template +func RunNotifyAndGetResults(debug bool, args ...string) ([]string, error) { + cmd := exec.Command("bash", "-c") + cmdLine := `echo "hello from notify integration test :)"` + ` | ./notify ` + cmdLine += strings.Join(args, " ") + + cmdLine += " --v" + + cmd.Args = append(cmd.Args, cmdLine) + data, err := cmd.CombinedOutput() + if err != nil { + return nil, err + } + parts := []string{} + items := strings.Split(string(data), "\n") + for _, i := range items { + if i != "" { + if debug { + fmt.Printf("%s\n", i) + } + if strings.Contains(i, "notification sent for id:") { + parts = append(parts, i) + } + } + } + return parts, nil +} + +// TestCase is a single integration test case +type TestCase interface { + // Execute executes a test case and returns any errors if occurred + Execute() error +} diff --git a/pkg/providers/slack/slack.go b/pkg/providers/slack/slack.go index aa07cc9..4cf6893 100644 --- a/pkg/providers/slack/slack.go +++ b/pkg/providers/slack/slack.go @@ -79,7 +79,7 @@ func (p *Provider) Send(message, CliFormat string) error { continue } } - gologger.Verbose().Msgf("Slack notification sent successfully for id: %s", pr.ID) + gologger.Verbose().Msgf("Slack notification sent for id: %s", pr.ID) } return SlackErr From b9b6a8b56e5117b64cec873230803e5ea9d5fe76 Mon Sep 17 00:00:00 2001 From: Sajad Date: Wed, 24 Aug 2022 16:37:20 +0530 Subject: [PATCH 08/10] add delay option (#164) --- cmd/notify/notify.go | 1 + internal/runner/runner.go | 3 +++ pkg/types/types.go | 1 + 3 files changed, 5 insertions(+) diff --git a/cmd/notify/notify.go b/cmd/notify/notify.go index 031fc29..8c0ee66 100644 --- a/cmd/notify/notify.go +++ b/cmd/notify/notify.go @@ -55,6 +55,7 @@ func readConfig() { set.StringSliceVarP(&options.Providers, "provider", "p", []string{}, "provider to send the notification to (optional)", goflags.NormalizedStringSliceOptions) set.StringSliceVar(&options.IDs, "id", []string{}, "id to send the notification to (optional)", goflags.NormalizedStringSliceOptions) set.IntVarP(&options.RateLimit, "rate-limit", "rl", 1, "maximum number of HTTP requests to send per second") + set.IntVarP(&options.Delay, "delay", "d", 0, "delay in seconds between each notification") set.BoolVar(&options.Bulk, "bulk", false, "enable bulk processing") set.IntVarP(&options.CharLimit, "char-limit", "cl", 4000, "max character limit per message") set.StringVarP(&options.MessageFormat, "msg-format", "mf", "", "add custom formatting to message") diff --git a/internal/runner/runner.go b/internal/runner/runner.go index 9f87c9f..d7a8402 100644 --- a/internal/runner/runner.go +++ b/internal/runner/runner.go @@ -128,6 +128,9 @@ func (r *Runner) Run() error { func (r *Runner) sendMessage(msg string) error { if len(msg) > 0 { + if r.options.Delay > 0 { + time.Sleep(time.Duration(r.options.Delay) * time.Second) + } gologger.Silent().Msgf("%s\n", msg) err := r.providers.Send(msg) if err != nil { diff --git a/pkg/types/types.go b/pkg/types/types.go index 233751b..7caa01c 100644 --- a/pkg/types/types.go +++ b/pkg/types/types.go @@ -12,6 +12,7 @@ type Options struct { IDs goflags.StringSlice `yaml:"ids,omitempty"` Proxy string `yaml:"proxy,omitempty"` RateLimit int `yaml:"rate_limit,omitempty"` + Delay int `yaml:"delay,omitempty"` MessageFormat string `yaml:"message_format,omitempty"` From ae8f638c4702675ff641902b8fd5ba5406861ca0 Mon Sep 17 00:00:00 2001 From: Sajad Date: Wed, 24 Aug 2022 16:42:12 +0530 Subject: [PATCH 09/10] add parsemode option for telegram (#166) --- README.md | 2 ++ pkg/providers/telegram/telegram.go | 15 +++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 403dcb5..a78fe9e 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,8 @@ telegram: telegram_api_key: "XXXXXXXXXXXX" telegram_chat_id: "XXXXXXXX" telegram_format: "{{data}}" + # https://core.telegram.org/bots/api#formatting-options + telegram_parsemode: "Markdown" # None/Markdown/MarkdownV2/HTML pushover: - id: "push" diff --git a/pkg/providers/telegram/telegram.go b/pkg/providers/telegram/telegram.go index c085529..8252675 100644 --- a/pkg/providers/telegram/telegram.go +++ b/pkg/providers/telegram/telegram.go @@ -16,10 +16,11 @@ type Provider struct { } type Options struct { - ID string `yaml:"id,omitempty"` - TelegramAPIKey string `yaml:"telegram_api_key,omitempty"` - TelegramChatID string `yaml:"telegram_chat_id,omitempty"` - TelegramFormat string `yaml:"telegram_format,omitempty"` + ID string `yaml:"id,omitempty"` + TelegramAPIKey string `yaml:"telegram_api_key,omitempty"` + TelegramChatID string `yaml:"telegram_chat_id,omitempty"` + TelegramFormat string `yaml:"telegram_format,omitempty"` + TelegramParseMode string `yaml:"telegram_parsemode,omitempty"` } func New(options []*Options, ids []string) (*Provider, error) { @@ -38,8 +39,10 @@ func (p *Provider) Send(message, CliFormat string) error { var TelegramErr error for _, pr := range p.Telegram { msg := utils.FormatMessage(message, utils.SelectFormat(CliFormat, pr.TelegramFormat)) - - url := fmt.Sprintf("telegram://%s@telegram?channels=%s", pr.TelegramAPIKey, pr.TelegramChatID) + if pr.TelegramParseMode == "" { + pr.TelegramParseMode = "None" + } + url := fmt.Sprintf("telegram://%s@telegram?channels=%s&parsemode=%s", pr.TelegramAPIKey, pr.TelegramChatID, pr.TelegramParseMode) err := shoutrrr.Send(url, msg) if err != nil { err = errors.Wrap(err, fmt.Sprintf("failed to send telegram notification for id: %s ", pr.ID)) From 545350f61c1bcf5e8c23894401ecdfeeef807a71 Mon Sep 17 00:00:00 2001 From: sandeep Date: Wed, 24 Aug 2022 17:11:22 +0530 Subject: [PATCH 10/10] version update --- README.md | 46 ++++++++++++++++++++++++--------------- internal/runner/banner.go | 4 ++-- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index a78fe9e..0fba128 100644 --- a/README.md +++ b/README.md @@ -35,8 +35,9 @@ Notify is a Go-based assistance package that enables you to stream the output of # Features - Supports for Slack / Discord / Telegram -- Supports for Pushover / Email / Teams -- Supports for File / Pipe output +- Supports for Pushover / Email +- Supports for Microsoft Teams / Google Chat +- Supports for File / Pipe input - Supports Line by Line / Bulk Post - Supports using Single / Multiple providers - Supports Custom Web-hooks @@ -51,20 +52,23 @@ notify -h This will display help for the tool. Here are all the switches it supports. -| Flag | Description | Example | -|--------------------|----------------------------------------------------|------------------------------| -| `-config` | Notify configuration file | `notify -config config.yaml` | -| `-silent` | Don't print the banner | `notify -silent` | -| `-version` | Show version of notify | `notify -version` | -| `-v` | Show Verbose output | `notify -v` | -| `-no-color` | Don't Use colors in output | `notify -nc` | -| `-data` | File path to read data from | `notify -i test.txt` | -| `-bulk` | Read and send data in bulk | `notify -bulk` | -| `-char-limit` | Character limit for message (default 4000) | `notify -cl 2000` | -| `-provider-config` | provider config path | `notify -pc provider.yaml` | -| `-provider` | provider to send the notification to (optional) | `notify -p slack,telegram` | -| `-id` | id to send the notification to (optional) | `notify -id recon,scans` | -| `-rate-limit` | maximum number of HTTP requests to send per second | `notify -rl 1` | +| Flag | Description | Example | +|--------------------|----------------------------------------------------|---------------------------------------| +| `-bulk` | enable bulk processing | `notify -bulk` | +| `-char-limit` | max character limit per message (default 4000) | `notify -cl 2000` | +| `-config` | notify configuration file | `notify -config config.yaml` | +| `-data` | input file to send for notify | `notify -i test.txt` | +| `-delay` | delay in seconds between each notification | `notify -d 2` | +| `-id` | id to send the notification to (optional) | `notify -id recon,scans` | +| `-msg-format` | add custom formatting to message | `notify -mf Hey {{data}}` | +| `-no-color` | disable colors in output | `notify -nc` | +| `-provider-config` | provider config path | `notify -pc provider.yaml` | +| `-provider` | provider to send the notification to (optional) | `notify -p slack,telegram` | +| `-proxy` | http proxy to use with notify | `notify -proxy http://127.0.0.1:8080` | +| `-rate-limit` | maximum number of HTTP requests to send per second | `notify -rl 1` | +| `-silent` | enable silent mode | `notify -silent` | +| `-verbose` | enable verbose mode | `notify -version` | +| `-version` | display version | `notify -version` | # Notify Installation @@ -109,8 +113,7 @@ telegram: telegram_api_key: "XXXXXXXXXXXX" telegram_chat_id: "XXXXXXXX" telegram_format: "{{data}}" - # https://core.telegram.org/bots/api#formatting-options - telegram_parsemode: "Markdown" # None/Markdown/MarkdownV2/HTML + telegram_parsemode: "Markdown" # None/Markdown/MarkdownV2/HTML (https://core.telegram.org/bots/api#formatting-options) pushover: - id: "push" @@ -131,6 +134,13 @@ smtp: smtp_format: "{{data}}" subject: "Email subject" +googlechat: + - id: "gc" + key: "XXXXXXXX" + token: "XXXXXX" + space: "XXXXXX" + google_chat_format: "{{data}}" + custom: - id: webhook custom_webook_url: http://host/api/webhook diff --git a/internal/runner/banner.go b/internal/runner/banner.go index 6ad47e1..d6d8f6c 100644 --- a/internal/runner/banner.go +++ b/internal/runner/banner.go @@ -8,12 +8,12 @@ const banner = ` __ _ ___ ___ ___ / /_(_) _/_ __ / _ \/ _ \/ __/ / _/ // / -/_//_/\___/\__/_/_/ \_, / v1.0.2 +/_//_/\___/\__/_/_/ \_, / v1.0.3 /___/ ` // Version is the current version -const Version = `1.0.2` +const Version = `1.0.3` // showBanner is used to show the banner to the user func showBanner() {