diff options
Diffstat (limited to 'pkg/ext/auth.go')
-rw-r--r-- | pkg/ext/auth.go | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/pkg/ext/auth.go b/pkg/ext/auth.go new file mode 100644 index 0000000..ef126ec --- /dev/null +++ b/pkg/ext/auth.go @@ -0,0 +1,85 @@ +package ext + +import ( + "context" + "encoding/base64" + "errors" + "log/slog" + "net/http" + + serverconfig "git.gabrielgio.me/cerrado/pkg/config" +) + +type authService interface { + ValidateToken(token []byte) (bool, error) +} + +func DisableAuthentication(next HandlerFunc) HandlerFunc { + return func(w http.ResponseWriter, r *Request) { + ctx := r.Context() + ctx = context.WithValue(ctx, "disableAuthentication", true) + r.Request = r.WithContext(ctx) + next(w, r) + } +} + +func VerifyRespository( + config *serverconfig.ConfigurationRepository, +) func(next HandlerFunc) HandlerFunc { + return func(next HandlerFunc) HandlerFunc { + return func(w http.ResponseWriter, r *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 HandlerFunc) HandlerFunc { + return func(next HandlerFunc) HandlerFunc { + return func(w http.ResponseWriter, r *Request) { + cookie, err := r.Cookie("auth") + if err != nil { + if !errors.Is(err, http.ErrNoCookie) { + slog.Error("Error loading cookie", "error", err) + } + + next(w, r) + return + } + + value, err := base64.StdEncoding.DecodeString(cookie.Value) + if err != nil { + slog.Error("Error decoding", "error", err) + next(w, r) + return + } + + valid, err := auth.ValidateToken(value) + if err != nil { + slog.Error("Error validating token", "error", err, "cookie", cookie.Value) + next(w, r) + return + } + + ctx := r.Context() + ctx = context.WithValue(ctx, "logged", valid) + r.Request = r.WithContext(ctx) + + slog.Info("Validated token", "valid?", valid) + next(w, r) + } + } +} + +func IsLoggedIn(ctx context.Context) bool { + t, ok := ctx.Value("logged").(bool) + return ok && t +} |