Skip to content

Commit 3a0b5be

Browse files
feat: move templ component from foundations to shield; add bunch of tests
1 parent e88fb14 commit 3a0b5be

File tree

9 files changed

+104
-16
lines changed

9 files changed

+104
-16
lines changed

README.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
# shield
2+
23
Shield is a comprehensive opinionated authentication framework for Go, built on Postgres.
34

45
It is built on top of sqlc, pgx and supporting SSO, MFA out of the box.
56

6-
There is no intention to adapt this framework for other stacks.
7+
## FAQ
8+
9+
<details>
10+
<summary>Can shield support my stack (mysql, database/sql, etc.), please?</summary>
11+
12+
No, not at the moment. There is no intention to adapt this framework for other stacks in the near future.
13+
14+
</details>
715

816
## LICENSE
917

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module go.inout.gg/shield
33
go 1.23.1
44

55
require (
6+
github.com/a-h/templ v0.2.747
67
github.com/coreos/go-oidc/v3 v3.11.0
78
github.com/go-playground/mold/v4 v4.5.0
89
github.com/go-playground/validator/v10 v10.22.0

go.sum

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
github.com/a-h/templ v0.2.747 h1:D0dQ2lxC3W7Dxl6fxQ/1zZHBQslSkTSvl5FxP/CfdKg=
2+
github.com/a-h/templ v0.2.747/go.mod h1:69ObQIbrcuwPCU32ohNaWce3Cb7qM5GMiqN1K+2yop4=
13
github.com/caarlos0/env/v11 v11.1.0 h1:a5qZqieE9ZfzdvbbdhTalRrHT5vu/4V1/ad1Ka6frhI=
24
github.com/caarlos0/env/v11 v11.1.0/go.mod h1:LwgkYk1kDvfGpHthrWWLof3Ny7PezzFwS4QrsJdHTMo=
35
github.com/coreos/go-oidc/v3 v3.11.0 h1:Ia3MxdwpSw702YW0xgfmP1GVCMA9aEFWu12XUZ3/OtI=
@@ -29,8 +31,8 @@ github.com/go-webauthn/x v0.1.14 h1:1wrB8jzXAofojJPAaRxnZhRgagvLGnLjhCAwg3kTpT0=
2931
github.com/go-webauthn/x v0.1.14/go.mod h1:UuVvFZ8/NbOnkDz3y1NaxtUN87pmtpC1PQ+/5BBQRdc=
3032
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
3133
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
32-
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
33-
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
34+
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
35+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
3436
github.com/google/go-tpm v0.9.1 h1:0pGc4X//bAlmZzMKf8iz6IsDo1nYTbYJ6FZN/rg4zdM=
3537
github.com/google/go-tpm v0.9.1/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY=
3638
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=

internal/sliceutil/sliceutil_test.go

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package sliceutil_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
"go.inout.gg/shield/internal/sliceutil"
8+
)
9+
10+
func TestFilter(t *testing.T) {
11+
t.Run("Filter should work", func(t *testing.T) {
12+
result := sliceutil.Filter([]string{"even", "odd", "even"}, func(v string) bool {
13+
return v == "odd"
14+
})
15+
16+
assert.Equal(t, []string{"odd"}, result)
17+
})
18+
19+
t.Run("Filter should keep the slice", func(t *testing.T) {
20+
result := sliceutil.Filter([]int{1, 2, 3, 4}, func(v int) bool {
21+
return true
22+
})
23+
24+
assert.Equal(t, []int{1, 2, 3, 4}, result)
25+
})
26+
27+
t.Run("Filter should return empty slice", func(t *testing.T) {
28+
result := sliceutil.Filter([]int{1, 2, 3, 4}, func(v int) bool {
29+
return false
30+
})
31+
32+
assert.Equal(t, []int{}, result)
33+
})
34+
35+
t.Run("Filter should handle empty slice", func(t *testing.T) {
36+
result := sliceutil.Filter([]int{}, func(v int) bool {
37+
return true
38+
})
39+
40+
assert.Equal(t, []int{}, result)
41+
})
42+
}

csrf/middleware.go shieldcsrf/middleware.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Package csrf implements a CSRF protection middleware based on the double
22
// submit cookie pattern.
3-
package csrf
3+
package shieldcsrf
44

55
import (
66
"context"

csrf/middleware_test.go shieldcsrf/middleware_test.go

+13-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package csrf
1+
package shieldcsrf
22

33
import (
44
"net/http"
@@ -10,17 +10,19 @@ import (
1010

1111
var checksumSecret = "really-long-and-super-protected-checksum-secret"
1212

13-
var safeMethods = []string{http.MethodGet, http.MethodHead, http.MethodOptions, http.MethodTrace}
14-
var unsafeMethods = []string{http.MethodPost, http.MethodPut, http.MethodPatch, http.MethodDelete}
15-
var testHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
16-
tok, err := FromRequest(r)
17-
if err != nil {
18-
http.Error(w, err.Error(), http.StatusInternalServerError)
19-
}
13+
var (
14+
safeMethods = []string{http.MethodGet, http.MethodHead, http.MethodOptions, http.MethodTrace}
15+
unsafeMethods = []string{http.MethodPost, http.MethodPut, http.MethodPatch, http.MethodDelete}
16+
testHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
17+
tok, err := FromRequest(r)
18+
if err != nil {
19+
http.Error(w, err.Error(), http.StatusInternalServerError)
20+
}
2021

21-
SetToken(w, tok)
22-
_, _ = w.Write([]byte("ok"))
23-
})
22+
SetToken(w, tok)
23+
_, _ = w.Write([]byte("ok"))
24+
})
25+
)
2426

2527
func TestMethods(t *testing.T) {
2628
mux := http.NewServeMux()

shieldcsrf/shieldcsrf.go

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Package shieldcsrf provides an HTTP middleware helping to prevent CSRF attacks
2+
// by employing Double Submit Cookie pattern.
3+
//
4+
// Check out https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html
5+
// for more information.
6+
package shieldcsrf

csrf/csrf.go shieldcsrf/token.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package csrf
1+
package shieldcsrf
22

33
import (
44
"crypto/sha256"

shieldtempl/csrf.go

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package shieldtempl
2+
3+
import (
4+
"context"
5+
"io"
6+
7+
"github.com/a-h/templ"
8+
"go.inout.gg/shield/shieldcsrf"
9+
)
10+
11+
// CsrfToken returns a component that renders a CSRF token as an input field.
12+
func CsrfToken(name string) templ.Component {
13+
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {
14+
tok, err := shieldcsrf.FromContext(ctx)
15+
if err != nil {
16+
return err
17+
}
18+
19+
_, err = w.Write(
20+
[]byte(
21+
"<input type=\"hidden\" name=\"" + name + "\"" + "value=\"" + tok.String() + "\">",
22+
),
23+
)
24+
25+
return err
26+
})
27+
}

0 commit comments

Comments
 (0)