diff --git a/plugins/base/imap.go b/plugins/base/imap.go index 1ffa774..5de5735 100755 --- a/plugins/base/imap.go +++ b/plugins/base/imap.go @@ -289,7 +289,7 @@ func searchCriteriaHeader(k, v string) *imap.SearchCriteria { } } -func searchCriteriaOr(criteria... *imap.SearchCriteria) *imap.SearchCriteria { +func searchCriteriaOr(criteria ...*imap.SearchCriteria) *imap.SearchCriteria { or := criteria[0] for _, c := range criteria[1:] { or = &imap.SearchCriteria{ diff --git a/plugins/carddav/carddav.go b/plugins/carddav/carddav.go new file mode 100644 index 0000000..55c76b4 --- /dev/null +++ b/plugins/carddav/carddav.go @@ -0,0 +1,52 @@ +package koushincarddav + +import ( + "fmt" + "net/http" + "net/url" + + "git.sr.ht/~emersion/koushin" + "github.com/emersion/go-webdav/carddav" +) + +var errNoAddressBook = fmt.Errorf("carddav: no address book found") + +type authRoundTripper struct { + upstream http.RoundTripper + session *koushin.Session +} + +func (rt *authRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + rt.session.SetHTTPBasicAuth(req) + return rt.upstream.RoundTrip(req) +} + +func getAddressBook(u *url.URL, session *koushin.Session) (*carddav.Client, *carddav.AddressBook, 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 +} diff --git a/plugins/carddav/plugin.go b/plugins/carddav/plugin.go index 317a0d0..99e5f62 100644 --- a/plugins/carddav/plugin.go +++ b/plugins/carddav/plugin.go @@ -30,20 +30,9 @@ func sanityCheckURL(u *url.URL) error { return nil } -type authRoundTripper struct { - upstream http.RoundTripper - session *koushin.Session -} - -func (rt *authRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { - rt.session.SetHTTPBasicAuth(req) - return rt.upstream.RoundTrip(req) -} - func newPlugin(srv *koushin.Server) (koushin.Plugin, error) { u, err := srv.Upstream("carddavs", "carddav+insecure", "https", "http+insecure") if _, ok := err.(*koushin.NoUpstreamError); ok { - srv.Logger().Print("carddav: no upstream server provided") return nil, nil } else if err != nil { return nil, fmt.Errorf("carddav: failed to parse upstream CardDAV server: %v", err) @@ -74,36 +63,17 @@ func newPlugin(srv *koushin.Server) (koushin.Plugin, error) { p := koushin.GoPlugin{Name: "carddav"} + registerRoutes(&p, u) + p.Inject("compose.html", func(ctx *koushin.Context, _data koushin.RenderData) error { data := _data.(*koushinbase.ComposeRenderData) - rt := authRoundTripper{ - upstream: http.DefaultTransport, - session: ctx.Session, - } - c, err := carddav.NewClient(&http.Client{Transport: &rt}, u.String()) - if err != nil { - return fmt.Errorf("failed to create CardDAV client: %v", err) - } - - principal, err := c.FindCurrentUserPrincipal() - if err != nil { - return fmt.Errorf("failed to query CardDAV principal: %v", err) - } - - addressBookHomeSet, err := c.FindAddressBookHomeSet(principal) - if err != nil { - return fmt.Errorf("failed to query CardDAV address book home set: %v", err) - } - - addressBooks, err := c.FindAddressBooks(addressBookHomeSet) - if err != nil { - return fmt.Errorf("failed to query CardDAV address books: %v", err) - } - if len(addressBooks) == 0 { + c, addressBook, err := getAddressBook(u, ctx.Session) + if err == errNoAddressBook { return nil + } else if err != nil { + return err } - addressBook := addressBooks[0] query := carddav.AddressBookQuery{ DataRequest: carddav.AddressDataRequest{ diff --git a/plugins/carddav/public/address-book.html b/plugins/carddav/public/address-book.html new file mode 100644 index 0000000..f521564 --- /dev/null +++ b/plugins/carddav/public/address-book.html @@ -0,0 +1,34 @@ +{{template "head.html"}} + +
+ Back +
+ +No contact.
+{{end}} + +{{template "foot.html"}} diff --git a/plugins/carddav/public/address-object.html b/plugins/carddav/public/address-object.html new file mode 100644 index 0000000..2c96fd4 --- /dev/null +++ b/plugins/carddav/public/address-object.html @@ -0,0 +1,22 @@ +{{template "head.html"}} + ++ Back +
+ +{{$fn := .AddressObject.Card.Value "FN"}} + +