diff --git a/csclient/csclient.go b/csclient/csclient.go index 4ec73dd..6de8bf5 100644 --- a/csclient/csclient.go +++ b/csclient/csclient.go @@ -20,6 +20,7 @@ import ( "gopkg.in/errgo.v1" "gopkg.in/juju/charm.v6-unstable" "gopkg.in/macaroon-bakery.v1/httpbakery" + "gopkg.in/macaroon.v1" "gopkg.in/juju/charmrepo.v2-unstable/csclient/params" ) @@ -73,6 +74,10 @@ type Params struct { // If nil, no interaction will be allowed. This field // is ignored if BakeryClient is provided. VisitWebPage func(url *url.URL) error + + // Auth holds a list of macaroons that will be added to the cookie jar of + // the HTTP Client that is used by this client. + Auth macaroon.Slice } type httpClient interface { @@ -94,6 +99,15 @@ func New(p Params) *Client { VisitWebPage: p.VisitWebPage, } } + if len(p.Auth) > 0 { + url, err := url.Parse(p.URL) + // A non-nil error here will get caught at request time when we try + // to parse the URL, and without a valid URL, the macaroons don't matter + // anyway. + if err == nil { + httpbakery.SetCookie(bclient.Jar, url, p.Auth) + } + } return &Client{ bclient: bclient, params: p, diff --git a/csclient/csclient_resources_test.go b/csclient/csclient_resources_test.go index b796cd5..64f367c 100644 --- a/csclient/csclient_resources_test.go +++ b/csclient/csclient_resources_test.go @@ -9,6 +9,7 @@ import ( "io" "io/ioutil" "net/http" + "net/url" "strings" "github.com/juju/testing" @@ -16,6 +17,8 @@ import ( gc "gopkg.in/check.v1" "gopkg.in/juju/charm.v6-unstable" "gopkg.in/juju/charm.v6-unstable/resource" + "gopkg.in/macaroon-bakery.v1/httpbakery" + "gopkg.in/macaroon.v1" "gopkg.in/juju/charmrepo.v2-unstable/csclient/params" ) @@ -160,6 +163,26 @@ func (ResourceSuite) TestResourceMeta(c *gc.C) { c.Assert(resdata, gc.DeepEquals, result) } +type InternalSuite struct{} + +var _ = gc.Suite(InternalSuite{}) + +func (s InternalSuite) TestMacaroon(c *gc.C) { + var m macaroon.Macaroon + macs := macaroon.Slice{&m} + client := New(Params{ + URL: "https://foo.com", + Auth: macs, + }) + u, err := url.Parse("https://foo.com") + c.Assert(err, jc.ErrorIsNil) + bc := client.bclient.(*httpbakery.Client) + cookies := bc.Jar.Cookies(u) + expected, err := httpbakery.NewCookie(macs) + c.Assert(err, jc.ErrorIsNil) + c.Assert(cookies, gc.DeepEquals, []*http.Cookie{expected}) +} + type fakeClient struct { *testing.Stub ReturnDoWithBody *http.Response