cerrado @ e25638d698b96ed9e46bcfbd58ce6ce1f439474a

feat: Filter private repository from the UI

Now the whole application takes public into account.
diff --git a/pkg/ext/auth.go b/pkg/ext/auth.go
index 304f4ad3fe1d2e9f97f9f930ac1e527c74787c6c..5c3070e869de09ec7b6c8239603cf037330085c1 100644
--- a/pkg/ext/auth.go
+++ b/pkg/ext/auth.go
@@ -6,6 +6,8 @@ 	"encoding/base64"
 	"errors"
 	"log/slog"
 	"net/http"
+
+	serverconfig "git.gabrielgio.me/cerrado/pkg/config"
 )
 
 type authService interface {
@@ -20,6 +22,25 @@ 		next(w, r.WithContext(ctx))
 	}
 }
 
+func VerifyRespository(
+	config *serverconfig.ConfigurationRepository,
+) func(next http.HandlerFunc) http.HandlerFunc {
+	return func(next http.HandlerFunc) http.HandlerFunc {
+		return func(w http.ResponseWriter, r *http.Request) {
+			name := r.PathValue("name")
+			if name != "" {
+				repo := config.GetByName(name)
+				if repo != nil && !repo.Public && !IsLoggedIn(r.Context()) {
+					NotFound(w, r)
+					return
+				}
+			}
+
+			next(w, r)
+		}
+	}
+}
+
 func Authenticate(auth authService) func(next http.HandlerFunc) http.HandlerFunc {
 	return func(next http.HandlerFunc) http.HandlerFunc {
 		return func(w http.ResponseWriter, r *http.Request) {
@@ -28,6 +49,7 @@ 			if err != nil {
 				if !errors.Is(err, http.ErrNoCookie) {
 					slog.Error("Error loading cookie", "error", err)
 				}
+
 				next(w, r)
 				return
 			}
@@ -47,10 +69,15 @@ 				return
 			}
 
 			ctx := r.Context()
-			ctx = context.WithValue(ctx, "logged", true)
+			ctx = context.WithValue(ctx, "logged", valid)
 
 			slog.Info("Validated token", "valid?", valid)
 			next(w, r.WithContext(ctx))
 		}
 	}
 }
+
+func IsLoggedIn(ctx context.Context) bool {
+	t, ok := ctx.Value("logged").(bool)
+	return ok && t
+}
diff --git a/pkg/handler/git/handler.go b/pkg/handler/git/handler.go
index 42761595323c97d0ea49dc3fe69d618446284bcc..6225b1a444f98701f9049c856c2b63e5c248adc6 100644
--- a/pkg/handler/git/handler.go
+++ b/pkg/handler/git/handler.go
@@ -13,6 +13,7 @@ 	"strings"
 
 	"git.gabrielgio.me/cerrado/pkg/ext"
 	"git.gabrielgio.me/cerrado/pkg/service"
+	"git.gabrielgio.me/cerrado/pkg/u"
 	"git.gabrielgio.me/cerrado/templates"
 	"github.com/alecthomas/chroma/v2"
 	"github.com/alecthomas/chroma/v2/formatters/html"
@@ -44,9 +45,17 @@ 	}
 }
 
 func (g *GitHandler) List(w http.ResponseWriter, r *http.Request) error {
+	// this is the only handler that needs to handle authentication itself.
+	// everything else relay on name path parameter
+	logged := ext.IsLoggedIn(r.Context())
+
 	repos, err := g.gitService.ListRepositories()
 	if err != nil {
 		return err
+	}
+
+	if !logged {
+		repos = u.Filter(repos, isPublic)
 	}
 
 	f, err := os.Open(g.config.GetRootReadme())
@@ -375,3 +384,7 @@ 		lexer = lexers.Get("txt")
 	}
 	return lexer
 }
+
+func isPublic(r *service.Repository) bool {
+	return r.Public
+}
diff --git a/pkg/handler/router.go b/pkg/handler/router.go
index 82ee8fdc32a068b111399bd610fddc7496dd90d2..8d27b743bf46ad25bd31a4a984ceffdd2626bc0c 100644
--- a/pkg/handler/router.go
+++ b/pkg/handler/router.go
@@ -34,6 +34,7 @@
 	mux := ext.NewRouter()
 	mux.AddMiddleware(ext.Compress)
 	mux.AddMiddleware(ext.Log)
+	mux.AddMiddleware(ext.VerifyRespository(configRepo))
 
 	if configRepo.IsAuthEnabled() {
 		mux.AddMiddleware(ext.Authenticate(authService))
diff --git a/pkg/u/list.go b/pkg/u/list.go
index 39d7b117fa7b9a509be2fa3f7946dc11945ce812..835ecd289214a9c5a4f30d249c39ee70e957e4ab 100644
--- a/pkg/u/list.go
+++ b/pkg/u/list.go
@@ -1,5 +1,17 @@
 package u
 
+func Filter[T any](v []T, f func(T) bool) []T {
+	var result []T
+
+	for _, s := range v {
+		if f(s) {
+			result = append(result, s)
+		}
+	}
+
+	return result
+}
+
 func First[T any](v []T) (T, bool) {
 	if len(v) == 0 {
 		var zero T
@@ -25,7 +37,7 @@ 	return v[len(v)-1]
 }
 
 func ChunkBy[T any](items []T, chunkSize int) [][]T {
-	var chunks = make([][]T, 0, (len(items)/chunkSize)+1)
+	chunks := make([][]T, 0, (len(items)/chunkSize)+1)
 	for chunkSize < len(items) {
 		items, chunks = items[chunkSize:], append(chunks, items[0:chunkSize:chunkSize])
 	}