action.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. package pop3_server
  2. import (
  3. "database/sql"
  4. "github.com/Jinnrry/gopop"
  5. log "github.com/sirupsen/logrus"
  6. "github.com/spf13/cast"
  7. "pmail/db"
  8. "pmail/models"
  9. "pmail/services/detail"
  10. "pmail/utils/array"
  11. "pmail/utils/context"
  12. "pmail/utils/errors"
  13. "pmail/utils/id"
  14. "pmail/utils/password"
  15. )
  16. type action struct {
  17. }
  18. func (a action) User(ctx *gopop.Data, username string) error {
  19. if ctx.Ctx == nil {
  20. tc := &context.Context{}
  21. tc.SetValue(context.LogID, id.GenLogID())
  22. ctx.Ctx = tc
  23. }
  24. ctx.User = username
  25. return nil
  26. }
  27. func (a action) Pass(ctx *gopop.Data, pwd string) error {
  28. if ctx.Ctx == nil {
  29. tc := &context.Context{}
  30. tc.SetValue(context.LogID, id.GenLogID())
  31. ctx.Ctx = tc
  32. }
  33. var user models.User
  34. encodePwd := password.Encode(pwd)
  35. err := db.Instance.Get(&user, db.WithContext(ctx.Ctx.(*context.Context), "select * from user where account =? and password =?"), ctx.User, encodePwd)
  36. if err != nil && !errors.Is(err, sql.ErrNoRows) {
  37. log.WithContext(ctx.Ctx.(*context.Context)).Errorf("%+v", err)
  38. }
  39. if user.ID > 0 {
  40. ctx.Status = gopop.TRANSACTION
  41. ctx.Ctx.(*context.Context).UserID = user.ID
  42. ctx.Ctx.(*context.Context).UserName = user.Name
  43. ctx.Ctx.(*context.Context).UserAccount = user.Account
  44. return nil
  45. }
  46. return errors.New("password error")
  47. }
  48. func (a action) Apop(ctx *gopop.Data, username, digest string) error {
  49. if ctx.Ctx == nil {
  50. tc := &context.Context{}
  51. tc.SetValue(context.LogID, id.GenLogID())
  52. ctx.Ctx = tc
  53. }
  54. var user models.User
  55. err := db.Instance.Get(&user, db.WithContext(ctx.Ctx.(*context.Context), "select * from user where account =? "), username)
  56. if err != nil && !errors.Is(err, sql.ErrNoRows) {
  57. log.WithContext(ctx.Ctx.(*context.Context)).Errorf("%+v", err)
  58. }
  59. if user.ID > 0 && digest == password.Md5Encode(user.Password) {
  60. ctx.User = username
  61. ctx.Status = gopop.TRANSACTION
  62. ctx.Ctx.(*context.Context).UserID = user.ID
  63. ctx.Ctx.(*context.Context).UserName = user.Name
  64. ctx.Ctx.(*context.Context).UserAccount = user.Account
  65. return nil
  66. }
  67. return errors.New("password error")
  68. }
  69. type statInfo struct {
  70. Num int64 `json:"num"`
  71. Size int64 `json:"size"`
  72. }
  73. func (a action) Stat(ctx *gopop.Data) (msgNum, msgSize int64, err error) {
  74. var si statInfo
  75. err = db.Instance.Get(&si, db.WithContext(ctx.Ctx.(*context.Context), "select count(1) as `num`, sum(length(text)+length(html)) as `size` from email"))
  76. if err != nil && !errors.Is(err, sql.ErrNoRows) {
  77. log.WithContext(ctx.Ctx.(*context.Context)).Errorf("%+v", err)
  78. err = nil
  79. return 0, 0, nil
  80. }
  81. return si.Num, si.Size, nil
  82. }
  83. func (a action) Uidl(ctx *gopop.Data, id int64) (string, error) {
  84. return cast.ToString(id), nil
  85. }
  86. type listItem struct {
  87. Id int64 `json:"id"`
  88. Size int64 `json:"size"`
  89. }
  90. func (a action) List(ctx *gopop.Data, msg string) ([]gopop.MailInfo, error) {
  91. var res []listItem
  92. var id int64
  93. if msg != "" {
  94. id = cast.ToInt64(msg)
  95. if id == 0 {
  96. return nil, errors.New("params error")
  97. }
  98. }
  99. var err error
  100. if id != 0 {
  101. err = db.Instance.Select(&res, db.WithContext(ctx.Ctx.(*context.Context), "select id, length(text)+length(html) as `size` from email where id =?"), id)
  102. } else {
  103. err = db.Instance.Select(&res, db.WithContext(ctx.Ctx.(*context.Context), "select id, length(text)+length(html) as `size` from email"))
  104. }
  105. if err != nil && !errors.Is(err, sql.ErrNoRows) {
  106. log.WithContext(ctx.Ctx.(*context.Context)).Errorf("%+v", err)
  107. err = nil
  108. return []gopop.MailInfo{}, nil
  109. }
  110. ret := []gopop.MailInfo{}
  111. for _, re := range res {
  112. ret = append(ret, gopop.MailInfo{
  113. Id: re.Id,
  114. Size: re.Size,
  115. })
  116. }
  117. return ret, nil
  118. }
  119. func (a action) Retr(ctx *gopop.Data, id int64) (string, int64, error) {
  120. email, err := detail.GetEmailDetail(ctx.Ctx.(*context.Context), cast.ToInt(id), false)
  121. if err != nil {
  122. log.WithContext(ctx.Ctx.(*context.Context)).Errorf("%+v", err)
  123. return "", 0, errors.New("server error")
  124. }
  125. ret := email.ToTransObj().BuildBytes(ctx.Ctx.(*context.Context), false)
  126. return string(ret), cast.ToInt64(len(ret)), nil
  127. }
  128. func (a action) Delete(ctx *gopop.Data, id int64) error {
  129. ctx.DeleteIds = append(ctx.DeleteIds, id)
  130. ctx.DeleteIds = array.Unique(ctx.DeleteIds)
  131. return nil
  132. }
  133. func (a action) Rest(ctx *gopop.Data) error {
  134. ctx.DeleteIds = []int64{}
  135. return nil
  136. }
  137. func (a action) Top(ctx *gopop.Data, id int64, n int) (string, error) {
  138. //email, err := detail.GetEmailDetail(ctx.Ctx.(*context.Context), cast.ToInt(id), false)
  139. //if err != nil {
  140. // log.WithContext(ctx.Ctx.(*context.Context)).Errorf("%+v", err)
  141. // return "", errors.New("server error")
  142. //}
  143. //
  144. //ret := email.ToTransObj().BuilderHeaders(ctx.Ctx.(*context.Context))
  145. //return string(ret), nil
  146. return "", errors.New("not supported")
  147. }
  148. func (a action) Noop(ctx *gopop.Data) error {
  149. return nil
  150. }
  151. func (a action) Quit(ctx *gopop.Data) error {
  152. if len(ctx.DeleteIds) > 0 {
  153. _, err := db.Instance.Exec(db.WithContext(ctx.Ctx.(*context.Context), "DELETE FROM email WHERE id in ?"), ctx.DeleteIds)
  154. if err != nil {
  155. log.WithContext(ctx.Ctx.(*context.Context)).Errorf("%+v", err)
  156. }
  157. }
  158. return nil
  159. }