Personal Git forge.

Code git clone ssh://git.poy.ooo:6969/~poyo/farga ZIP
app/middleware/auth.go / 2KiB #5fe96a0e
Raw
package middlewareimport (	"context"	"farga/db/types"	"farga/lib"	"net/http"	"time"	"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 := sessionCookie.Value				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)					http.Redirect(w, r, "/auth/login?err=InvalidSession", http.StatusSeeOther)					return				}				// anonymous sessions carry no user, so treat them as logged out.				if session.UserID == nil {					next.ServeHTTP(w, r.WithContext(ctx))					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))		})	}}