package core import ( "arimelody-web/controller" "arimelody-web/model" "context" "fmt" "net/http" "os" "strings" ) func RequireAccount(next http.Handler) http.HandlerFunc { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { session := r.Context().Value("session").(*model.Session) if session.Account == nil { // TODO: include context in redirect http.Redirect(w, r, "/admin/login", http.StatusFound) return } next.ServeHTTP(w, r) }) } func EnforceSession(app *model.AppState, next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { session, err := controller.GetSessionFromRequest(app, r) if err != nil { fmt.Fprintf(os.Stderr, "WARN: Failed to retrieve session: %v\n", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } if session == nil { // create a new session session, err = controller.CreateSession(app.DB, r.UserAgent()) if err != nil { fmt.Fprintf(os.Stderr, "WARN: Failed to create session: %v\n", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } http.SetCookie(w, &http.Cookie{ Name: model.COOKIE_TOKEN, Value: session.Token, Expires: session.ExpiresAt, Secure: strings.HasPrefix(app.Config.BaseUrl, "https"), HttpOnly: true, Path: "/", }) } ctx := context.WithValue(r.Context(), "session", session) next.ServeHTTP(w, r.WithContext(ctx)) }) }