1diff --git a/pkg/ext/auth.go b/pkg/ext/auth.go
2index 304f4ad3fe1d2e9f97f9f930ac1e527c74787c6c..5c3070e869de09ec7b6c8239603cf037330085c1 100644
3--- a/pkg/ext/auth.go
4+++ b/pkg/ext/auth.go
5@@ -6,6 +6,8 @@ "encoding/base64"
6 "errors"
7 "log/slog"
8 "net/http"
9+
10+ serverconfig "git.gabrielgio.me/cerrado/pkg/config"
11 )
12
13 type authService interface {
14@@ -20,6 +22,25 @@ next(w, r.WithContext(ctx))
15 }
16 }
17
18+func VerifyRespository(
19+ config *serverconfig.ConfigurationRepository,
20+) func(next http.HandlerFunc) http.HandlerFunc {
21+ return func(next http.HandlerFunc) http.HandlerFunc {
22+ return func(w http.ResponseWriter, r *http.Request) {
23+ name := r.PathValue("name")
24+ if name != "" {
25+ repo := config.GetByName(name)
26+ if repo != nil && !repo.Public && !IsLoggedIn(r.Context()) {
27+ NotFound(w, r)
28+ return
29+ }
30+ }
31+
32+ next(w, r)
33+ }
34+ }
35+}
36+
37 func Authenticate(auth authService) func(next http.HandlerFunc) http.HandlerFunc {
38 return func(next http.HandlerFunc) http.HandlerFunc {
39 return func(w http.ResponseWriter, r *http.Request) {
40@@ -28,6 +49,7 @@ if err != nil {
41 if !errors.Is(err, http.ErrNoCookie) {
42 slog.Error("Error loading cookie", "error", err)
43 }
44+
45 next(w, r)
46 return
47 }
48@@ -47,10 +69,15 @@ return
49 }
50
51 ctx := r.Context()
52- ctx = context.WithValue(ctx, "logged", true)
53+ ctx = context.WithValue(ctx, "logged", valid)
54
55 slog.Info("Validated token", "valid?", valid)
56 next(w, r.WithContext(ctx))
57 }
58 }
59 }
60+
61+func IsLoggedIn(ctx context.Context) bool {
62+ t, ok := ctx.Value("logged").(bool)
63+ return ok && t
64+}
65diff --git a/pkg/handler/git/handler.go b/pkg/handler/git/handler.go
66index 42761595323c97d0ea49dc3fe69d618446284bcc..6225b1a444f98701f9049c856c2b63e5c248adc6 100644
67--- a/pkg/handler/git/handler.go
68+++ b/pkg/handler/git/handler.go
69@@ -13,6 +13,7 @@ "strings"
70
71 "git.gabrielgio.me/cerrado/pkg/ext"
72 "git.gabrielgio.me/cerrado/pkg/service"
73+ "git.gabrielgio.me/cerrado/pkg/u"
74 "git.gabrielgio.me/cerrado/templates"
75 "github.com/alecthomas/chroma/v2"
76 "github.com/alecthomas/chroma/v2/formatters/html"
77@@ -44,9 +45,17 @@ }
78 }
79
80 func (g *GitHandler) List(w http.ResponseWriter, r *http.Request) error {
81+ // this is the only handler that needs to handle authentication itself.
82+ // everything else relay on name path parameter
83+ logged := ext.IsLoggedIn(r.Context())
84+
85 repos, err := g.gitService.ListRepositories()
86 if err != nil {
87 return err
88+ }
89+
90+ if !logged {
91+ repos = u.Filter(repos, isPublic)
92 }
93
94 f, err := os.Open(g.config.GetRootReadme())
95@@ -375,3 +384,7 @@ lexer = lexers.Get("txt")
96 }
97 return lexer
98 }
99+
100+func isPublic(r *service.Repository) bool {
101+ return r.Public
102+}
103diff --git a/pkg/handler/router.go b/pkg/handler/router.go
104index 82ee8fdc32a068b111399bd610fddc7496dd90d2..8d27b743bf46ad25bd31a4a984ceffdd2626bc0c 100644
105--- a/pkg/handler/router.go
106+++ b/pkg/handler/router.go
107@@ -34,6 +34,7 @@
108 mux := ext.NewRouter()
109 mux.AddMiddleware(ext.Compress)
110 mux.AddMiddleware(ext.Log)
111+ mux.AddMiddleware(ext.VerifyRespository(configRepo))
112
113 if configRepo.IsAuthEnabled() {
114 mux.AddMiddleware(ext.Authenticate(authService))
115diff --git a/pkg/u/list.go b/pkg/u/list.go
116index 39d7b117fa7b9a509be2fa3f7946dc11945ce812..835ecd289214a9c5a4f30d249c39ee70e957e4ab 100644
117--- a/pkg/u/list.go
118+++ b/pkg/u/list.go
119@@ -1,5 +1,17 @@
120 package u
121
122+func Filter[T any](v []T, f func(T) bool) []T {
123+ var result []T
124+
125+ for _, s := range v {
126+ if f(s) {
127+ result = append(result, s)
128+ }
129+ }
130+
131+ return result
132+}
133+
134 func First[T any](v []T) (T, bool) {
135 if len(v) == 0 {
136 var zero T
137@@ -25,7 +37,7 @@ return v[len(v)-1]
138 }
139
140 func ChunkBy[T any](items []T, chunkSize int) [][]T {
141- var chunks = make([][]T, 0, (len(items)/chunkSize)+1)
142+ chunks := make([][]T, 0, (len(items)/chunkSize)+1)
143 for chunkSize < len(items) {
144 items, chunks = items[chunkSize:], append(chunks, items[0:chunkSize:chunkSize])
145 }