~netlandish/links-dev

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
1

[PATCH links] gobwebs bump

Details
Message ID
<20260915145315.13527-1-peter@netlandish.com>
Sender timestamp
1789462392
DKIM signature
missing
Download raw message
Patch: +35 -56
Now using RemoteIPMiddleware and supporting functions from gobweb
---
 analytics/helpers.go     |  4 ++--
 analytics/routes_test.go |  3 ++-
 client.go                |  3 ++-
 cmd/api/main.go          |  3 ++-
 cmd/links/main.go        |  2 +-
 cmd/list/main.go         |  3 ++-
 cmd/short/main.go        |  3 ++-
 cmd/test/helpers.go      |  4 ++--
 core/middleware.go       | 11 -----------
 go.mod                   | 12 ++++++------
 go.sum                   | 24 ++++++++++++------------
 helpers.go               | 16 ----------------
 short/routes_test.go     |  3 ++-
 13 files changed, 35 insertions(+), 56 deletions(-)

diff --git a/analytics/helpers.go b/analytics/helpers.go
index dcc346a..4b54281 100644
--- a/analytics/helpers.go
+++ b/analytics/helpers.go
@@ -4,7 +4,6 @@ import (
	"context"
	"database/sql"
	"fmt"
	"links"
	"links/models"
	"net"
	"net/http"
@@ -12,6 +11,7 @@ import (

	sq "github.com/Masterminds/squirrel"
	"github.com/oschwald/geoip2-golang"
	gcore "netlandish.com/x/gobwebs/core"
	"netlandish.com/x/gobwebs/database"
)

@@ -117,7 +117,7 @@ func AddMetaAnalytics(ctx context.Context, req *http.Request, dailyTotalID int,
		}
	}

	ip := links.IPForContext(req.Context())
	ip := gcore.IPForContext(req.Context())
	if ip != "" {
		db, err := geoip2.Open(geoPath)
		if err != nil {
diff --git a/analytics/routes_test.go b/analytics/routes_test.go
index c6cd46f..eb8b936 100644
--- a/analytics/routes_test.go
+++ b/analytics/routes_test.go
@@ -19,6 +19,7 @@ import (
	"github.com/labstack/echo/v4"
	"github.com/stretchr/testify/require"
	oauth2 "netlandish.com/x/gobwebs-oauth2"
	gcore "netlandish.com/x/gobwebs/core"
	"netlandish.com/x/gobwebs/crypto"
	"netlandish.com/x/gobwebs/server"
)
@@ -151,7 +152,7 @@ func TestAPI(t *testing.T) {
		path, ok := srv.Config.File.Get("geo", "path")
		if ok {
			// test config has geodb path set. Let's set an IP so we can test the db integration
			req = req.WithContext(links.IPContext(request.Context(), "142.250.217.196")) // www.google.com
			req = req.WithContext(gcore.IPContext(request.Context(), "142.250.217.196")) // www.google.com
		}

		// Add fake analytics entries
diff --git a/client.go b/client.go
index 95f5318..2932a51 100644
--- a/client.go
+++ b/client.go
@@ -10,6 +10,7 @@ import (
	"git.sr.ht/~emersion/gqlclient"
	oauth2 "netlandish.com/x/gobwebs-oauth2"
	"netlandish.com/x/gobwebs/auth"
	"netlandish.com/x/gobwebs/core"
	"netlandish.com/x/gobwebs/server"
)

@@ -75,7 +76,7 @@ func Execute(ctx context.Context, op *gqlclient.Operation, result any) error {
	token := grant.Encode(ctx)
	trans.AddHeader("Authorization", fmt.Sprintf("Internal %s", token))

	ip := IPForContext(ctx)
	ip := core.IPForContext(ctx)
	if ip != "" {
		trans.AddHeader("X-Real-IP", ip)
	}
diff --git a/cmd/api/main.go b/cmd/api/main.go
index 0b18c50..f0e8d11 100644
--- a/cmd/api/main.go
+++ b/cmd/api/main.go
@@ -27,6 +27,7 @@ import (
	oauth2 "netlandish.com/x/gobwebs-oauth2"
	feedback "netlandish.com/x/gobwebs-ses-feedback"
	"netlandish.com/x/gobwebs/config"
	gcore "netlandish.com/x/gobwebs/core"
	"netlandish.com/x/gobwebs/crypto"
	"netlandish.com/x/gobwebs/database"
	"netlandish.com/x/gobwebs/email"
@@ -131,7 +132,7 @@ func run() error {
		WithQueues(eq, wq).
		WithMiddleware(
			database.DBIMiddleware(db),
			core.RemoteIPMiddleware,
			gcore.RemoteIPMiddleware,
			loaders.Middleware(),
			core.TimezoneContext(),
			crypto.Middleware(entropy),
diff --git a/cmd/links/main.go b/cmd/links/main.go
index 9e87726..e279193 100644
--- a/cmd/links/main.go
+++ b/cmd/links/main.go
@@ -229,7 +229,7 @@ func run() error {
		WithQueues(eq, wq, wqi, imq).
		WithMiddleware(
			database.DBIMiddleware(db),
			core.RemoteIPMiddleware,
			gcore.RemoteIPMiddleware,
			core.TimezoneContext(),
			crypto.Middleware(entropy),
			domain.DomainContext(models.DomainServiceLinks),
diff --git a/cmd/list/main.go b/cmd/list/main.go
index 8ebd05a..58b0245 100644
--- a/cmd/list/main.go
+++ b/cmd/list/main.go
@@ -20,6 +20,7 @@ import (
	sq "github.com/Masterminds/squirrel"
	"github.com/labstack/echo/v4"
	"netlandish.com/x/gobwebs/config"
	gcore "netlandish.com/x/gobwebs/core"
	"netlandish.com/x/gobwebs/crypto"
	"netlandish.com/x/gobwebs/database"
	"netlandish.com/x/gobwebs/email"
@@ -93,7 +94,7 @@ func run() error {
		WithQueues(eq, wq).
		WithMiddleware(
			database.DBIMiddleware(db),
			core.RemoteIPMiddleware,
			gcore.RemoteIPMiddleware,
			core.TimezoneContext(),
			crypto.Middleware(entropy),
			domain.DomainContext(models.DomainServiceList),
diff --git a/cmd/short/main.go b/cmd/short/main.go
index 73e68dc..6b09d08 100644
--- a/cmd/short/main.go
+++ b/cmd/short/main.go
@@ -18,6 +18,7 @@ import (
	sq "github.com/Masterminds/squirrel"
	"github.com/labstack/echo/v4"
	"netlandish.com/x/gobwebs/config"
	gcore "netlandish.com/x/gobwebs/core"
	"netlandish.com/x/gobwebs/crypto"
	"netlandish.com/x/gobwebs/database"
	"netlandish.com/x/gobwebs/email"
@@ -91,7 +92,7 @@ func run() error {
		WithQueues(eq, wq).
		WithMiddleware(
			database.DBIMiddleware(db),
			core.RemoteIPMiddleware,
			gcore.RemoteIPMiddleware,
			core.TimezoneContext(),
			crypto.Middleware(entropy),
			domain.DomainContext(models.DomainServiceShort),
diff --git a/cmd/test/helpers.go b/cmd/test/helpers.go
index f058416..41d4329 100644
--- a/cmd/test/helpers.go
+++ b/cmd/test/helpers.go
@@ -193,7 +193,7 @@ func NewAPITestServer(t *testing.T) (*server.Server, *echo.Echo, string) {
		DefaultMiddlewareWithConfig(mwConf).
		WithMiddleware(
			database.DBIMiddleware(db),
			core.RemoteIPMiddleware,
			gcore.RemoteIPMiddleware,
			core.TimezoneContext(),
			crypto.Middleware(entropy),
			core.InternalAuthMiddleware(accounts.NewUserFetch()),
@@ -269,7 +269,7 @@ func getMWChain(s *server.Server, f echo.HandlerFunc, user *models.User) echo.Ha
	entropy, _ := s.Config.File.Get("access", "entropy")
	cryptoMiddleware := crypto.Middleware(entropy)
	handlerFunc := cryptoMiddleware(f)
	handlerFunc = core.RemoteIPMiddleware(handlerFunc)
	handlerFunc = gcore.RemoteIPMiddleware(handlerFunc)
	timezoneMiddleware := core.TimezoneContext()
	handlerFunc = timezoneMiddleware(handlerFunc)
	serverMiddleware := server.Middleware(s)
diff --git a/core/middleware.go b/core/middleware.go
index 304bd0c..e8a72f4 100644
--- a/core/middleware.go
+++ b/core/middleware.go
@@ -91,14 +91,3 @@ func CORSReadOnlyMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
		return next(c)
	}
}

func RemoteIPMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
	return func(c echo.Context) error {
		c.SetRequest(
			c.Request().WithContext(
				links.IPContext(c.Request().Context(), c.RealIP()),
			),
		)
		return next(c)
	}
}
diff --git a/go.mod b/go.mod
index be5051f..3b4fd36 100644
--- a/go.mod
+++ b/go.mod
@@ -33,12 +33,12 @@ require (
	golang.org/x/text v0.27.0
	golang.org/x/time v0.8.0
	hg.code.netlandish.com/~netlandish/sendygo v0.0.0-20230124192435-bbf347776232
	netlandish.com/x/gobwebs v0.1.16
	netlandish.com/x/gobwebs-auditlog v0.3.3
	netlandish.com/x/gobwebs-formguard v0.3.1
	netlandish.com/x/gobwebs-graphql v0.3.1
	netlandish.com/x/gobwebs-oauth2 v0.2.14
	netlandish.com/x/gobwebs-ses-feedback v0.2.14
	netlandish.com/x/gobwebs v0.1.17
	netlandish.com/x/gobwebs-auditlog v0.3.4
	netlandish.com/x/gobwebs-formguard v0.3.2
	netlandish.com/x/gobwebs-graphql v0.3.2
	netlandish.com/x/gobwebs-oauth2 v0.2.15
	netlandish.com/x/gobwebs-ses-feedback v0.2.15
	petersanchez.com/x/carrier v0.2.6
	petersanchez.com/x/carrier/ses v0.0.0-20260908210515-f3c6132b8e61
	petersanchez.com/x/carrier/smtp v0.0.0-20260908210515-f3c6132b8e61
diff --git a/go.sum b/go.sum
index f84e607..97447e0 100644
--- a/go.sum
+++ b/go.sum
@@ -2582,18 +2582,18 @@ modernc.org/z v1.0.1-0.20210308123920-1f282aa71362/go.mod h1:8/SRk5C/HgiQWCgXdfp
modernc.org/z v1.0.1/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA=
modernc.org/z v1.2.20/go.mod h1:zU9FiF4PbHdOTUxw+IF8j7ArBMRPsHgq10uVPt6xTzo=
modernc.org/zappy v1.0.0/go.mod h1:hHe+oGahLVII/aTTyWK/b53VDHMAGCBYYeZ9sn83HC4=
netlandish.com/x/gobwebs v0.1.16 h1:nUOC73J2PryIm1kesKtcgRTnRmltwUT8/A39gTY/9Yk=
netlandish.com/x/gobwebs v0.1.16/go.mod h1:2jf9Zn0yiggw+lXtk+aP5PlXa19fExCOvAsxaJPhmv0=
netlandish.com/x/gobwebs-auditlog v0.3.3 h1:PBwm3hccJ14r6sQxQzl9Vs3GpCjZ6GVEED+8JdqvUkA=
netlandish.com/x/gobwebs-auditlog v0.3.3/go.mod h1:r1fwrGMp0jOZ/BeAufXRg6pOom1JeaLjTFUU7Mg/WHg=
netlandish.com/x/gobwebs-formguard v0.3.1 h1:3AdxEcVfErqmFhESVVnyZ4VRcs8xXktBMYOQHLVX/qw=
netlandish.com/x/gobwebs-formguard v0.3.1/go.mod h1:v/mLy2FMorXagtQk13QUsm/7xQGWTIzjJvSbFRESgYw=
netlandish.com/x/gobwebs-graphql v0.3.1 h1:cPNITWCD5i9+UBJah50wdniG371y0P/tdCQiRy6StAw=
netlandish.com/x/gobwebs-graphql v0.3.1/go.mod h1:KMXW4jYeTu6ChyiG7aLHXOtTwMCRgY4ed6NCHS2LtHQ=
netlandish.com/x/gobwebs-oauth2 v0.2.14 h1:3T3GgO1rO1CeFO2QVK5ndnAehQWHQd54G/cy7BW4PkY=
netlandish.com/x/gobwebs-oauth2 v0.2.14/go.mod h1:RO8tev6Xy1KBPqGWz6cQBHXUQyE7v2xRMIs4Fd9M2kY=
netlandish.com/x/gobwebs-ses-feedback v0.2.14 h1:pCH+mLWucC4n6ZYvXBg+FQvfPH3csUEdn6UxPaU/Msg=
netlandish.com/x/gobwebs-ses-feedback v0.2.14/go.mod h1:8VqQFR4eORxzGcVf4sM0ME4TBWkdqeMw14Itl4j8MGw=
netlandish.com/x/gobwebs v0.1.17 h1:NHTkicwy3CjlTgSdcgFMNHFpWtpgYwZ08pitL9y71S0=
netlandish.com/x/gobwebs v0.1.17/go.mod h1:2jf9Zn0yiggw+lXtk+aP5PlXa19fExCOvAsxaJPhmv0=
netlandish.com/x/gobwebs-auditlog v0.3.4 h1:1KltddWOgy34cHOGpdoCF8LBjsNN447kXs9rkjNtlQs=
netlandish.com/x/gobwebs-auditlog v0.3.4/go.mod h1:ZHlBBkBGw5OyoHwQp3qiKDbs8EUhRIIdkIc8Nb2do/w=
netlandish.com/x/gobwebs-formguard v0.3.2 h1:giooK4x7lo+4f8DnlWntS6UmAcvpCzeJO6fkTcVEO7U=
netlandish.com/x/gobwebs-formguard v0.3.2/go.mod h1:0flzVl44Q6grobYq2eeEfTl7wtrNzoaOT9lkZQcyFGo=
netlandish.com/x/gobwebs-graphql v0.3.2 h1:/PbHVB8UBSJ7Iv0aoCDatGGBTeflMxW3e5QSptDBchc=
netlandish.com/x/gobwebs-graphql v0.3.2/go.mod h1:uqmWwIT7MFd9SPkmtNvr8OTSRFH2LLVHRwuq1FL9SA8=
netlandish.com/x/gobwebs-oauth2 v0.2.15 h1:Ch/5WcEn3iGo2Ml5uLVRMqUYXVL3PkuTTuijJCebWPQ=
netlandish.com/x/gobwebs-oauth2 v0.2.15/go.mod h1:fJoaihXFmZf8WtMZdTuhoMzBSywrVINnlhjBqWmUY2s=
netlandish.com/x/gobwebs-ses-feedback v0.2.15 h1:GSdLOd89J1xarfpuadbdAL02z6/BqEiNsvZpy0OmsPI=
netlandish.com/x/gobwebs-ses-feedback v0.2.15/go.mod h1:f9EvJCa9Zcy0a7o+zuGQ/h8WdLCaURk0RiASLh7Paes=
petersanchez.com/x/carrier v0.2.6 h1:3siN90JCjMbAdXZ1wh/SakPwwHb4gXj4IghzOSLjJcE=
petersanchez.com/x/carrier v0.2.6/go.mod h1:GLiDI9OThDmruufk/VHlR6Ihvq/hIJQyA5beU6AFNYk=
petersanchez.com/x/carrier/ses v0.0.0-20260908210515-f3c6132b8e61 h1:ZX535miQ/79f2IjOqNMhIkJF3nrbvTRaGp7OO7RSuVs=
diff --git a/helpers.go b/helpers.go
index 6617434..690e3b4 100644
--- a/helpers.go
+++ b/helpers.go
@@ -1259,22 +1259,6 @@ func NewRateLimiterConfig(conf *config.Config) (middleware.RateLimiterConfig, er
	return rlConfig, nil
}

var IPCtxKey = &contextKey{"remote_ip"}

// IPContext adds a domain model to context for immediate use
func IPContext(ctx context.Context, ip string) context.Context {
	return context.WithValue(ctx, IPCtxKey, ip)
}

// IPForContext fetches current domain from the request context
func IPForContext(ctx context.Context) string {
	ip, ok := ctx.Value(IPCtxKey).(string)
	if !ok {
		return ""
	}
	return ip
}

// SanitizeUTF8 will strip out invalid utf-8 characters.
// Invalid UTF-8 bytes are replaced with the Unicode replacement character.
func SanitizeUTF8(input string) string {
diff --git a/short/routes_test.go b/short/routes_test.go
index ec708fa..ca894be 100644
--- a/short/routes_test.go
+++ b/short/routes_test.go
@@ -19,6 +19,7 @@ import (
	"github.com/jarcoal/httpmock"
	"github.com/labstack/echo/v4"
	"github.com/stretchr/testify/require"
	gcore "netlandish.com/x/gobwebs/core"
	"netlandish.com/x/gobwebs/database"
	"netlandish.com/x/gobwebs/server"
)
@@ -254,7 +255,7 @@ func TestRedirectHandler(t *testing.T) {
		_, ok := srv.Config.File.Get("geo", "path")
		if ok {
			// test config has geodb path set. Let's set an IP so we can test the db integration
			request = request.WithContext(links.IPContext(request.Context(), "142.250.217.196")) // www.google.com
			request = request.WithContext(gcore.IPContext(request.Context(), "142.250.217.196")) // www.google.com
		}

		recorder := httptest.NewRecorder()
-- 
2.54.0
Details
Message ID
<DLG3JNMW6BBR.2ZA66OFLUBW7S@netlandish.com>
In-Reply-To
<20260915145315.13527-1-peter@netlandish.com> (view parent)
Sender timestamp
1789474840
DKIM signature
missing
Download raw message
Applied.

To git@git.code.netlandish.com:~netlandish/links
   9ba9753..e7f4dd2  master -> master
Reply to thread Export thread (mbox)