diff options
author | Simon Ser <contact@emersion.fr> | 2019-12-11 15:24:39 +0100 |
---|---|---|
committer | Simon Ser <contact@emersion.fr> | 2019-12-11 15:24:39 +0100 |
commit | f07ab5263246d940fbc1d646bcdb5663398378d0 (patch) | |
tree | 3610a240635cbbac0932c359defd2962c05c3d75 | |
parent | 1b5bc568fb638314b62ea3d6635de56109680da9 (diff) | |
download | alps-f07ab5263246d940fbc1d646bcdb5663398378d0.tar.gz alps-f07ab5263246d940fbc1d646bcdb5663398378d0.zip |
Add docs
-rw-r--r-- | plugin.go | 7 | ||||
-rw-r--r-- | server.go | 8 | ||||
-rw-r--r-- | session.go | 11 | ||||
-rw-r--r-- | template.go | 4 |
4 files changed, 26 insertions, 4 deletions
@@ -8,10 +8,17 @@ import ( const pluginDir = "plugins" +// Plugin extends koushin with additional functionality. type Plugin interface { + // Name should return the plugin name. Name() string + // LoadTemplate populates t with the plugin's functions and templates. LoadTemplate(t *template.Template) error + // SetRoutes populates group with the plugin's routes. SetRoutes(group *echo.Group) + // Inject is called prior to rendering a template. It can extend the + // template data by setting new items in the Extra map. Inject(name string, data interface{}) error + // Close is called when the plugin is unloaded. Close() error } @@ -14,9 +14,10 @@ const cookieName = "koushin_session" const messagesPerPage = 50 +// Server holds all the koushin server state. type Server struct { Sessions *SessionManager - Plugins []Plugin + Plugins []Plugin imap struct { host string @@ -98,11 +99,13 @@ func newServer(imapURL, smtpURL string) (*Server, error) { type Context struct { echo.Context Server *Server - Session *Session + Session *Session // nil if user isn't logged in } var aLongTimeAgo = time.Unix(233431200, 0) +// SetSession sets a cookie for the provided session. Passing a nil session +// unsets the cookie. func (ctx *Context) SetSession(s *Session) { cookie := http.Cookie{ Name: cookieName, @@ -127,6 +130,7 @@ type Options struct { Theme string } +// New creates a new server. func New(e *echo.Echo, options *Options) error { s, err := newServer(options.IMAPURL, options.SMTPURL) if err != nil { @@ -23,8 +23,9 @@ func generateToken() (string, error) { return base64.URLEncoding.EncodeToString(b), nil } -var ErrSessionExpired = errors.New("session expired") +var errSessionExpired = errors.New("session expired") +// AuthError wraps an authentication error. type AuthError struct { cause error } @@ -33,6 +34,7 @@ func (err AuthError) Error() string { return fmt.Sprintf("authentication failed: %v", err.cause) } +// Session is an active user session. It may also hold an IMAP connection. type Session struct { manager *SessionManager username, password string @@ -49,6 +51,8 @@ func (s *Session) ping() { s.pings <- struct{}{} } +// Do executes an IMAP operation on this session. The IMAP client can only be +// used from inside f. func (s *Session) Do(f func(*imapclient.Client) error) error { s.locker.Lock() defer s.locker.Unlock() @@ -65,6 +69,7 @@ func (s *Session) Do(f func(*imapclient.Client) error) error { return f(s.imapConn) } +// Close destroys the session. This can be used to log the user out. func (s *Session) Close() { select { case <-s.closed: @@ -74,6 +79,8 @@ func (s *Session) Close() { } } +// SessionManager keeps track of active sessions. It connects and re-connects +// to the upstream IMAP server as necessary. It prunes expired sessions. type SessionManager struct { newIMAPClient func() (*imapclient.Client, error) @@ -113,6 +120,8 @@ func (sm *SessionManager) get(token string) (*Session, error) { return session, nil } +// Put connects to the IMAP server and creates a new session. If authentication +// fails, the error will be of type AuthError. func (sm *SessionManager) Put(username, password string) (*Session, error) { c, err := sm.connect(username, password) if err != nil { diff --git a/template.go b/template.go index 3bdcc9d..cdcbf66 100644 --- a/template.go +++ b/template.go @@ -21,6 +21,7 @@ type GlobalRenderData struct { Username string // TODO: list of mailboxes + // Additional plugin-specific data Extra map[string]interface{} } @@ -28,7 +29,8 @@ type GlobalRenderData struct { // template-specific fields. type RenderData struct { Global GlobalRenderData - Extra map[string]interface{} + // Additional plugin-specific data + Extra map[string]interface{} } func NewRenderData(ctx *Context) *RenderData { |