package hwsauth import ( "net/http" "time" "git.haelnorr.com/h/golib/hws" ) // Checks if the model is set in the context and shows 401 page if not logged in func (auth *Authenticator[T]) LoginReq(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { _, ok := getAuthorizedModel[T](r.Context()) if !ok { page, err := auth.errorPage(http.StatusUnauthorized) if err != nil { auth.server.ThrowError(w, r, hws.HWSError{ Error: err, Message: "Failed to get valid error page", StatusCode: http.StatusInternalServerError, RenderErrorPage: true, }) } err = page.Render(r.Context(), w) if err != nil { auth.server.ThrowError(w, r, hws.HWSError{ Error: err, Message: "Failed to render error page", StatusCode: http.StatusInternalServerError, RenderErrorPage: true, }) } return } next.ServeHTTP(w, r) }) } // Checks if the model is set in the context and redirects them to the landing page if // they are logged in func (auth *Authenticator[T]) LogoutReq(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { _, ok := getAuthorizedModel[T](r.Context()) if ok { http.Redirect(w, r, auth.LandingPage, http.StatusFound) return } next.ServeHTTP(w, r) }) } // FreshReq protects a route from access if the auth token is not fresh. // A status code of 444 will be written to the header and the request will be terminated. // As an example, this can be used on the client to show a confirm password dialog to refresh their login func (auth *Authenticator[T]) FreshReq(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { model, ok := getAuthorizedModel[T](r.Context()) if !ok { page, err := auth.errorPage(http.StatusUnauthorized) if err != nil { auth.server.ThrowError(w, r, hws.HWSError{ Error: err, Message: "Failed to get valid error page", StatusCode: http.StatusInternalServerError, RenderErrorPage: true, }) } err = page.Render(r.Context(), w) if err != nil { auth.server.ThrowError(w, r, hws.HWSError{ Error: err, Message: "Failed to render error page", StatusCode: http.StatusInternalServerError, RenderErrorPage: true, }) } return } isFresh := time.Now().Before(time.Unix(model.fresh, 0)) if !isFresh { w.WriteHeader(444) return } next.ServeHTTP(w, r) }) }