158 lines
3.9 KiB
Go
158 lines
3.9 KiB
Go
/*
|
|
* @Author: Bartuccio Antoine
|
|
* @Date: 2018-07-16 15:37:29
|
|
* @Last Modified by: klmp200
|
|
* @Last Modified time: 2018-07-17 23:47:56
|
|
*/
|
|
|
|
package gowebframework
|
|
|
|
import (
|
|
"encoding/json"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
)
|
|
|
|
var session_folder_path string = ".session"
|
|
var folder_perm os.FileMode = 0770
|
|
|
|
type FileSessionProvider struct{}
|
|
|
|
// Used to hide FileSession variables and still be able to write inside json with json.Marshal
|
|
type unexportedFileSession struct {
|
|
UUID string
|
|
LastUse time.Time
|
|
Data map[string]interface{}
|
|
}
|
|
type FileSession struct {
|
|
uuid string
|
|
lastUse time.Time
|
|
data map[string]interface{}
|
|
}
|
|
|
|
// Convert a unexportedFileSession to a FileSession
|
|
func (session unexportedFileSession) fileSession() FileSession {
|
|
return FileSession{
|
|
uuid: session.UUID,
|
|
lastUse: session.LastUse,
|
|
data: session.Data,
|
|
}
|
|
}
|
|
|
|
func (provider FileSessionProvider) checkOrCreateFolder() {
|
|
folder, err := os.Open(session_folder_path)
|
|
if err != nil {
|
|
// Auto create folder if doesn't exist
|
|
log.Println("No session folder found, creating " + session_folder_path)
|
|
err = os.Mkdir(session_folder_path, folder_perm)
|
|
if err != nil {
|
|
log.Fatal("Could not create session directory, exiting")
|
|
}
|
|
return
|
|
}
|
|
folder_infos, err := folder.Stat()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
if !folder_infos.IsDir() {
|
|
log.Fatal(session_folder_path + " is not a directory, exiting")
|
|
}
|
|
if !isWritable(session_folder_path) {
|
|
log.Fatal(session_folder_path + " directory is not writable, exiting")
|
|
}
|
|
}
|
|
|
|
func (provider FileSessionProvider) SessionInit(uuid string) (Session, error) {
|
|
provider.checkOrCreateFolder()
|
|
provider.SessionDestroy(uuid)
|
|
session := FileSession{}
|
|
session.uuid = uuid
|
|
session.data = make(map[string]interface{})
|
|
session.lastUse = time.Now()
|
|
return session, session.writeSession()
|
|
}
|
|
|
|
func (provider FileSessionProvider) SessionRead(uuid string) (Session, error) {
|
|
provider.checkOrCreateFolder()
|
|
data, err := ioutil.ReadFile(filepath.Join(session_folder_path, uuid+".json"))
|
|
if err != nil {
|
|
return provider.SessionInit(uuid)
|
|
}
|
|
unexported_session := unexportedFileSession{}
|
|
err = json.Unmarshal(data, &unexported_session)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
session := unexported_session.fileSession()
|
|
return session, session.writeSession()
|
|
}
|
|
|
|
func (provider FileSessionProvider) SessionDestroy(uuid string) error {
|
|
provider.checkOrCreateFolder()
|
|
return os.Remove(filepath.Join(session_folder_path, uuid+".json"))
|
|
}
|
|
|
|
func (provider FileSessionProvider) SessionClearExpired(maxLifetime time.Duration) {
|
|
provider.checkOrCreateFolder()
|
|
directory, _ := ioutil.ReadDir(session_folder_path)
|
|
for _, file := range directory {
|
|
session := unexportedFileSession{}
|
|
data, err := ioutil.ReadFile(filepath.Join(session_folder_path, file.Name()))
|
|
if err != nil {
|
|
log.Println(err)
|
|
} else {
|
|
err = json.Unmarshal(data, &session)
|
|
if err != nil {
|
|
log.Println(err)
|
|
} else {
|
|
if session.LastUse.Add(maxLifetime).Sub(time.Now()) <= 0 {
|
|
// Session expired
|
|
provider.SessionDestroy(session.UUID)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
func (session FileSession) unexportedFileSession() unexportedFileSession {
|
|
return unexportedFileSession{
|
|
UUID: session.uuid,
|
|
LastUse: session.lastUse,
|
|
Data: session.data,
|
|
}
|
|
}
|
|
|
|
// Write a session on the disk
|
|
func (session FileSession) writeSession() error {
|
|
session.lastUse = time.Now()
|
|
data, _ := json.Marshal(session.unexportedFileSession())
|
|
err := ioutil.WriteFile(filepath.Join(session_folder_path, session.uuid+".json"), data, folder_perm)
|
|
return err
|
|
}
|
|
|
|
func (session FileSession) Set(key string, value interface{}) error {
|
|
session.data[key] = value
|
|
return session.writeSession()
|
|
}
|
|
|
|
func (session FileSession) Get(key string) interface{} {
|
|
value, ok := session.data[key]
|
|
if !ok {
|
|
return nil
|
|
}
|
|
return value
|
|
}
|
|
|
|
func (session FileSession) Delete(key string) error {
|
|
delete(session.data, key)
|
|
return session.writeSession()
|
|
}
|
|
|
|
func (session FileSession) SessionUUID() string {
|
|
return session.uuid
|
|
}
|