mirror of
https://github.com/miniflux/v2.git
synced 2025-06-27 16:36:00 +00:00
Use vanilla HTTP handlers (refactoring)
This commit is contained in:
parent
1eba1730d1
commit
f49b42f70f
121 changed files with 4339 additions and 3369 deletions
|
@ -6,9 +6,12 @@ package middleware
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"github.com/miniflux/miniflux/http/cookie"
|
||||
"github.com/miniflux/miniflux/http/request"
|
||||
"github.com/miniflux/miniflux/http/response/html"
|
||||
"github.com/miniflux/miniflux/logger"
|
||||
"github.com/miniflux/miniflux/model"
|
||||
)
|
||||
|
@ -17,20 +20,21 @@ import (
|
|||
func (m *Middleware) AppSession(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
var err error
|
||||
session := m.getSessionValueFromCookie(r)
|
||||
session := m.getAppSessionValueFromCookie(r)
|
||||
|
||||
if session == nil {
|
||||
logger.Debug("[Middleware:Session] Session not found")
|
||||
logger.Debug("[Middleware:AppSession] Session not found")
|
||||
|
||||
session, err = m.store.CreateSession()
|
||||
if err != nil {
|
||||
logger.Error("[Middleware:Session] %v", err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
logger.Error("[Middleware:AppSession] %v", err)
|
||||
html.ServerError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
http.SetCookie(w, cookie.New(cookie.CookieSessionID, session.ID, m.cfg.IsHTTPS, m.cfg.BasePath()))
|
||||
} else {
|
||||
logger.Debug("[Middleware:Session] %s", session)
|
||||
logger.Debug("[Middleware:AppSession] %s", session)
|
||||
}
|
||||
|
||||
if r.Method == "POST" {
|
||||
|
@ -38,9 +42,8 @@ func (m *Middleware) AppSession(next http.Handler) http.Handler {
|
|||
headerValue := r.Header.Get("X-Csrf-Token")
|
||||
|
||||
if session.Data.CSRF != formValue && session.Data.CSRF != headerValue {
|
||||
logger.Error(`[Middleware:Session] Invalid or missing CSRF token: Form="%s", Header="%s"`, formValue, headerValue)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte("Invalid or missing CSRF session!"))
|
||||
logger.Error(`[Middleware:AppSession] Invalid or missing CSRF token: Form="%s", Header="%s"`, formValue, headerValue)
|
||||
html.BadRequest(w, errors.New("invalid or missing CSRF"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -56,15 +59,15 @@ func (m *Middleware) AppSession(next http.Handler) http.Handler {
|
|||
})
|
||||
}
|
||||
|
||||
func (m *Middleware) getSessionValueFromCookie(r *http.Request) *model.Session {
|
||||
sessionCookie, err := r.Cookie(cookie.CookieSessionID)
|
||||
if err == http.ErrNoCookie {
|
||||
func (m *Middleware) getAppSessionValueFromCookie(r *http.Request) *model.Session {
|
||||
cookieValue := request.Cookie(r, cookie.CookieSessionID)
|
||||
if cookieValue == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
session, err := m.store.Session(sessionCookie.Value)
|
||||
session, err := m.store.Session(cookieValue)
|
||||
if err != nil {
|
||||
logger.Error("[Middleware:Session] %v", err)
|
||||
logger.Error("[Middleware:AppSession] %v", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/miniflux/miniflux/http/response/json"
|
||||
"github.com/miniflux/miniflux/logger"
|
||||
)
|
||||
|
||||
|
@ -15,35 +16,30 @@ import (
|
|||
func (m *Middleware) BasicAuth(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
|
||||
errorResponse := `{"error_message": "Not Authorized"}`
|
||||
|
||||
username, password, authOK := r.BasicAuth()
|
||||
if !authOK {
|
||||
logger.Debug("[Middleware:BasicAuth] No authentication headers sent")
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte(errorResponse))
|
||||
json.Unauthorized(w)
|
||||
return
|
||||
}
|
||||
|
||||
if err := m.store.CheckPassword(username, password); err != nil {
|
||||
logger.Info("[Middleware:BasicAuth] Invalid username or password: %s", username)
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte(errorResponse))
|
||||
json.Unauthorized(w)
|
||||
return
|
||||
}
|
||||
|
||||
user, err := m.store.UserByUsername(username)
|
||||
if err != nil {
|
||||
logger.Error("[Middleware:BasicAuth] %v", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(errorResponse))
|
||||
json.ServerError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
if user == nil {
|
||||
logger.Info("[Middleware:BasicAuth] User not found: %s", username)
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte(errorResponse))
|
||||
json.Unauthorized(w)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
25
middleware/common_headers.go
Normal file
25
middleware/common_headers.go
Normal file
|
@ -0,0 +1,25 @@
|
|||
// Copyright 2018 Frédéric Guillot. All rights reserved.
|
||||
// Use of this source code is governed by the Apache 2.0
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// CommonHeaders sends common HTTP headers.
|
||||
func (m *Middleware) CommonHeaders(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("X-XSS-Protection", "1; mode=block")
|
||||
w.Header().Set("X-Content-Type-Options", "nosniff")
|
||||
w.Header().Set("X-Frame-Options", "DENY")
|
||||
w.Header().Set("Content-Security-Policy", "default-src 'self'; img-src *; media-src *; frame-src *; child-src *")
|
||||
|
||||
if m.cfg.IsHTTPS && m.cfg.HasHSTS() {
|
||||
w.Header().Set("Strict-Transport-Security", "max-age=31536000")
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
|
@ -8,27 +8,25 @@ import (
|
|||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/miniflux/miniflux/http/response/json"
|
||||
"github.com/miniflux/miniflux/logger"
|
||||
)
|
||||
|
||||
// FeverAuth handles Fever API authentication.
|
||||
func (m *Middleware) FeverAuth(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
logger.Debug("[Middleware:Fever]")
|
||||
|
||||
apiKey := r.FormValue("api_key")
|
||||
|
||||
user, err := m.store.UserByFeverToken(apiKey)
|
||||
if err != nil {
|
||||
logger.Error("[Fever] %v", err)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write([]byte(`{"api_version": 3, "auth": 0}`))
|
||||
logger.Error("[Middleware:Fever] %v", err)
|
||||
json.OK(w, map[string]int{"api_version": 3, "auth": 0})
|
||||
return
|
||||
}
|
||||
|
||||
if user == nil {
|
||||
logger.Info("[Middleware:Fever] Fever authentication failure")
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write([]byte(`{"api_version": 3, "auth": 0}`))
|
||||
json.OK(w, map[string]int{"api_version": 3, "auth": 0})
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/miniflux/miniflux/logger"
|
||||
|
||||
"github.com/tomasen/realip"
|
||||
)
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/miniflux/miniflux/http/cookie"
|
||||
"github.com/miniflux/miniflux/http/request"
|
||||
"github.com/miniflux/miniflux/http/response"
|
||||
"github.com/miniflux/miniflux/http/route"
|
||||
"github.com/miniflux/miniflux/logger"
|
||||
"github.com/miniflux/miniflux/model"
|
||||
|
@ -19,17 +21,18 @@ import (
|
|||
// UserSession handles the user session middleware.
|
||||
func (m *Middleware) UserSession(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
session := m.getSessionFromCookie(r)
|
||||
session := m.getUserSessionFromCookie(r)
|
||||
|
||||
if session == nil {
|
||||
logger.Debug("[Middleware:UserSession] Session not found")
|
||||
if m.isPublicRoute(r) {
|
||||
next.ServeHTTP(w, r)
|
||||
} else {
|
||||
http.Redirect(w, r, route.Path(m.router, "login"), http.StatusFound)
|
||||
response.Redirect(w, r, route.Path(m.router, "login"))
|
||||
}
|
||||
} else {
|
||||
logger.Debug("[Middleware:UserSession] %s", session)
|
||||
|
||||
ctx := r.Context()
|
||||
ctx = context.WithValue(ctx, UserIDContextKey, session.UserID)
|
||||
ctx = context.WithValue(ctx, IsAuthenticatedContextKey, true)
|
||||
|
@ -58,13 +61,13 @@ func (m *Middleware) isPublicRoute(r *http.Request) bool {
|
|||
}
|
||||
}
|
||||
|
||||
func (m *Middleware) getSessionFromCookie(r *http.Request) *model.UserSession {
|
||||
sessionCookie, err := r.Cookie(cookie.CookieUserSessionID)
|
||||
if err == http.ErrNoCookie {
|
||||
func (m *Middleware) getUserSessionFromCookie(r *http.Request) *model.UserSession {
|
||||
cookieValue := request.Cookie(r, cookie.CookieUserSessionID)
|
||||
if cookieValue == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
session, err := m.store.UserSessionByToken(sessionCookie.Value)
|
||||
session, err := m.store.UserSessionByToken(cookieValue)
|
||||
if err != nil {
|
||||
logger.Error("[Middleware:UserSession] %v", err)
|
||||
return nil
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue