mirror of
https://github.com/phishingclub/phishingclub.git
synced 2026-02-12 16:12:44 +00:00
456 lines
9.9 KiB
Go
456 lines
9.9 KiB
Go
package config
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/fs"
|
|
"net"
|
|
"os"
|
|
"reflect"
|
|
"testing"
|
|
"testing/fstest"
|
|
|
|
"github.com/go-errors/errors"
|
|
|
|
"github.com/phishingclub/phishingclub/data"
|
|
"github.com/phishingclub/phishingclub/file"
|
|
"github.com/phishingclub/phishingclub/file/filemock"
|
|
)
|
|
|
|
const (
|
|
DEFAULT_ADMIN_ADDR = "127.0.0.1:8002"
|
|
DEFAULT_PHISHING_HTTP_ADDR = "127.0.0.1:8000"
|
|
DEFAULT_PHISHING_HTTPS_ADDR = "127.0.0.1:8001"
|
|
DEFAULT_ACME_EMAIL = ""
|
|
)
|
|
|
|
var (
|
|
adminHost = "phish.test"
|
|
adminTLS = false
|
|
adminPublicCertPath = fmt.Sprintf(
|
|
"%s/%s",
|
|
data.DefaultAdminCertDir,
|
|
data.DefaultAdminPublicCertFileName,
|
|
)
|
|
adminPrivateCertPath = fmt.Sprintf(
|
|
"%s/%s",
|
|
data.DefaultAdminCertDir,
|
|
data.DefaultAdminPrivateCertFileName,
|
|
)
|
|
|
|
configFileOK = []byte(`{
|
|
"administration": {
|
|
"address": "127.0.0.1:4000"
|
|
}
|
|
}`)
|
|
configFileEmpty = []byte("{")
|
|
databaseOK = Database{
|
|
Engine: DefaultAdministrationUseSqlite,
|
|
DSN: DefaultAdministrationDSN,
|
|
}
|
|
)
|
|
|
|
func newTestConfig() *Config {
|
|
return &Config{
|
|
acme: ACME{
|
|
Email: DEFAULT_ACME_EMAIL,
|
|
},
|
|
tlsCertPath: adminPublicCertPath,
|
|
tlsKeyPath: adminPrivateCertPath,
|
|
adminNetAddress: net.TCPAddr{
|
|
IP: net.IPv4(127, 0, 0, 1),
|
|
Port: DefaultDevAdministrationPort,
|
|
},
|
|
phishingHTTPNetAddress: net.TCPAddr{
|
|
IP: net.IPv4(127, 0, 0, 1),
|
|
Port: DefaultDevHTTPPhishingPort,
|
|
},
|
|
phishingHTTPSNetAddress: net.TCPAddr{
|
|
IP: net.IPv4(127, 0, 0, 1),
|
|
Port: DefaultDevHTTPSPhishingPort,
|
|
},
|
|
database: databaseOK,
|
|
fileWriter: &filemock.Writer{},
|
|
}
|
|
}
|
|
|
|
func TestNewConfig(t *testing.T) {
|
|
t.Run("happy path", testNewConfigHappyPath)
|
|
t.Run("invalid administration address and port split", testNewConfigInvalidAdministrationAddress)
|
|
t.Run("invalid administration ip", testNewConfigInvalidAdministrationIP)
|
|
t.Run("invalid administration port", testNewConfigInvalidAdministrationPort)
|
|
t.Run("invalid administration port string", testNewConfigInvalidAdministrationPortString)
|
|
t.Run("invalid database", testNewConfigInvalidDatabase)
|
|
t.Run("writer with nil", testNewConfigWithNilWriter)
|
|
|
|
}
|
|
|
|
func testNewConfigWithNilWriter(t *testing.T) {
|
|
_, err := NewConfig(
|
|
DEFAULT_ACME_EMAIL,
|
|
adminHost,
|
|
adminTLS,
|
|
adminPublicCertPath,
|
|
adminPrivateCertPath,
|
|
"127.0.0.1:8080",
|
|
DEFAULT_PHISHING_HTTP_ADDR,
|
|
DEFAULT_PHISHING_HTTPS_ADDR,
|
|
databaseOK,
|
|
nil,
|
|
"",
|
|
"",
|
|
|
|
IPSecurityConfig{
|
|
AdminAllowed: defaultAdminAllowed,
|
|
TrustedProxies: defaultTrustedProxies,
|
|
TrustedIPHeader: DefaultTrustedIPHeader,
|
|
},
|
|
)
|
|
if err == nil {
|
|
if !errors.Is(err, ErrWriterIsNil) {
|
|
t.Error("expected ErrWriterIsNil error from nil writer")
|
|
}
|
|
t.Error("expected error from nil writer")
|
|
return
|
|
}
|
|
}
|
|
|
|
func testNewConfigInvalidAdministrationAddress(t *testing.T) {
|
|
_, err := NewConfig(
|
|
DEFAULT_ACME_EMAIL,
|
|
adminHost,
|
|
adminTLS,
|
|
adminPublicCertPath,
|
|
adminPrivateCertPath,
|
|
"foobar",
|
|
DEFAULT_PHISHING_HTTP_ADDR,
|
|
DEFAULT_PHISHING_HTTPS_ADDR,
|
|
databaseOK,
|
|
&filemock.Writer{},
|
|
"",
|
|
"",
|
|
IPSecurityConfig{
|
|
AdminAllowed: defaultAdminAllowed,
|
|
TrustedProxies: defaultTrustedProxies,
|
|
TrustedIPHeader: DefaultTrustedIPHeader,
|
|
},
|
|
)
|
|
if err == nil {
|
|
t.Error("expected error from invalid address")
|
|
return
|
|
}
|
|
}
|
|
|
|
func testNewConfigInvalidAdministrationIP(t *testing.T) {
|
|
_, err := NewConfig(
|
|
DEFAULT_ACME_EMAIL,
|
|
adminHost,
|
|
adminTLS,
|
|
adminPublicCertPath,
|
|
adminPrivateCertPath,
|
|
"999.00.999.999:1234",
|
|
DEFAULT_PHISHING_HTTP_ADDR,
|
|
DEFAULT_PHISHING_HTTPS_ADDR,
|
|
databaseOK,
|
|
&filemock.Writer{},
|
|
"",
|
|
"",
|
|
IPSecurityConfig{
|
|
AdminAllowed: defaultAdminAllowed,
|
|
TrustedProxies: defaultTrustedProxies,
|
|
TrustedIPHeader: DefaultTrustedIPHeader,
|
|
},
|
|
)
|
|
if !errors.Is(err, ErrInvalidIP) {
|
|
t.Error(err)
|
|
return
|
|
}
|
|
}
|
|
|
|
func testNewConfigHappyPath(t *testing.T) {
|
|
addr := "127.0.0.1:1234"
|
|
c, err := NewConfig(
|
|
DEFAULT_ACME_EMAIL,
|
|
adminHost,
|
|
adminTLS,
|
|
adminPublicCertPath,
|
|
adminPrivateCertPath,
|
|
addr,
|
|
DEFAULT_PHISHING_HTTP_ADDR,
|
|
DEFAULT_PHISHING_HTTPS_ADDR,
|
|
databaseOK,
|
|
&filemock.Writer{},
|
|
"",
|
|
"",
|
|
IPSecurityConfig{
|
|
AdminAllowed: defaultAdminAllowed,
|
|
TrustedProxies: defaultTrustedProxies,
|
|
TrustedIPHeader: DefaultTrustedIPHeader,
|
|
},
|
|
)
|
|
if err != nil {
|
|
t.Error(err)
|
|
return
|
|
}
|
|
if c.AdminNetAddress() != addr {
|
|
t.Errorf("expected %s but got %s", addr, c.AdminNetAddress())
|
|
return
|
|
}
|
|
if c.database.DSN != databaseOK.DSN {
|
|
t.Errorf("expected %s but got %s", databaseOK.DSN, c.database.DSN)
|
|
return
|
|
}
|
|
if c.database.Engine != databaseOK.Engine {
|
|
t.Errorf("expected %s but got %s", databaseOK.Engine, c.database.Engine)
|
|
return
|
|
}
|
|
}
|
|
|
|
func testNewConfigInvalidAdministrationPort(t *testing.T) {
|
|
_, err := NewConfig(
|
|
DEFAULT_ACME_EMAIL,
|
|
adminHost,
|
|
adminTLS,
|
|
adminPublicCertPath,
|
|
adminPrivateCertPath,
|
|
"127.0.0.1:-1",
|
|
DEFAULT_PHISHING_HTTP_ADDR,
|
|
DEFAULT_PHISHING_HTTPS_ADDR,
|
|
databaseOK,
|
|
&filemock.Writer{},
|
|
"",
|
|
"",
|
|
IPSecurityConfig{
|
|
AdminAllowed: defaultAdminAllowed,
|
|
TrustedProxies: defaultTrustedProxies,
|
|
TrustedIPHeader: DefaultTrustedIPHeader,
|
|
},
|
|
)
|
|
if !errors.Is(err, ErrInvalidPort) {
|
|
t.Error(err)
|
|
return
|
|
}
|
|
}
|
|
|
|
func testNewConfigInvalidAdministrationPortString(t *testing.T) {
|
|
_, err := NewConfig(
|
|
DEFAULT_ACME_EMAIL,
|
|
adminHost,
|
|
adminTLS,
|
|
adminPublicCertPath,
|
|
adminPrivateCertPath,
|
|
"127.0.0.1:999999999999999999999999999999999999999999",
|
|
DEFAULT_PHISHING_HTTP_ADDR,
|
|
DEFAULT_PHISHING_HTTPS_ADDR,
|
|
databaseOK,
|
|
&filemock.Writer{},
|
|
"",
|
|
"",
|
|
IPSecurityConfig{
|
|
AdminAllowed: defaultAdminAllowed,
|
|
TrustedProxies: defaultTrustedProxies,
|
|
TrustedIPHeader: DefaultTrustedIPHeader,
|
|
},
|
|
)
|
|
if err == nil {
|
|
t.Error("expected error from invalid string port")
|
|
return
|
|
}
|
|
}
|
|
|
|
func testNewConfigInvalidDatabase(t *testing.T) {
|
|
_, err := NewConfig(
|
|
DEFAULT_ACME_EMAIL,
|
|
adminHost,
|
|
adminTLS,
|
|
adminPublicCertPath,
|
|
adminPrivateCertPath,
|
|
"127.0.0.1:1234",
|
|
DEFAULT_PHISHING_HTTP_ADDR,
|
|
DEFAULT_PHISHING_HTTPS_ADDR,
|
|
Database{
|
|
Engine: "foobar",
|
|
DSN: "file:./data.db?cache=shared&mode=rwc&_fk=1",
|
|
}, &filemock.Writer{},
|
|
"",
|
|
"",
|
|
IPSecurityConfig{
|
|
AdminAllowed: defaultAdminAllowed,
|
|
TrustedProxies: defaultTrustedProxies,
|
|
TrustedIPHeader: DefaultTrustedIPHeader,
|
|
},
|
|
)
|
|
if err == nil {
|
|
t.Errorf("expected %s but got %s", ErrInvalidDatabase, err)
|
|
return
|
|
}
|
|
}
|
|
|
|
func TestSetFileWriter(t *testing.T) {
|
|
t.Run("happypath", func(t *testing.T) {
|
|
c := newTestConfig()
|
|
err := c.SetFileWriter(&filemock.Writer{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
return
|
|
}
|
|
})
|
|
t.Run("nil writer", func(t *testing.T) {
|
|
c := newTestConfig()
|
|
err := c.SetFileWriter(nil)
|
|
if err == nil {
|
|
if !errors.Is(err, ErrWriterIsNil) {
|
|
t.Error("expected ErrWriterIsNil error from nil writer")
|
|
}
|
|
t.Error("expected error from nil writer")
|
|
return
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestWriteToFile(t *testing.T) {
|
|
filepath := "./testFile"
|
|
c := newTestConfig()
|
|
m := filemock.Writer{}
|
|
dto := c.ToDTO()
|
|
conf, err := json.MarshalIndent(dto, "", " ")
|
|
if err != nil {
|
|
t.Error(err)
|
|
return
|
|
}
|
|
m.
|
|
On("Write", filepath, conf, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.FileMode(0644)).
|
|
Return(0, nil)
|
|
err = c.SetFileWriter(&m)
|
|
if err != nil {
|
|
t.Error(err)
|
|
return
|
|
}
|
|
err = c.WriteToFile(filepath)
|
|
if err != nil {
|
|
t.Error(err)
|
|
return
|
|
}
|
|
}
|
|
|
|
func TestToDTO(t *testing.T) {
|
|
addr := "127.0.0.1:1234"
|
|
c, err := NewConfig(
|
|
DEFAULT_ACME_EMAIL,
|
|
adminHost,
|
|
adminTLS,
|
|
adminPublicCertPath,
|
|
adminPrivateCertPath,
|
|
addr,
|
|
DEFAULT_PHISHING_HTTP_ADDR,
|
|
DEFAULT_PHISHING_HTTPS_ADDR,
|
|
databaseOK,
|
|
&filemock.Writer{},
|
|
"",
|
|
"",
|
|
IPSecurityConfig{
|
|
AdminAllowed: defaultAdminAllowed,
|
|
TrustedProxies: defaultTrustedProxies,
|
|
TrustedIPHeader: DefaultTrustedIPHeader,
|
|
},
|
|
)
|
|
if err != nil {
|
|
t.Error(err)
|
|
return
|
|
}
|
|
dto := c.ToDTO()
|
|
if dto.AdministrationServer.Address != addr {
|
|
t.Errorf("expected %s but got %s", addr, dto.AdministrationServer.Address)
|
|
return
|
|
}
|
|
}
|
|
|
|
func TestNewDTOFromFile(t *testing.T) {
|
|
|
|
t.Run("happypath", testNewDTOFromFileHappyPath)
|
|
t.Run("file error", testNewDTOFromFileFileError)
|
|
t.Run("bad content", testNewDTOFromFileBadContent)
|
|
}
|
|
|
|
func testNewDTOFromFileHappyPath(t *testing.T) {
|
|
filesystem := fstest.MapFS{}
|
|
path := "config.json"
|
|
filesystem[path] = &fstest.MapFile{
|
|
Data: configFileOK,
|
|
}
|
|
dto, err := NewDTOFromFile(filesystem, path)
|
|
if err != nil {
|
|
t.Error(err)
|
|
return
|
|
}
|
|
if dto.AdministrationServer.Address != "127.0.0.1:4000" {
|
|
t.Errorf("Expected %s Got %s", "127.0.0.1:4000", dto.AdministrationServer.Address)
|
|
return
|
|
}
|
|
}
|
|
|
|
func testNewDTOFromFileFileError(t *testing.T) {
|
|
filesystem := fstest.MapFS{}
|
|
path := "config.json"
|
|
_, err := NewDTOFromFile(filesystem, path)
|
|
if !errors.Is(err, fs.ErrNotExist) {
|
|
t.Errorf("expected %s but got %s", fs.ErrNotExist, err)
|
|
return
|
|
}
|
|
}
|
|
|
|
func testNewDTOFromFileBadContent(t *testing.T) {
|
|
filesystem := fstest.MapFS{}
|
|
path := "config.json"
|
|
filesystem[path] = &fstest.MapFile{
|
|
Data: configFileEmpty,
|
|
}
|
|
_, err := NewDTOFromFile(filesystem, path)
|
|
if err == nil {
|
|
t.Error("expected error from invalid file contents")
|
|
return
|
|
}
|
|
}
|
|
|
|
func TestNewDefaultConfig(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
want *Config
|
|
}{
|
|
{
|
|
name: "happypath",
|
|
want: &Config{
|
|
tlsCertPath: adminPublicCertPath,
|
|
tlsKeyPath: adminPrivateCertPath,
|
|
adminNetAddress: net.TCPAddr{
|
|
IP: net.IPv4(127, 0, 0, 1),
|
|
Port: DefaultDevAdministrationPort,
|
|
},
|
|
database: Database{
|
|
Engine: DefaultAdministrationUseSqlite,
|
|
DSN: DefaultAdministrationDSN,
|
|
},
|
|
fileWriter: &file.FileWriter{},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := NewDevDefaultConfig(); !reflect.DeepEqual(got, tt.want) {
|
|
t.Errorf("NewDefaultConfig() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestConfig_Database(t *testing.T) {
|
|
t.Run("happypath", func(t *testing.T) {
|
|
c := newTestConfig()
|
|
if !reflect.DeepEqual(c.Database(), databaseOK) {
|
|
t.Errorf("expected %v but got %v", databaseOK, c.Database())
|
|
return
|
|
}
|
|
})
|
|
}
|