ducky-dash/handler/middleware.go

94 lines
1.9 KiB
Go

package handler
import (
"context"
"database/sql"
"errors"
"net/http"
"strings"
"git.duckylabs.xyz/duckbox/ducky-dash/db"
"git.duckylabs.xyz/duckbox/ducky-dash/models"
"git.duckylabs.xyz/duckbox/ducky-dash/pkg/sb"
"github.com/google/uuid"
)
func WithAuth(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
if strings.Contains(r.URL.Path, "/public") {
next.ServeHTTP(w, r)
return
}
user := getAuthenticatedUser(r)
if !user.LoggedIn {
path := r.URL.Path
http.Redirect(w, r, "/login?to="+path, http.StatusSeeOther)
return
}
next.ServeHTTP(w, r)
}
return http.HandlerFunc(fn)
}
func WithUser(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
if strings.Contains(r.URL.Path, "/public") {
next.ServeHTTP(w, r)
return
}
cookie, err := r.Cookie("at")
if err != nil {
next.ServeHTTP(w, r)
return
}
resp, err := sb.Client.Auth.User(r.Context(), cookie.Value)
if err != nil {
next.ServeHTTP(w, r)
return
}
user := models.AuthenticatedUser{
ID: uuid.MustParse(resp.ID),
Email: resp.Email,
LoggedIn: true,
}
ctx := context.WithValue(r.Context(), models.UserContextKey, user)
next.ServeHTTP(w, r.WithContext(ctx))
}
return http.HandlerFunc(fn)
}
func WithAccountSetup(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
user := getAuthenticatedUser(r)
account, err := db.GetAccountByUserID(user.ID)
// The user has not setup his account yet.
// Hence, redirect him to /account/setup
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
http.Redirect(w, r, "/setup/account", http.StatusSeeOther)
return
}
next.ServeHTTP(w, r)
return
}
user.Account = account
ctx := context.WithValue(r.Context(), models.UserContextKey, user)
next.ServeHTTP(w, r.WithContext(ctx))
}
return http.HandlerFunc(fn)
}