session/session_test.go
Andrew Thornton e3605d8b28
All checks were successful
continuous-integration/drone/push Build is passing
Provide function to regenerate RawStore within session (#4)
There is currently no easy way to regenerate the session id within Sessioner
meaning it is hard to update the session ID early on in a request tree.

RegenerateSession will look in the request scope for the session, grab the session
release, regenerate and then flush the old session before updating the RawStore in the
session.

Signed-off-by: Andrew Thornton <art27@cantab.net>

Reviewed-on: #4
2021-12-19 06:16:15 +08:00

202 lines
4.9 KiB
Go

// Copyright 2014 The Macaron Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"): you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package session
import (
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
chi "github.com/go-chi/chi/v5"
. "github.com/smartystreets/goconvey/convey"
)
func Test_Sessioner(t *testing.T) {
Convey("Use session middleware", t, func() {
c := chi.NewRouter()
c.Use(Sessioner())
c.Get("/", func(resp http.ResponseWriter, req *http.Request) {})
resp := httptest.NewRecorder()
req, err := http.NewRequest("GET", "/", nil)
So(err, ShouldBeNil)
c.ServeHTTP(resp, req)
})
Convey("Register invalid provider", t, func() {
Convey("Provider not exists", func() {
defer func() {
So(recover(), ShouldNotBeNil)
}()
c := chi.NewRouter()
c.Use(Sessioner(Options{
Provider: "fake",
}))
})
Convey("Provider value is nil", func() {
defer func() {
So(recover(), ShouldNotBeNil)
}()
Register("fake", nil)
})
Convey("Register twice", func() {
defer func() {
So(recover(), ShouldNotBeNil)
}()
Register("memory", &MemProvider{})
})
})
}
func testProvider(opt Options) {
Convey("Basic operation", func() {
c := chi.NewRouter()
c.Use(Sessioner(opt))
var initialSid string
c.Get("/", func(resp http.ResponseWriter, req *http.Request) {
sess := GetSession(req)
sess.Set("uname", "unknwon")
initialSid = sess.ID()
})
c.Get("/reg", func(resp http.ResponseWriter, req *http.Request) {
sess := GetSession(req)
So(initialSid, ShouldEqual, sess.ID())
raw, err := RegenerateSession(resp, req)
So(err, ShouldBeNil)
So(sess, ShouldNotBeNil)
So(sess, ShouldEqual, raw)
So(initialSid, ShouldNotEqual, sess.ID())
uname := sess.Get("uname")
So(uname, ShouldNotBeNil)
So(uname, ShouldEqual, "unknwon")
sess.Set("uname", "lunny")
uname = sess.Get("uname")
So(uname, ShouldNotBeNil)
So(uname, ShouldEqual, "lunny")
})
c.Get("/get", func(resp http.ResponseWriter, req *http.Request) {
sess := GetSession(req)
sid := sess.ID()
So(sid, ShouldNotBeEmpty)
raw, err := sess.Read(sid)
So(err, ShouldBeNil)
So(raw, ShouldNotBeNil)
uname := sess.Get("uname")
So(uname, ShouldNotBeNil)
So(uname, ShouldEqual, "lunny")
So(sess.Delete("uname"), ShouldBeNil)
So(sess.Get("uname"), ShouldBeNil)
So(sess.Destroy(resp, req), ShouldBeNil)
})
resp := httptest.NewRecorder()
req, err := http.NewRequest("GET", "/", nil)
So(err, ShouldBeNil)
c.ServeHTTP(resp, req)
cookie := resp.Header().Get("Set-Cookie")
resp = httptest.NewRecorder()
req, err = http.NewRequest("GET", "/reg", nil)
So(err, ShouldBeNil)
req.Header.Set("Cookie", cookie)
c.ServeHTTP(resp, req)
cookie = resp.Header().Get("Set-Cookie")
resp = httptest.NewRecorder()
req, err = http.NewRequest("GET", "/get", nil)
So(err, ShouldBeNil)
req.Header.Set("Cookie", cookie)
c.ServeHTTP(resp, req)
})
Convey("Regenrate empty session", func() {
c := chi.NewRouter()
c.Use(Sessioner(opt))
c.Get("/", func(resp http.ResponseWriter, req *http.Request) {
sess := GetSession(req)
raw, err := sess.RegenerateID(resp, req)
So(err, ShouldBeNil)
So(raw, ShouldNotBeNil)
})
resp := httptest.NewRecorder()
req, err := http.NewRequest("GET", "/", nil)
So(err, ShouldBeNil)
req.Header.Set("Cookie", "MacaronSession=ad2c7e3cbecfcf48; Path=/;")
c.ServeHTTP(resp, req)
})
Convey("GC session", func() {
c := chi.NewRouter()
opt2 := opt
opt2.Gclifetime = 1
c.Use(Sessioner(opt2))
c.Get("/", func(resp http.ResponseWriter, req *http.Request) {
sess := GetSession(req)
sess.Set("uname", "unknwon")
So(sess.ID(), ShouldNotBeEmpty)
uname := sess.Get("uname")
So(uname, ShouldNotBeNil)
So(uname, ShouldEqual, "unknwon")
So(sess.Flush(), ShouldBeNil)
So(sess.Get("uname"), ShouldBeNil)
time.Sleep(2 * time.Second)
sess.GC()
So(sess.Count(), ShouldEqual, 0)
})
resp := httptest.NewRecorder()
req, err := http.NewRequest("GET", "/", nil)
So(err, ShouldBeNil)
c.ServeHTTP(resp, req)
})
Convey("Detect invalid sid", func() {
c := chi.NewRouter()
c.Use(Sessioner(opt))
c.Get("/", func(resp http.ResponseWriter, req *http.Request) {
sess := GetSession(req)
raw, err := sess.Read("../session/ad2c7e3cbecfcf486")
So(strings.Contains(err.Error(), "invalid 'sid': "), ShouldBeTrue)
So(raw, ShouldBeNil)
})
resp := httptest.NewRecorder()
req, err := http.NewRequest("GET", "/", nil)
So(err, ShouldBeNil)
c.ServeHTTP(resp, req)
})
}