Skip to content

Commit

Permalink
feat: basic auth on webhook
Browse files Browse the repository at this point in the history
  • Loading branch information
hairmare committed Mar 31, 2022
1 parent 0b1977c commit 7d37bf1
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 2 deletions.
20 changes: 19 additions & 1 deletion app/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,30 @@ var rootCmd = &cobra.Command{
logrus.Fatal(err)
}

// read basic auth flags
basicAuthUsers := make(map[string]string)
authString, err := cmd.Flags().GetString("http-basic-auth-users")
if err != nil {
logrus.Fatal(err)
}
if authString != "" {
for _, user := range strings.Split(authString, ",") {
userParts := strings.Split(user, ":")
if len(userParts) != 2 {
logrus.Fatalf("invalid basic auth user: %s", user)
}
basicAuthUsers[userParts[0]] = userParts[1]
}
}

// build config struct
cfg := &mopsos.Config{
DBProvider: provider,
DBDSN: dsn,
DBMigrate: migrate,

HttpListener: listener,
HttpListener: listener,
BasicAuthUsers: basicAuthUsers,

EnableTracing: enableTracing,
TracingTarget: tracingTarget,
Expand Down Expand Up @@ -113,6 +130,7 @@ func Execute() {

// webserver flags
rootCmd.Flags().String("http-listener", ":8080", "HTTP listener")
rootCmd.Flags().String("http-basic-auth-users", "", "Comma-separated list of clusters and tokens, e.g. 'cluster1:token1,cluster2:token2'")

// otel flags
rootCmd.Flags().Bool("otel", false, "Enable OpenTelemetry tracing")
Expand Down
3 changes: 2 additions & 1 deletion app/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ type Config struct {
DBDSN string
DBMigrate bool

HttpListener string
HttpListener string
BasicAuthUsers map[string]string

EnableTracing bool
TracingTarget string
Expand Down
36 changes: 36 additions & 0 deletions app/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"net/http"

"github.com/adfinis-sygroup/mopsos/app/models"
otelObs "github.com/cloudevents/sdk-go/observability/opentelemetry/v2/client"
cloudevents "github.com/cloudevents/sdk-go/v2"
"github.com/cloudevents/sdk-go/v2/binding"
Expand Down Expand Up @@ -41,13 +42,40 @@ func (s *Server) Start() {
})
mux.Handle("/webhook", otelhttp.NewHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()

// get basic auth credentials
username, password, ok := r.BasicAuth()
if !ok {
http.Error(w, "missing Authorization header", http.StatusUnauthorized)
return
}
if !s.checkAuth(username, password) {
http.Error(w, "invalid credentials", http.StatusUnauthorized)
return
}

// get event
message := httproto.NewMessageFromHttpRequest(r)
event, err := binding.ToEvent(context.TODO(), message)
if err != nil {
logrus.WithError(err).Error("failed to decode event")
return
}

// TODO consider how to harmonise this with what the handler does later on
record := &models.Record{}
if err := event.DataAs(record); err != nil {
logrus.WithError(err).Errorf("failed to unmarshal event data")
http.Error(w, "failed to unmarshal event data", http.StatusInternalServerError)
return
}

// reject record that have not been sent from the right auth
if record.ClusterName != username {
http.Error(w, "event data does not match username", http.StatusUnauthorized)
return
}

err = s.HandleReceivedEvent(ctx, *event)
if err != nil {
logrus.WithError(err).Error("failed to handle event")
Expand Down Expand Up @@ -85,3 +113,11 @@ func (s *Server) HandleReceivedEvent(ctx context.Context, event cloudevents.Even

return nil
}

// checkAuth checks if the username and password are correct
func (s *Server) checkAuth(username, password string) bool {
logrus.WithFields(logrus.Fields{
"username": username,
}).Debug("checking credentials")
return s.config.BasicAuthUsers[username] == password
}

0 comments on commit 7d37bf1

Please sign in to comment.