stash/pkg/session/authentication_test.go

189 lines
4.1 KiB
Go

package session
import (
"errors"
"net/http"
"testing"
)
type config struct {
username string
password string
dangerousAllowPublicWithoutAuth bool
securityTripwireAccessedFromPublicInternet string
}
func (c *config) HasCredentials() bool {
return c.username != "" && c.password != ""
}
func (c *config) GetDangerousAllowPublicWithoutAuth() bool {
return c.dangerousAllowPublicWithoutAuth
}
func (c *config) GetSecurityTripwireAccessedFromPublicInternet() string {
return c.securityTripwireAccessedFromPublicInternet
}
func (c *config) IsNewSystem() bool {
return false
}
func TestCheckAllowPublicWithoutAuth(t *testing.T) {
c := &config{}
doTest := func(caseIndex int, r *http.Request, expectedErr interface{}) {
t.Helper()
err := CheckAllowPublicWithoutAuth(c, r)
if expectedErr == nil && err == nil {
return
}
if expectedErr == nil {
t.Errorf("[%d]: unexpected error: %v", caseIndex, err)
return
}
if !errors.As(err, expectedErr) {
t.Errorf("[%d]: expected %T, got %v (%T)", caseIndex, expectedErr, err, err)
return
}
}
{
// direct connection tests
testCases := []struct {
address string
err error
}{
{"192.168.1.1:8080", nil},
{"192.168.1.1:8080", nil},
{"100.64.0.1:8080", nil},
{"127.0.0.1:8080", nil},
{"[::1]:8080", nil},
{"[fe80::c081:1c1a:ae39:d3cd%Ethernet 5]:9999", nil},
{"193.168.1.1:8080", &ExternalAccessError{}},
{"[2002:9fc4:ed97:e472:5170:5766:520c:c901]:9999", &ExternalAccessError{}},
}
// try with no X-FORWARDED-FOR and valid one
xFwdVals := []string{"", "192.168.1.1"}
for i, xFwdVal := range xFwdVals {
header := make(http.Header)
header.Set("X-FORWARDED-FOR", xFwdVal)
for ii, tc := range testCases {
r := &http.Request{
RemoteAddr: tc.address,
Header: header,
}
doTest((i*len(testCases) + ii), r, tc.err)
}
}
}
{
// X-FORWARDED-FOR
testCases := []struct {
proxyChain string
err error
}{
{"192.168.1.1, 192.168.1.2, 100.64.0.1, 127.0.0.1", nil},
{"192.168.1.1, 193.168.1.1", &ExternalAccessError{}},
{"193.168.1.1, 192.168.1.1", &ExternalAccessError{}},
}
const remoteAddr = "192.168.1.1:8080"
header := make(http.Header)
for i, tc := range testCases {
header.Set("X-FORWARDED-FOR", tc.proxyChain)
r := &http.Request{
RemoteAddr: remoteAddr,
Header: header,
}
doTest(i, r, tc.err)
}
}
{
// test invalid request IPs
invalidIPs := []string{"192.168.1.a:9999", "192.168.1.1"}
for _, remoteAddr := range invalidIPs {
r := &http.Request{
RemoteAddr: remoteAddr,
}
err := CheckAllowPublicWithoutAuth(c, r)
if err == nil {
t.Errorf("[%s]: expected error", remoteAddr)
continue
}
}
}
{
// test overrides
r := &http.Request{
RemoteAddr: "193.168.1.1:8080",
}
c.username = "admin"
c.password = "admin"
if err := CheckAllowPublicWithoutAuth(c, r); err != nil {
t.Errorf("unexpected error: %v", err)
}
c.username = ""
c.password = ""
c.dangerousAllowPublicWithoutAuth = true
if err := CheckAllowPublicWithoutAuth(c, r); err != nil {
t.Errorf("unexpected error: %v", err)
}
}
}
func TestCheckExternalAccessTripwire(t *testing.T) {
c := &config{}
c.securityTripwireAccessedFromPublicInternet = "4.4.4.4"
// always return nil if authentication configured or dangerous key set
c.username = "admin"
c.password = "admin"
if err := CheckExternalAccessTripwire(c); err != nil {
t.Errorf("unexpected error %v", err)
}
c.username = ""
c.password = ""
// HACK - this key isn't publically exposed
c.dangerousAllowPublicWithoutAuth = true
if err := CheckExternalAccessTripwire(c); err != nil {
t.Errorf("unexpected error %v", err)
}
c.dangerousAllowPublicWithoutAuth = false
if err := CheckExternalAccessTripwire(c); err == nil {
t.Errorf("expected error %v", ExternalAccessError("4.4.4.4"))
}
c.securityTripwireAccessedFromPublicInternet = ""
if err := CheckExternalAccessTripwire(c); err != nil {
t.Errorf("unexpected error %v", err)
}
}