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]
|
||||
path = "/filestack"
|
||||
|
||||
## HTTP basic auth
|
||||
#username = ""
|
||||
#password = ""
|
||||
|
||||
[inputs.webhooks.github]
|
||||
path = "/github"
|
||||
# secret = ""
|
||||
|
||||
## HTTP basic auth
|
||||
#username = ""
|
||||
#password = ""
|
||||
|
||||
[inputs.webhooks.mandrill]
|
||||
path = "/mandrill"
|
||||
|
||||
## HTTP basic auth
|
||||
#username = ""
|
||||
#password = ""
|
||||
|
||||
[inputs.webhooks.rollbar]
|
||||
path = "/rollbar"
|
||||
|
||||
## HTTP basic auth
|
||||
#username = ""
|
||||
#password = ""
|
||||
|
||||
[inputs.webhooks.papertrail]
|
||||
path = "/papertrail"
|
||||
|
||||
## HTTP basic auth
|
||||
#username = ""
|
||||
#password = ""
|
||||
|
||||
[inputs.webhooks.particle]
|
||||
path = "/particle"
|
||||
|
||||
## HTTP basic auth
|
||||
#username = ""
|
||||
#password = ""
|
||||
```
|
||||
|
||||
## Available webhooks
|
||||
|
|
|
|||
|
|
@ -2,19 +2,21 @@ package filestack
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/plugins/common/auth"
|
||||
)
|
||||
|
||||
type FilestackWebhook struct {
|
||||
Path string
|
||||
acc telegraf.Accumulator
|
||||
log telegraf.Logger
|
||||
auth.BasicAuth
|
||||
}
|
||||
|
||||
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) {
|
||||
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 {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/gorilla/mux"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/plugins/common/auth"
|
||||
)
|
||||
|
||||
type GithubWebhook struct {
|
||||
|
|
@ -18,6 +19,7 @@ type GithubWebhook struct {
|
|||
Secret string
|
||||
acc telegraf.Accumulator
|
||||
log telegraf.Logger
|
||||
auth.BasicAuth
|
||||
}
|
||||
|
||||
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) {
|
||||
defer r.Body.Close()
|
||||
|
||||
if !gh.Verify(r) {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
eventType := r.Header.Get("X-Github-Event")
|
||||
data, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -2,20 +2,22 @@ package mandrill
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/plugins/common/auth"
|
||||
)
|
||||
|
||||
type MandrillWebhook struct {
|
||||
Path string
|
||||
acc telegraf.Accumulator
|
||||
log telegraf.Logger
|
||||
auth.BasicAuth
|
||||
}
|
||||
|
||||
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) {
|
||||
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 {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -9,12 +9,14 @@ import (
|
|||
"github.com/gorilla/mux"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/plugins/common/auth"
|
||||
)
|
||||
|
||||
type PapertrailWebhook struct {
|
||||
Path string
|
||||
acc telegraf.Accumulator
|
||||
log telegraf.Logger
|
||||
auth.BasicAuth
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
if !pt.Verify(r) {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
data := r.PostFormValue("payload")
|
||||
if data == "" {
|
||||
http.Error(w, "Bad Request", http.StatusBadRequest)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/gorilla/mux"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/plugins/common/auth"
|
||||
)
|
||||
|
||||
type event struct {
|
||||
|
|
@ -40,6 +41,7 @@ type ParticleWebhook struct {
|
|||
Path string
|
||||
acc telegraf.Accumulator
|
||||
log telegraf.Logger
|
||||
auth.BasicAuth
|
||||
}
|
||||
|
||||
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) {
|
||||
defer r.Body.Close()
|
||||
|
||||
if !rb.Verify(r) {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
e := newEvent()
|
||||
if err := json.NewDecoder(r.Body).Decode(e); err != nil {
|
||||
rb.acc.AddError(err)
|
||||
|
|
|
|||
|
|
@ -3,19 +3,21 @@ package rollbar
|
|||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/plugins/common/auth"
|
||||
)
|
||||
|
||||
type RollbarWebhook struct {
|
||||
Path string
|
||||
acc telegraf.Accumulator
|
||||
log telegraf.Logger
|
||||
auth.BasicAuth
|
||||
}
|
||||
|
||||
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) {
|
||||
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 {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -53,21 +53,45 @@ func (wb *Webhooks) SampleConfig() string {
|
|||
[inputs.webhooks.filestack]
|
||||
path = "/filestack"
|
||||
|
||||
## HTTP basic auth
|
||||
#username = ""
|
||||
#password = ""
|
||||
|
||||
[inputs.webhooks.github]
|
||||
path = "/github"
|
||||
# secret = ""
|
||||
|
||||
## HTTP basic auth
|
||||
#username = ""
|
||||
#password = ""
|
||||
|
||||
[inputs.webhooks.mandrill]
|
||||
path = "/mandrill"
|
||||
|
||||
## HTTP basic auth
|
||||
#username = ""
|
||||
#password = ""
|
||||
|
||||
[inputs.webhooks.rollbar]
|
||||
path = "/rollbar"
|
||||
|
||||
## HTTP basic auth
|
||||
#username = ""
|
||||
#password = ""
|
||||
|
||||
[inputs.webhooks.papertrail]
|
||||
path = "/papertrail"
|
||||
|
||||
## HTTP basic auth
|
||||
#username = ""
|
||||
#password = ""
|
||||
|
||||
[inputs.webhooks.particle]
|
||||
path = "/particle"
|
||||
|
||||
## HTTP basic auth
|
||||
#username = ""
|
||||
#password = ""
|
||||
`
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue