Skip to content

Commit

Permalink
Unit test fixes due to macaroon API change.
Browse files Browse the repository at this point in the history
  • Loading branch information
Veebers committed Apr 6, 2018
1 parent e7a1ace commit 7515a16
Show file tree
Hide file tree
Showing 38 changed files with 234 additions and 115 deletions.
1 change: 1 addition & 0 deletions api/apiclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,7 @@ func (st *state) connectStream(path string, attrs url.Values, extraHeaders http.
if resp.Header.Get("Content-Type") == "application/json" {
var result params.ErrorResult
jsonErr := json.Unmarshal(body, &result)
// Here we find that the body is truncated.
if jsonErr != nil {
return nil, errors.Annotate(jsonErr, "reading error response")
}
Expand Down
65 changes: 33 additions & 32 deletions api/crossmodelrelations/crossmodelrelations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (

"github.com/juju/juju/api/base/testing"
"github.com/juju/juju/api/crossmodelrelations"
apitesting "github.com/juju/juju/api/testing"
"github.com/juju/juju/apiserver/params"
coretesting "github.com/juju/juju/testing"
)
Expand Down Expand Up @@ -143,13 +144,13 @@ func (s *CrossModelRelationsSuite) TestPublishRelationChangeDischargeRequired(c
c.Check(callCount, gc.Equals, 2)
c.Check(err, jc.ErrorIsNil)
c.Check(dischargeMac, gc.HasLen, 2)
c.Assert(dischargeMac[0], jc.DeepEquals, mac)
c.Assert(dischargeMac[1].Id(), gc.Equals, "discharge mac")
apitesting.MacaroonEquals(c, dischargeMac[0], mac)
c.Assert(dischargeMac[1].Id(), jc.DeepEquals, []byte("discharge mac"))
// Macaroon has been cached.
ms, ok := s.cache.Get("token")
c.Assert(ok, jc.IsTrue)
c.Assert(ms[0], jc.DeepEquals, mac)
c.Assert(ms[1].Id(), gc.Equals, "discharge mac")
apitesting.MacaroonEquals(c, ms[0], mac)
c.Assert(ms[1].Id(), jc.DeepEquals, []byte("discharge mac"))
}

func (s *CrossModelRelationsSuite) TestRegisterRemoteRelations(c *gc.C) {
Expand Down Expand Up @@ -252,13 +253,13 @@ func (s *CrossModelRelationsSuite) TestRegisterRemoteRelationDischargeRequired(c
c.Assert(result, gc.HasLen, 1)
c.Check(result[0].Error, gc.IsNil)
c.Check(dischargeMac, gc.HasLen, 2)
c.Assert(dischargeMac[0], jc.DeepEquals, mac)
c.Assert(dischargeMac[1].Id(), gc.Equals, "discharge mac")
apitesting.MacaroonEquals(c, dischargeMac[0], mac)
c.Assert(dischargeMac[1].Id(), jc.DeepEquals, []byte("discharge mac"))
// Macaroon has been cached.
ms, ok := s.cache.Get("token")
c.Assert(ok, jc.IsTrue)
c.Assert(ms[0], jc.DeepEquals, mac)
c.Assert(ms[1].Id(), gc.Equals, "discharge mac")
apitesting.MacaroonEquals(c, ms[0], mac)
c.Assert(ms[1].Id(), jc.DeepEquals, []byte("discharge mac"))
}

func (s *CrossModelRelationsSuite) TestWatchRelationUnits(c *gc.C) {
Expand Down Expand Up @@ -338,13 +339,13 @@ func (s *CrossModelRelationsSuite) TestWatchRelationUnitsDischargeRequired(c *gc
c.Check(callCount, gc.Equals, 2)
c.Check(err, jc.ErrorIsNil)
c.Assert(dischargeMac, gc.HasLen, 2)
c.Assert(dischargeMac[0], jc.DeepEquals, mac)
c.Assert(dischargeMac[1].Id(), gc.Equals, "discharge mac")
apitesting.MacaroonEquals(c, dischargeMac[0], mac)
c.Assert(dischargeMac[1].Id(), jc.DeepEquals, []byte("discharge mac"))
// Macaroon has been cached.
ms, ok := s.cache.Get("token")
c.Assert(ok, jc.IsTrue)
c.Assert(ms[0], jc.DeepEquals, mac)
c.Assert(ms[1].Id(), gc.Equals, "discharge mac")
apitesting.MacaroonEquals(c, ms[0], mac)
c.Assert(ms[1].Id(), jc.DeepEquals, []byte("discharge mac"))
}

func (s *CrossModelRelationsSuite) TestRelationUnitSettings(c *gc.C) {
Expand Down Expand Up @@ -424,13 +425,13 @@ func (s *CrossModelRelationsSuite) TestRelationUnitSettingsDischargeRequired(c *
c.Assert(result, gc.HasLen, 1)
c.Check(result[0].Error, gc.IsNil)
c.Check(dischargeMac, gc.HasLen, 2)
c.Assert(dischargeMac[0], jc.DeepEquals, mac)
c.Assert(dischargeMac[1].Id(), gc.Equals, "discharge mac")
apitesting.MacaroonEquals(c, dischargeMac[0], mac)
c.Assert(dischargeMac[1].Id(), jc.DeepEquals, []byte("discharge mac"))
// Macaroon has been cached.
ms, ok := s.cache.Get("token")
c.Assert(ok, jc.IsTrue)
c.Assert(ms[0], jc.DeepEquals, mac)
c.Assert(ms[1].Id(), gc.Equals, "discharge mac")
apitesting.MacaroonEquals(c, ms[0], mac)
c.Assert(ms[1].Id(), jc.DeepEquals, []byte("discharge mac"))
}

func (s *CrossModelRelationsSuite) TestWatchRelationStatus(c *gc.C) {
Expand Down Expand Up @@ -510,13 +511,13 @@ func (s *CrossModelRelationsSuite) TestWatchRelationStatusDischargeRequired(c *g
c.Check(callCount, gc.Equals, 2)
c.Check(err, jc.ErrorIsNil)
c.Assert(dischargeMac, gc.HasLen, 2)
c.Assert(dischargeMac[0], jc.DeepEquals, mac)
c.Assert(dischargeMac[1].Id(), gc.Equals, "discharge mac")
apitesting.MacaroonEquals(c, dischargeMac[0], mac)
c.Assert(dischargeMac[1].Id(), jc.DeepEquals, []byte("discharge mac"))
// Macaroon has been cached.
ms, ok := s.cache.Get("token")
c.Assert(ok, jc.IsTrue)
c.Assert(ms[0], jc.DeepEquals, mac)
c.Assert(ms[1].Id(), gc.Equals, "discharge mac")
apitesting.MacaroonEquals(c, ms[0], mac)
c.Assert(ms[1].Id(), jc.DeepEquals, []byte("discharge mac"))
}

func (s *CrossModelRelationsSuite) TestPublishIngressNetworkChange(c *gc.C) {
Expand Down Expand Up @@ -594,13 +595,13 @@ func (s *CrossModelRelationsSuite) TestPublishIngressNetworkChangeDischargeRequi
c.Check(callCount, gc.Equals, 2)
c.Check(err, jc.ErrorIsNil)
c.Check(dischargeMac, gc.HasLen, 2)
c.Assert(dischargeMac[0], jc.DeepEquals, mac)
c.Assert(dischargeMac[1].Id(), gc.Equals, "discharge mac")
apitesting.MacaroonEquals(c, dischargeMac[0], mac)
c.Assert(dischargeMac[1].Id(), jc.DeepEquals, []byte("discharge mac"))
// Macaroon has been cached.
ms, ok := s.cache.Get("token")
c.Assert(ok, jc.IsTrue)
c.Assert(ms[0], jc.DeepEquals, mac)
c.Assert(ms[1].Id(), gc.Equals, "discharge mac")
apitesting.MacaroonEquals(c, ms[0], mac)
c.Assert(ms[1].Id(), jc.DeepEquals, []byte("discharge mac"))
}

func (s *CrossModelRelationsSuite) TestWatchEgressAddressesForRelation(c *gc.C) {
Expand Down Expand Up @@ -678,13 +679,13 @@ func (s *CrossModelRelationsSuite) TestWatchEgressAddressesForRelationDischargeR
c.Check(callCount, gc.Equals, 2)
c.Check(err, jc.ErrorIsNil)
c.Assert(dischargeMac, gc.HasLen, 2)
c.Assert(dischargeMac[0], jc.DeepEquals, mac)
c.Assert(dischargeMac[1].Id(), gc.Equals, "discharge mac")
apitesting.MacaroonEquals(c, dischargeMac[0], mac)
c.Assert(dischargeMac[1].Id(), jc.DeepEquals, []byte("discharge mac"))
// Macaroon has been cached.
ms, ok := s.cache.Get("token")
c.Assert(ok, jc.IsTrue)
c.Assert(ms[0], jc.DeepEquals, mac)
c.Assert(ms[1].Id(), gc.Equals, "discharge mac")
apitesting.MacaroonEquals(c, ms[0], mac)
c.Assert(ms[1].Id(), jc.DeepEquals, []byte("discharge mac"))
}

func (s *CrossModelRelationsSuite) TestWatchOfferStatus(c *gc.C) {
Expand Down Expand Up @@ -764,11 +765,11 @@ func (s *CrossModelRelationsSuite) TestWatchOfferStatusDischargeRequired(c *gc.C
c.Check(callCount, gc.Equals, 2)
c.Check(err, jc.ErrorIsNil)
c.Assert(dischargeMac, gc.HasLen, 2)
c.Assert(dischargeMac[0], jc.DeepEquals, mac)
c.Assert(dischargeMac[1].Id(), gc.Equals, "discharge mac")
apitesting.MacaroonEquals(c, dischargeMac[0], mac)
c.Assert(dischargeMac[1].Id(), jc.DeepEquals, []byte("discharge mac"))
// Macaroon has been cached.
ms, ok := s.cache.Get("offer-uuid")
c.Assert(ok, jc.IsTrue)
c.Assert(ms[0], jc.DeepEquals, mac)
c.Assert(ms[1].Id(), gc.Equals, "discharge mac")
apitesting.MacaroonEquals(c, ms[0], mac)
c.Assert(ms[1].Id(), jc.DeepEquals, []byte("discharge mac"))
}
3 changes: 2 additions & 1 deletion api/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"gopkg.in/macaroon.v2-unstable"

"github.com/juju/juju/api"
apitesting "github.com/juju/juju/api/testing"
"github.com/juju/juju/apiserver/params"
jujutesting "github.com/juju/juju/juju/testing"
"github.com/juju/juju/state"
Expand Down Expand Up @@ -249,7 +250,7 @@ func (s *httpSuite) TestAuthHTTPRequest(c *gc.C) {
req = s.authHTTPRequest(c, apiInfo)
c.Assert(req.Header.Get(params.MachineNonceHeader), gc.Equals, "foo")
macaroons := httpbakery.RequestMacaroons(req)
c.Assert(macaroons, jc.DeepEquals, apiInfo.Macaroons)
apitesting.MacaroonsEqual(c, macaroons, apiInfo.Macaroons)
}

func (s *httpSuite) authHTTPRequest(c *gc.C, info *api.Info) *http.Request {
Expand Down
8 changes: 7 additions & 1 deletion api/migrationmaster/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/juju/juju/api/base"
apitesting "github.com/juju/juju/api/base/testing"
"github.com/juju/juju/api/migrationmaster"
macapitesting "github.com/juju/juju/api/testing"
"github.com/juju/juju/apiserver/params"
"github.com/juju/juju/core/migration"
"github.com/juju/juju/resource"
Expand Down Expand Up @@ -103,6 +104,11 @@ func (s *ClientSuite) TestMigrationStatus(c *gc.C) {
client := migrationmaster.NewClient(apiCaller, nil)
status, err := client.MigrationStatus()
c.Assert(err, jc.ErrorIsNil)
// Extract macaroons so we can compare them separately
// (as they can't be compared using DeepEquals due to 'UnmarshaledAs')
statusMacs := status.TargetInfo.Macaroons
status.TargetInfo.Macaroons = nil
macapitesting.MacaroonEquals(c, statusMacs[0][0], mac)
c.Assert(status, gc.DeepEquals, migration.MigrationStatus{
MigrationId: "id",
ModelUUID: modelUUID,
Expand All @@ -114,7 +120,7 @@ func (s *ClientSuite) TestMigrationStatus(c *gc.C) {
CACert: "cert",
AuthTag: names.NewUserTag("admin"),
Password: "secret",
Macaroons: macs,
// Macaroons: macs,
},
})
}
Expand Down
24 changes: 24 additions & 0 deletions api/testing/macaroonsuite.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,27 @@ func (jar *ClearableCookieJar) Cookies(u *url.URL) []*http.Cookie {
func (jar *ClearableCookieJar) SetCookies(u *url.URL, cookies []*http.Cookie) {
jar.jar.SetCookies(u, cookies)
}

func MacaroonsEqual(c *gc.C, ms1, ms2 []macaroon.Slice) error {
if len(ms1) != len(ms2) {
return errors.Errorf("length mismatch, %d vs %d", len(ms1), len(ms2))
}

for i := 0; i < len(ms1); i++ {
m1 := ms1[i]
m2 := ms2[i]
if len(m1) != len(m2) {
return errors.Errorf("length mismatch, %d vs %d", len(m1), len(m2))
}
for i := 0; i < len(m1); i++ {
MacaroonEquals(c, m1[i], m2[i])
}
}
return nil
}

func MacaroonEquals(c *gc.C, m1, m2 *macaroon.Macaroon) {
c.Assert(m1.Id(), jc.DeepEquals, m2.Id())
c.Assert(m1.Signature(), jc.DeepEquals, m2.Signature())
c.Assert(m1.Location(), jc.DeepEquals, m2.Location())
}
10 changes: 6 additions & 4 deletions apiserver/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -687,11 +687,13 @@ func (srv *Server) endpoints() []apihttp.Endpoint {
pattern: "/gui-version",
handler: guiVersionHandler,
}, {
pattern: localOfferAccessLocationPath + "/discharge",
handler: appOfferDischargeMux,
pattern: localOfferAccessLocationPath + "/discharge",
handler: appOfferDischargeMux,
unauthenticated: true,
}, {
pattern: localOfferAccessLocationPath + "/publickey",
handler: appOfferDischargeMux,
pattern: localOfferAccessLocationPath + "/publickey",
handler: appOfferDischargeMux,
unauthenticated: true,
}}
if srv.registerIntrospectionHandlers != nil {
add := func(subpath string, h http.Handler) {
Expand Down
8 changes: 4 additions & 4 deletions apiserver/authentication/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ func (u *UserAuthenticator) authenticateMacaroons(
// The root keys for these macaroons are stored in MongoDB.
// Expire the documents after after a set amount of time.
expiryTime := u.Clock.Now().Add(localLoginExpiryTime)
service, err := u.Service.ExpireStorageAt(u.Clock.Now().Sub(expiryTime))
service, err := u.Service.ExpireStorageAfter(time.Until(expiryTime))
if err != nil {
return nil, errors.Trace(err)
}
Expand Down Expand Up @@ -300,12 +300,12 @@ type BakeryService interface {
}

// ExpirableStorageBakeryService extends BakeryService
// with the ExpireStorageAt method so that root keys are
// with the ExpireStorageAfter method so that root keys are
// removed from storage at that time.
type ExpirableStorageBakeryService interface {
BakeryService

// ExpireStorageAt returns a new ExpirableStorageBakeryService with
// ExpireStorageAfter returns a new ExpirableStorageBakeryService with
// a store that will expire items added to it at the specified time.
ExpireStorageAt(time.Duration) (ExpirableStorageBakeryService, error)
ExpireStorageAfter(time.Duration) (ExpirableStorageBakeryService, error)
}
12 changes: 6 additions & 6 deletions apiserver/authentication/user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ func (s *userAuthenticatorSuite) TestCreateLocalLoginMacaroon(c *gc.C) {
)
c.Assert(err, jc.ErrorIsNil)
service.CheckCallNames(c, "NewMacaroon")
service.CheckCall(c, 0, "NewMacaroon", "", []byte(nil), []checkers.Caveat{
service.CheckCall(c, 0, "NewMacaroon", []checkers.Caveat{
{Condition: "is-authenticated-user bobbrown"},
{Condition: "time-before 0001-01-01T00:02:00Z"},
})
Expand All @@ -196,11 +196,11 @@ func (s *userAuthenticatorSuite) TestAuthenticateLocalLoginMacaroon(c *gc.C) {
)
c.Assert(err, gc.FitsTypeOf, &common.DischargeRequiredError{})

service.CheckCallNames(c, "CheckAny", "ExpireStorageAt", "NewMacaroon")
service.CheckCallNames(c, "CheckAny", "ExpireStorageAfter", "NewMacaroon")
calls := service.Calls()
c.Assert(calls[1].Args, jc.DeepEquals, []interface{}{clock.Now().Add(24 * time.Hour)})
c.Assert(calls[1].Args, jc.DeepEquals, []interface{}{time.Until(clock.Now().Add(24 * time.Hour))})
c.Assert(calls[2].Args, jc.DeepEquals, []interface{}{
"", []byte(nil), []checkers.Caveat{
[]checkers.Caveat{
checkers.NeedDeclaredCaveat(
checkers.Caveat{
Location: "https://testing.invalid:1234/auth",
Expand Down Expand Up @@ -232,8 +232,8 @@ func (s *mockBakeryService) NewMacaroon(caveats []checkers.Caveat) (*macaroon.Ma
return &macaroon.Macaroon{}, s.NextErr()
}

func (s *mockBakeryService) ExpireStorageAt(t time.Duration) (authentication.ExpirableStorageBakeryService, error) {
s.MethodCall(s, "ExpireStorageAt", t)
func (s *mockBakeryService) ExpireStorageAfter(t time.Duration) (authentication.ExpirableStorageBakeryService, error) {
s.MethodCall(s, "ExpireStorageAfter", t)
return s, s.NextErr()
}

Expand Down
10 changes: 5 additions & 5 deletions apiserver/bakeryutil/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ package bakeryutil
import (
"time"

"gopkg.in/macaroon-bakery.v1/bakery"
"gopkg.in/macaroon-bakery.v2-unstable/bakery"

"github.com/juju/errors"
"github.com/juju/juju/apiserver/authentication"
Expand Down Expand Up @@ -51,17 +51,17 @@ func NewBakeryService(
}

// ExpirableStorageBakeryService wraps bakery.Service,
// adding the ExpireStorageAt method.
// adding the ExpireStorageAfter method.
type ExpirableStorageBakeryService struct {
*bakery.Service
Key *bakery.KeyPair
Store bakerystorage.ExpirableStorage
Locator bakery.PublicKeyLocator
}

// ExpireStorageAt implements authentication.ExpirableStorageBakeryService.
func (s *ExpirableStorageBakeryService) ExpireStorageAt(t time.Time) (authentication.ExpirableStorageBakeryService, error) {
store := s.Store.ExpireAt(t)
// ExpireStorageAfter implements authentication.ExpirableStorageBakeryService.
func (s *ExpirableStorageBakeryService) ExpireStorageAfter(t time.Duration) (authentication.ExpirableStorageBakeryService, error) {
store := s.Store.ExpireAfter(t)
service, err := bakery.NewService(bakery.NewServiceParams{
Location: s.Location(),
Store: store,
Expand Down
6 changes: 3 additions & 3 deletions apiserver/common/crossmodel/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ func (a *AuthContext) CreateConsumeOfferMacaroon(offer *params.ApplicationOfferD
return nil, errors.Trace(err)
}
expiryTime := a.clock.Now().Add(localOfferPermissionExpiryTime)
bakery, err := a.localOfferBakeryService.ExpireStorageAt(a.clock.Now().Sub(expiryTime))
bakery, err := a.localOfferBakeryService.ExpireStorageAfter(time.Until(expiryTime))
if err != nil {
return nil, errors.Trace(err)
}
Expand All @@ -224,7 +224,7 @@ func (a *AuthContext) CreateConsumeOfferMacaroon(offer *params.ApplicationOfferD
// CreateRemoteRelationMacaroon creates a macaroon that authorises access to the specified relation.
func (a *AuthContext) CreateRemoteRelationMacaroon(sourceModelUUID, offerUUID string, username string, rel names.Tag) (*macaroon.Macaroon, error) {
expiryTime := a.clock.Now().Add(localOfferPermissionExpiryTime)
bakery, err := a.localOfferBakeryService.ExpireStorageAt(a.clock.Now().Sub(expiryTime))
bakery, err := a.localOfferBakeryService.ExpireStorageAfter(time.Until(expiryTime))
if err != nil {
return nil, errors.Trace(err)
}
Expand Down Expand Up @@ -310,7 +310,7 @@ func (a *authenticator) checkMacaroons(mac macaroon.Slice, requiredValues map[st
return nil, errors.Trace(err)
}
expiryTime := a.ctxt.clock.Now().Add(localOfferPermissionExpiryTime)
bakery, err := a.bakery.ExpireStorageAt(a.ctxt.clock.Now().Sub(expiryTime))
bakery, err := a.bakery.ExpireStorageAfter(time.Until(expiryTime))
if err != nil {
return nil, errors.Trace(err)
}
Expand Down
14 changes: 7 additions & 7 deletions apiserver/common/crossmodel/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,9 @@ func (s *authSuite) TestCreateConsumeOfferMacaroon(c *gc.C) {
cav := mac.Caveats()
c.Assert(cav, gc.HasLen, 4)
c.Assert(bytes.HasPrefix(cav[0].Id, []byte("time-before")), jc.IsTrue)
c.Assert(cav[1].Id, gc.Equals, "declared source-model-uuid "+coretesting.ModelTag.Id())
c.Assert(cav[2].Id, gc.Equals, "declared offer-uuid mysql-uuid")
c.Assert(cav[3].Id, gc.Equals, "declared username mary")
c.Assert(cav[1].Id, jc.DeepEquals, []byte("declared source-model-uuid "+coretesting.ModelTag.Id()))
c.Assert(cav[2].Id, jc.DeepEquals, []byte("declared offer-uuid mysql-uuid"))
c.Assert(cav[3].Id, jc.DeepEquals, []byte("declared username mary"))
}

func (s *authSuite) TestCreateRemoteRelationMacaroon(c *gc.C) {
Expand All @@ -225,10 +225,10 @@ func (s *authSuite) TestCreateRemoteRelationMacaroon(c *gc.C) {
cav := mac.Caveats()
c.Assert(cav, gc.HasLen, 5)
c.Assert(bytes.HasPrefix(cav[0].Id, []byte("time-before")), jc.IsTrue)
c.Assert(cav[1].Id, gc.Equals, "declared source-model-uuid "+coretesting.ModelTag.Id())
c.Assert(cav[2].Id, gc.Equals, "declared offer-uuid mysql-uuid")
c.Assert(cav[3].Id, gc.Equals, "declared username mary")
c.Assert(cav[4].Id, gc.Equals, "declared relation-key mediawiki:db mysql:server")
c.Assert(cav[1].Id, jc.DeepEquals, []byte("declared source-model-uuid "+coretesting.ModelTag.Id()))
c.Assert(cav[2].Id, jc.DeepEquals, []byte("declared offer-uuid mysql-uuid"))
c.Assert(cav[3].Id, jc.DeepEquals, []byte("declared username mary"))
c.Assert(cav[4].Id, jc.DeepEquals, []byte("declared relation-key mediawiki:db mysql:server"))
}

func (s *authSuite) TestCheckOfferMacaroons(c *gc.C) {
Expand Down
Loading

0 comments on commit 7515a16

Please sign in to comment.