コード例 #1
0
ファイル: csclient_test.go プロジェクト: jrwren/charmrepo
func (s *suite) TestMacaroonAuthorization(c *gc.C) {
	ch := charmRepo.CharmDir("wordpress")
	curl := charm.MustParseReference("~charmers/utopic/wordpress-42")
	purl := charm.MustParseReference("utopic/wordpress-42")
	err := s.client.UploadCharmWithRevision(curl, ch, 42)
	c.Assert(err, gc.IsNil)

	err = s.client.Put("/"+curl.Path()+"/meta/perm/read", []string{"bob"})
	c.Assert(err, gc.IsNil)

	// Create a client without basic auth credentials
	client := csclient.New(csclient.Params{
		URL: s.srv.URL,
	})

	var result struct{ IdRevision struct{ Revision int } }
	// TODO 2015-01-23: once supported, rewrite the test using POST requests.
	_, err = client.Meta(purl, &result)
	c.Assert(err, gc.ErrorMatches, `cannot get "/utopic/wordpress-42/meta/any\?include=id-revision": cannot get discharge from ".*": third party refused discharge: cannot discharge: no discharge`)
	c.Assert(httpbakery.IsDischargeError(errgo.Cause(err)), gc.Equals, true)

	s.discharge = func(cond, arg string) ([]checkers.Caveat, error) {
		return []checkers.Caveat{checkers.DeclaredCaveat("username", "bob")}, nil
	}
	_, err = client.Meta(curl, &result)
	c.Assert(err, gc.IsNil)
	c.Assert(result.IdRevision.Revision, gc.Equals, curl.Revision)

	visitURL := "http://0.1.2.3/visitURL"
	s.discharge = func(cond, arg string) ([]checkers.Caveat, error) {
		return nil, &httpbakery.Error{
			Code:    httpbakery.ErrInteractionRequired,
			Message: "interaction required",
			Info: &httpbakery.ErrorInfo{
				VisitURL: visitURL,
				WaitURL:  "http://0.1.2.3/waitURL",
			}}
	}

	client = csclient.New(csclient.Params{
		URL: s.srv.URL,
		VisitWebPage: func(vurl *neturl.URL) error {
			c.Check(vurl.String(), gc.Equals, visitURL)
			return fmt.Errorf("stopping interaction")
		}})

	_, err = client.Meta(purl, &result)
	c.Assert(err, gc.ErrorMatches, `cannot get "/utopic/wordpress-42/meta/any\?include=id-revision": cannot get discharge from ".*": cannot start interactive session: stopping interaction`)
	c.Assert(result.IdRevision.Revision, gc.Equals, curl.Revision)
	c.Assert(httpbakery.IsInteractionError(errgo.Cause(err)), gc.Equals, true)
}
コード例 #2
0
ファイル: csclient_test.go プロジェクト: jrwren/charmrepo
func (s *suite) SetUpTest(c *gc.C) {
	s.IsolatedMgoSuite.SetUpTest(c)
	s.startServer(c, s.Session)
	s.client = csclient.New(csclient.Params{
		URL:      s.srv.URL,
		User:     s.serverParams.AuthUsername,
		Password: s.serverParams.AuthPassword,
	})
}
コード例 #3
0
ファイル: charmstore.go プロジェクト: jrwren/charmrepo
// NewCharmStore creates and returns a charm store repository.
// The given parameters are used to instantiate the charm store.
//
// The errors returned from the interface methods will
// preserve the causes returned from the underlying csclient
// methods.
func NewCharmStore(p NewCharmStoreParams) Interface {
	return &CharmStore{
		client: csclient.New(csclient.Params{
			URL:          p.URL,
			HTTPClient:   p.HTTPClient,
			VisitWebPage: p.VisitWebPage,
		}),
	}
}
コード例 #4
0
ファイル: csclient_test.go プロジェクト: jrwren/charmrepo
func (s *suite) TestDoAuthorization(c *gc.C) {
	// Add a charm to be deleted.
	err := s.client.UploadCharmWithRevision(
		charm.MustParseReference("~charmers/utopic/wordpress-42"),
		charmRepo.CharmArchive(c.MkDir(), "wordpress"),
		42,
	)
	c.Assert(err, gc.IsNil)

	// Check that when we use incorrect authorization,
	// we get an error trying to delete the charm
	client := csclient.New(csclient.Params{
		URL:      s.srv.URL,
		User:     s.serverParams.AuthUsername,
		Password: "******",
	})
	req, err := http.NewRequest("DELETE", "", nil)
	c.Assert(err, gc.IsNil)
	_, err = client.Do(req, "/~charmers/utopic/wordpress-42/archive")
	c.Assert(err, gc.ErrorMatches, "invalid user name or password")
	c.Assert(errgo.Cause(err), gc.Equals, params.ErrUnauthorized)

	client = csclient.New(csclient.Params{
		URL:      s.srv.URL,
		User:     s.serverParams.AuthUsername,
		Password: s.serverParams.AuthPassword,
	})

	// Check that the charm is still there.
	err = client.Get("/~charmers/utopic/wordpress-42/expand-id", nil)
	c.Assert(err, gc.IsNil)

	// Then check that when we use the correct authorization,
	// the delete succeeds.
	req, err = http.NewRequest("DELETE", "", nil)
	c.Assert(err, gc.IsNil)
	resp, err := client.Do(req, "/~charmers/utopic/wordpress-42/archive")
	c.Assert(err, gc.IsNil)
	resp.Body.Close()

	// Check that it's now really gone.
	err = client.Get("/utopic/wordpress-42/expand-id", nil)
	c.Assert(err, gc.ErrorMatches, `no matching charm or bundle for "cs:utopic/wordpress-42"`)
}
コード例 #5
0
ファイル: migrate.go プロジェクト: rogpeppe/misc
func main() {
	flag.Parse()
	bundleName := flag.Arg(0)
	setCacheDir()
	data, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		log.Fatal(err)
	}
	cs := csclient.New(csclient.Params{})
	isSubordinate := isSubordinateFunc(cs)
	bundles, err := migratebundle.Migrate(data, isSubordinate)
	if err != nil {
		log.Fatal(err)
	}
	if len(bundles) != 1 && bundleName == "" {
		var names []string
		for name := range bundles {
			names = append(names, name)
		}
		sort.Strings(names)
		log.Fatal("bundle name argument required (available bundles: %v)", strings.Join(names, " "))
	}
	var bd *charm.BundleData
	if bundleName != "" {
		bd := bundles[bundleName]
		if bd == nil {
			log.Fatal("bundle %q not found in bundle", bundleName)
		}
	} else {
		for _, b := range bundles {
			bd = b
		}
	}
	if !*verify {
		return
	}
	csRepo := charmrepo.NewCharmStore(charmrepo.NewCharmStoreParams{})
	charms, err := fetchCharms(csRepo, bd.RequiredCharms())
	if err != nil {
		log.Fatal(err)
	}
	if err := bd.VerifyWithCharms(verifyConstraint, charms); err != nil {
		verr := err.(*charm.VerificationError)
		fmt.Fprintf(os.Stderr, "verification failed with %d errors\n", len(verr.Errors))
		for _, err := range verr.Errors {
			fmt.Fprintf(os.Stderr, "%s\n", err)
		}
		os.Exit(1)
	}
	data, err = yaml.Marshal(bd)
	if err != nil {
		log.Fatal(err)
	}
	os.Stdout.Write(data)
}
コード例 #6
0
ファイル: csclient_test.go プロジェクト: jrwren/charmrepo
func badResponseClient(resp *http.Response, err error) *csclient.Client {
	client := httpbakery.NewHTTPClient()
	client.Transport = &cannedRoundTripper{
		resp:  resp,
		error: err,
	}
	return csclient.New(csclient.Params{
		URL:        "http://0.1.2.3",
		User:       "******",
		HTTPClient: client,
	})
}
コード例 #7
0
ファイル: csclient_test.go プロジェクト: jrwren/charmrepo
func (s *suite) TestLogin(c *gc.C) {
	ch := charmRepo.CharmDir("wordpress")
	url := charm.MustParseReference("~charmers/utopic/wordpress-42")
	purl := charm.MustParseReference("utopic/wordpress-42")
	err := s.client.UploadCharmWithRevision(url, ch, 42)
	c.Assert(err, gc.IsNil)

	err = s.client.Put("/"+url.Path()+"/meta/perm/read", []string{"bob"})
	c.Assert(err, gc.IsNil)
	httpClient := httpbakery.NewHTTPClient()
	client := csclient.New(csclient.Params{
		URL:        s.srv.URL,
		HTTPClient: httpClient,
	})

	var result struct{ IdRevision struct{ Revision int } }
	_, err = client.Meta(purl, &result)
	c.Assert(err, gc.NotNil)

	// Try logging in when the discharger fails.
	err = client.Login()
	c.Assert(err, gc.ErrorMatches, `cannot retrieve the authentication macaroon: cannot get discharge from ".*": third party refused discharge: cannot discharge: no discharge`)

	// Allow the discharge.
	s.discharge = func(cond, arg string) ([]checkers.Caveat, error) {
		return []checkers.Caveat{checkers.DeclaredCaveat("username", "bob")}, nil
	}
	err = client.Login()
	c.Assert(err, gc.IsNil)

	// Change discharge so that we're sure the cookies are being
	// used rather than the discharge mechanism.
	s.discharge = func(cond, arg string) ([]checkers.Caveat, error) {
		return nil, fmt.Errorf("no discharge")
	}

	// Check that the request still works.
	_, err = client.Meta(purl, &result)
	c.Assert(err, gc.IsNil)
	c.Assert(result.IdRevision.Revision, gc.Equals, url.Revision)

	// Check that we've got one cookie.
	srvURL, err := neturl.Parse(s.srv.URL)
	c.Assert(err, gc.IsNil)
	c.Assert(httpClient.Jar.Cookies(srvURL), gc.HasLen, 1)

	// Log in again.
	err = client.Login()
	c.Assert(err, gc.IsNil)

	// Check that we still only have one cookie.
	c.Assert(httpClient.Jar.Cookies(srvURL), gc.HasLen, 1)
}
コード例 #8
0
ファイル: csclient_test.go プロジェクト: jrwren/charmrepo
func (s *suite) TestWhoAmI(c *gc.C) {
	httpClient := httpbakery.NewHTTPClient()
	client := csclient.New(csclient.Params{
		URL:        s.srv.URL,
		HTTPClient: httpClient,
	})
	response, err := client.WhoAmI()
	c.Assert(err, gc.ErrorMatches, `cannot retrieve whoami response: cannot get discharge from ".*": third party refused discharge: cannot discharge: no discharge`)
	s.discharge = func(cond, arg string) ([]checkers.Caveat, error) {
		return []checkers.Caveat{checkers.DeclaredCaveat("username", "bob")}, nil
	}

	response, err = client.WhoAmI()
	c.Assert(err, gc.IsNil)
	c.Assert(response.User, gc.Equals, "bob")
}
コード例 #9
0
ファイル: csclient_test.go プロジェクト: jrwren/charmrepo
func (s *suite) TestDefaultServerURL(c *gc.C) {
	// Add a charm used for tests.
	err := s.client.UploadCharmWithRevision(
		charm.MustParseReference("~charmers/vivid/testing-wordpress-42"),
		charmRepo.CharmDir("wordpress"),
		42,
	)
	c.Assert(err, gc.IsNil)

	// Patch the default server URL.
	s.PatchValue(&csclient.ServerURL, s.srv.URL)

	// Instantiate a client using the default server URL.
	client := csclient.New(csclient.Params{
		User:     s.serverParams.AuthUsername,
		Password: s.serverParams.AuthPassword,
	})
	c.Assert(client.ServerURL(), gc.Equals, s.srv.URL)

	// Check that the request succeeds.
	err = client.Get("/vivid/testing-wordpress-42/expand-id", nil)
	c.Assert(err, gc.IsNil)
}
コード例 #10
0
ファイル: csclient_test.go プロジェクト: jrwren/charmrepo
func (s *suite) TestSetHTTPHeader(c *gc.C) {
	var header http.Header
	srv := httptest.NewServer(http.HandlerFunc(func(_ http.ResponseWriter, req *http.Request) {
		header = req.Header
	}))
	defer srv.Close()

	sendRequest := func(client *csclient.Client) {
		req, err := http.NewRequest("GET", "", nil)
		c.Assert(err, jc.ErrorIsNil)
		_, err = client.Do(req, "/")
		c.Assert(err, jc.ErrorIsNil)
	}
	client := csclient.New(csclient.Params{
		URL: srv.URL,
	})

	// Make a first request without custom headers.
	sendRequest(client)
	defaultHeaderLen := len(header)

	// Make a second request adding a couple of custom headers.
	h := make(http.Header)
	h.Set("k1", "v1")
	h.Add("k2", "v2")
	h.Add("k2", "v3")
	client.SetHTTPHeader(h)
	sendRequest(client)
	c.Assert(header, gc.HasLen, defaultHeaderLen+len(h))
	c.Assert(header.Get("k1"), gc.Equals, "v1")
	c.Assert(header[http.CanonicalHeaderKey("k2")], jc.DeepEquals, []string{"v2", "v3"})

	// Make a third request without custom headers.
	client.SetHTTPHeader(nil)
	sendRequest(client)
	c.Assert(header, gc.HasLen, defaultHeaderLen)
}