|
@@ -0,0 +1,198 @@
|
|
|
|
|
+package pop3_server
|
|
|
|
|
+
|
|
|
|
|
+import (
|
|
|
|
|
+ "database/sql"
|
|
|
|
|
+ "github.com/Jinnrry/gopop"
|
|
|
|
|
+ log "github.com/sirupsen/logrus"
|
|
|
|
|
+ "github.com/spf13/cast"
|
|
|
|
|
+ "pmail/db"
|
|
|
|
|
+ "pmail/models"
|
|
|
|
|
+ "pmail/services/detail"
|
|
|
|
|
+ "pmail/utils/array"
|
|
|
|
|
+ "pmail/utils/context"
|
|
|
|
|
+ "pmail/utils/errors"
|
|
|
|
|
+ "pmail/utils/id"
|
|
|
|
|
+ "pmail/utils/password"
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+type action struct {
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (a action) User(ctx *gopop.Data, username string) error {
|
|
|
|
|
+ if ctx.Ctx == nil {
|
|
|
|
|
+ tc := &context.Context{}
|
|
|
|
|
+ tc.SetValue(context.LogID, id.GenLogID())
|
|
|
|
|
+ ctx.Ctx = tc
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ctx.User = username
|
|
|
|
|
+ return nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (a action) Pass(ctx *gopop.Data, pwd string) error {
|
|
|
|
|
+ if ctx.Ctx == nil {
|
|
|
|
|
+ tc := &context.Context{}
|
|
|
|
|
+ tc.SetValue(context.LogID, id.GenLogID())
|
|
|
|
|
+ ctx.Ctx = tc
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ var user models.User
|
|
|
|
|
+
|
|
|
|
|
+ encodePwd := password.Encode(pwd)
|
|
|
|
|
+
|
|
|
|
|
+ err := db.Instance.Get(&user, db.WithContext(ctx.Ctx.(*context.Context), "select * from user where account =? and password =?"), ctx.User, encodePwd)
|
|
|
|
|
+ if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
|
|
|
|
+ log.WithContext(ctx.Ctx.(*context.Context)).Errorf("%+v", err)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if user.ID > 0 {
|
|
|
|
|
+ ctx.Status = gopop.TRANSACTION
|
|
|
|
|
+
|
|
|
|
|
+ ctx.Ctx.(*context.Context).UserID = user.ID
|
|
|
|
|
+ ctx.Ctx.(*context.Context).UserName = user.Name
|
|
|
|
|
+ ctx.Ctx.(*context.Context).UserAccount = user.Account
|
|
|
|
|
+
|
|
|
|
|
+ return nil
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return errors.New("password error")
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (a action) Apop(ctx *gopop.Data, username, digest string) error {
|
|
|
|
|
+ if ctx.Ctx == nil {
|
|
|
|
|
+ tc := &context.Context{}
|
|
|
|
|
+ tc.SetValue(context.LogID, id.GenLogID())
|
|
|
|
|
+ ctx.Ctx = tc
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ var user models.User
|
|
|
|
|
+
|
|
|
|
|
+ err := db.Instance.Get(&user, db.WithContext(ctx.Ctx.(*context.Context), "select * from user where account =? "), username)
|
|
|
|
|
+ if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
|
|
|
|
+ log.WithContext(ctx.Ctx.(*context.Context)).Errorf("%+v", err)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if user.ID > 0 && digest == password.Md5Encode(user.Password) {
|
|
|
|
|
+ ctx.User = username
|
|
|
|
|
+ ctx.Status = gopop.TRANSACTION
|
|
|
|
|
+
|
|
|
|
|
+ ctx.Ctx.(*context.Context).UserID = user.ID
|
|
|
|
|
+ ctx.Ctx.(*context.Context).UserName = user.Name
|
|
|
|
|
+ ctx.Ctx.(*context.Context).UserAccount = user.Account
|
|
|
|
|
+
|
|
|
|
|
+ return nil
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return errors.New("password error")
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+type statInfo struct {
|
|
|
|
|
+ Num int64 `json:"num"`
|
|
|
|
|
+ Size int64 `json:"size"`
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (a action) Stat(ctx *gopop.Data) (msgNum, msgSize int64, err error) {
|
|
|
|
|
+ var si statInfo
|
|
|
|
|
+ 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"))
|
|
|
|
|
+ if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
|
|
|
|
+ log.WithContext(ctx.Ctx.(*context.Context)).Errorf("%+v", err)
|
|
|
|
|
+ err = nil
|
|
|
|
|
+ return 0, 0, nil
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return si.Num, si.Size, nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (a action) Uidl(ctx *gopop.Data, id int64) (string, error) {
|
|
|
|
|
+ return cast.ToString(id), nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+type listItem struct {
|
|
|
|
|
+ Id int64 `json:"id"`
|
|
|
|
|
+ Size int64 `json:"size"`
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (a action) List(ctx *gopop.Data, msg string) ([]gopop.MailInfo, error) {
|
|
|
|
|
+ var res []listItem
|
|
|
|
|
+ var id int64
|
|
|
|
|
+ if msg != "" {
|
|
|
|
|
+ id = cast.ToInt64(msg)
|
|
|
|
|
+ if id == 0 {
|
|
|
|
|
+ return nil, errors.New("params error")
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ var err error
|
|
|
|
|
+ if id != 0 {
|
|
|
|
|
+ err = db.Instance.Select(&res, db.WithContext(ctx.Ctx.(*context.Context), "select id, length(text)+length(html) as `size` from email where id =?"), id)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ err = db.Instance.Select(&res, db.WithContext(ctx.Ctx.(*context.Context), "select id, length(text)+length(html) as `size` from email"))
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
|
|
|
|
+ log.WithContext(ctx.Ctx.(*context.Context)).Errorf("%+v", err)
|
|
|
|
|
+ err = nil
|
|
|
|
|
+ return []gopop.MailInfo{}, nil
|
|
|
|
|
+ }
|
|
|
|
|
+ ret := []gopop.MailInfo{}
|
|
|
|
|
+ for _, re := range res {
|
|
|
|
|
+ ret = append(ret, gopop.MailInfo{
|
|
|
|
|
+ Id: re.Id,
|
|
|
|
|
+ Size: re.Size,
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ return ret, nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (a action) Retr(ctx *gopop.Data, id int64) (string, int64, error) {
|
|
|
|
|
+
|
|
|
|
|
+ email, err := detail.GetEmailDetail(ctx.Ctx.(*context.Context), cast.ToInt(id), false)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ log.WithContext(ctx.Ctx.(*context.Context)).Errorf("%+v", err)
|
|
|
|
|
+ return "", 0, errors.New("server error")
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ret := email.ToTransObj().BuildBytes(ctx.Ctx.(*context.Context), false)
|
|
|
|
|
+ return string(ret), cast.ToInt64(len(ret)), nil
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (a action) Delete(ctx *gopop.Data, id int64) error {
|
|
|
|
|
+ ctx.DeleteIds = append(ctx.DeleteIds, id)
|
|
|
|
|
+ ctx.DeleteIds = array.Unique(ctx.DeleteIds)
|
|
|
|
|
+ return nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (a action) Rest(ctx *gopop.Data) error {
|
|
|
|
|
+ ctx.DeleteIds = []int64{}
|
|
|
|
|
+ return nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (a action) Top(ctx *gopop.Data, id int64, n int) (string, error) {
|
|
|
|
|
+ //email, err := detail.GetEmailDetail(ctx.Ctx.(*context.Context), cast.ToInt(id), false)
|
|
|
|
|
+ //if err != nil {
|
|
|
|
|
+ // log.WithContext(ctx.Ctx.(*context.Context)).Errorf("%+v", err)
|
|
|
|
|
+ // return "", errors.New("server error")
|
|
|
|
|
+ //}
|
|
|
|
|
+ //
|
|
|
|
|
+ //ret := email.ToTransObj().BuilderHeaders(ctx.Ctx.(*context.Context))
|
|
|
|
|
+ //return string(ret), nil
|
|
|
|
|
+
|
|
|
|
|
+ return "", errors.New("not supported")
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (a action) Noop(ctx *gopop.Data) error {
|
|
|
|
|
+ return nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (a action) Quit(ctx *gopop.Data) error {
|
|
|
|
|
+ if len(ctx.DeleteIds) > 0 {
|
|
|
|
|
+
|
|
|
|
|
+ _, err := db.Instance.Exec(db.WithContext(ctx.Ctx.(*context.Context), "DELETE FROM email WHERE id in ?"), ctx.DeleteIds)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ log.WithContext(ctx.Ctx.(*context.Context)).Errorf("%+v", err)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return nil
|
|
|
|
|
+}
|