Repos / bykclk/echo-scs-session / 1b2eee47df6b / github.com/wainuiomata/echo-scs-session/session.go

github.com/wainuiomata/echo-scs-session/session.go

29 of 38 statements covered · → +0.0% · commit 1b2eee47df6b

File coverage
76.3%
14 uncovered lines in 7 blocks
30 lines, fully covered · expand
1
package session
2
3
import (
4
	"net/http"
5
	"time"
6
7
	"github.com/alexedwards/scs/v2"
8
	"github.com/labstack/echo/v4"
9
	"github.com/labstack/echo/v4/middleware"
10
)
11
12
type SessionConfig struct {
13
	Skipper        middleware.Skipper
14
	SessionManager *scs.SessionManager
15
}
16
17
var DefaultSessionConfig = SessionConfig{
18
	Skipper: middleware.DefaultSkipper,
19
}
20
21
func LoadAndSave(sessionManager *scs.SessionManager) echo.MiddlewareFunc {
22
	c := DefaultSessionConfig
23
	c.SessionManager = sessionManager
24
25
	return LoadAndSaveWithConfig(c)
26
}
27
28
func LoadAndSaveWithConfig(config SessionConfig) echo.MiddlewareFunc {
29
30
	if config.Skipper == nil {
31
		config.Skipper = DefaultSessionConfig.Skipper
32
	}
33
34
	if config.SessionManager == nil {
35
		panic("Session middleware requires a session manager")
36
	}
37
38
	return func(next echo.HandlerFunc) echo.HandlerFunc {
39
		return func(c echo.Context) error {
40
			if config.Skipper(c) {
41
				return next(c)
42
			}
11 lines, fully covered · expand
43
44
			ctx := c.Request().Context()
45
46
			var token string
47
			cookie, err := c.Cookie(config.SessionManager.Cookie.Name)
48
			if err == nil {
49
				token = cookie.Value
50
			}
51
52
			ctx, err = config.SessionManager.Load(ctx, token)
53
			if err != nil {
54
				return err
55
			}
18 lines, fully covered · expand
56
57
			c.SetRequest(c.Request().WithContext(ctx))
58
59
			c.Response().Before(func() {
60
				if config.SessionManager.Status(ctx) != scs.Unmodified {
61
					responseCookie := &http.Cookie{
62
						Name:     config.SessionManager.Cookie.Name,
63
						Path:     config.SessionManager.Cookie.Path,
64
						Domain:   config.SessionManager.Cookie.Domain,
65
						Secure:   config.SessionManager.Cookie.Secure,
66
						HttpOnly: config.SessionManager.Cookie.HttpOnly,
67
						SameSite: config.SessionManager.Cookie.SameSite,
68
					}
69
70
					switch config.SessionManager.Status(ctx) {
71
					case scs.Modified:
72
						token, _, err := config.SessionManager.Commit(ctx)
73
						if err != nil {
74
							panic(err)
75
						}
76
77
						responseCookie.Value = token
78
79
					case scs.Destroyed:
80
						responseCookie.Expires = time.Unix(1, 0)
81
						responseCookie.MaxAge = -1
15 lines, fully covered · expand
82
					}
83
84
					c.SetCookie(responseCookie)
85
					addHeaderIfMissing(c.Response(), "Cache-Control", `no-cache="Set-Cookie"`)
86
					addHeaderIfMissing(c.Response(), "Vary", "Cookie")
87
				}
88
			})
89
90
			return next(c)
91
		}
92
	}
93
}
94
95
func addHeaderIfMissing(w http.ResponseWriter, key, value string) {
96
	for _, h := range w.Header()[key] {
97
		if h == value {
98
			return
99
		}
100
	}
101
	w.Header().Add(key, value)
102
}
Executed, with hit count Never executed Not a statement The rail maps all 102 lines of the file.