From c32b03210c5afdf4064860fac41cbd53860f999d Mon Sep 17 00:00:00 2001 From: tcely Date: Sun, 3 Mar 2019 14:46:37 -0500 Subject: [PATCH] add additional tests --- api_test.go | 185 +++++++++++++++++++++++++++++++++++++++++++++ db_test.go | 28 ++++++- validation_test.go | 27 ++++++- 3 files changed, 238 insertions(+), 2 deletions(-) diff --git a/api_test.go b/api_test.go index 96b3b2f6..7240b113 100644 --- a/api_test.go +++ b/api_test.go @@ -383,6 +383,130 @@ func TestApiManyUpdateWithCredentials(t *testing.T) { } } +func TestApiManyUpdateWithCredentialsInBody(t *testing.T) { + validTxtData := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + + updateJSON := map[string]interface{}{ + "username": "", + "password": "", + "subdomain": "", + "txt": ""} + + router := setupRouter(true, false) + server := httptest.NewServer(router) + defer server.Close() + e := getExpect(t, server) + // User without defined CIDR masks + newUser, err := DB.Register(cidrslice{}) + if err != nil { + t.Errorf("Could not create new user, got error [%v]", err) + } + + // User with defined allow from - CIDR masks, all invalid + // (httpexpect doesn't provide a way to mock remote ip) + newUserWithCIDR, err := DB.Register(cidrslice{"192.168.1.1/32", "invalid"}) + if err != nil { + t.Errorf("Could not create new user with CIDR, got error [%v]", err) + } + + // Another user with valid CIDR mask to match the httpexpect default + newUserWithValidCIDR, err := DB.Register(cidrslice{"10.1.2.3/32", "invalid"}) + if err != nil { + t.Errorf("Could not create new user with a valid CIDR, got error [%v]", err) + } + + for _, test := range []struct { + user string + pass string + subdomain string + txt interface{} + status int + }{ + {"non-uuid-user", "tooshortpass", "non-uuid-subdomain", validTxtData, 401}, + {"a097455b-52cc-4569-90c8-7a4b97c6eba8", "tooshortpass", "bb97455b-52cc-4569-90c8-7a4b97c6eba8", validTxtData, 401}, + {"a097455b-52cc-4569-90c8-7a4b97c6eba8", "LongEnoughPassButNoUserExists___________", "bb97455b-52cc-4569-90c8-7a4b97c6eba8", validTxtData, 401}, + {newUser.Username.String(), newUser.Password, "a097455b-52cc-4569-90c8-7a4b97c6eba8", validTxtData, 401}, + {newUser.Username.String(), newUser.Password, newUser.Subdomain, "tooshortfortxt", 400}, + {newUser.Username.String(), newUser.Password, newUser.Subdomain, 1234567890, 401}, + {newUser.Username.String(), newUser.Password, newUser.Subdomain, validTxtData, 200}, + {newUserWithCIDR.Username.String(), newUserWithCIDR.Password, newUserWithCIDR.Subdomain, validTxtData, 401}, + {newUserWithValidCIDR.Username.String(), newUserWithValidCIDR.Password, newUserWithValidCIDR.Subdomain, validTxtData, 200}, + {newUser.Username.String(), "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", newUser.Subdomain, validTxtData, 401}, + } { + updateJSON = map[string]interface{}{ + "username": test.user, + "password": test.pass, + "subdomain": test.subdomain, + "txt": test.txt} + e.POST("/update"). + WithJSON(updateJSON). + WithHeader("X-Forwarded-For", "10.1.2.3"). + Expect(). + Status(test.status) + } +} + +func TestApiManyUpdateWithPasswordInBody(t *testing.T) { + validTxtData := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + + updateJSON := map[string]interface{}{ + "password": "", + "subdomain": "", + "txt": ""} + + router := setupRouter(true, false) + server := httptest.NewServer(router) + defer server.Close() + e := getExpect(t, server) + // User without defined CIDR masks + newUser, err := DB.Register(cidrslice{}) + if err != nil { + t.Errorf("Could not create new user, got error [%v]", err) + } + + // User with defined allow from - CIDR masks, all invalid + // (httpexpect doesn't provide a way to mock remote ip) + newUserWithCIDR, err := DB.Register(cidrslice{"192.168.1.1/32", "invalid"}) + if err != nil { + t.Errorf("Could not create new user with CIDR, got error [%v]", err) + } + + // Another user with valid CIDR mask to match the httpexpect default + newUserWithValidCIDR, err := DB.Register(cidrslice{"10.1.2.3/32", "invalid"}) + if err != nil { + t.Errorf("Could not create new user with a valid CIDR, got error [%v]", err) + } + + for _, test := range []struct { + user string + pass string + subdomain string + txt interface{} + status int + }{ + {"non-uuid-user", "tooshortpass", "non-uuid-subdomain", validTxtData, 401}, + {"a097455b-52cc-4569-90c8-7a4b97c6eba8", "tooshortpass", "bb97455b-52cc-4569-90c8-7a4b97c6eba8", validTxtData, 401}, + {"a097455b-52cc-4569-90c8-7a4b97c6eba8", "LongEnoughPassButNoUserExists___________", "bb97455b-52cc-4569-90c8-7a4b97c6eba8", validTxtData, 401}, + {newUser.Username.String(), newUser.Password, "a097455b-52cc-4569-90c8-7a4b97c6eba8", validTxtData, 401}, + {newUser.Username.String(), newUser.Password, newUser.Subdomain, "tooshortfortxt", 400}, + {newUser.Username.String(), newUser.Password, newUser.Subdomain, 1234567890, 401}, + {newUser.Username.String(), newUser.Password, newUser.Subdomain, validTxtData, 200}, + {newUserWithCIDR.Username.String(), newUserWithCIDR.Password, newUserWithCIDR.Subdomain, validTxtData, 401}, + {newUserWithValidCIDR.Username.String(), newUserWithValidCIDR.Password, newUserWithValidCIDR.Subdomain, validTxtData, 200}, + {newUser.Username.String(), "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", newUser.Subdomain, validTxtData, 401}, + } { + updateJSON = map[string]interface{}{ + "password": test.pass, + "subdomain": test.subdomain, + "txt": test.txt} + e.POST("/update"). + WithJSON(updateJSON). + WithHeader("X-Forwarded-For", "10.1.2.3"). + Expect(). + Status(test.status) + } +} + func TestApiManyUpdateWithIpCheckHeaders(t *testing.T) { updateJSON := map[string]interface{}{ @@ -439,6 +563,67 @@ func TestApiManyUpdateWithIpCheckHeaders(t *testing.T) { Config.API.UseHeader = false } +func TestApiManyUpdateWithoutAuth(t *testing.T) { + validTxtData := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + + updateJSON := map[string]interface{}{ + "subdomain": "", + "txt": ""} + + router := setupRouter(true, true) + server := httptest.NewServer(router) + defer server.Close() + e := getExpect(t, server) + // User without defined CIDR masks + newUser, err := DB.Register(cidrslice{}) + if err != nil { + t.Errorf("Could not create new user, got error [%v]", err) + } + + // User with defined allow from - CIDR masks, all invalid + // (httpexpect doesn't provide a way to mock remote ip) + newUserWithCIDR, err := DB.Register(cidrslice{"192.168.1.1/32", "invalid"}) + if err != nil { + t.Errorf("Could not create new user with CIDR, got error [%v]", err) + } + + // Another user with valid CIDR mask to match the httpexpect default + newUserWithValidCIDR, err := DB.Register(cidrslice{"10.1.2.3/32", "invalid"}) + if err != nil { + t.Errorf("Could not create new user with a valid CIDR, got error [%v]", err) + } + + for _, test := range []struct { + user string + pass string + subdomain string + txt interface{} + status int + }{ + {"non-uuid-user", "tooshortpass", "non-uuid-subdomain", validTxtData, 400}, + {"a097455b-52cc-4569-90c8-7a4b97c6eba8", "tooshortpass", "bb97455b-52cc-4569-90c8-7a4b97c6eba8", validTxtData, 200}, + {"a097455b-52cc-4569-90c8-7a4b97c6eba8", "LongEnoughPassButNoUserExists___________", "bb97455b-52cc-4569-90c8-7a4b97c6eba8", validTxtData, 200}, + {newUser.Username.String(), newUser.Password, "a097455b-52cc-4569-90c8-7a4b97c6eba8", validTxtData, 200}, + {newUser.Username.String(), newUser.Password, newUser.Subdomain, "tooshortfortxt", 400}, + {newUser.Username.String(), newUser.Password, newUser.Subdomain, 1234567890, 400}, + {newUser.Username.String(), newUser.Password, newUser.Subdomain, validTxtData, 200}, + {newUserWithCIDR.Username.String(), newUserWithCIDR.Password, newUserWithCIDR.Subdomain, validTxtData, 200}, + {newUserWithValidCIDR.Username.String(), newUserWithValidCIDR.Password, newUserWithValidCIDR.Subdomain, validTxtData, 200}, + {newUser.Username.String(), "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", newUser.Subdomain, validTxtData, 200}, + } { + updateJSON = map[string]interface{}{ + "subdomain": test.subdomain, + "txt": test.txt} + e.POST("/update"). + WithJSON(updateJSON). + WithHeader("X-Api-User", test.user). + WithHeader("X-Api-Key", test.pass). + WithHeader("X-Forwarded-For", "10.1.2.3"). + Expect(). + Status(test.status) + } +} + func TestApiHealthCheck(t *testing.T) { router := setupRouter(false, false) server := httptest.NewServer(router) diff --git a/db_test.go b/db_test.go index 9e578ffe..4c58926a 100644 --- a/db_test.go +++ b/db_test.go @@ -76,6 +76,32 @@ func TestRegisterMany(t *testing.T) { } } +func TestGetBySubdomain(t *testing.T) { + // Create reg to refer to + reg, err := DB.Register(cidrslice{}) + if err != nil { + t.Errorf("Registration failed, got error [%v]", err) + } + + regUser, err := DB.GetBySubdomain(reg.Subdomain) + if err != nil { + t.Errorf("Could not get test user, got error [%v]", err) + } + + if reg.Username != regUser.Username { + t.Errorf("GetBySubdomain username [%q] did not match the original [%q]", regUser.Username, reg.Username) + } + + if reg.Subdomain != regUser.Subdomain { + t.Errorf("GetBySubdomain subdomain [%q] did not match the original [%q]", regUser.Subdomain, reg.Subdomain) + } + + // regUser password already is a bcrypt hash + if !correctPassword(reg.Password, regUser.Password) { + t.Errorf("GetBySubdomain password [%s] does not match the hash [%s]", reg.Password, regUser.Password) + } +} + func TestGetByUsername(t *testing.T) { // Create reg to refer to reg, err := DB.Register(cidrslice{}) @@ -98,7 +124,7 @@ func TestGetByUsername(t *testing.T) { // regUser password already is a bcrypt hash if !correctPassword(reg.Password, regUser.Password) { - t.Errorf("The password [%s] does not match the hash [%s]", reg.Password, regUser.Password) + t.Errorf("GetByUsername password [%s] does not match the hash [%s]", reg.Password, regUser.Password) } } diff --git a/validation_test.go b/validation_test.go index 37dd05fc..702ea17d 100644 --- a/validation_test.go +++ b/validation_test.go @@ -6,6 +6,31 @@ import ( "github.com/google/uuid" ) +func TestGetValidSubdomain(t *testing.T) { + v1, _ := uuid.Parse("a097455b-52cc-4569-90c8-7a4b97c6eba8") + for i, test := range []struct { + subdomain string + output uuid.UUID + shouldErr bool + }{ + {"a097455b-52cc-4569-90c8-7a4b97c6eba8", v1, false}, + {"a-97455b-52cc-4569-90c8-7a4b97c6eba8", uuid.UUID{}, true}, + {"", uuid.UUID{}, true}, + {"&!#!25123!%!'%", uuid.UUID{}, true}, + } { + ret, err := getValidSubdomain(test.subdomain) + if test.shouldErr && err == nil { + t.Errorf("Test %d: Expected error, but there was none", i) + } + if !test.shouldErr && err != nil { + t.Errorf("Test %d: Expected no error, but got [%v]", i, err) + } + if ret != test.output { + t.Errorf("Test %d: Expected return value %v, but got %v", i, test.output, ret) + } + } +} + func TestGetValidUsername(t *testing.T) { v1, _ := uuid.Parse("a097455b-52cc-4569-90c8-7a4b97c6eba8") for i, test := range []struct { @@ -49,7 +74,7 @@ func TestValidKey(t *testing.T) { } } -func TestGetValidSubdomain(t *testing.T) { +func TestValidSubdomain(t *testing.T) { for i, test := range []struct { subdomain string output bool