Something went wrong. Try again.
Lightweight and easily self-hostable Git forge.
Something went wrong. Try again.
2.9 kB · 94 lines
Go
at master
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495package middleware
import ( "context" "farga/db/types" "farga/lib" "fmt" "net/http" "time"
"github.com/google/uuid" "github.com/gorilla/mux")
// Use to force users to authenticate if they're not. Pass user to context.func RequireAuth(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { loggedIn, ok := r.Context().Value(lib.LoggedInKey).(bool)
if !loggedIn || !ok { http.Redirect(w, r, "/auth/login?err=RequireAuth", http.StatusFound) return }
next.ServeHTTP(w, r) })}
// Use when you don't want anyone with a session cookie accessing a page.func ExcludeAuth(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { loggedIn, ok := r.Context().Value(lib.LoggedInKey).(bool)
if loggedIn && ok { http.Redirect(w, r, "/?err=AlreadyAuthenticated", http.StatusFound) return }
next.ServeHTTP(w, r) })}
func RequireAdmin(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { loggedIn, loggedInOk := r.Context().Value(lib.LoggedInKey).(bool) user, userOk := r.Context().Value(lib.UserKey).(*types.User)
if !loggedInOk || !userOk || !loggedIn || user.Role != types.RoleAdmin { http.Redirect(w, r, "/?err=Forbidden", http.StatusFound) return }
next.ServeHTTP(w, r) })}
// paves the road for later use of ExcludeAuth and RequireAuth middlewares.func GeneralAuth(store Store) mux.MiddlewareFunc { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { sessionCookie, err := r.Cookie(lib.SessionKey) ctx := context.WithValue(r.Context(), lib.LoggedInKey, false) if err == nil && sessionCookie != nil { sessionToken, err := uuid.Parse(sessionCookie.Value) if err != nil { lib.DeleteCookie(w, lib.SessionKey) http.Redirect(w, r, "/auth/login?err=InvalidSession", http.StatusSeeOther) fmt.Println(err) return }
session, err := store.Session(sessionToken) // if it doesn't exist or expired if err != nil || time.Time(session.CreatedAt).Before(time.Now().AddDate(0, 0, -lib.SessionDurationDays)) { lib.DeleteCookie(w, lib.SessionKey) store.DeleteSession(sessionToken.String()) http.Redirect(w, r, "/auth/login?err=InvalidSession", http.StatusSeeOther) return }
user, err := store.User(*session.UserID) if err != nil { lib.DeleteCookie(w, lib.SessionKey) http.Redirect(w, r, "/auth/login?err=UserNotFound", http.StatusSeeOther) return } ctx = context.WithValue(r.Context(), lib.SessionKey, sessionCookie.Value) ctx = context.WithValue(ctx, lib.UserKey, user) ctx = context.WithValue(ctx, lib.LoggedInKey, true) } next.ServeHTTP(w, r.WithContext(ctx)) }) }}