Browse Source

Save username/password in session

This is required for authenticating with the SMTP server when composing
a new message.
master
Simon Ser 4 years ago
parent
commit
702719c072
No known key found for this signature in database GPG Key ID: FDE7BE0E88F5E48
2 changed files with 26 additions and 13 deletions
  1. +20
    -11
      conn_pool.go
  2. +6
    -2
      server.go

+ 20
- 11
conn_pool.go View File

@@ -20,30 +20,35 @@ func generateToken() (string, error) {

var ErrSessionExpired = errors.New("session expired")

type Session struct {
imapConn *imapclient.Client
username, password string
}

// TODO: expiration timer
type ConnPool struct {
locker sync.Mutex
conns map[string]*imapclient.Client
sessions map[string]*Session
}

func NewConnPool() *ConnPool {
return &ConnPool{
conns: make(map[string]*imapclient.Client),
sessions: make(map[string]*Session),
}
}

func (pool *ConnPool) Get(token string) (*imapclient.Client, error) {
func (pool *ConnPool) Get(token string) (*Session, error) {
pool.locker.Lock()
defer pool.locker.Unlock()

conn, ok := pool.conns[token]
session, ok := pool.sessions[token]
if !ok {
return nil, ErrSessionExpired
}
return conn, nil
return session, nil
}

func (pool *ConnPool) Put(conn *imapclient.Client) (token string, err error) {
func (pool *ConnPool) Put(imapConn *imapclient.Client, username, password string) (token string, err error) {
pool.locker.Lock()
defer pool.locker.Unlock()

@@ -51,22 +56,26 @@ func (pool *ConnPool) Put(conn *imapclient.Client) (token string, err error) {
var err error
token, err = generateToken()
if err != nil {
conn.Logout()
imapConn.Logout()
return "", err
}

if _, ok := pool.conns[token]; !ok {
if _, ok := pool.sessions[token]; !ok {
break
}
}

pool.conns[token] = conn
pool.sessions[token] = &Session{
imapConn: imapConn,
username: username,
password: password,
}

go func() {
<-conn.LoggedOut()
<-imapConn.LoggedOut()

pool.locker.Lock()
delete(pool.conns, token)
delete(pool.sessions, token)
pool.locker.Unlock()
}()



+ 6
- 2
server.go View File

@@ -93,6 +93,7 @@ func NewServer(imapURL, smtpURL string) (*Server, error) {
type context struct {
echo.Context
server *Server
session *Session
conn *imapclient.Client
}

@@ -126,7 +127,7 @@ func handleLogin(ectx echo.Context) error {
return ctx.Render(http.StatusOK, "login.html", nil)
}

token, err := ctx.server.imap.pool.Put(conn)
token, err := ctx.server.imap.pool.Put(conn, username, password)
if err != nil {
return fmt.Errorf("failed to put connection in pool: %v", err)
}
@@ -167,6 +168,8 @@ func handleGetPart(ctx *context, raw bool) error {
disp, dispParams, _ := part.Header.ContentDisposition()
filename := dispParams["filename"]

// TODO: set Content-Length if possible

if !strings.EqualFold(mimeType, "text/plain") || strings.EqualFold(disp, "attachment") {
dispParams := make(map[string]string)
if filename != "" {
@@ -235,13 +238,14 @@ func New(imapURL, smtpURL string) *echo.Echo {
return err
}

ctx.conn, err = ctx.server.imap.pool.Get(cookie.Value)
ctx.session, err = ctx.server.imap.pool.Get(cookie.Value)
if err == ErrSessionExpired {
ctx.setToken("")
return ctx.Redirect(http.StatusFound, "/login")
} else if err != nil {
return err
}
ctx.conn = ctx.session.imapConn

return next(ctx)
}


Loading…
Cancel
Save