aboutsummaryrefslogtreecommitdiff
path: root/plugins/carddav
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/carddav')
-rw-r--r--plugins/carddav/carddav.go26
-rw-r--r--plugins/carddav/plugin.go48
-rw-r--r--plugins/carddav/routes.go7
3 files changed, 50 insertions, 31 deletions
diff --git a/plugins/carddav/carddav.go b/plugins/carddav/carddav.go
index 55c76b4..0c1a06d 100644
--- a/plugins/carddav/carddav.go
+++ b/plugins/carddav/carddav.go
@@ -21,32 +21,10 @@ func (rt *authRoundTripper) RoundTrip(req *http.Request) (*http.Response, error)
return rt.upstream.RoundTrip(req)
}
-func getAddressBook(u *url.URL, session *koushin.Session) (*carddav.Client, *carddav.AddressBook, error) {
+func newClient(u *url.URL, session *koushin.Session) (*carddav.Client, error) {
rt := authRoundTripper{
upstream: http.DefaultTransport,
session: session,
}
- c, err := carddav.NewClient(&http.Client{Transport: &rt}, u.String())
- if err != nil {
- return nil, nil, fmt.Errorf("failed to create CardDAV client: %v", err)
- }
-
- principal, err := c.FindCurrentUserPrincipal()
- if err != nil {
- return nil, nil, fmt.Errorf("failed to query CardDAV principal: %v", err)
- }
-
- addressBookHomeSet, err := c.FindAddressBookHomeSet(principal)
- if err != nil {
- return nil, nil, fmt.Errorf("failed to query CardDAV address book home set: %v", err)
- }
-
- addressBooks, err := c.FindAddressBooks(addressBookHomeSet)
- if err != nil {
- return nil, nil, fmt.Errorf("failed to query CardDAV address books: %v", err)
- }
- if len(addressBooks) == 0 {
- return nil, nil, errNoAddressBook
- }
- return c, &addressBooks[0], nil
+ return carddav.NewClient(&http.Client{Transport: &rt}, u.String())
}
diff --git a/plugins/carddav/plugin.go b/plugins/carddav/plugin.go
index 99e5f62..a77762b 100644
--- a/plugins/carddav/plugin.go
+++ b/plugins/carddav/plugin.go
@@ -30,6 +30,44 @@ func sanityCheckURL(u *url.URL) error {
return nil
}
+type plugin struct {
+ koushin.GoPlugin
+ url *url.URL
+ homeSetCache map[string]string
+}
+
+func (p *plugin) clientWithAddressBook(session *koushin.Session) (*carddav.Client, *carddav.AddressBook, error) {
+ c, err := newClient(p.url, session)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to create CardDAV client: %v", err)
+ }
+
+ homeSet, ok := p.homeSetCache[session.Username()]
+ if !ok {
+ principal, err := c.FindCurrentUserPrincipal()
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to query CardDAV principal: %v", err)
+ }
+
+ homeSet, err = c.FindAddressBookHomeSet(principal)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to query CardDAV address book home set: %v", err)
+ }
+
+ p.homeSetCache[session.Username()] = homeSet
+ // TODO: evict entries from the cache if it's getting too big
+ }
+
+ addressBooks, err := c.FindAddressBooks(homeSet)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to query CardDAV address books: %v", err)
+ }
+ if len(addressBooks) == 0 {
+ return nil, nil, errNoAddressBook
+ }
+ return c, &addressBooks[0], nil
+}
+
func newPlugin(srv *koushin.Server) (koushin.Plugin, error) {
u, err := srv.Upstream("carddavs", "carddav+insecure", "https", "http+insecure")
if _, ok := err.(*koushin.NoUpstreamError); ok {
@@ -61,14 +99,18 @@ func newPlugin(srv *koushin.Server) (koushin.Plugin, error) {
srv.Logger().Printf("Configured upstream CardDAV server: %v", u)
- p := koushin.GoPlugin{Name: "carddav"}
+ p := &plugin{
+ GoPlugin: koushin.GoPlugin{Name: "carddav"},
+ url: u,
+ homeSetCache: make(map[string]string),
+ }
- registerRoutes(&p, u)
+ registerRoutes(p)
p.Inject("compose.html", func(ctx *koushin.Context, _data koushin.RenderData) error {
data := _data.(*koushinbase.ComposeRenderData)
- c, addressBook, err := getAddressBook(u, ctx.Session)
+ c, addressBook, err := p.clientWithAddressBook(ctx.Session)
if err == errNoAddressBook {
return nil
} else if err != nil {
diff --git a/plugins/carddav/routes.go b/plugins/carddav/routes.go
index 82b729e..2f33852 100644
--- a/plugins/carddav/routes.go
+++ b/plugins/carddav/routes.go
@@ -3,7 +3,6 @@ package koushincarddav
import (
"fmt"
"net/http"
- "net/url"
"git.sr.ht/~emersion/koushin"
"github.com/emersion/go-vcard"
@@ -22,11 +21,11 @@ type AddressObjectRenderData struct {
AddressObject *carddav.AddressObject
}
-func registerRoutes(p *koushin.GoPlugin, u *url.URL) {
+func registerRoutes(p *plugin) {
p.GET("/contacts", func(ctx *koushin.Context) error {
queryText := ctx.QueryParam("query")
- c, addressBook, err := getAddressBook(u, ctx.Session)
+ c, addressBook, err := p.clientWithAddressBook(ctx.Session)
if err != nil {
return err
}
@@ -70,7 +69,7 @@ func registerRoutes(p *koushin.GoPlugin, u *url.URL) {
p.GET("/contacts/:uid", func(ctx *koushin.Context) error {
uid := ctx.Param("uid")
- c, addressBook, err := getAddressBook(u, ctx.Session)
+ c, addressBook, err := p.clientWithAddressBook(ctx.Session)
if err != nil {
return err
}