| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- // SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
- // SPDX-License-Identifier: Apache-2.0
- package ui // import "miniflux.app/v2/internal/ui"
- import (
- "context"
- "log/slog"
- "net/http"
- "strings"
- "miniflux.app/v2/internal/http/request"
- "miniflux.app/v2/internal/http/response"
- "miniflux.app/v2/internal/model"
- "miniflux.app/v2/internal/storage"
- )
- type webSessionMiddleware struct {
- basePath string
- store *storage.Storage
- }
- func newWebSessionMiddleware(basePath string, store *storage.Storage) *webSessionMiddleware {
- return &webSessionMiddleware{basePath: basePath, store: store}
- }
- func (m *webSessionMiddleware) handle(next http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if isStaticAssetRoute(r) {
- next.ServeHTTP(w, r)
- return
- }
- session, err := m.loadWebSessionFromCookie(r)
- if err != nil {
- response.HTMLServerError(w, r, err)
- return
- }
- if session == nil {
- var secret string
- session, secret = model.NewWebSession(r.UserAgent(), request.ClientIP(r))
- if err := m.store.CreateWebSession(session); err != nil {
- response.HTMLServerError(w, r, err)
- return
- }
- setSessionCookie(w, session, secret)
- }
- ctx := context.WithValue(r.Context(), request.WebSessionContextKey, session)
- r = r.WithContext(ctx)
- if !request.IsAuthenticated(r) && !isPublicRoute(r) {
- response.HTMLRedirect(w, r, loginRedirectURL(m.basePath, r.RequestURI))
- return
- }
- next.ServeHTTP(w, r)
- if session.IsDirty() {
- if err := m.store.UpdateWebSession(session); err != nil {
- slog.Error("Unable to persist web session changes",
- slog.String("session_id", session.ID),
- slog.Any("error", err),
- )
- }
- }
- })
- }
- func (m *webSessionMiddleware) loadWebSessionFromCookie(r *http.Request) (*model.WebSession, error) {
- cookieValue := request.CookieValue(r, sessionCookieName)
- if cookieValue == "" {
- return nil, nil
- }
- sessionID, secret, ok := strings.Cut(cookieValue, ".")
- if !ok || sessionID == "" || secret == "" {
- return nil, nil
- }
- session, err := m.store.WebSessionByID(sessionID)
- if err != nil {
- return nil, err
- }
- if session == nil || !session.VerifySecret(secret) {
- return nil, nil
- }
- return session, nil
- }
|