~netlandish/links

4969ca73faa40d481fb4c258800ee53e35860720 — Peter Sanchez 9 months ago 1cac770
Moving external reverse proxy checking route to it's own service.

References: https://todo.code.netlandish.com/~netlandish/links/46
7 files changed, 103 insertions(+), 41 deletions(-)

M .gitignore
M Makefile
A cmd/domains/main.go
M cmd/links/main.go
M cmd/list/main.go
M cmd/short/main.go
M config.example.ini
M .gitignore => .gitignore +1 -0
@@ 15,6 15,7 @@ links
links-api
links-short
links-list
links-domains
main
tmp
media

M Makefile => Makefile +5 -1
@@ 7,6 7,7 @@ LINKSRC:=$(shell find ./cmd/links/ -name '*.go')
APISRC:=$(shell find ./cmd/api/ -name '*.go')
SHORTSRC:=$(shell find ./cmd/short/ -name '*.go')
LISTSRC:=$(shell find ./cmd/list/ -name '*.go')
DOMSRC:=$(shell find ./cmd/domains/ -name '*.go')

all: links links-api links-short links-list



@@ 14,7 15,7 @@ links: $(LINKSRC)
	$(GO) build $(GOFLAGS) -ldflags "$(LDFLAGS)" -o $@ $(LINKSRC)

clean:
	rm -f ./links ./links-api ./links-short ./links-list
	rm -f ./links ./links-api ./links-short ./links-list ./links-domains

trans:
	$(GO) generate ./internal/translations/translations.go


@@ 31,6 32,9 @@ links-short:
links-list:
	$(GO) build $(GOFLAGS) -ldflags "$(LDFLAGS)" -o $@ $(LISTSRC)

links-domains:
	$(GO) build $(GOFLAGS) -ldflags "$(LDFLAGS)" -o $@ $(DOMSRC)

schema:
	cd api && $(GO) generate ./graph


A cmd/domains/main.go => cmd/domains/main.go +85 -0
@@ 0,0 1,85 @@
package main

import (
	"fmt"
	"links/cmd"
	"links/core"
	"net/http"
	"os"
	"strconv"

	"github.com/labstack/echo/v4"
	"netlandish.com/x/gobwebs/config"
	"netlandish.com/x/gobwebs/database"
	"netlandish.com/x/gobwebs/server"
)

// Version set at build time
var Version string

func main() {
	if err := run(); err != nil {
		fmt.Fprintf(os.Stderr, "Error starting application: %s\n", err)
		os.Exit(1)
	}
}

func run() error {
	config, err := config.LoadConfig("./config.ini")
	if err != nil {
		return err
	}

	if val, ok := config.File.Get("links", "domains-listen-address"); ok {
		if val != "" {
			config.ListenAddr = val
		}
	}

	if val, ok := config.File.Get("links", "domains-listen-port"); ok {
		config.ListenPort, err = strconv.Atoi(val)
		if err != nil {
			return fmt.Errorf("links:domains-listen-port must be an integer value")
		}
	}

	db, err := cmd.OpenDB(config)
	if err != nil {
		return fmt.Errorf("Unable to open connection to PostgreSQL: %v", err)
	}
	defer db.Close()

	e := echo.New()
	e.GET("/_check/domain", func(c echo.Context) error {
		domain := c.QueryParam("domain")
		if domain == "" {
			return c.NoContent(http.StatusBadRequest)
		}
		domains, err := core.ValidDomain(c.Request().Context(), domain, -1, true)
		if err != nil {
			return err
		}
		if len(domains) != 1 {
			return c.NoContent(http.StatusBadRequest)
		}
		return c.NoContent(http.StatusOK)
	}).Name = "domain_check"

	mwConf := &server.MiddlewareConfig{
		Sessions:      false,
		ServerContext: false,
	}
	srv := server.New(e, db, config).
		Initialize().
		WithAppInfo("links-domains", Version).
		DefaultMiddlewareWithConfig(mwConf).
		WithMiddleware(
			database.Middleware(db),
			core.TimezoneContext(),
			core.CORSReadOnlyMiddleware,
		)

	srv.Run()

	return nil
}

M cmd/links/main.go => cmd/links/main.go +4 -33
@@ 131,12 131,6 @@ func run() error {
		return fmt.Errorf("Unknown storage service configured")
	}

	var domCheck bool
	if domCheckVal, ok := config.File.Get("links", "enable-domain-check"); ok {
		if domCheckVal == "true" {
			domCheck = true
		}
	}
	tlsman := cmd.LoadAutoTLS(config, db, models.DomainServiceLinks)

	e := echo.New()


@@ 183,35 177,12 @@ func run() error {
		WithMiddleware(
			database.Middleware(db),
			core.TimezoneContext(),
			crypto.Middleware(entropy),
			core.DomainContext(models.DomainServiceLinks),
			core.DomainRedirect,
			auth.AuthMiddleware(accounts.NewUserFetch()),
		)

	// Split here to do as little middleware processing as needed
	// to serve the domain check.
	if tlsman == nil && domCheck {
		e.GET("/_check/domain", func(c echo.Context) error {
			domain := c.QueryParam("domain")
			if domain == "" {
				return c.NoContent(http.StatusBadRequest)
			}
			domains, err := core.ValidDomain(c.Request().Context(), domain, -1, true)
			if err != nil {
				return err
			}
			if len(domains) != 1 {
				return c.NoContent(http.StatusBadRequest)
			}
			return c.NoContent(http.StatusOK)
		}).Name = "domain_check"
	}

	// Continue with middlewares...
	srv.WithMiddleware(
		crypto.Middleware(entropy),
		core.DomainContext(models.DomainServiceLinks),
		core.DomainRedirect,
		auth.AuthMiddleware(accounts.NewUserFetch()),
	)

	if tlsman != nil {
		srv = srv.WithCertManager(tlsman)
	}

M cmd/list/main.go => cmd/list/main.go +1 -1
@@ 54,7 54,7 @@ func run() error {
	if val, ok := config.File.Get("links", "list-listen-port"); ok {
		config.ListenPort, err = strconv.Atoi(val)
		if err != nil {
			return fmt.Errorf("links:api-listen-port must be an integer value")
			return fmt.Errorf("links:list-listen-port must be an integer value")
		}
	}


M cmd/short/main.go => cmd/short/main.go +1 -1
@@ 52,7 52,7 @@ func run() error {
	if val, ok := config.File.Get("links", "short-listen-port"); ok {
		config.ListenPort, err = strconv.Atoi(val)
		if err != nil {
			return fmt.Errorf("links:api-listen-port must be an integer value")
			return fmt.Errorf("links:short-listen-port must be an integer value")
		}
	}


M config.example.ini => config.example.ini +6 -5
@@ 117,10 117,6 @@ api-origin=http://127.0.0.1:8080/query
auto-tls=true
# Where will SSL certs be stored. If empty, the value of `./cache` is used.
ssl-cert-cachedir=/var/www/.cache
# Enable domain TLS support check. If set to true then the 
# /_check/domain route will be added.
# Default false
enable-domain-check=false

## DNS CHECKS



@@ 151,7 147,12 @@ list-listen-port=8002

api-service-domain=domain.com
api-listen-address=localhost
api-listen-port=8080
api-listen-port=8003

# Optional domains service. Set this if you plan to use
# domain checking via Caddy, tlstunnel, etc.
domains-listen-address=localhost
domains-listen-port=8004

[stripe]
secret-key=