| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- 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"
- "strings"
- )
- 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
- }
- infos := strings.Split(username, "@")
- if len(infos) > 1 {
- username = infos[0]
- }
- log.WithContext(ctx.Ctx).Debugf("POP3 User %s", username)
- 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
- }
- log.WithContext(ctx.Ctx).Debugf("POP3 PASS %s , User:%s", pwd, ctx.User)
- 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
- }
- infos := strings.Split(username, "@")
- if len(infos) > 1 {
- username = infos[0]
- }
- log.WithContext(ctx.Ctx).Debugf("POP3 APOP %s %s", username, digest)
- 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
- log.WithContext(ctx.Ctx).Debugf("POP3 STAT RETURT :0,0")
- return 0, 0, nil
- }
- log.WithContext(ctx.Ctx).Debugf("POP3 STAT RETURT : %d,%d", si.Num, si.Size)
- return si.Num, si.Size, nil
- }
- func (a action) Uidl(ctx *gopop.Data, id int64) (string, error) {
- log.WithContext(ctx.Ctx).Debugf("POP3 Uidl RETURT : %d", id)
- 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
- }
|