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.

125 satır
3.1KB

  1. package main
  2. import (
  3. "encoding/json"
  4. "io/ioutil"
  5. "log"
  6. "os"
  7. "path/filepath"
  8. "time"
  9. )
  10. //a state is a alphanumerical string lessthan 128 bytes.
  11. //when messages comes in we need to differentiate what state is this in.
  12. //default state is where command can happen
  13. //where the state is stored,
  14. // in sessions/openID.json
  15. //if there is no such file, we are in default state.
  16. //First state is to record user's name, email, and phone number.
  17. // for individual state
  18. // state/statename/openID.json
  19. var sessionDir = "sessions"
  20. var stateDir = "state"
  21. //openIDSession openID user's session
  22. type openIDSession struct {
  23. State string `json:"State"` //name of the current state alphanumerical string
  24. CreateAt int32 `json:"CreateAt"` //when is this session created
  25. UpdateAt int32 `json:"UpdateAt"` //when is this session updated
  26. Expire int32 `json:"Expire"` //unix timestamp of when this state expires
  27. }
  28. //read sessions/openID.json to check whether its a state for ongoing dialog
  29. func getCurrentSesssion(openID string) (result openIDSession, err error) {
  30. path := getSessionPath(openID)
  31. log.Printf("read session from %s\r\n", path)
  32. body, err := ioutil.ReadFile(path)
  33. if err != nil { //read file error
  34. if isFileExist(path) {
  35. log.Println("Error session reading " + path)
  36. }
  37. return //empty and expired session
  38. }
  39. err = json.Unmarshal(body, &result)
  40. if err != nil {
  41. log.Printf("Session Content [path=%s] not correct: ", path)
  42. }
  43. //we don't check Expire, we give the caller full control on
  44. //how to deal wiht expired session
  45. return
  46. }
  47. func writeSession(openid string, ss openIDSession) (err error) {
  48. path := getSessionPath(openid)
  49. r, err := json.Marshal(ss)
  50. if err == nil {
  51. err = ioutil.WriteFile(path, r, 0600)
  52. if err != nil {
  53. log.Printf("Error writing session %s: \r\n %s \r\n", openid, r)
  54. log.Println(err)
  55. } else {
  56. log.Println("write session to " + path)
  57. }
  58. } else {
  59. log.Printf("Error encoding session %s ", openid)
  60. log.Println(err)
  61. }
  62. return
  63. }
  64. //create if not available
  65. func setSessionState(openID, state string, expireAfter int32) (updatedSession openIDSession, err error) {
  66. s, err := getCurrentSesssion(openID)
  67. now := int32(time.Now().Unix())
  68. if s.CreateAt == 0 {
  69. s.CreateAt = now
  70. }
  71. s.UpdateAt = now
  72. s.State = state
  73. s.Expire = now + expireAfter
  74. err = writeSession(openID, s)
  75. return s, err
  76. }
  77. func isExpired(timestamp int32) bool {
  78. now := int32(time.Now().Unix())
  79. return now > timestamp
  80. }
  81. func getSessionPath(openID string) (path string) {
  82. path = sessionDir + string(os.PathSeparator) + openID + ".json"
  83. ensurePathExist(path)
  84. return path
  85. }
  86. func getStatePath(openID, stateName string) (path string) {
  87. path = stateDir + string(os.PathSeparator) + stateName + string(os.PathSeparator) + openID + ".json"
  88. ensurePathExist(path)
  89. return
  90. }
  91. func ensurePathExist(path string) {
  92. d := filepath.Dir(path)
  93. if !isFileExist(d) {
  94. log.Println("Creating path [" + d + "]")
  95. os.MkdirAll(d, 0700)
  96. }
  97. }
  98. func deleteSession(openID string) {
  99. path := getSessionPath(openID)
  100. if isFileExist(path) {
  101. err := os.Remove(path)
  102. if err != nil {
  103. log.Println(err)
  104. } else {
  105. log.Println("delete session :" + path)
  106. }
  107. }
  108. }