Export Context
This allows plugins to access it.
This commit is contained in:
parent
ed7ea8df33
commit
d8f411176f
28
handlers.go
28
handlers.go
|
@ -25,7 +25,7 @@ type MailboxRenderData struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleGetMailbox(ectx echo.Context) error {
|
func handleGetMailbox(ectx echo.Context) error {
|
||||||
ctx := ectx.(*context)
|
ctx := ectx.(*Context)
|
||||||
|
|
||||||
mboxName, err := url.PathUnescape(ctx.Param("mbox"))
|
mboxName, err := url.PathUnescape(ctx.Param("mbox"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -43,7 +43,7 @@ func handleGetMailbox(ectx echo.Context) error {
|
||||||
var mailboxes []*imap.MailboxInfo
|
var mailboxes []*imap.MailboxInfo
|
||||||
var msgs []imapMessage
|
var msgs []imapMessage
|
||||||
var mbox *imap.MailboxStatus
|
var mbox *imap.MailboxStatus
|
||||||
err = ctx.session.Do(func(c *imapclient.Client) error {
|
err = ctx.Session.Do(func(c *imapclient.Client) error {
|
||||||
var err error
|
var err error
|
||||||
if mailboxes, err = listMailboxes(c); err != nil {
|
if mailboxes, err = listMailboxes(c); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -77,12 +77,12 @@ func handleGetMailbox(ectx echo.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleLogin(ectx echo.Context) error {
|
func handleLogin(ectx echo.Context) error {
|
||||||
ctx := ectx.(*context)
|
ctx := ectx.(*Context)
|
||||||
|
|
||||||
username := ctx.FormValue("username")
|
username := ctx.FormValue("username")
|
||||||
password := ctx.FormValue("password")
|
password := ctx.FormValue("password")
|
||||||
if username != "" && password != "" {
|
if username != "" && password != "" {
|
||||||
s, err := ctx.server.sessions.Put(username, password)
|
s, err := ctx.Server.sessions.Put(username, password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if _, ok := err.(AuthError); ok {
|
if _, ok := err.(AuthError); ok {
|
||||||
return ctx.Render(http.StatusOK, "login.html", nil)
|
return ctx.Render(http.StatusOK, "login.html", nil)
|
||||||
|
@ -98,9 +98,9 @@ func handleLogin(ectx echo.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleLogout(ectx echo.Context) error {
|
func handleLogout(ectx echo.Context) error {
|
||||||
ctx := ectx.(*context)
|
ctx := ectx.(*Context)
|
||||||
|
|
||||||
ctx.session.Close()
|
ctx.Session.Close()
|
||||||
ctx.setToken("")
|
ctx.setToken("")
|
||||||
return ctx.Redirect(http.StatusFound, "/login")
|
return ctx.Redirect(http.StatusFound, "/login")
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ type MessageRenderData struct {
|
||||||
MailboxPage int
|
MailboxPage int
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleGetPart(ctx *context, raw bool) error {
|
func handleGetPart(ctx *Context, raw bool) error {
|
||||||
mboxName, uid, err := parseMboxAndUid(ctx.Param("mbox"), ctx.Param("uid"))
|
mboxName, uid, err := parseMboxAndUid(ctx.Param("mbox"), ctx.Param("uid"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return echo.NewHTTPError(http.StatusBadRequest, err)
|
return echo.NewHTTPError(http.StatusBadRequest, err)
|
||||||
|
@ -128,7 +128,7 @@ func handleGetPart(ctx *context, raw bool) error {
|
||||||
var msg *imapMessage
|
var msg *imapMessage
|
||||||
var part *message.Entity
|
var part *message.Entity
|
||||||
var mbox *imap.MailboxStatus
|
var mbox *imap.MailboxStatus
|
||||||
err = ctx.session.Do(func(c *imapclient.Client) error {
|
err = ctx.Session.Do(func(c *imapclient.Client) error {
|
||||||
var err error
|
var err error
|
||||||
msg, part, err = getMessagePart(c, mboxName, uid, partPath)
|
msg, part, err = getMessagePart(c, mboxName, uid, partPath)
|
||||||
mbox = c.Mailbox()
|
mbox = c.Mailbox()
|
||||||
|
@ -188,11 +188,11 @@ type ComposeRenderData struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleCompose(ectx echo.Context) error {
|
func handleCompose(ectx echo.Context) error {
|
||||||
ctx := ectx.(*context)
|
ctx := ectx.(*Context)
|
||||||
|
|
||||||
var msg OutgoingMessage
|
var msg OutgoingMessage
|
||||||
if strings.ContainsRune(ctx.session.username, '@') {
|
if strings.ContainsRune(ctx.Session.username, '@') {
|
||||||
msg.From = ctx.session.username
|
msg.From = ctx.Session.username
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.Request().Method == http.MethodGet && ctx.Param("uid") != "" {
|
if ctx.Request().Method == http.MethodGet && ctx.Param("uid") != "" {
|
||||||
|
@ -208,7 +208,7 @@ func handleCompose(ectx echo.Context) error {
|
||||||
|
|
||||||
var inReplyTo *imapMessage
|
var inReplyTo *imapMessage
|
||||||
var part *message.Entity
|
var part *message.Entity
|
||||||
err = ctx.session.Do(func(c *imapclient.Client) error {
|
err = ctx.Session.Do(func(c *imapclient.Client) error {
|
||||||
var err error
|
var err error
|
||||||
inReplyTo, part, err = getMessagePart(c, mboxName, uid, partPath)
|
inReplyTo, part, err = getMessagePart(c, mboxName, uid, partPath)
|
||||||
return err
|
return err
|
||||||
|
@ -257,13 +257,13 @@ func handleCompose(ectx echo.Context) error {
|
||||||
msg.Text = ctx.FormValue("text")
|
msg.Text = ctx.FormValue("text")
|
||||||
msg.InReplyTo = ctx.FormValue("in_reply_to")
|
msg.InReplyTo = ctx.FormValue("in_reply_to")
|
||||||
|
|
||||||
c, err := ctx.server.connectSMTP()
|
c, err := ctx.Server.connectSMTP()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer c.Close()
|
defer c.Close()
|
||||||
|
|
||||||
auth := sasl.NewPlainClient("", ctx.session.username, ctx.session.password)
|
auth := sasl.NewPlainClient("", ctx.Session.username, ctx.Session.password)
|
||||||
if err := c.Auth(auth); err != nil {
|
if err := c.Auth(auth); err != nil {
|
||||||
return echo.NewHTTPError(http.StatusForbidden, err)
|
return echo.NewHTTPError(http.StatusForbidden, err)
|
||||||
}
|
}
|
||||||
|
|
23
server.go
23
server.go
|
@ -91,15 +91,20 @@ func newServer(imapURL, smtpURL string) (*Server, error) {
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type context struct {
|
// Context is the context used by HTTP handlers.
|
||||||
|
//
|
||||||
|
// Use a type assertion to get it from a echo.Context:
|
||||||
|
//
|
||||||
|
// ctx := ectx.(*koushin.Context)
|
||||||
|
type Context struct {
|
||||||
echo.Context
|
echo.Context
|
||||||
server *Server
|
Server *Server
|
||||||
session *Session
|
Session *Session
|
||||||
}
|
}
|
||||||
|
|
||||||
var aLongTimeAgo = time.Unix(233431200, 0)
|
var aLongTimeAgo = time.Unix(233431200, 0)
|
||||||
|
|
||||||
func (c *context) setToken(token string) {
|
func (c *Context) setToken(token string) {
|
||||||
cookie := http.Cookie{
|
cookie := http.Cookie{
|
||||||
Name: cookieName,
|
Name: cookieName,
|
||||||
Value: token,
|
Value: token,
|
||||||
|
@ -151,7 +156,7 @@ func New(e *echo.Echo, options *Options) error {
|
||||||
|
|
||||||
e.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
|
e.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return func(ectx echo.Context) error {
|
return func(ectx echo.Context) error {
|
||||||
ctx := &context{Context: ectx, server: s}
|
ctx := &Context{Context: ectx, Server: s}
|
||||||
ctx.Set("context", ctx)
|
ctx.Set("context", ctx)
|
||||||
|
|
||||||
cookie, err := ctx.Cookie(cookieName)
|
cookie, err := ctx.Cookie(cookieName)
|
||||||
|
@ -166,14 +171,14 @@ func New(e *echo.Echo, options *Options) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.session, err = ctx.server.sessions.Get(cookie.Value)
|
ctx.Session, err = ctx.Server.sessions.Get(cookie.Value)
|
||||||
if err == ErrSessionExpired {
|
if err == ErrSessionExpired {
|
||||||
ctx.setToken("")
|
ctx.setToken("")
|
||||||
return ctx.Redirect(http.StatusFound, "/login")
|
return ctx.Redirect(http.StatusFound, "/login")
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ctx.session.Ping()
|
ctx.Session.Ping()
|
||||||
|
|
||||||
return next(ctx)
|
return next(ctx)
|
||||||
}
|
}
|
||||||
|
@ -182,11 +187,11 @@ func New(e *echo.Echo, options *Options) error {
|
||||||
e.GET("/mailbox/:mbox", handleGetMailbox)
|
e.GET("/mailbox/:mbox", handleGetMailbox)
|
||||||
|
|
||||||
e.GET("/message/:mbox/:uid", func(ectx echo.Context) error {
|
e.GET("/message/:mbox/:uid", func(ectx echo.Context) error {
|
||||||
ctx := ectx.(*context)
|
ctx := ectx.(*Context)
|
||||||
return handleGetPart(ctx, false)
|
return handleGetPart(ctx, false)
|
||||||
})
|
})
|
||||||
e.GET("/message/:mbox/:uid/raw", func(ectx echo.Context) error {
|
e.GET("/message/:mbox/:uid/raw", func(ectx echo.Context) error {
|
||||||
ctx := ectx.(*context)
|
ctx := ectx.(*Context)
|
||||||
return handleGetPart(ctx, true)
|
return handleGetPart(ctx, true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
12
template.go
12
template.go
|
@ -31,12 +31,12 @@ type RenderData struct {
|
||||||
Extra map[string]interface{}
|
Extra map[string]interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRenderData(ctx *context) *RenderData {
|
func NewRenderData(ctx *Context) *RenderData {
|
||||||
global := GlobalRenderData{Extra: make(map[string]interface{})}
|
global := GlobalRenderData{Extra: make(map[string]interface{})}
|
||||||
|
|
||||||
if ctx.session != nil {
|
if ctx.Session != nil {
|
||||||
global.LoggedIn = true
|
global.LoggedIn = true
|
||||||
global.Username = ctx.session.username
|
global.Username = ctx.Session.username
|
||||||
}
|
}
|
||||||
|
|
||||||
return &RenderData{
|
return &RenderData{
|
||||||
|
@ -52,10 +52,10 @@ type renderer struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *renderer) Render(w io.Writer, name string, data interface{}, ectx echo.Context) error {
|
func (r *renderer) Render(w io.Writer, name string, data interface{}, ectx echo.Context) error {
|
||||||
// ectx is the raw *echo.context, not our own *context
|
// ectx is the raw *echo.context, not our own *Context
|
||||||
ctx := ectx.Get("context").(*context)
|
ctx := ectx.Get("context").(*Context)
|
||||||
|
|
||||||
for _, plugin := range ctx.server.plugins {
|
for _, plugin := range ctx.Server.plugins {
|
||||||
if err := plugin.Inject(name, data); err != nil {
|
if err := plugin.Inject(name, data); err != nil {
|
||||||
return fmt.Errorf("failed to run plugin '%v': %v", plugin.Name(), err)
|
return fmt.Errorf("failed to run plugin '%v': %v", plugin.Name(), err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue