aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Ser <contact@emersion.fr>2019-12-11 15:24:39 +0100
committerSimon Ser <contact@emersion.fr>2019-12-11 15:24:39 +0100
commitf07ab5263246d940fbc1d646bcdb5663398378d0 (patch)
tree3610a240635cbbac0932c359defd2962c05c3d75
parent1b5bc568fb638314b62ea3d6635de56109680da9 (diff)
downloadalps-f07ab5263246d940fbc1d646bcdb5663398378d0.tar.gz
alps-f07ab5263246d940fbc1d646bcdb5663398378d0.zip
Add docs
-rw-r--r--plugin.go7
-rw-r--r--server.go8
-rw-r--r--session.go11
-rw-r--r--template.go4
4 files changed, 26 insertions, 4 deletions
diff --git a/plugin.go b/plugin.go
index 73f3962..aa964ec 100644
--- a/plugin.go
+++ b/plugin.go
@@ -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
}
diff --git a/server.go b/server.go
index 44392a0..1c9ca73 100644
--- a/server.go
+++ b/server.go
@@ -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 {
diff --git a/session.go b/session.go
index e4e2eb0..1f536eb 100644
--- a/session.go
+++ b/session.go
@@ -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 {