github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/stateauthenticator/context_test.go (about) 1 // Copyright 2018 Canonical Ltd. All rights reserved. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package stateauthenticator_test 5 6 import ( 7 "net/http" 8 9 "github.com/juju/clock" 10 jc "github.com/juju/testing/checkers" 11 gc "gopkg.in/check.v1" 12 "gopkg.in/macaroon-bakery.v2-unstable/bakery" 13 "gopkg.in/macaroon-bakery.v2-unstable/bakery/checkers" 14 "gopkg.in/macaroon-bakery.v2-unstable/bakerytest" 15 "gopkg.in/macaroon-bakery.v2-unstable/httpbakery" 16 17 "github.com/juju/juju/apiserver/stateauthenticator" 18 "github.com/juju/juju/controller" 19 statetesting "github.com/juju/juju/state/testing" 20 ) 21 22 // TODO(babbageclunk): These have been extracted pretty mechanically 23 // from the API server tests as part of the apiserver/httpserver 24 // split. They should be updated to test via the public interface 25 // rather than the export_test functions. 26 27 type macaroonCommonSuite struct { 28 statetesting.StateSuite 29 discharger *bakerytest.Discharger 30 authenticator *stateauthenticator.Authenticator 31 } 32 33 func (s *macaroonCommonSuite) SetUpTest(c *gc.C) { 34 s.StateSuite.SetUpTest(c) 35 authenticator, err := stateauthenticator.NewAuthenticator(s.StatePool, clock.WallClock) 36 c.Assert(err, jc.ErrorIsNil) 37 s.authenticator = authenticator 38 } 39 40 func (s *macaroonCommonSuite) TearDownTest(c *gc.C) { 41 if s.discharger != nil { 42 s.discharger.Close() 43 } 44 s.StateSuite.TearDownTest(c) 45 } 46 47 type macaroonAuthSuite struct { 48 macaroonCommonSuite 49 } 50 51 var _ = gc.Suite(&macaroonAuthSuite{}) 52 53 func (s *macaroonAuthSuite) SetUpTest(c *gc.C) { 54 s.discharger = bakerytest.NewDischarger(nil, noCheck) 55 s.ControllerConfig = map[string]interface{}{ 56 controller.IdentityURL: s.discharger.Location(), 57 } 58 s.macaroonCommonSuite.SetUpTest(c) 59 } 60 61 func (s *macaroonAuthSuite) TestServerBakery(c *gc.C) { 62 m, err := stateauthenticator.ServerMacaroon(s.authenticator) 63 c.Assert(err, gc.IsNil) 64 bsvc, err := stateauthenticator.ServerBakeryService(s.authenticator) 65 c.Assert(err, gc.IsNil) 66 67 // Check that we can add a third party caveat addressed to the 68 // discharger, which indirectly ensures that the discharger's public 69 // key has been added to the bakery service's locator. 70 m = m.Clone() 71 err = bsvc.AddCaveat(m, checkers.Caveat{ 72 Location: s.discharger.Location(), 73 Condition: "true", 74 }) 75 c.Assert(err, jc.ErrorIsNil) 76 77 // Check that we can discharge the macaroon and check it with 78 // the service. 79 client := httpbakery.NewClient() 80 ms, err := client.DischargeAll(m) 81 c.Assert(err, jc.ErrorIsNil) 82 83 err = bsvc.(*bakery.Service).Check(ms, checkers.New()) 84 c.Assert(err, gc.IsNil) 85 } 86 87 func noCheck(_ *http.Request, _, _ string) ([]checkers.Caveat, error) { 88 return nil, nil 89 } 90 91 type macaroonAuthWrongPublicKeySuite struct { 92 macaroonCommonSuite 93 } 94 95 var _ = gc.Suite(&macaroonAuthWrongPublicKeySuite{}) 96 97 func (s *macaroonAuthWrongPublicKeySuite) SetUpTest(c *gc.C) { 98 s.discharger = bakerytest.NewDischarger(nil, noCheck) 99 wrongKey, err := bakery.GenerateKey() 100 c.Assert(err, gc.IsNil) 101 s.ControllerConfig = map[string]interface{}{ 102 controller.IdentityURL: s.discharger.Location(), 103 controller.IdentityPublicKey: wrongKey.Public.String(), 104 } 105 s.macaroonCommonSuite.SetUpTest(c) 106 } 107 108 func (s *macaroonAuthWrongPublicKeySuite) TearDownTest(c *gc.C) { 109 s.discharger.Close() 110 s.StateSuite.TearDownTest(c) 111 } 112 113 func (s *macaroonAuthWrongPublicKeySuite) TestDischargeFailsWithWrongPublicKey(c *gc.C) { 114 m, err := stateauthenticator.ServerMacaroon(s.authenticator) 115 c.Assert(err, gc.IsNil) 116 m = m.Clone() 117 bsvc, err := stateauthenticator.ServerBakeryService(s.authenticator) 118 c.Assert(err, gc.IsNil) 119 err = bsvc.AddCaveat(m, checkers.Caveat{ 120 Location: s.discharger.Location(), 121 Condition: "true", 122 }) 123 c.Assert(err, gc.IsNil) 124 client := httpbakery.NewClient() 125 126 _, err = client.DischargeAll(m) 127 c.Assert(err, gc.ErrorMatches, `cannot get discharge from ".*": third party refused discharge: cannot discharge: discharger cannot decode caveat id: public key mismatch`) 128 } 129 130 type macaroonNoURLSuite struct { 131 macaroonCommonSuite 132 } 133 134 var _ = gc.Suite(&macaroonNoURLSuite{}) 135 136 func (s *macaroonNoURLSuite) TestNoBakeryWhenNoIdentityURL(c *gc.C) { 137 // By default, when there is no identity location, no 138 // bakery service or macaroon is created. 139 _, err := stateauthenticator.ServerMacaroon(s.authenticator) 140 c.Assert(err, gc.ErrorMatches, "macaroon authentication is not configured") 141 _, err = stateauthenticator.ServerBakeryService(s.authenticator) 142 c.Assert(err, gc.ErrorMatches, "macaroon authentication is not configured") 143 }