func (s *CharmSuite) SetUpTest(c *gc.C) { db := s.jcSuite.Session.DB("juju-testing") params := charmstore.ServerParams{ AuthUsername: "******", AuthPassword: "******", } handler, err := charmstore.NewServer(db, nil, "", params, charmstore.V4) c.Assert(err, jc.ErrorIsNil) s.Handler = handler s.Server = httptest.NewServer(handler) s.Client = csclient.New(csclient.Params{ URL: s.Server.URL, User: params.AuthUsername, Password: params.AuthPassword, }) urls := map[string]string{ "mysql": "quantal/mysql-23", "dummy": "quantal/dummy-24", "riak": "quantal/riak-25", "wordpress": "quantal/wordpress-26", "logging": "quantal/logging-27", } for name, url := range urls { testcharms.UploadCharm(c, s.Client, url, name) } s.jcSuite.PatchValue(&charmrepo.CacheDir, c.MkDir()) // Patch the charm repo initializer function: it is replaced with a charm // store repo pointing to the testing server. s.jcSuite.PatchValue(&charmrevisionupdater.NewCharmStore, func(p charmrepo.NewCharmStoreParams) charmrepo.Interface { p.URL = s.Server.URL return charmrepo.NewCharmStore(p) }) s.charms = make(map[string]*state.Charm) }
func (s *charmStoreSuite) SetUpTest(c *gc.C) { s.JujuConnSuite.SetUpTest(c) // Set up the third party discharger. s.discharger = bakerytest.NewDischarger(nil, func(req *http.Request, cond string, arg string) ([]checkers.Caveat, error) { cookie, err := req.Cookie(clientUserCookie) if err != nil { return nil, errors.Annotate(err, "discharge denied to non-clients") } return []checkers.Caveat{ checkers.DeclaredCaveat("username", cookie.Value), }, nil }) // Set up the charm store testing server. db := s.Session.DB("juju-testing") params := charmstore.ServerParams{ AuthUsername: "******", AuthPassword: "******", IdentityLocation: s.discharger.Location(), PublicKeyLocator: s.discharger, } handler, err := charmstore.NewServer(db, nil, "", params, charmstore.V4) c.Assert(err, jc.ErrorIsNil) s.handler = handler s.srv = httptest.NewServer(handler) s.client = csclient.New(csclient.Params{ URL: s.srv.URL, User: params.AuthUsername, Password: params.AuthPassword, }) // Initialize the charm cache dir. s.PatchValue(&charmrepo.CacheDir, c.MkDir()) // Point the CLI to the charm store testing server. original := newCharmStoreClient s.PatchValue(&newCharmStoreClient, func() (*csClient, error) { csclient, err := original() if err != nil { return nil, err } csclient.params.URL = s.srv.URL // Add a cookie so that the discharger can detect whether the // HTTP client is the juju environment or the juju client. lurl, err := url.Parse(s.discharger.Location()) if err != nil { panic(err) } csclient.params.HTTPClient.Jar.SetCookies(lurl, []*http.Cookie{{ Name: clientUserCookie, Value: clientUserName, }}) return csclient, nil }) // Point the Juju API server to the charm store testing server. s.PatchValue(&csclient.ServerURL, s.srv.URL) }
// authorize acquires and return the charm store delegatable macaroon to be // used to add the charm corresponding to the given URL. // The macaroon is properly attenuated so that it can only be used to deploy // the given charm URL. func (c *csClient) authorize(curl *charm.URL) (*macaroon.Macaroon, error) { client := csclient.New(csclient.Params{ URL: c.params.URL, HTTPClient: c.params.HTTPClient, VisitWebPage: c.params.VisitWebPage, }) var m *macaroon.Macaroon if err := client.Get("/delegatable-macaroon", &m); err != nil { return nil, errors.Trace(err) } if err := m.AddFirstPartyCaveat("is-entity " + curl.String()); err != nil { return nil, errors.Trace(err) } return m, nil }
func (s *serviceSuite) TestAddCharmWithAuthorization(c *gc.C) { // Upload a new charm to the charm store. curl, _ := s.UploadCharm(c, "cs:~restricted/precise/wordpress-3", "wordpress") // Change permissions on the new charm such that only bob // can read from it. s.DischargeUser = "******" err := s.Client.Put("/"+curl.Path()+"/meta/perm/read", []string{"bob"}) c.Assert(err, jc.ErrorIsNil) // Try to add a charm to the environment without authorization. s.DischargeUser = "" err = s.APIState.Client().AddCharm(curl) c.Assert(err, gc.ErrorMatches, `cannot retrieve charm "cs:~restricted/precise/wordpress-3": cannot get archive: cannot get discharge from "https://.*": third party refused discharge: cannot discharge: discharge denied`) tryAs := func(user string) error { client := csclient.New(csclient.Params{ URL: s.Srv.URL, }) s.DischargeUser = user var m *macaroon.Macaroon err = client.Get("/delegatable-macaroon", &m) c.Assert(err, gc.IsNil) return service.AddCharmWithAuthorization(s.State, params.AddCharmWithAuthorization{URL: curl.String()}) } // Try again with authorization for the wrong user. err = tryAs("joe") c.Assert(err, gc.ErrorMatches, `cannot retrieve charm "cs:~restricted/precise/wordpress-3": cannot get archive: unauthorized: access denied for user "joe"`) // Try again with the correct authorization this time. err = tryAs("bob") c.Assert(err, gc.IsNil) // Verify that it has actually been uploaded. _, err = s.State.Charm(curl) c.Assert(err, gc.IsNil) }