mirror of
https://codeberg.org/Codeberg/pages-server.git
synced 2025-04-25 06:16:58 +00:00
WIP
This commit is contained in:
parent
dd5124912e
commit
0e334d8e64
32 changed files with 611 additions and 211 deletions
31
config/assets/test_config.toml
Normal file
31
config/assets/test_config.toml
Normal file
|
@ -0,0 +1,31 @@
|
|||
logLevel = 'trace'
|
||||
|
||||
[server]
|
||||
host = '127.0.0.1'
|
||||
port = 443
|
||||
httpPort = 80
|
||||
httpServerEnabled = true
|
||||
mainDomain = 'codeberg.page'
|
||||
rawDomain = 'raw.codeberg.page'
|
||||
allowedCorsDomains = ['fonts.codeberg.org', 'design.codeberg.org']
|
||||
blacklistedPaths = []
|
||||
|
||||
[gitea]
|
||||
root = 'codeberg.org'
|
||||
token = 'XXXXX'
|
||||
lfsEnabled = true
|
||||
followSymlinks = true
|
||||
|
||||
[database]
|
||||
type = 'sqlite'
|
||||
conn = 'certs.sqlite'
|
||||
|
||||
[ACME]
|
||||
email = 'a@b.c'
|
||||
apiEndpoint = 'https://example.com'
|
||||
acceptTerms = false
|
||||
useRateLimits = true
|
||||
eab_hmac = ''
|
||||
eab_kid = ''
|
||||
dnsProvider = ''
|
||||
accountConfigFile = ''
|
43
config/config.go
Normal file
43
config/config.go
Normal file
|
@ -0,0 +1,43 @@
|
|||
package config
|
||||
|
||||
type Config struct {
|
||||
LogLevel string
|
||||
Server ServerConfig
|
||||
Gitea GiteaConfig
|
||||
Database DatabaseConfig
|
||||
ACME ACMEConfig
|
||||
}
|
||||
|
||||
type ServerConfig struct {
|
||||
Host string
|
||||
Port uint16
|
||||
HttpPort uint16
|
||||
HttpServerEnabled bool
|
||||
MainDomain string
|
||||
RawDomain string
|
||||
AllowedCorsDomains []string
|
||||
BlacklistedPaths []string
|
||||
}
|
||||
|
||||
type GiteaConfig struct {
|
||||
Root string
|
||||
Token string
|
||||
LFSEnabled bool
|
||||
FollowSymlinks bool
|
||||
}
|
||||
|
||||
type DatabaseConfig struct {
|
||||
Type string
|
||||
Conn string
|
||||
}
|
||||
|
||||
type ACMEConfig struct {
|
||||
Email string
|
||||
APIEndpoint string
|
||||
AcceptTerms bool
|
||||
UseRateLimits bool
|
||||
EAB_HMAC string
|
||||
EAB_KID string
|
||||
DNSProvider string
|
||||
AccountConfigFile string
|
||||
}
|
32
config/program.go
Normal file
32
config/program.go
Normal file
|
@ -0,0 +1,32 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"codeberg.org/codeberg/pages/server/cache"
|
||||
"codeberg.org/codeberg/pages/server/certificates"
|
||||
"codeberg.org/codeberg/pages/server/database"
|
||||
"codeberg.org/codeberg/pages/server/gitea"
|
||||
)
|
||||
|
||||
type HandlerConfig struct {
|
||||
mainDomainSuffix string
|
||||
rawDomain string
|
||||
giteaClient *gitea.Client
|
||||
blacklistedPaths []string
|
||||
allowedCorsDomains []string
|
||||
defaultBranches []string
|
||||
dnsLookupCache cache.ICache
|
||||
canonicalDomainCache cache.ICache
|
||||
redirectsCache cache.ICache
|
||||
}
|
||||
|
||||
type TLSConfig struct {
|
||||
mainDomainSuffix string
|
||||
firstDefaultBranch string
|
||||
giteaClient *gitea.Client
|
||||
acmeClient *certificates.AcmeClient
|
||||
keyCache cache.ICache
|
||||
challengeCache cache.ICache
|
||||
dnsLookupCache cache.ICache
|
||||
canonicalDomainCache cache.ICache
|
||||
certDB database.CertDB
|
||||
}
|
77
config/setup.go
Normal file
77
config/setup.go
Normal file
|
@ -0,0 +1,77 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/pelletier/go-toml/v2"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var ALWAYS_BLACKLISTED_PATHS = []string{
|
||||
"/.well-known/acme-challenge/",
|
||||
}
|
||||
|
||||
func ReadConfig(ctx *cli.Context) (*Config, error) {
|
||||
// if config is not given as argument return empty config
|
||||
if !ctx.IsSet("config-file") {
|
||||
return &Config{}, nil
|
||||
}
|
||||
|
||||
configFile := path.Clean(ctx.String("config-file"))
|
||||
|
||||
log.Debug().Str("config-file", configFile).Msg("reading config file")
|
||||
content, err := os.ReadFile(configFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
config := &Config{}
|
||||
err = toml.Unmarshal(content, config)
|
||||
return config, err
|
||||
}
|
||||
|
||||
func MergeConfig(ctx *cli.Context, config *Config) {
|
||||
if ctx.IsSet("log-level") {
|
||||
config.LogLevel = ctx.String("log-level")
|
||||
}
|
||||
|
||||
mergeServerConfig(ctx, &config.Server)
|
||||
}
|
||||
|
||||
func mergeServerConfig(ctx *cli.Context, config *ServerConfig) {
|
||||
if ctx.IsSet("host") {
|
||||
config.Host = ctx.String("host")
|
||||
}
|
||||
if ctx.IsSet("port") {
|
||||
config.Port = uint16(ctx.Uint("port"))
|
||||
}
|
||||
if ctx.IsSet("http-port") {
|
||||
config.HttpPort = uint16(ctx.Uint("http-port"))
|
||||
}
|
||||
if ctx.IsSet("enable-http-server") {
|
||||
config.HttpServerEnabled = ctx.Bool("enable-http-server")
|
||||
}
|
||||
if ctx.IsSet("pages-domain") {
|
||||
config.MainDomain = ctx.String("pages-domain")
|
||||
}
|
||||
if ctx.IsSet("raw-domain") {
|
||||
config.RawDomain = ctx.String("raw-domain")
|
||||
}
|
||||
if ctx.IsSet("allowed-cors-domains") {
|
||||
config.AllowedCorsDomains = ctx.StringSlice("allowed-cors-domains")
|
||||
}
|
||||
if ctx.IsSet("blacklisted-paths") {
|
||||
config.BlacklistedPaths = ctx.StringSlice("blacklisted-paths")
|
||||
}
|
||||
|
||||
// add the paths that should always be blacklisted
|
||||
config.BlacklistedPaths = append(config.BlacklistedPaths, ALWAYS_BLACKLISTED_PATHS...)
|
||||
}
|
||||
|
||||
func mergeGiteaConfig(ctx *cli.Context, config *GiteaConfig) {
|
||||
if ctx.IsSet("gitea-root") {
|
||||
config.Root = ctx.String("gitea-root")
|
||||
}
|
||||
}
|
167
config/setup_test.go
Normal file
167
config/setup_test.go
Normal file
|
@ -0,0 +1,167 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/pelletier/go-toml/v2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
cmd "codeberg.org/codeberg/pages/cli"
|
||||
)
|
||||
|
||||
func runApp(t *testing.T, fn func(*cli.Context) error, args []string) {
|
||||
app := cmd.CreatePagesApp()
|
||||
app.Action = fn
|
||||
|
||||
// os.Args always contains the binary name
|
||||
args = append([]string{"testing"}, args...)
|
||||
|
||||
err := app.Run(args)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestReadConfigShouldReturnEmptyConfigWhenConfigArgEmpty(t *testing.T) {
|
||||
runApp(
|
||||
t,
|
||||
func(ctx *cli.Context) error {
|
||||
cfg, err := ReadConfig(ctx)
|
||||
assert.Equal(t, &Config{}, cfg)
|
||||
|
||||
return err
|
||||
},
|
||||
[]string{},
|
||||
)
|
||||
}
|
||||
|
||||
func TestReadConfigShouldReturnConfigFromFileWhenConfigArgPresent(t *testing.T) {
|
||||
runApp(
|
||||
t,
|
||||
func(ctx *cli.Context) error {
|
||||
content, err := os.ReadFile("assets/test_config.toml")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
expectedConfig := &Config{}
|
||||
err = toml.Unmarshal(content, expectedConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg, err := ReadConfig(ctx)
|
||||
assert.Equal(t, expectedConfig, cfg)
|
||||
|
||||
return err
|
||||
},
|
||||
[]string{"--config-file", "assets/test_config.toml"},
|
||||
)
|
||||
}
|
||||
|
||||
func TestMergeServerConfigShouldAddDefaultBlacklistedPathsToBlacklistedPaths(t *testing.T) {
|
||||
runApp(
|
||||
t,
|
||||
func(ctx *cli.Context) error {
|
||||
cfg := &ServerConfig{}
|
||||
mergeServerConfig(ctx, cfg)
|
||||
|
||||
expected := ALWAYS_BLACKLISTED_PATHS
|
||||
assert.Equal(t, expected, cfg.BlacklistedPaths)
|
||||
|
||||
return nil
|
||||
},
|
||||
[]string{},
|
||||
)
|
||||
}
|
||||
|
||||
func TestMergeServerConfigShouldReplaceAllExistingValuesGivenAllArgsExist(t *testing.T) {
|
||||
runApp(
|
||||
t,
|
||||
func(ctx *cli.Context) error {
|
||||
cfg := &ServerConfig{
|
||||
Host: "original",
|
||||
Port: 8080,
|
||||
HttpPort: 80,
|
||||
HttpServerEnabled: false,
|
||||
MainDomain: "original",
|
||||
RawDomain: "original",
|
||||
AllowedCorsDomains: []string{"original"},
|
||||
BlacklistedPaths: []string{"original"},
|
||||
}
|
||||
|
||||
mergeServerConfig(ctx, cfg)
|
||||
|
||||
expectedConfig := &ServerConfig{
|
||||
Host: "changed",
|
||||
Port: 8443,
|
||||
HttpPort: 443,
|
||||
HttpServerEnabled: true,
|
||||
MainDomain: "changed",
|
||||
RawDomain: "changed",
|
||||
AllowedCorsDomains: []string{"changed"},
|
||||
BlacklistedPaths: append([]string{"changed"}, ALWAYS_BLACKLISTED_PATHS...),
|
||||
}
|
||||
|
||||
assert.Equal(t, expectedConfig, cfg)
|
||||
|
||||
return nil
|
||||
},
|
||||
[]string{
|
||||
"--pages-domain", "changed",
|
||||
"--raw-domain", "changed",
|
||||
"--allowed-cors-domains", "changed",
|
||||
"--blacklisted-paths", "changed",
|
||||
"--host", "changed",
|
||||
"--port", "8443",
|
||||
"--http-port", "443",
|
||||
"--enable-http-server",
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func TestMergeServerConfigShouldReplaceOnlyOneValueExistingValueGivenOnlyOneArgExists(t *testing.T) {
|
||||
type testValuePair struct {
|
||||
args []string
|
||||
callback func(*ServerConfig)
|
||||
}
|
||||
testValuePairs := []testValuePair{
|
||||
{args: []string{"--host", "changed"}, callback: func(sc *ServerConfig) { sc.Host = "changed" }},
|
||||
{args: []string{"--port", "8443"}, callback: func(sc *ServerConfig) { sc.Port = 8443 }},
|
||||
{args: []string{"--http-port", "443"}, callback: func(sc *ServerConfig) { sc.HttpPort = 443 }},
|
||||
{args: []string{"--enable-http-server"}, callback: func(sc *ServerConfig) { sc.HttpServerEnabled = true }},
|
||||
{args: []string{"--pages-domain", "changed"}, callback: func(sc *ServerConfig) { sc.MainDomain = "changed" }},
|
||||
{args: []string{"--raw-domain", "changed"}, callback: func(sc *ServerConfig) { sc.RawDomain = "changed" }},
|
||||
{args: []string{"--allowed-cors-domains", "changed"}, callback: func(sc *ServerConfig) { sc.AllowedCorsDomains = []string{"changed", "changed"} }}, // don't ask why, the cli lib always adds two strings when running all tests and one when running a single test
|
||||
{args: []string{"--blacklisted-paths", "changed"}, callback: func(sc *ServerConfig) { sc.BlacklistedPaths = []string{"changed", "changed"} }}, // same here
|
||||
}
|
||||
|
||||
for _, pair := range testValuePairs {
|
||||
runApp(
|
||||
t,
|
||||
func(ctx *cli.Context) error {
|
||||
cfg := ServerConfig{
|
||||
Host: "original",
|
||||
Port: 8080,
|
||||
HttpPort: 80,
|
||||
HttpServerEnabled: false,
|
||||
MainDomain: "original",
|
||||
RawDomain: "original",
|
||||
AllowedCorsDomains: []string{"original"},
|
||||
BlacklistedPaths: []string{"original"},
|
||||
}
|
||||
|
||||
expectedConfig := cfg
|
||||
pair.callback(&expectedConfig)
|
||||
expectedConfig.BlacklistedPaths = append(expectedConfig.BlacklistedPaths, ALWAYS_BLACKLISTED_PATHS...)
|
||||
|
||||
mergeServerConfig(ctx, &cfg)
|
||||
|
||||
assert.Equal(t, expectedConfig, cfg)
|
||||
|
||||
return nil
|
||||
},
|
||||
pair.args,
|
||||
)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue