feat: HTTP basic auth for webhooks (#9332)
Co-authored-by: Sebastian Spaink <3441183+sspaink@users.noreply.github.com>
This commit is contained in:
parent
7e2f22c00c
commit
f76729cfb9
|
|
@ -0,0 +1,23 @@
|
||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/subtle"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BasicAuth struct {
|
||||||
|
Username string `toml:"username"`
|
||||||
|
Password string `toml:"password"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BasicAuth) Verify(r *http.Request) bool {
|
||||||
|
if b.Username == "" && b.Password == "" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
username, password, ok := r.BasicAuth()
|
||||||
|
|
||||||
|
usernameComparison := subtle.ConstantTimeCompare([]byte(username), []byte(b.Username)) == 1
|
||||||
|
passwordComparison := subtle.ConstantTimeCompare([]byte(password), []byte(b.Password)) == 1
|
||||||
|
return ok && usernameComparison && passwordComparison
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBasicAuth_VerifyWithCredentials(t *testing.T) {
|
||||||
|
auth := BasicAuth{"username", "password"}
|
||||||
|
|
||||||
|
r := httptest.NewRequest("GET", "/github", nil)
|
||||||
|
r.SetBasicAuth(auth.Username, auth.Password)
|
||||||
|
|
||||||
|
require.True(t, auth.Verify(r))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBasicAuth_VerifyWithoutCredentials(t *testing.T) {
|
||||||
|
auth := BasicAuth{}
|
||||||
|
|
||||||
|
r := httptest.NewRequest("GET", "/github", nil)
|
||||||
|
|
||||||
|
require.True(t, auth.Verify(r))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBasicAuth_VerifyWithInvalidCredentials(t *testing.T) {
|
||||||
|
auth := BasicAuth{"username", "password"}
|
||||||
|
|
||||||
|
r := httptest.NewRequest("GET", "/github", nil)
|
||||||
|
r.SetBasicAuth("wrong-username", "wrong-password")
|
||||||
|
|
||||||
|
require.False(t, auth.Verify(r))
|
||||||
|
}
|
||||||
|
|
@ -23,21 +23,45 @@ sudo service telegraf start
|
||||||
[inputs.webhooks.filestack]
|
[inputs.webhooks.filestack]
|
||||||
path = "/filestack"
|
path = "/filestack"
|
||||||
|
|
||||||
|
## HTTP basic auth
|
||||||
|
#username = ""
|
||||||
|
#password = ""
|
||||||
|
|
||||||
[inputs.webhooks.github]
|
[inputs.webhooks.github]
|
||||||
path = "/github"
|
path = "/github"
|
||||||
# secret = ""
|
# secret = ""
|
||||||
|
|
||||||
|
## HTTP basic auth
|
||||||
|
#username = ""
|
||||||
|
#password = ""
|
||||||
|
|
||||||
[inputs.webhooks.mandrill]
|
[inputs.webhooks.mandrill]
|
||||||
path = "/mandrill"
|
path = "/mandrill"
|
||||||
|
|
||||||
|
## HTTP basic auth
|
||||||
|
#username = ""
|
||||||
|
#password = ""
|
||||||
|
|
||||||
[inputs.webhooks.rollbar]
|
[inputs.webhooks.rollbar]
|
||||||
path = "/rollbar"
|
path = "/rollbar"
|
||||||
|
|
||||||
|
## HTTP basic auth
|
||||||
|
#username = ""
|
||||||
|
#password = ""
|
||||||
|
|
||||||
[inputs.webhooks.papertrail]
|
[inputs.webhooks.papertrail]
|
||||||
path = "/papertrail"
|
path = "/papertrail"
|
||||||
|
|
||||||
|
## HTTP basic auth
|
||||||
|
#username = ""
|
||||||
|
#password = ""
|
||||||
|
|
||||||
[inputs.webhooks.particle]
|
[inputs.webhooks.particle]
|
||||||
path = "/particle"
|
path = "/particle"
|
||||||
|
|
||||||
|
## HTTP basic auth
|
||||||
|
#username = ""
|
||||||
|
#password = ""
|
||||||
```
|
```
|
||||||
|
|
||||||
## Available webhooks
|
## Available webhooks
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,21 @@ package filestack
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
|
||||||
"github.com/influxdata/telegraf"
|
"github.com/influxdata/telegraf"
|
||||||
|
"github.com/influxdata/telegraf/plugins/common/auth"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FilestackWebhook struct {
|
type FilestackWebhook struct {
|
||||||
Path string
|
Path string
|
||||||
acc telegraf.Accumulator
|
acc telegraf.Accumulator
|
||||||
log telegraf.Logger
|
log telegraf.Logger
|
||||||
|
auth.BasicAuth
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs *FilestackWebhook) Register(router *mux.Router, acc telegraf.Accumulator, log telegraf.Logger) {
|
func (fs *FilestackWebhook) Register(router *mux.Router, acc telegraf.Accumulator, log telegraf.Logger) {
|
||||||
|
|
@ -27,7 +29,13 @@ func (fs *FilestackWebhook) Register(router *mux.Router, acc telegraf.Accumulato
|
||||||
|
|
||||||
func (fs *FilestackWebhook) eventHandler(w http.ResponseWriter, r *http.Request) {
|
func (fs *FilestackWebhook) eventHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
defer r.Body.Close()
|
defer r.Body.Close()
|
||||||
body, err := io.ReadAll(r.Body)
|
|
||||||
|
if !fs.Verify(r) {
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := ioutil.ReadAll(r.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
|
||||||
"github.com/influxdata/telegraf"
|
"github.com/influxdata/telegraf"
|
||||||
|
"github.com/influxdata/telegraf/plugins/common/auth"
|
||||||
)
|
)
|
||||||
|
|
||||||
type GithubWebhook struct {
|
type GithubWebhook struct {
|
||||||
|
|
@ -18,6 +19,7 @@ type GithubWebhook struct {
|
||||||
Secret string
|
Secret string
|
||||||
acc telegraf.Accumulator
|
acc telegraf.Accumulator
|
||||||
log telegraf.Logger
|
log telegraf.Logger
|
||||||
|
auth.BasicAuth
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gh *GithubWebhook) Register(router *mux.Router, acc telegraf.Accumulator, log telegraf.Logger) {
|
func (gh *GithubWebhook) Register(router *mux.Router, acc telegraf.Accumulator, log telegraf.Logger) {
|
||||||
|
|
@ -30,6 +32,12 @@ func (gh *GithubWebhook) Register(router *mux.Router, acc telegraf.Accumulator,
|
||||||
|
|
||||||
func (gh *GithubWebhook) eventHandler(w http.ResponseWriter, r *http.Request) {
|
func (gh *GithubWebhook) eventHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
defer r.Body.Close()
|
defer r.Body.Close()
|
||||||
|
|
||||||
|
if !gh.Verify(r) {
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
eventType := r.Header.Get("X-Github-Event")
|
eventType := r.Header.Get("X-Github-Event")
|
||||||
data, err := io.ReadAll(r.Body)
|
data, err := io.ReadAll(r.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -2,20 +2,22 @@ package mandrill
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/influxdata/telegraf"
|
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
|
||||||
|
"github.com/influxdata/telegraf"
|
||||||
|
"github.com/influxdata/telegraf/plugins/common/auth"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MandrillWebhook struct {
|
type MandrillWebhook struct {
|
||||||
Path string
|
Path string
|
||||||
acc telegraf.Accumulator
|
acc telegraf.Accumulator
|
||||||
log telegraf.Logger
|
log telegraf.Logger
|
||||||
|
auth.BasicAuth
|
||||||
}
|
}
|
||||||
|
|
||||||
func (md *MandrillWebhook) Register(router *mux.Router, acc telegraf.Accumulator, log telegraf.Logger) {
|
func (md *MandrillWebhook) Register(router *mux.Router, acc telegraf.Accumulator, log telegraf.Logger) {
|
||||||
|
|
@ -33,7 +35,13 @@ func (md *MandrillWebhook) returnOK(w http.ResponseWriter, _ *http.Request) {
|
||||||
|
|
||||||
func (md *MandrillWebhook) eventHandler(w http.ResponseWriter, r *http.Request) {
|
func (md *MandrillWebhook) eventHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
defer r.Body.Close()
|
defer r.Body.Close()
|
||||||
body, err := io.ReadAll(r.Body)
|
|
||||||
|
if !md.Verify(r) {
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := ioutil.ReadAll(r.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,14 @@ import (
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
|
||||||
"github.com/influxdata/telegraf"
|
"github.com/influxdata/telegraf"
|
||||||
|
"github.com/influxdata/telegraf/plugins/common/auth"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PapertrailWebhook struct {
|
type PapertrailWebhook struct {
|
||||||
Path string
|
Path string
|
||||||
acc telegraf.Accumulator
|
acc telegraf.Accumulator
|
||||||
log telegraf.Logger
|
log telegraf.Logger
|
||||||
|
auth.BasicAuth
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pt *PapertrailWebhook) Register(router *mux.Router, acc telegraf.Accumulator, log telegraf.Logger) {
|
func (pt *PapertrailWebhook) Register(router *mux.Router, acc telegraf.Accumulator, log telegraf.Logger) {
|
||||||
|
|
@ -30,6 +32,11 @@ func (pt *PapertrailWebhook) eventHandler(w http.ResponseWriter, r *http.Request
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !pt.Verify(r) {
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
data := r.PostFormValue("payload")
|
data := r.PostFormValue("payload")
|
||||||
if data == "" {
|
if data == "" {
|
||||||
http.Error(w, "Bad Request", http.StatusBadRequest)
|
http.Error(w, "Bad Request", http.StatusBadRequest)
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
|
||||||
"github.com/influxdata/telegraf"
|
"github.com/influxdata/telegraf"
|
||||||
|
"github.com/influxdata/telegraf/plugins/common/auth"
|
||||||
)
|
)
|
||||||
|
|
||||||
type event struct {
|
type event struct {
|
||||||
|
|
@ -40,6 +41,7 @@ type ParticleWebhook struct {
|
||||||
Path string
|
Path string
|
||||||
acc telegraf.Accumulator
|
acc telegraf.Accumulator
|
||||||
log telegraf.Logger
|
log telegraf.Logger
|
||||||
|
auth.BasicAuth
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rb *ParticleWebhook) Register(router *mux.Router, acc telegraf.Accumulator, log telegraf.Logger) {
|
func (rb *ParticleWebhook) Register(router *mux.Router, acc telegraf.Accumulator, log telegraf.Logger) {
|
||||||
|
|
@ -51,6 +53,12 @@ func (rb *ParticleWebhook) Register(router *mux.Router, acc telegraf.Accumulator
|
||||||
|
|
||||||
func (rb *ParticleWebhook) eventHandler(w http.ResponseWriter, r *http.Request) {
|
func (rb *ParticleWebhook) eventHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
defer r.Body.Close()
|
defer r.Body.Close()
|
||||||
|
|
||||||
|
if !rb.Verify(r) {
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
e := newEvent()
|
e := newEvent()
|
||||||
if err := json.NewDecoder(r.Body).Decode(e); err != nil {
|
if err := json.NewDecoder(r.Body).Decode(e); err != nil {
|
||||||
rb.acc.AddError(err)
|
rb.acc.AddError(err)
|
||||||
|
|
|
||||||
|
|
@ -3,19 +3,21 @@ package rollbar
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
|
||||||
"github.com/influxdata/telegraf"
|
"github.com/influxdata/telegraf"
|
||||||
|
"github.com/influxdata/telegraf/plugins/common/auth"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RollbarWebhook struct {
|
type RollbarWebhook struct {
|
||||||
Path string
|
Path string
|
||||||
acc telegraf.Accumulator
|
acc telegraf.Accumulator
|
||||||
log telegraf.Logger
|
log telegraf.Logger
|
||||||
|
auth.BasicAuth
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rb *RollbarWebhook) Register(router *mux.Router, acc telegraf.Accumulator, log telegraf.Logger) {
|
func (rb *RollbarWebhook) Register(router *mux.Router, acc telegraf.Accumulator, log telegraf.Logger) {
|
||||||
|
|
@ -27,7 +29,13 @@ func (rb *RollbarWebhook) Register(router *mux.Router, acc telegraf.Accumulator,
|
||||||
|
|
||||||
func (rb *RollbarWebhook) eventHandler(w http.ResponseWriter, r *http.Request) {
|
func (rb *RollbarWebhook) eventHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
defer r.Body.Close()
|
defer r.Body.Close()
|
||||||
data, err := io.ReadAll(r.Body)
|
|
||||||
|
if !rb.Verify(r) {
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := ioutil.ReadAll(r.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -53,21 +53,45 @@ func (wb *Webhooks) SampleConfig() string {
|
||||||
[inputs.webhooks.filestack]
|
[inputs.webhooks.filestack]
|
||||||
path = "/filestack"
|
path = "/filestack"
|
||||||
|
|
||||||
|
## HTTP basic auth
|
||||||
|
#username = ""
|
||||||
|
#password = ""
|
||||||
|
|
||||||
[inputs.webhooks.github]
|
[inputs.webhooks.github]
|
||||||
path = "/github"
|
path = "/github"
|
||||||
# secret = ""
|
# secret = ""
|
||||||
|
|
||||||
|
## HTTP basic auth
|
||||||
|
#username = ""
|
||||||
|
#password = ""
|
||||||
|
|
||||||
[inputs.webhooks.mandrill]
|
[inputs.webhooks.mandrill]
|
||||||
path = "/mandrill"
|
path = "/mandrill"
|
||||||
|
|
||||||
|
## HTTP basic auth
|
||||||
|
#username = ""
|
||||||
|
#password = ""
|
||||||
|
|
||||||
[inputs.webhooks.rollbar]
|
[inputs.webhooks.rollbar]
|
||||||
path = "/rollbar"
|
path = "/rollbar"
|
||||||
|
|
||||||
|
## HTTP basic auth
|
||||||
|
#username = ""
|
||||||
|
#password = ""
|
||||||
|
|
||||||
[inputs.webhooks.papertrail]
|
[inputs.webhooks.papertrail]
|
||||||
path = "/papertrail"
|
path = "/papertrail"
|
||||||
|
|
||||||
|
## HTTP basic auth
|
||||||
|
#username = ""
|
||||||
|
#password = ""
|
||||||
|
|
||||||
[inputs.webhooks.particle]
|
[inputs.webhooks.particle]
|
||||||
path = "/particle"
|
path = "/particle"
|
||||||
|
|
||||||
|
## HTTP basic auth
|
||||||
|
#username = ""
|
||||||
|
#password = ""
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue