~juju-qa/ubuntu/xenial/juju/xenial-2.0-beta3

« back to all changes in this revision

Viewing changes to src/github.com/juju/idmclient/client.go

  • Committer: Martin Packman
  • Date: 2016-03-30 19:31:08 UTC
  • mfrom: (1.1.41)
  • Revision ID: martin.packman@canonical.com-20160330193108-h9iz3ak334uk0z5r
Merge new upstream source 2.0~beta3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2015 Canonical Ltd.
 
2
// Licensed under the LGPLv3, see LICENCE file for details.
 
3
 
 
4
package idmclient
 
5
 
 
6
import (
 
7
        "io"
 
8
        "net/http"
 
9
        "net/url"
 
10
 
 
11
        "github.com/juju/httprequest"
 
12
        "gopkg.in/errgo.v1"
 
13
        "gopkg.in/macaroon-bakery.v1/httpbakery"
 
14
 
 
15
        "github.com/juju/idmclient/params"
 
16
)
 
17
 
 
18
// Note: tests for this code are in the server implementation.
 
19
 
 
20
const (
 
21
        Production = "https://api.jujucharms.com/identity"
 
22
        Staging    = "https://api.staging.jujucharms.com/identity"
 
23
)
 
24
 
 
25
// Client represents the client of an identity server.
 
26
type Client struct {
 
27
        client
 
28
}
 
29
 
 
30
// NewParams holds the parameters for creating a new client.
 
31
type NewParams struct {
 
32
        BaseURL string
 
33
        Client  *httpbakery.Client
 
34
 
 
35
        // AuthUsername holds the username for admin login.
 
36
        AuthUsername string
 
37
 
 
38
        // AuthPassword holds the password for admin login.
 
39
        AuthPassword string
 
40
}
 
41
 
 
42
// New returns a new client.
 
43
func New(p NewParams) *Client {
 
44
        var c Client
 
45
        c.Client.BaseURL = p.BaseURL
 
46
        if p.AuthUsername != "" {
 
47
                c.Client.Doer = &basicAuthClient{
 
48
                        client:   p.Client,
 
49
                        user:     p.AuthUsername,
 
50
                        password: p.AuthPassword,
 
51
                }
 
52
        } else {
 
53
                c.Client.Doer = p.Client
 
54
        }
 
55
        c.Client.UnmarshalError = httprequest.ErrorUnmarshaler(new(params.Error))
 
56
        return &c
 
57
}
 
58
 
 
59
// basicAuthClient wraps a bakery.Client, adding a basic auth
 
60
// header to every request.
 
61
type basicAuthClient struct {
 
62
        client   *httpbakery.Client
 
63
        user     string
 
64
        password string
 
65
}
 
66
 
 
67
func (c *basicAuthClient) Do(req *http.Request) (*http.Response, error) {
 
68
        req.SetBasicAuth(c.user, c.password)
 
69
        return c.client.Do(req)
 
70
}
 
71
 
 
72
func (c *basicAuthClient) DoWithBody(req *http.Request, r io.ReadSeeker) (*http.Response, error) {
 
73
        req.SetBasicAuth(c.user, c.password)
 
74
        return c.client.DoWithBody(req, r)
 
75
}
 
76
 
 
77
// LoginMethods returns information about the available login methods
 
78
// for the given URL, which is expected to be a URL as passed to
 
79
// a VisitWebPage function during the macaroon bakery discharge process.
 
80
func LoginMethods(client *http.Client, u *url.URL) (*params.LoginMethods, error) {
 
81
        req, err := http.NewRequest("GET", u.String(), nil)
 
82
        if err != nil {
 
83
                return nil, errgo.Notef(err, "cannot create request")
 
84
        }
 
85
        req.Header.Set("Accept", "application/json")
 
86
        resp, err := client.Do(req)
 
87
        if err != nil {
 
88
                return nil, errgo.Notef(err, "cannot do request")
 
89
        }
 
90
        defer resp.Body.Close()
 
91
        if resp.StatusCode != http.StatusOK {
 
92
                var herr httpbakery.Error
 
93
                if err := httprequest.UnmarshalJSONResponse(resp, &herr); err != nil {
 
94
                        return nil, errgo.Notef(err, "cannot unmarshal error")
 
95
                }
 
96
                return nil, &herr
 
97
        }
 
98
        var lm params.LoginMethods
 
99
        if err := httprequest.UnmarshalJSONResponse(resp, &lm); err != nil {
 
100
                return nil, errgo.Notef(err, "cannot unmarshal login methods")
 
101
        }
 
102
        return &lm, nil
 
103
}
 
104
 
 
105
//go:generate httprequest-generate-client $IDM_SERVER_REPO/internal/v1 apiHandler client