alps

package module
v0.0.0-...-aaa30ea Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 22, 2020 License: MIT Imports: 26 Imported by: 0

README

alps

GoDoc builds.sr.ht status

A simple and extensible webmail.

Usage

Assuming SRV DNS records are properly set up (see RFC 6186):

go run ./cmd/alps example.org

To manually specify upstream servers:

go run ./cmd/alps imaps://mail.example.org:993 smtps://mail.example.org:465

Add -theme alps to use the alps theme. See docs/cli.md for more information.

When developing themes and plugins, the script contrib/hotreload.sh can be used to automatically reload alps on file changes.

Contributing

Send patches on the mailing list, report bugs on the issue tracker.

License

MIT

Documentation

Index

Constants

View Source
const PluginDir = "plugins"

PluginDir is the path to the plugins directory.

Variables

View Source
var ErrNoStoreEntry = fmt.Errorf("alps: no such entry in store")

ErrNoStoreEntry is returned by Store.Get when the entry doesn't exist.

Functions

func RegisterPluginLoader

func RegisterPluginLoader(f PluginLoaderFunc)

RegisterPluginLoader registers a plugin loader. The loader will be called on server start-up and reload.

Types

type AuthError

type AuthError struct {
	// contains filtered or unexported fields
}

AuthError wraps an authentication error.

func (AuthError) Error

func (err AuthError) Error() string

type BaseRenderData

type BaseRenderData struct {
	GlobalData GlobalRenderData
	// additional plugin-specific data
	Extra map[string]interface{}
}

BaseRenderData is the base type for templates. It should be extended with additional template-specific fields:

type MyRenderData struct {
    BaseRenderData
    // add additional fields here
}

func NewBaseRenderData

func NewBaseRenderData(ctx *Context) *BaseRenderData

NewBaseRenderData initializes a new BaseRenderData.

It can be used by routes to pre-fill the base data:

type MyRenderData struct {
    BaseRenderData
    // add additional fields here
}

data := &MyRenderData{
    BaseRenderData: *alps.NewBaseRenderData(ctx),
    // other fields...
}

func (*BaseRenderData) Global

func (brd *BaseRenderData) Global() *GlobalRenderData

Global implements RenderData.

func (*BaseRenderData) WithTitle

func (brd *BaseRenderData) WithTitle(title string) *BaseRenderData

type Context

type Context struct {
	echo.Context
	Server  *Server
	Session *Session // nil if user isn't logged in
}

Context is the context used by HTTP handlers.

Use a type assertion to get it from a echo.Context:

ctx := ectx.(*alps.Context)

func (*Context) GetLoginToken

func (ctx *Context) GetLoginToken() (string, string)

func (*Context) SetLoginToken

func (ctx *Context) SetLoginToken(username, password string)

func (*Context) SetSession

func (ctx *Context) SetSession(s *Session)

SetSession sets a cookie for the provided session. Passing a nil session unsets the cookie.

type DialIMAPFunc

type DialIMAPFunc func() (*imapclient.Client, error)

DialIMAPFunc connects to the upstream IMAP server.

type DialSMTPFunc

type DialSMTPFunc func() (*smtp.Client, error)

DialSMTPFunc connects to the upstream SMTP server.

type GlobalRenderData

type GlobalRenderData struct {
	Path []string
	URL  *url.URL

	LoggedIn bool

	// if logged in
	Username string

	Title string

	// additional plugin-specific data
	Extra map[string]interface{}
}

GlobalRenderData contains data available in all templates.

type GoPlugin

type GoPlugin struct {
	Name string
	// contains filtered or unexported fields
}

GoPlugin is a helper to create Go plugins.

Use this struct to define your plugin, then call RegisterPluginLoader:

p := GoPlugin{Name: "my-plugin"}
// Define routes, template functions, etc
alps.RegisterPluginLoader(p.Loader())

func (*GoPlugin) AddRoute

func (p *GoPlugin) AddRoute(method, path string, handler HandlerFunc)

AddRoute registers a new HTTP route.

func (*GoPlugin) DELETE

func (p *GoPlugin) DELETE(path string, handler HandlerFunc)

func (*GoPlugin) GET

func (p *GoPlugin) GET(path string, handler HandlerFunc)

func (*GoPlugin) Inject

func (p *GoPlugin) Inject(name string, f InjectFunc)

Inject registers a function to execute prior to rendering a template. The special name "*" matches any template.

func (*GoPlugin) Loader

func (p *GoPlugin) Loader() PluginLoaderFunc

Loader returns a loader function for this plugin.

func (*GoPlugin) POST

func (p *GoPlugin) POST(path string, handler HandlerFunc)

func (*GoPlugin) PUT

func (p *GoPlugin) PUT(path string, handler HandlerFunc)

func (*GoPlugin) Plugin

func (p *GoPlugin) Plugin() Plugin

Plugin returns an object implementing Plugin.

func (*GoPlugin) TemplateFuncs

func (p *GoPlugin) TemplateFuncs(funcs template.FuncMap)

TemplateFuncs registers new template functions.

type HandlerFunc

type HandlerFunc func(*Context) error

HandlerFunc is a function serving HTTP requests.

type InjectFunc

type InjectFunc func(ctx *Context, data RenderData) error

InjectFunc is a function that injects data prior to rendering a template.

type NoUpstreamError

type NoUpstreamError struct {
	// contains filtered or unexported fields
}

func (*NoUpstreamError) Error

func (err *NoUpstreamError) Error() string

type Options

type Options struct {
	Upstreams []string
	Theme     string
	Debug     bool
	LoginKey  *fernet.Key
}

type Plugin

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(ctx *Context, name string, data RenderData) error
	// Close is called when the plugin is unloaded.
	Close() error
}

Plugin extends alps with additional functionality.

type PluginLoaderFunc

type PluginLoaderFunc func(*Server) ([]Plugin, error)

PluginLoaderFunc loads plugins for the provided server.

type RenderData

type RenderData interface {
	// GlobalData returns a pointer to the global render data.
	Global() *GlobalRenderData
}

RenderData is implemented by template data structs. It can be used to inject additional data to all templates.

type Server

type Server struct {
	Sessions *SessionManager
	Options  *Options
	// contains filtered or unexported fields
}

Server holds all the alps server state.

func New

func New(e *echo.Echo, options *Options) (*Server, error)

New creates a new server.

func (*Server) Logger

func (s *Server) Logger() echo.Logger

Logger returns this server's logger.

func (*Server) Reload

func (s *Server) Reload() error

Reload loads Lua plugins and templates from disk.

func (*Server) Upstream

func (s *Server) Upstream(schemes ...string) (*url.URL, error)

Upstream retrieves the configured upstream server URL for the provided schemes. If no configured upstream server matches, a *NoUpstreamError is returned. An empty URL.Scheme means that the caller needs to perform auto-discovery with URL.Host.

type Session

type Session struct {
	// contains filtered or unexported fields
}

Session is an active user session. It may also hold an IMAP connection.

The session's password is not available to plugins. Plugins should use the session helpers to authenticate outgoing connections, for instance DoSMTP.

func (*Session) Close

func (s *Session) Close()

Close destroys the session. This can be used to log the user out.

func (*Session) DoIMAP

func (s *Session) DoIMAP(f func(*imapclient.Client) error) error

DoIMAP executes an IMAP operation on this session. The IMAP client can only be used from inside f.

func (*Session) DoSMTP

func (s *Session) DoSMTP(f func(*smtp.Client) error) error

DoSMTP executes an SMTP operation on this session. The SMTP client can only be used from inside f.

func (*Session) SetHTTPBasicAuth

func (s *Session) SetHTTPBasicAuth(req *http.Request)

SetHTTPBasicAuth adds an Authorization header field to the request with this session's credentials.

func (*Session) Store

func (s *Session) Store() Store

Store returns a store suitable for storing persistent user data.

func (*Session) Username

func (s *Session) Username() string

Username returns the session's username.

type SessionManager

type SessionManager struct {
	// contains filtered or unexported fields
}

SessionManager keeps track of active sessions. It connects and re-connects to the upstream IMAP server as necessary. It prunes expired sessions.

func (*SessionManager) Put

func (sm *SessionManager) Put(username, password string) (*Session, error)

Put connects to the IMAP server and creates a new session. If authentication fails, the error will be of type AuthError.

type Store

type Store interface {
	Get(key string, out interface{}) error
	Put(key string, v interface{}) error
}

Store allows storing per-user persistent data.

Store shouldn't be used from inside Session.DoIMAP.

Directories

Path Synopsis
cmd
docs
example-go-plugin
Package exampleplugin is an example Go plugin for alps.
Package exampleplugin is an example Go plugin for alps.
plugins
lua

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL