You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
157 lines
3.9 KiB
157 lines
3.9 KiB
/* |
|
* @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 |
|
}
|
|
|