deactive tests at the moment

This commit is contained in:
2023-11-17 07:29:35 +01:00
parent 97379c8e8a
commit 3865eb1d21
17 changed files with 305 additions and 305 deletions

91
test_todo/auth_test.go Normal file
View File

@@ -0,0 +1,91 @@
package main
import (
"log"
"os"
"testing"
"github.com/pyke369/golang-support/uconfig"
)
var fakeserver *HTTPServer
func init() {
config, err := uconfig.New("pdns-proxy-test.conf")
if err != nil {
log.Println(err)
os.Exit(1)
}
fakeserver = NewHTTPServer(
"127.0.0.01:8080",
"fixtures/test/server-key.pem",
"fixtures/test/server-cert.pem",
"",
"fixtures/test/ca.crt",
"",
"",
3,
3600,
)
populateHTTPServerAcls(config, fakeserver)
populateHTTPServerProfiles(config, fakeserver)
go fakeserver.Run()
}
// Testing Functions
func TestAuthRegexpProfiles(t *testing.T) {
v := fakeserver.getProfiles("validserver")
if len(v) != 1 || v[0] != "testS2S" {
t.Errorf("cannot valid test profile")
}
v = fakeserver.getProfiles("bidule.example.org")
if len(v) != 0 {
t.Errorf("too many validations")
}
}
func TestAuth(t *testing.T) {
for k, testCase := range []struct {
path, user, method string
expected bool
message string
}{
{"zones/specificdomain.example", "validserver", "POST", true, "valid user and path"},
{"zones/dev.example.org", "validserver", "GET", true, "valid user and path"},
{"zones/developper.example.org", "validserver", "GET", false, "valid user and invalid path"},
{"zones/otherdomain.example", "validserver", "GET", false, "valid user and invalid path"},
{"zones/dev.example.org", "validserver", "POST", false, "valid user, valid path, invalid method"},
{"zones/specificdomain.example", "invalidserver", "GET", false, "invalid user"},
} {
if fakeserver.nativeValidAuth(testCase.path, testCase.user, testCase.method) != testCase.expected {
result := "worked"
if testCase.expected {
result = "failed"
}
t.Errorf("%s but it %s on URL %d", testCase.message, result, k+1)
}
}
}
func TestInArray(t *testing.T) {
for k, testCase := range []struct {
search []string
list []string
expected bool
message string
}{
{[]string{"apple", "orange"}, []string{"kiwi", "apple"}, true, "apple should have matched"},
{[]string{"apple", "orange"}, []string{"kiwi", "apple"}, true, "apple should have matched"},
{[]string{"citrus", "orange"}, []string{"kiwi", "apple"}, false, "nothing should have matched"},
} {
if inArray(testCase.search, testCase.list) != testCase.expected {
result := "worked"
if testCase.expected {
result = "failed"
}
t.Errorf("%s but it %s on test %d", testCase.message, result, k+1)
}
}
}

189
test_todo/jsonrpc_test.go Normal file
View File

@@ -0,0 +1,189 @@
package main
import (
"bytes"
"crypto/tls"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"testing"
"time"
)
func newHTTPClient(timeout int, keyFile, certFile string) (*http.Client, error) {
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
return nil, err
}
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
InsecureSkipVerify: true,
}
tlsConfig.BuildNameToCertificate()
transport := &http.Transport{TLSClientConfig: tlsConfig}
return &http.Client{
Timeout: time.Duration(time.Duration(timeout) * time.Second),
Transport: transport}, nil
}
func jsonPost(url string, data []byte, client *http.Client) ([]byte, error) {
req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
return ioutil.ReadAll(resp.Body)
}
func deleteZone(url string, client *http.Client) error {
req, err := http.NewRequest("DELETE", url, nil)
if err != nil {
return nil
}
if _, err := client.Do(req); err != nil {
return err
}
return nil
}
func TestRecording(t *testing.T) {
// JSONRPCResponse is a jsonRPC response structure
type JSONRPCErrorOrResponse struct {
ID int `json:"id"`
JSONRPC string `json:"jsonrpc"`
Result []*JSONRPCResult `json:"result"`
Error struct {
Code int `json:"code"`
Message string `json:"message"`
} `json:"error"`
}
const (
configFile = "pdns-proxy-test.conf"
commandsFile = "fixtures/replay/commands.asc"
replayFile = "fixtures/replay/record"
)
var orig, rerun []*JSONRPCErrorOrResponse
badClient, err := newHTTPClient(30, "fixtures/test/client-key.pem", "fixtures/test/badclient-cert.pem")
if err != nil {
t.Errorf("cannot create bad client : %s", err)
return
}
client, err := newHTTPClient(30, "fixtures/test/client-key.pem", "fixtures/test/client-cert.pem")
if err != nil {
t.Errorf("cannot create client : %s", err)
return
}
h, err := loadConfig(configFile)
if err != nil {
log.Println(err)
os.Exit(1)
}
// disable nonce security
h.nonceGen = ""
go h.Run()
time.Sleep(3 * time.Second)
jsonCommands, err := ioutil.ReadFile(commandsFile)
// no command files, no need to continue
if err != nil {
return
}
for _, zone := range []string{
"10.in-addr.arpa",
"2.0.192.in-addr.arpa",
"toto.example.org",
"example.org",
} {
url := fmt.Sprintf("https://127.0.0.1:8443/api/v1/servers/localhost/zones/%s", zone)
deleteZone(url, client)
}
result, err := jsonPost("https://127.0.0.1:8443/jsonrpc", []byte("{}"), badClient)
if err != nil {
t.Errorf("Issue with the server call : %s", err)
return
}
badClientResponse := &JSONRPCErrorOrResponse{}
if err := json.Unmarshal(result, badClientResponse); err != nil {
t.Errorf("cannot decode response : %s", err)
return
}
//if badClientResponse.Error.Message != "Certificate for invalidserver is revoked" {
// t.Errorf("CRL not working")
// return
//}
result, err = jsonPost("https://127.0.0.1:8443/jsonrpc", jsonCommands, client)
if err != nil {
t.Errorf("Issue with the server call : %s", err)
return
}
// get the structuve of the query
jsonRPC, _, _, _, err := h.jrpcDecodeQuery(jsonCommands)
recording, err := ioutil.ReadFile(replayFile)
// no command files, let's try to save the result for the next time
if err != nil {
if err := ioutil.WriteFile(replayFile, result, 0644); err != nil {
t.Errorf("cannot write replay file")
}
return
}
// let's compare the 2 runs
if err := json.Unmarshal(recording, &orig); err != nil {
t.Errorf("cannot read replay file : %s", err)
return
}
if err := json.Unmarshal(result, &rerun); err != nil {
t.Errorf("cannot read result file : %s", err)
return
}
last := len(orig) - 1
for i := range orig {
if orig[i].Error != rerun[i].Error {
t.Errorf("the command \"pdns %s\" (line %d) has a different error message\n>>>>>>\n%s\n<<<<<<<\n%s",
jsonRPC[i], i, rerun[i].Error.Message, orig[i].Error.Message)
return
}
if rerun[i].Error.Message != "" {
log.Printf("\"dmdns %s\" : %s\n", jsonRPC[i], rerun[i].Error.Message)
}
if len(orig[i].Result) != len(rerun[i].Result) {
t.Errorf("the command \"pdns %s\" (line %d) has a different result length", jsonRPC[i], i)
return
}
for j := range orig[i].Result {
if orig[i].Result[j].Comment != rerun[i].Result[j].Comment {
t.Errorf("the command \"pdns %s\" (line %d) has a different error message\n>>>>>>\n%s\n<<<<<<<\n%s",
jsonRPC[i], i, rerun[i].Result[j].Comment, orig[i].Result[j].Comment)
return
}
if orig[i].Result[j].Result != rerun[i].Result[j].Result {
t.Errorf("the command \"pdns %s\" (line %d) has a different result %d:\n>>>>>>\n%s\n<<<<<<<\n%s",
jsonRPC[i], i, j, rerun[i].Result[j].Result, orig[i].Result[j].Result)
return
}
if orig[i].Result[j].Changes != rerun[i].Result[j].Changes {
t.Errorf("the command \"pdns %s\" (line %d) has a different result %d:\n>>>>>>\n%s\n<<<<<<<\n%s",
jsonRPC[i], i, j, rerun[i].Result[j].Changes, orig[i].Result[j].Changes)
return
}
log.Printf("%s : %s\n", rerun[i].Result[j].Comment, orig[i].Result[j].Result)
if i == last {
log.Println("\n" + rerun[i].Result[j].Changes)
}
}
}
}

68
test_todo/ldap_test.go Normal file
View File

@@ -0,0 +1,68 @@
package main
import (
"testing"
)
func hasLdapProfile() (bool, *LdapHandler) {
for _, profile := range fakeserver.authProfiles {
if p, ok := profile.(AuthProfileLdap); ok {
return true, p.ldap
}
}
return false, nil
}
func TestLdapAuth(t *testing.T) {
if ok, _ := hasLdapProfile(); !ok {
return
}
// optionnal test, need a ldap configuration in localtest.conf
v := fakeserver.getProfiles("xavier@example.org")
if len(v) != 1 {
t.Errorf("cannot valid test profile")
}
}
func TestLdapPool(t *testing.T) {
conns := []LdapClient{}
ok, l := hasLdapProfile()
if !ok {
return
}
cap := l.Cap()
// use all connexions in the pool, with one bonus
for i := 0; i < cap+1; i++ {
conn, err := l.GetConn()
if err != nil {
t.Errorf("Get error: %s", err)
}
conns = append(conns, conn)
}
// return the originally pooled connexions to the pool
for i := 0; i < cap; i++ {
if err := l.BackToPool(conns[i]); err != nil {
t.Errorf("BackToPool error: %s", err)
}
if nbConn := l.Len(); nbConn != i+1 {
t.Errorf("Pool didn't return used conn %d", nbConn)
}
// even if is was returned, it's still there
if !ldapIsAlive(conns[i]) {
t.Errorf("This connextion should not be closed")
}
}
// return the last one
if err := l.BackToPool(conns[cap]); err != nil {
t.Errorf("BackToPool error: %s", err)
}
if nbConn := l.Len(); nbConn != cap {
t.Errorf("The pool should be full")
}
// check it was closed
if ldapIsAlive(conns[cap]) {
t.Errorf("This connexion should be closed")
}
}

View File

@@ -0,0 +1,119 @@
config
{
profiles
{
{{< localtest.conf }}
testS2S
{
subjectRegexp: "validserver"
type: regexp
}
}
pdnsAcls
{
"testS2S"
{
regexp: "zones/dev\\..*"
perms: ["r"]
profiles: [ "testS2S" ]
},
"admin"
{
regexp: ".*"
perms: ["r", "w"]
profiles: [ "infra" ]
},
"writeTest"
{
regexp: "zones/specificdomain.example"
perms: ["r", "w"]
profiles: [ "testS2S" ]
},
}
jrpcAcls
{
"admin"
{
perms
{
"*": [ ".*" ]
}
pgpProfiles: [ "infra" ]
},
"testS2S"
{
perms
{
"*": [ ".*toto.example.org" ]
"list": [ ".*" ]
"search" [ ".*example.org" ]
}
sslProfiles: [ "testS2S" ]
},
"webui":
{
perms
{
"*": [ ".*corp.*" ]
}
sslProfiles: [ "infra" ]
}
"security"
{
perms
{
"dump": [ ".*" ]
"list": [ ".*" ]
"search": [ ".*" ]
}
sslProfiles: [ "security"]
}
}
http
{
port: ":8443"
ca: "fixtures/test/ca.crt"
key: "fixtures/test/server-key.pem"
cert: "fixtures/test/server-cert.pem"
}
pdns
{
api-key: "123password"
api-url: "http://127.0.0.1:8081/api/v1/servers/localhost"
timeout: 300
defaultTTL: 172800
}
zoneProfile
{
Native
{
nameservers: [ "a.iana-servers.net.", "b.iana-servers.net." ]
default: false
soa: "ns.icann.org. noc.dns.icann.org. 0 28800 7200 604800 86400"
whenRegexp
[
"(^|.*[^.]\\.)10\\.in-addr\\.arpa",
"(^|.*[^.]\\.)168\\.192\\.in-addr\\.arpa",
"(^|.*[^.]\\.)(1[6-9]|2[0-9]|3[0-1])\\.172\\.in-addr\\.arpa",
"(^|.*[^.]\\.)(6[4-9]|[7-9][0-9]|1([0-1][0-9]|2[0-7]))\\.100\\.in-addr\\.arpa",
]
}
Master
{
nameservers: [ "a.iana-servers.net.", "b.iana-servers.net." ]
default: true
soa: "ns.icann.org. noc.dns.icann.org. 0 28800 7200 604800 86400"
populate
{
spf
{
name: ""
type: "txt"
value: "v=spf1 -all"
}
}
}
}
}

View File

@@ -0,0 +1,104 @@
config
{
profiles:
{
infra:
{
subjectRegexp: ".*@example.org"
type: "ldap"
servers: [ "ldap" ]
bindCn: "cn=admin,dc=example,dc=org"
bindPw: "admin"
baseDN: "ou=users,dc=example,dc=org"
searchFilter: "(&(mail=%s))"
attribute: "description"
pgpAttribute: "pgpKey"
ssl: false
validValues: [ "infra", "vwf" ]
}
testS2S:
{
subjectRegexp: "validserver"
type: regexp
pgpKeys: "{{<fixtures/test/public-key.txt}}"
}
}
pdnsAcls:
{
"testS2S":
{
regexp: ".*"
perms: ["r", "w"]
profiles: [ "testS2S" ]
},
"admin":
{
regexp: ".*"
perms: ["r", "w"]
profiles: [ "infra" ]
},
"writeTest":
{
regexp: "zones/specificdomain.example"
perms: ["r", "w"]
profiles: [ "testS2S" ]
},
}
jrpcAcls:
{
"admin"
{
perms
{
"*": [ ".*" ]
}
pgpProfiles: [ "testS2S" ]
},
}
http:
{
port: "127.0.0.1:8443"
ca: "fixtures/test/ca.crt"
key: "fixtures/test/server-key.pem"
cert: "fixtures/test/server-cert.pem"
crl: "fixtures/test/root.crl.pem"
}
pdns:
{
api-key: "123password"
api-url: "http://127.0.0.1:8081/api/v1/servers/localhost"
defaultTTL: 172800
}
zoneProfile:
{
Native:
{
nameservers: [ "a.example.org.", "b.example.org." ]
default: true
autoIncrement: false
soa: "a.example.org. admin.example.org. 0 10380 3600 604800 3600"
populate
{
spf
{
name: ""
type: "txt"
value: "v=spf1 -all"
}
}
}
Master:
{
nameservers: [ "private-01.example.org.", "private-02.example.org." ]
soa: "private-01.example.org. admin.priv.example.org. 0 10380 3600 604800 3600"
autoIncrement: false
whenRegexp
[
"(^|.*[^.]\\.)10\\.in-addr\\.arpa",
"(^|.*[^.]\\.)168\\.192\\.in-addr\\.arpa",
"(^|.*[^.]\\.)(1[6-9]|2[0-9]|3[0-1])\\.172\\.in-addr\\.arpa",
"(^|.*[^.]\\.)(6[4-9]|[7-9][0-9]|1([0-1][0-9]|2[0-7]))\\.100\\.in-addr\\.arpa",
]
}
}
}

158
test_todo/pdns_test.go Normal file
View File

@@ -0,0 +1,158 @@
package main
import (
"bytes"
"context"
"encoding/json"
"net/http"
"strconv"
"testing"
"github.com/jarcoal/httpmock"
)
var (
pingBody = `{
"url": "/api/v1",
"version": 1
}`
getZonesBody = `[{
"account": "",
"dnssec": false,
"id": "example.org.",
"kind": "Native",
"last_check": 0,
"masters": [],
"name": "example.org.",
"notified_serial": 0,
"serial": 1,
"url": "/api/v1/servers/localhost/zones/example.org."},
{"account": "",
"dnssec": false,
"id": "example2.net.",
"kind": "Native",
"last_check": 0,
"masters": [],
"name": "example2.net.",
"notified_serial": 0,
"serial": 2019091801,
"url": "/api/v1/servers/localhost/zones/example2.net."
}]`
badPatchBody = `{
"error": "DNS Name 'email.example.org' is not canonical"
}`
addMasterZonePayload = `{
"name":"example.org",
"kind": "Master",
"dnssec":false,
"soa-edit":"INCEPTION-INCREMENT",
"masters": [],
"nameservers": ["ns1.example.org"]
}`
)
func TestPdnsPing(t *testing.T) {
httpmock.Activate()
defer httpmock.DeactivateAndReset()
httpmock.RegisterResponder("GET", testBaseURL+"/api",
func(req *http.Request) (*http.Response, error) {
if req.Header.Get("X-Api-Key") == testAPIKey {
return httpmock.NewJsonResponse(201, pingBody)
}
return httpmock.NewStringResponse(401, "Unauthorized"), nil
},
)
var response json.RawMessage
testClient, _ := initializePowerDNSTestClient()
_, _, err := testClient.sendQuery(context.Background(), "api", "GET", nil, &response)
if err != nil {
t.Errorf("%s", err)
}
isEqual, _ := areEqualJSON([]byte(strconv.Quote(pingBody)), response)
if !isEqual {
t.Error("Test Pdns Ping - Failed")
}
}
func TestPdnsGetZones(t *testing.T) {
httpmock.Activate()
defer httpmock.DeactivateAndReset()
httpmock.RegisterResponder("GET", generateTestAPIVhostURL()+"/zones",
func(req *http.Request) (*http.Response, error) {
if req.Header.Get("X-Api-Key") == testAPIKey {
return httpmock.NewJsonResponse(201, getZonesBody)
}
return httpmock.NewStringResponse(401, "Unauthorized"), nil
},
)
var response json.RawMessage
testClient, _ := initializePowerDNSTestClient()
_, _, err := testClient.sendQuery(context.Background(), generateTestRequestURI()+"/zones", "GET", nil, &response)
if err != nil {
t.Errorf("%s", err)
}
isEqual, _ := areEqualJSON([]byte(strconv.Quote(getZonesBody)), response)
if !isEqual {
t.Error("Test Pdns getZones - Failed")
}
}
func TestPdnsBadGet(t *testing.T) {
httpmock.Activate()
defer httpmock.DeactivateAndReset()
httpmock.RegisterResponder("GET", generateTestAPIVhostURL()+"/zone",
func(req *http.Request) (*http.Response, error) {
if req.Header.Get("X-Api-Key") == testAPIKey {
return httpmock.NewJsonResponse(404, "Not found")
}
return httpmock.NewStringResponse(401, "Unauthorized"), nil
},
)
var response json.RawMessage
testClient, _ := initializePowerDNSTestClient()
testClient.sendQuery(context.Background(), generateTestRequestURI()+"/zone", "GET", nil, &response)
isEqual, _ := areEqualJSON([]byte(strconv.Quote("Not found")), response)
if !isEqual {
t.Error("Test Pdns bad get - Failed")
}
}
func testPdnsBadPatch(t *testing.T) {
httpmock.Activate()
defer httpmock.DeactivateAndReset()
httpmock.RegisterResponder("PATCH", generateTestAPIVhostURL()+"/zones/example.org.",
func(req *http.Request) (*http.Response, error) {
if req.Header.Get("X-Api-Key") == testAPIKey {
return httpmock.NewJsonResponse(422, badPatchBody)
}
return httpmock.NewStringResponse(401, "Unauthorized"), nil
},
)
var response json.RawMessage
testClient, _ := initializePowerDNSTestClient()
testClient.sendQuery(context.Background(), generateTestRequestURI()+"/zones/example.org.", "PATCH", nil, &response)
isEqual, _ := areEqualJSON([]byte(strconv.Quote(badPatchBody)), response)
if !isEqual {
t.Error("Test Pdns bad patch - Failed")
}
}
func TestPdnsPatchRecord(t *testing.T) {
httpmock.Activate()
defer httpmock.DeactivateAndReset()
httpmock.RegisterResponder("PATCH", generateTestAPIVhostURL()+"/zones/example.org.",
func(req *http.Request) (*http.Response, error) {
if req.Header.Get("X-Api-Key") == testAPIKey {
return httpmock.NewJsonResponse(204, nil)
}
return httpmock.NewStringResponse(401, "Unauthorized"), nil
},
)
var response json.RawMessage
testClient, _ := initializePowerDNSTestClient()
testClient.sendQuery(context.Background(), generateTestRequestURI()+"/zones/example.org.", "PATCH", nil, &response)
t.Logf("Response is: %s", response)
if !bytes.Equal(response, []byte("null")) {
t.Error("Test Pdns patch record - Failed")
}
}

52
test_todo/test_utils.go Normal file
View File

@@ -0,0 +1,52 @@
package main
import (
"encoding/json"
"fmt"
"math/rand"
"reflect"
)
const (
testBaseURL string = "http://localhost:8081"
testVhost string = "localhost"
testAPIKey string = "123Password"
)
func generateTestAPIURL() string {
return fmt.Sprintf("%s/api/v1", testBaseURL)
}
func generateTestAPIVhostURL() string {
return fmt.Sprintf("%s/servers/%s", generateTestAPIURL(), testVhost)
}
func generateTestRequestURI() string {
return fmt.Sprintf("api/v1/servers/%s", testVhost)
}
func initializePowerDNSTestClient() (*PowerDNS, error) {
pdns, err := NewClient(testBaseURL, testAPIKey, 3, 7200)
return pdns, err
}
func generateTestZone() string {
domain := fmt.Sprintf("test-%d.com", rand.Int())
return domain
}
func areEqualJSON(s1, s2 []byte) (bool, error) {
var o1 interface{}
var o2 interface{}
var err error
err = json.Unmarshal([]byte(s1), &o1)
if err != nil {
return false, fmt.Errorf("Error mashalling string 1 :: %s", err.Error())
}
err = json.Unmarshal(s2, &o2)
if err != nil {
return false, fmt.Errorf("Error mashalling string 2 :: %s", err.Error())
}
return reflect.DeepEqual(o1, o2), nil
}

19
test_todo/utils_test.go Normal file
View File

@@ -0,0 +1,19 @@
package main
import (
"testing"
)
func TestAddQuotes(t *testing.T) {
for s, wanted := range map[string]string{
"toto": "\"toto\"",
"\"titi": "\"titi\"",
"\"tutu\"": "\"tutu\"",
"te\"te": "\"te\\\"te\"",
"\"\"ta\"ta": "\"ta\\\"ta\"",
} {
if res := addQuotes(s); res != wanted {
t.Errorf("%s quoted as %s and not %s", s, res, wanted)
}
}
}