Gut the Session interface
This commit is contained in:
@@ -60,13 +60,13 @@ func (m *msa) Login(user, pass string) (smtp.User, error) {
|
|||||||
return nil, fmt.Errorf("Login failed")
|
return nil, fmt.Errorf("Login failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sid := atomic.AddUint64(&m.sid, uint64(1))
|
||||||
session := &Session{
|
session := &Session{
|
||||||
ID: atomic.AddUint64(&m.sid, uint64(1)),
|
ID: fmt.Sprintf("submission:%d", sid),
|
||||||
Account: account,
|
Handler: &sender{msa: m, account: account},
|
||||||
Handler: &Sender{},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Beginning submission session %d for %s", session.ID, user)
|
log.Printf("Beginning session %d for username=%s", session.ID, account.Username)
|
||||||
// FIXME: TODO: Track ongoing sessions for termination or notifications
|
// FIXME: TODO: Track ongoing sessions for termination or notifications
|
||||||
|
|
||||||
return session, nil
|
return session, nil
|
||||||
|
@@ -3,6 +3,7 @@ package smtp
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
@@ -58,14 +59,21 @@ func (m *mta) Login(user, pass string) (smtp.User, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *mta) AnonymousLogin() (smtp.User, error) {
|
func (m *mta) AnonymousLogin() (smtp.User, error) {
|
||||||
|
sid := atomic.AddUint64(&m.sid, uint64(1))
|
||||||
session := &Session{
|
session := &Session{
|
||||||
ID: atomic.AddUint64(&m.sid, uint64(1)),
|
ID: fmt.Sprintf("smtp:%d", sid),
|
||||||
Account: nil,
|
Handler: m,
|
||||||
Handler: &Receiver{},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Beginning SMTP session %d", session.ID)
|
log.Printf("Beginning session %d", session.ID)
|
||||||
// FIXME: TODO: Track ongoing sessions for termination or notifications
|
// FIXME: TODO: Track ongoing sessions for termination or notifications
|
||||||
|
|
||||||
return session, nil
|
return session, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// User implementation for go-smtp after this point
|
||||||
|
// Since only anonymous login is permitted, there's no need to introduce an
|
||||||
|
// intermediary to track the logged-in user.
|
||||||
|
func (m *mta) ServeSMTP(from string, to []string, r io.Reader) error {
|
||||||
|
return fmt.Errorf("Not yet implemented")
|
||||||
|
}
|
||||||
|
@@ -1,20 +0,0 @@
|
|||||||
package smtp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Receiver struct{}
|
|
||||||
|
|
||||||
func (r *Receiver) Name() string {
|
|
||||||
return "smtp-starttls"
|
|
||||||
}
|
|
||||||
|
|
||||||
// It seems odd to have a Receiver called Send, but what we're looking for is an
|
|
||||||
// attempt from an arbitrary source to send an email to known accounts.
|
|
||||||
//
|
|
||||||
// We might want to clean this interface
|
|
||||||
func (r *Receiver) Send(from string, to []string, reader io.Reader) error {
|
|
||||||
return fmt.Errorf("Not yet implemented")
|
|
||||||
}
|
|
@@ -3,19 +3,17 @@ package smtp
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"ur.gs/crockery/internal/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Sender struct{}
|
// Submission requires the sender to be logged in, so this struct tracks the
|
||||||
|
// logged-in account per-session
|
||||||
func (s *Sender) Name() string {
|
type sender struct {
|
||||||
return "submission-starttls"
|
msa *msa
|
||||||
|
account *store.Account
|
||||||
}
|
}
|
||||||
|
|
||||||
// We're looking for the email to be from a logged-in account, to anywhere
|
func (s *sender) ServeSMTP(from string, to []string, r io.Reader) error {
|
||||||
// on the internet - including locally!
|
|
||||||
//
|
|
||||||
// Should we handle local delivery differently to remote delivery, or connect
|
|
||||||
// to ourselves, i.e., from submission, to smtp?
|
|
||||||
func (s *Sender) Send(from string, to []string, reader io.Reader) error {
|
|
||||||
return fmt.Errorf("Not yet implemented")
|
return fmt.Errorf("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
@@ -5,19 +5,14 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"ur.gs/crockery/internal/store"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Handler interface {
|
type Handler interface {
|
||||||
Name() string
|
ServeSMTP(from string, to []string, r io.Reader) error
|
||||||
Send(from string, to []string, r io.Reader) error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// type Session implements the User interface for emersion/go-smtp
|
|
||||||
type Session struct {
|
type Session struct {
|
||||||
ID uint64
|
ID string
|
||||||
Account *store.Account
|
|
||||||
Handler Handler
|
Handler Handler
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,14 +23,14 @@ func (s *Session) Send(from string, to []string, r io.Reader) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("%s session %d for %s: from=%s, to=%s, r=<<EOF\n%s\nEOF", s.Handler.Name(), s.ID, s.Account.Username, from, to, string(data))
|
log.Printf("session=%d from=%s to=%s r=<<EOF\n%s\nEOF", s.ID, from, to, string(data))
|
||||||
|
|
||||||
memR := bytes.NewReader(data)
|
// TODO: a chain of middlewares here
|
||||||
return s.Handler.Send(from, to, memR)
|
return s.Handler.ServeSMTP(from, to, bytes.NewReader(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) Logout() error {
|
func (s *Session) Logout() error {
|
||||||
log.Printf("Ending %s session %d for %s", s.Handler.Name(), s.ID, s.Account.Username)
|
log.Printf("Ending session %d", s.ID)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user