codes.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package notifications
  2. import (
  3. "crypto/sha1" // #nosec
  4. "encoding/hex"
  5. "fmt"
  6. "time"
  7. "github.com/unknwon/com"
  8. m "github.com/grafana/grafana/pkg/models"
  9. "github.com/grafana/grafana/pkg/setting"
  10. )
  11. const timeLimitCodeLength = 12 + 6 + 40
  12. // create a time limit code
  13. // code format: 12 length date time string + 6 minutes string + 40 sha1 encoded string
  14. func createTimeLimitCode(data string, minutes int, startInf interface{}) string {
  15. format := "200601021504"
  16. var start, end time.Time
  17. var startStr, endStr string
  18. if startInf == nil {
  19. // Use now time create code
  20. start = time.Now()
  21. startStr = start.Format(format)
  22. } else {
  23. // use start string create code
  24. startStr = startInf.(string)
  25. start, _ = time.ParseInLocation(format, startStr, time.Local)
  26. startStr = start.Format(format)
  27. }
  28. end = start.Add(time.Minute * time.Duration(minutes))
  29. endStr = end.Format(format)
  30. // create sha1 encode string
  31. sh := sha1.New()
  32. sh.Write([]byte(data + setting.SecretKey + startStr + endStr + com.ToStr(minutes)))
  33. encoded := hex.EncodeToString(sh.Sum(nil))
  34. code := fmt.Sprintf("%s%06d%s", startStr, minutes, encoded)
  35. return code
  36. }
  37. // verify time limit code
  38. func validateUserEmailCode(user *m.User, code string) bool {
  39. if len(code) <= 18 {
  40. return false
  41. }
  42. minutes := setting.EmailCodeValidMinutes
  43. code = code[:timeLimitCodeLength]
  44. // split code
  45. start := code[:12]
  46. lives := code[12:18]
  47. if d, err := com.StrTo(lives).Int(); err == nil {
  48. minutes = d
  49. }
  50. // right active code
  51. data := com.ToStr(user.Id) + user.Email + user.Login + user.Password + user.Rands
  52. retCode := createTimeLimitCode(data, minutes, start)
  53. fmt.Printf("code : %s\ncode2: %s", retCode, code)
  54. if retCode == code && minutes > 0 {
  55. // check time is expired or not
  56. before, _ := time.ParseInLocation("200601021504", start, time.Local)
  57. now := time.Now()
  58. if before.Add(time.Minute*time.Duration(minutes)).Unix() > now.Unix() {
  59. return true
  60. }
  61. }
  62. return false
  63. }
  64. func getLoginForEmailCode(code string) string {
  65. if len(code) <= timeLimitCodeLength {
  66. return ""
  67. }
  68. // use tail hex username query user
  69. hexStr := code[timeLimitCodeLength:]
  70. b, _ := hex.DecodeString(hexStr)
  71. return string(b)
  72. }
  73. func createUserEmailCode(u *m.User, startInf interface{}) string {
  74. minutes := setting.EmailCodeValidMinutes
  75. data := com.ToStr(u.Id) + u.Email + u.Login + u.Password + u.Rands
  76. code := createTimeLimitCode(data, minutes, startInf)
  77. // add tail hex username
  78. code += hex.EncodeToString([]byte(u.Login))
  79. return code
  80. }