feat(auth): add username header

This commit is contained in:
Nicolas Carlier 2023-02-13 21:17:46 +00:00
parent 13194eb0ca
commit 2fb8e9aa84
5 changed files with 28 additions and 9 deletions

View File

@ -150,6 +150,14 @@ You have several ways to provide parameters to your webhook script:
Therefore the name can be altered.
*ex: `CONTENT-TYPE` will become `content_type`.*
Webhookd adds some additional parameters to the script:
- `hook_id`: hook ID (auto-increment)
- `hook_name`: hook name
- `hook_method`: HTTP request method
- `x_forwarded_for`: client IP
- `x_webauth_user`: username if authentication is enabled
*Example:*
The script:

View File

@ -4,7 +4,8 @@ import (
"net/http"
)
// Authenticator is a generic interface to validate an HTTP request
// Authenticator is a generic interface to validate HTTP request credentials.
// It's returns the authentication result along with the principal (username) if it has one.
type Authenticator interface {
Validate(r *http.Request) bool
Validate(r *http.Request) (bool, *string)
}

View File

@ -52,12 +52,12 @@ func NewHtpasswdFromFile(path string) (*HtpasswdFile, error) {
}
// Validate HTTP request credentials
func (h *HtpasswdFile) Validate(r *http.Request) bool {
func (h *HtpasswdFile) Validate(r *http.Request) (bool, *string) {
user, passwd, ok := r.BasicAuth()
if !ok {
return false
if ok && h.validateCredentials(user, passwd) {
return true, &user
}
return h.validateCredentials(user, passwd)
return false, nil
}
func (h *HtpasswdFile) validateCredentials(user string, password string) bool {

View File

@ -16,8 +16,12 @@ func TestValidateCredentials(t *testing.T) {
req, err := http.NewRequest("POST", "http://localhost:8080", nil)
assert.Nil(t, err, "")
req.SetBasicAuth("foo", "bar")
assert.Equal(t, true, htpasswdFile.Validate(req), "credentials should be valid")
ok, username := htpasswdFile.Validate(req)
assert.Equal(t, true, ok, "credentials should be valid")
assert.Equal(t, "foo", *username, "invalid username")
req.SetBasicAuth("foo", "bad")
assert.Equal(t, false, htpasswdFile.Validate(req), "credentials should not be valid")
ok, username = htpasswdFile.Validate(req)
assert.Equal(t, false, ok, "credentials should be invalid")
assert.True(t, username == nil, "username should be nil")
}

View File

@ -6,11 +6,17 @@ import (
"github.com/ncarlier/webhookd/pkg/auth"
)
const xWebAuthUser = "X-WebAuth-User"
// AuthN is a middleware to checks HTTP request credentials
func AuthN(authenticator auth.Authenticator) Middleware {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if authenticator.Validate(r) {
w.Header().Del(xWebAuthUser)
if ok, username := authenticator.Validate(r); ok {
if username != nil {
w.Header().Set(xWebAuthUser, *username)
}
next.ServeHTTP(w, r)
return
}