add various tests for web.go
This commit is contained in:
parent
de9cc37738
commit
8e86f5992e
1 changed files with 374 additions and 0 deletions
374
web_test.go
Normal file
374
web_test.go
Normal file
|
|
@ -0,0 +1,374 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
)
|
||||
|
||||
var (
|
||||
addr = "localhost"
|
||||
port uint16 = 1234
|
||||
rawCfg = Config{
|
||||
ServerPort: port,
|
||||
Users: []User{
|
||||
User{
|
||||
Username: "user",
|
||||
// "secret" -> bcrypt-hashed
|
||||
Password: "$2a$12$He9X4KNAFJQy0CL2c9.Df.tjXwCkideOogwJ7DNtO/I8qzeJZfc3i",
|
||||
Records: []string{
|
||||
"record.example.org",
|
||||
},
|
||||
},
|
||||
User{
|
||||
Username: "user2",
|
||||
// "secret" -> bcrypt-hashed
|
||||
Password: "$2a$12$He9X4KNAFJQy0CL2c9.Df.tjXwCkideOogwJ7DNtO/I8qzeJZfc3i",
|
||||
Records: []string{
|
||||
"record2.example.org",
|
||||
},
|
||||
},
|
||||
User{
|
||||
Username: "bad-hash",
|
||||
Password: "secret",
|
||||
Records: []string{
|
||||
"record3.example.org",
|
||||
},
|
||||
},
|
||||
},
|
||||
RRConfigs: []RRConfig{
|
||||
RRConfig{
|
||||
Recordname: "record.example.org",
|
||||
Zonename: "zone.example.org",
|
||||
Nameserver: "ns1.example.org",
|
||||
Tsigalgo: "hmac-sha256",
|
||||
Tsigid: "tsig-id",
|
||||
Tsigkey: "some-secret-key",
|
||||
},
|
||||
RRConfig{
|
||||
Recordname: "record2.example.org",
|
||||
Zonename: "zone.example.org",
|
||||
Nameserver: "ns1.example.org",
|
||||
Tsigalgo: "hmac-sha256",
|
||||
Tsigid: "tsig-id",
|
||||
Tsigkey: "some-secret-key",
|
||||
},
|
||||
RRConfig{
|
||||
Recordname: "record3.example.org",
|
||||
Zonename: "zone.example.org",
|
||||
Nameserver: "ns1.example.org",
|
||||
Tsigalgo: "hmac-sha256",
|
||||
Tsigid: "tsig-id",
|
||||
Tsigkey: "some-secret-key",
|
||||
},
|
||||
},
|
||||
}
|
||||
cfg *Config
|
||||
)
|
||||
|
||||
// pre-initialize config for all testcases
|
||||
func init() {
|
||||
var err error
|
||||
cfg, err = prepareConfig(&rawCfg)
|
||||
if err != nil {
|
||||
log.Fatalf("Preparing config failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func prepareRequest(t *testing.T, params map[string]string, headers map[string]string) *http.Request {
|
||||
req, err := http.NewRequest("GET", "http://"+addr, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Generating request failed: %v", err)
|
||||
}
|
||||
|
||||
// append http parameters to http request
|
||||
q := req.URL.Query()
|
||||
for k, v := range params {
|
||||
q.Add(k, v)
|
||||
}
|
||||
req.URL.RawQuery = q.Encode()
|
||||
|
||||
// set headers
|
||||
for k, v := range headers {
|
||||
req.Header.Set(k, v)
|
||||
}
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
type credentials struct {
|
||||
username string
|
||||
password string
|
||||
}
|
||||
|
||||
func TestIsAuthenticated(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
auth *credentials
|
||||
expUser *User
|
||||
}{
|
||||
{
|
||||
"missing basicauth",
|
||||
nil,
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"non-existent user",
|
||||
&credentials{
|
||||
"unknown",
|
||||
"secret",
|
||||
},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"invalid hash",
|
||||
&credentials{
|
||||
"bad-hash",
|
||||
"secret",
|
||||
},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"correct user",
|
||||
&credentials{
|
||||
"user",
|
||||
"secret",
|
||||
},
|
||||
&User{
|
||||
Username: "user",
|
||||
Password: "$2a$12$He9X4KNAFJQy0CL2c9.Df.tjXwCkideOogwJ7DNtO/I8qzeJZfc3i",
|
||||
Records: []string{
|
||||
"record.example.org",
|
||||
},
|
||||
records: map[string]bool{
|
||||
"record.example.org": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
req := prepareRequest(t, nil, nil)
|
||||
if tc.auth != nil {
|
||||
req.SetBasicAuth(tc.auth.username, tc.auth.password)
|
||||
}
|
||||
|
||||
res := isAuthenticated(cfg, req)
|
||||
if !reflect.DeepEqual(tc.expUser, res) {
|
||||
t.Errorf("%s: res: %s", tc.name,
|
||||
cmp.Diff(tc.expUser, res, cmp.AllowUnexported(User{})))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyHostname(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
user *User
|
||||
hostname string
|
||||
expMsg string
|
||||
expRrconfig *RRConfig
|
||||
}{
|
||||
{
|
||||
"empty hostname",
|
||||
cfg.users["user"],
|
||||
"",
|
||||
"nohost",
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"user not allowed",
|
||||
cfg.users["user2"],
|
||||
"record.example.org",
|
||||
"badauth",
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"correct hostname",
|
||||
cfg.users["user"],
|
||||
"record.example.org",
|
||||
"",
|
||||
cfg.rrconfigs["record.example.org"],
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
msg, rrconfig := verifyHostname(cfg, tc.user, tc.hostname)
|
||||
|
||||
if !reflect.DeepEqual(tc.expMsg, msg) {
|
||||
t.Errorf("%s: res: %s", tc.name,
|
||||
cmp.Diff(tc.expMsg, msg))
|
||||
}
|
||||
if !reflect.DeepEqual(tc.expRrconfig, rrconfig) {
|
||||
t.Errorf("%s: res: %s", tc.name,
|
||||
cmp.Diff(tc.expRrconfig, rrconfig))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetIpAddress(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
params map[string]string
|
||||
headers map[string]string
|
||||
remoteAddr string
|
||||
expAddr net.IP
|
||||
}{
|
||||
{
|
||||
"no address",
|
||||
nil,
|
||||
nil,
|
||||
"",
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"remote addr - invalid ip",
|
||||
nil,
|
||||
nil,
|
||||
"1.1.1:1234",
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"remote addr - missing port",
|
||||
nil,
|
||||
nil,
|
||||
"1.1.1.1",
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"remote addr - valid",
|
||||
nil,
|
||||
nil,
|
||||
"1.1.1.1:1234",
|
||||
net.ParseIP("1.1.1.1"),
|
||||
},
|
||||
{
|
||||
"X-Real-IP - empty",
|
||||
nil,
|
||||
map[string]string{
|
||||
"X-Real-IP": "",
|
||||
},
|
||||
"1.1.1.1:1234",
|
||||
net.ParseIP("1.1.1.1"),
|
||||
},
|
||||
{
|
||||
"X-Real-IP - invalid",
|
||||
nil,
|
||||
map[string]string{
|
||||
"X-Real-IP": "2.2.2",
|
||||
},
|
||||
"1.1.1.1:1234",
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"X-Real-IP - valid",
|
||||
nil,
|
||||
map[string]string{
|
||||
"X-Real-IP": "2.2.2.2",
|
||||
},
|
||||
"1.1.1.1:1234",
|
||||
net.ParseIP("2.2.2.2"),
|
||||
},
|
||||
{
|
||||
"X-Forwarded-For - empty",
|
||||
nil,
|
||||
map[string]string{
|
||||
"X-Forwarded-For": "",
|
||||
"X-Real-IP": "2.2.2.2",
|
||||
},
|
||||
"1.1.1.1:1234",
|
||||
net.ParseIP("2.2.2.2"),
|
||||
},
|
||||
{
|
||||
"X-Forwarded-For - comma only",
|
||||
nil,
|
||||
map[string]string{
|
||||
"X-Forwarded-For": ",",
|
||||
"X-Real-IP": "2.2.2.2",
|
||||
},
|
||||
"1.1.1.1:1234",
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"X-Forwarded-For - invalid entry",
|
||||
nil,
|
||||
map[string]string{
|
||||
"X-Forwarded-For": "3.3.3",
|
||||
"X-Real-IP": "2.2.2.2",
|
||||
},
|
||||
"1.1.1.1:1234",
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"X-Forwarded-For - one entry",
|
||||
nil,
|
||||
map[string]string{
|
||||
"X-Forwarded-For": "3.3.3.3",
|
||||
"X-Real-IP": "2.2.2.2",
|
||||
},
|
||||
"1.1.1.1:1234",
|
||||
net.ParseIP("3.3.3.3"),
|
||||
},
|
||||
{
|
||||
"X-Forwarded-For - multiple entries",
|
||||
nil,
|
||||
map[string]string{
|
||||
"X-Forwarded-For": "3.3.3.3, 3.3.3.4",
|
||||
"X-Real-IP": "2.2.2.2",
|
||||
},
|
||||
"1.1.1.1:1234",
|
||||
net.ParseIP("3.3.3.3"),
|
||||
},
|
||||
{
|
||||
"myip - empty",
|
||||
map[string]string{
|
||||
"myip": "",
|
||||
},
|
||||
map[string]string{
|
||||
"X-Forwarded-For": "3.3.3.3, 3.3.3.4",
|
||||
"X-Real-IP": "2.2.2.2",
|
||||
},
|
||||
"1.1.1.1:1234",
|
||||
net.ParseIP("3.3.3.3"),
|
||||
},
|
||||
{
|
||||
"myip - invalid",
|
||||
map[string]string{
|
||||
"myip": "1.2.3",
|
||||
},
|
||||
map[string]string{
|
||||
"X-Forwarded-For": "3.3.3.3, 3.3.3.4",
|
||||
"X-Real-IP": "2.2.2.2",
|
||||
},
|
||||
"1.1.1.1:1234",
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"myip - valid",
|
||||
map[string]string{
|
||||
"myip": "4.4.4.4",
|
||||
},
|
||||
map[string]string{
|
||||
"X-Forwarded-For": "3.3.3.3, 3.3.3.4",
|
||||
"X-Real-IP": "2.2.2.2",
|
||||
},
|
||||
"1.1.1.1:1234",
|
||||
net.ParseIP("4.4.4.4"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
req := prepareRequest(t, tc.params, tc.headers)
|
||||
req.RemoteAddr = tc.remoteAddr
|
||||
|
||||
addr := getIpAddress(req)
|
||||
if !reflect.DeepEqual(tc.expAddr, addr) {
|
||||
t.Errorf("%s: res: %s", tc.name,
|
||||
cmp.Diff(tc.expAddr, addr))
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue