Skip to content
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,13 @@ jobs:
- run: sudo add-apt-repository ppa:inkscape.dev/stable
- run: sudo apt-get update
- run: sudo apt-get install inkscape -y
- name: Set up MariaDB
id: mariadb
uses: rusher/action-setup-mariadb@v1.6
with:
tag: '11.4'
local: true # Force local installation
root-password: 'myRootPassword'
database: 'myDb'
- run: go build ./cmd/violet/
- run: go test ./...
- run: DB="root:myRootPassword@tcp(127.0.0.1)/myDb" go test ./...
6 changes: 6 additions & 0 deletions Makefile
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could place the entire build system within the makefile in future.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My idea is to eventually have a build system for debian packages which can be loaded onto the server via the standard packaging system.

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.PHONY: all sqlc

all: sqlc

sqlc:
sqlc generate
24 changes: 4 additions & 20 deletions certs/certs.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"github.com/1f349/violet/logger"
"github.com/1f349/violet/utils"
"github.com/mrmelon54/certgen"
"github.com/mrmelon54/rescheduler"
"io/fs"
"math/big"
"os"
Expand All @@ -28,13 +27,12 @@ type Certs struct {
m map[string]*tls.Certificate
ca *certgen.CertGen
sn atomic.Int64
r *rescheduler.Rescheduler
t *time.Ticker
ts chan struct{}
}

// New creates a new cert list
func New(certDir fs.FS, keyDir fs.FS, selfCert bool) *Certs {
func New(certDir fs.FS, keyDir fs.FS, selfCert bool, gap time.Duration) *Certs {
c := &Certs{
cDir: certDir,
kDir: keyDir,
Expand All @@ -45,15 +43,13 @@ func New(certDir fs.FS, keyDir fs.FS, selfCert bool) *Certs {
}

if !selfCert {
// the rescheduler isn't even used in self cert mode so why initialise it
c.r = rescheduler.NewRescheduler(c.threadCompile)

c.t = time.NewTicker(2 * time.Hour)
// the refresh loop isn't even used in self cert mode so why initialise it
c.t = time.NewTicker(gap)
go func() {
for {
select {
case <-c.t.C:
c.Compile()
c.threadCompile()
case <-c.ts:
return
}
Expand Down Expand Up @@ -121,18 +117,6 @@ func (c *Certs) GetCertForDomain(domain string) *tls.Certificate {
return nil
}

// Compile loads the certificates and keys from the directories.
//
// This method makes use of the rescheduler instead of just ignoring multiple
// calls.
func (c *Certs) Compile() {
// don't bother compiling in self-signed mode
if c.ss {
return
}
c.r.Run()
}

func (c *Certs) Stop() {
if c.t != nil {
c.t.Stop()
Expand Down
4 changes: 2 additions & 2 deletions certs/certs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func TestCertsNew_Lookup(t *testing.T) {
},
}

certs := New(certDir, keyDir, false)
certs := New(certDir, keyDir, false, 5*time.Second)
assert.NoError(t, certs.internalCompile(certs.m))
cc := certs.GetCertForDomain("example.com")
leaf := certgen.TlsLeaf(cc)
Expand All @@ -67,7 +67,7 @@ func TestCertsNew_SelfSigned(t *testing.T) {
return
}

certs := New(nil, nil, true)
certs := New(nil, nil, true, 5*time.Second)
cc := certs.GetCertForDomain("example.com")
leaf := certgen.TlsLeaf(cc)
assert.Equal(t, []string{"example.com"}, leaf.DNSNames)
Expand Down
16 changes: 10 additions & 6 deletions cmd/violet/conf.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package main

import "github.com/1f349/violet/utils"

type startUpConfig struct {
SelfSigned bool `json:"self_signed"`
ErrorPagePath string `json:"error_page_path"`
Listen listenConfig `json:"listen"`
InkscapeCmd string `json:"inkscape"`
RateLimit uint64 `json:"rate_limit"`
MetricsToken string `json:"metrics_token"`
SelfSigned bool `json:"self_signed"`
ErrorPagePath string `json:"error_page_path"`
Listen listenConfig `json:"listen"`
InkscapeCmd string `json:"inkscape"`
RateLimit uint64 `json:"rate_limit"`
MetricsToken string `json:"metrics_token"`
TableRefresh utils.DurationText `json:"table_refresh"`
CertRefresh utils.DurationText `json:"cert_refresh"`
}

type listenConfig struct {
Expand Down
24 changes: 16 additions & 8 deletions cmd/violet/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,20 @@ func (s *serveCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{})
certDir := os.DirFS(filepath.Join(wd, "certs"))
keyDir := os.DirFS(filepath.Join(wd, "keys"))

dynamicErrorPages, err := errorPages.New(errorPageDir)
if err != nil {
logger.Logger.Fatal("Failed to load error pages", "err", err)
}

serviceCtx, cancelService := context.WithCancel(context.Background())

ws := websocket.NewServer()
allowedDomains := domains.New(db) // load allowed domains
acmeChallenges := utils.NewAcmeChallenge() // load acme challenge store
allowedCerts := certs.New(certDir, keyDir, config.SelfSigned) // load certificate manager
hybridTransport := proxy.NewHybridTransport(ws) // load reverse proxy
dynamicFavicons := favicons.New(db, config.InkscapeCmd) // load dynamic favicon provider
dynamicErrorPages := errorPages.New(errorPageDir) // load dynamic error page provider
dynamicRouter := router.NewManager(db, hybridTransport) // load dynamic router manager
allowedDomains := domains.New(serviceCtx, db, time.Duration(config.TableRefresh)) // load allowed domains
acmeChallenges := utils.NewAcmeChallenge() // load acme challenge store
allowedCerts := certs.New(certDir, keyDir, config.SelfSigned, time.Duration(config.CertRefresh)) // load certificate manager
hybridTransport := proxy.NewHybridTransport(ws) // load reverse proxy
dynamicFavicons := favicons.New(db, config.InkscapeCmd) // load dynamic favicon provider
dynamicRouter := router.NewManager(serviceCtx, db, hybridTransport, time.Duration(config.TableRefresh)) // load dynamic router manager

// struct containing config for the http servers
srvConf := &conf.Conf{
Expand All @@ -150,7 +156,7 @@ func (s *serveCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{})
}

// create the compilable list and run a first time compile
allCompilables := utils.MultiCompilable{allowedDomains, allowedCerts, dynamicFavicons, dynamicErrorPages, dynamicRouter}
allCompilables := utils.MultiCompilable{dynamicFavicons}
allCompilables.Compile()

_, httpsPort, ok := utils.SplitDomainPort(config.Listen.Https, 443)
Expand Down Expand Up @@ -219,6 +225,8 @@ func (s *serveCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{})
os.Exit(1)
})

cancelService()

// stop updating certificates
allowedCerts.Stop()

Expand Down
5 changes: 3 additions & 2 deletions cmd/violet/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"path"
"path/filepath"
"strconv"
"time"
)

type setupCmd struct {
Expand Down Expand Up @@ -154,7 +155,7 @@ func (s *setupCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{})

// domain manager to add a domain, no need to compile here as the program needs
// to be run again with the serve subcommand
allowedDomains := domains.New(db)
allowedDomains := domains.New(context.Background(), db, 5*time.Second)
allowedDomains.Put(answers.FirstDomain, true)

// don't bother with this part is the api won't be listening
Expand All @@ -181,7 +182,7 @@ func (s *setupCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{})

// add with the route manager, no need to compile as this will run when opened
// with the serve subcommand
routeManager := router.NewManager(db, proxy.NewHybridTransportWithCalls(&nilTransport{}, &nilTransport{}, &websocket.Server{}))
routeManager := router.NewManager(context.Background(), db, proxy.NewHybridTransportWithCalls(&nilTransport{}, &nilTransport{}, &websocket.Server{}), 5*time.Minute)
err = routeManager.InsertRoute(target.RouteWithActive{
Route: target.Route{
Src: path.Join(apiUrl.Host, apiUrl.Path),
Expand Down
2 changes: 1 addition & 1 deletion database/db.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions database/domain.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions database/favicon.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions database/migrations/20240308125121_domains.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE domains;
6 changes: 6 additions & 0 deletions database/migrations/20240308125121_domains.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
CREATE TABLE IF NOT EXISTS domains
(
id INTEGER PRIMARY KEY AUTO_INCREMENT,
domain TEXT UNIQUE NOT NULL,
active BOOLEAN NOT NULL DEFAULT 1
);
4 changes: 0 additions & 4 deletions database/migrations/20240308125121_init.down.sql

This file was deleted.

36 changes: 0 additions & 36 deletions database/migrations/20240308125121_init.up.sql

This file was deleted.

1 change: 1 addition & 0 deletions database/migrations/20251207020207_favicons.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE favicons;
8 changes: 8 additions & 0 deletions database/migrations/20251207020207_favicons.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CREATE TABLE IF NOT EXISTS favicons
(
id INTEGER PRIMARY KEY AUTO_INCREMENT,
host TEXT NOT NULL,
svg TEXT,
png TEXT,
ico TEXT
);
1 change: 1 addition & 0 deletions database/migrations/20251207020211_routes.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE routes;
9 changes: 9 additions & 0 deletions database/migrations/20251207020211_routes.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CREATE TABLE IF NOT EXISTS routes
(
id INTEGER PRIMARY KEY AUTO_INCREMENT,
source TEXT UNIQUE NOT NULL,
destination TEXT NOT NULL,
description TEXT NOT NULL,
flags INTEGER NOT NULL DEFAULT 0,
active BOOLEAN NOT NULL DEFAULT 1
);
1 change: 1 addition & 0 deletions database/migrations/20251207020214_redirects.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE redirects;
10 changes: 10 additions & 0 deletions database/migrations/20251207020214_redirects.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CREATE TABLE IF NOT EXISTS redirects
(
id INTEGER PRIMARY KEY AUTO_INCREMENT,
source TEXT UNIQUE NOT NULL,
destination TEXT NOT NULL,
description TEXT NOT NULL,
flags INTEGER NOT NULL DEFAULT 0,
code INTEGER NOT NULL DEFAULT 0,
active BOOLEAN NOT NULL DEFAULT 1
);
12 changes: 6 additions & 6 deletions database/models.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions database/queries/domain.sql
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@ FROM domains
WHERE active = 1;

-- name: AddDomain :exec
INSERT OR
REPLACE
INTO domains (domain, active)
VALUES (?, ?);

-- name: DeleteDomain :exec
INSERT OR
REPLACE
INTO domains(domain, active)
VALUES (?, false);
Loading
Loading