Add docs
This commit is contained in:
parent
1b5bc568fb
commit
f07ab52632
4 changed files with 26 additions and 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 {
|
||||
|
|
11
session.go
11
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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue