diff --git a/README.md b/README.md index 86f4d0f9..44137662 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ Gin middleware for session management with multi-backend support: - [GORM](#gorm) - [memstore](#memstore) - [PostgreSQL](#postgresql) +- [Filesystem](#Filesystem) ## Usage @@ -456,3 +457,40 @@ func main() { r.Run(":8000") } ``` + +### Filesystem + +```go +package main + +import ( + "github.com/gin-contrib/sessions" + "github.com/gin-contrib/sessions/filesystem" + "github.com/gin-gonic/gin" +) + +func main() { + r := gin.Default() + + var sessionPath = "/tmp/" // in case of empty string, the system's default tmp folder is used + + store := filesystem.NewStore(sessionPath,[]byte("secret")) + r.Use(sessions.Sessions("mysession", store)) + + r.GET("/incr", func(c *gin.Context) { + session := sessions.Default(c) + var count int + v := session.Get("count") + if v == nil { + count = 0 + } else { + count = v.(int) + count++ + } + session.Set("count", count) + session.Save() + c.JSON(200, gin.H{"count": count}) + }) + r.Run(":8000") +} +``` diff --git a/_example/filesystem/main.go b/_example/filesystem/main.go new file mode 100644 index 00000000..3ea148d7 --- /dev/null +++ b/_example/filesystem/main.go @@ -0,0 +1,30 @@ +package main + +import ( + sessions "github.com/geschke/gin-contrib-sessions" + "github.com/geschke/gin-contrib-sessions/filesystem" + "github.com/gin-gonic/gin" +) + +func main() { + sessionPath := "/tmp/" + r := gin.Default() + store := filesystem.NewStore(sessionPath, []byte("secret")) + r.Use(sessions.Sessions("mysession", store)) + + r.GET("/incr", func(c *gin.Context) { + session := sessions.Default(c) + var count int + v := session.Get("count") + if v == nil { + count = 0 + } else { + count = v.(int) + count++ + } + session.Set("count", count) + session.Save() + c.JSON(200, gin.H{"count": count}) + }) + r.Run(":8000") +} diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go new file mode 100644 index 00000000..7aa19913 --- /dev/null +++ b/filesystem/filesystem.go @@ -0,0 +1,31 @@ +package filesystem + +import ( + "github.com/gin-contrib/sessions" + gsessions "github.com/gorilla/sessions" +) + +type Store interface { + sessions.Store +} + +// Keys are defined in pairs to allow key rotation, but the common case is to set a single +// authentication key and optionally an encryption key. +// +// The first key in a pair is used for authentication and the second for encryption. The +// encryption key can be set to nil or omitted in the last pair, but the authentication key +// is required in all pairs. +// +// It is recommended to use an authentication key with 32 or 64 bytes. The encryption key, +// if set, must be either 16, 24, or 32 bytes to select AES-128, AES-192, or AES-256 modes. +func NewStore(path string, keyPairs ...[]byte) Store { + return &store{gsessions.NewFilesystemStore(path, keyPairs...)} +} + +type store struct { + *gsessions.FilesystemStore +} + +func (c *store) Options(options sessions.Options) { + c.FilesystemStore.Options = options.ToGorillaOptions() +} diff --git a/filesystem/filesystem_test.go b/filesystem/filesystem_test.go new file mode 100644 index 00000000..0418c369 --- /dev/null +++ b/filesystem/filesystem_test.go @@ -0,0 +1,40 @@ +package filesystem + +import ( + "os" + "testing" + + "github.com/gin-contrib/sessions" + "github.com/gin-contrib/sessions/tester" +) + +var sessionPath = os.TempDir() + +var newStore = func(_ *testing.T) sessions.Store { + store := NewStore(sessionPath, []byte("secret")) + return store +} + +func TestFilesystem_SessionGetSet(t *testing.T) { + tester.GetSet(t, newStore) +} + +func TestFilesystem_SessionDeleteKey(t *testing.T) { + tester.DeleteKey(t, newStore) +} + +func TestFilesystem_SessionFlashes(t *testing.T) { + tester.Flashes(t, newStore) +} + +func TestFilesystem_SessionClear(t *testing.T) { + tester.Clear(t, newStore) +} + +func TestFilesystem_SessionOptions(t *testing.T) { + tester.Options(t, newStore) +} + +func TestFilesystem_SessionMany(t *testing.T) { + tester.Many(t, newStore) +}