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

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/apiserver/authcontext.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:
21
21
// authContext holds authentication context shared
22
22
// between all API endpoints.
23
23
type authContext struct {
24
 
        srv *Server
 
24
        st *state.State
25
25
 
26
26
        agentAuth authentication.AgentAuthenticator
27
27
        userAuth  authentication.UserAuthenticator
28
28
 
29
29
        // macaroonAuthOnce guards the fields below it.
30
30
        macaroonAuthOnce   sync.Once
31
 
        _macaroonAuth      *authentication.MacaroonAuthenticator
 
31
        _macaroonAuth      *authentication.ExternalMacaroonAuthenticator
32
32
        _macaroonAuthError error
33
33
}
34
34
 
35
 
// newAuthContext creates a new authentication context for srv.
36
 
func newAuthContext(srv *Server) *authContext {
37
 
        return &authContext{
38
 
                srv: srv,
 
35
// newAuthContext creates a new authentication context for st.
 
36
func newAuthContext(st *state.State) (*authContext, error) {
 
37
        ctxt := &authContext{st: st}
 
38
 
 
39
        // TODO(axw) consider storing macaroons in Mongo. We're currently
 
40
        // storing them in-memory, which means that if a client logs into
 
41
        // one API server, they cannot use the macaroon in another one.
 
42
        bakeryService, err := newBakeryService(st, nil)
 
43
        if err != nil {
 
44
                return nil, errors.Trace(err)
39
45
        }
 
46
        ctxt.userAuth.Service = bakeryService
 
47
        return ctxt, nil
40
48
}
41
49
 
42
50
// Authenticate implements authentication.EntityAuthenticator
78
86
// logins. If it fails once, it will always fail.
79
87
func (ctxt *authContext) macaroonAuth() (authentication.EntityAuthenticator, error) {
80
88
        ctxt.macaroonAuthOnce.Do(func() {
81
 
                ctxt._macaroonAuth, ctxt._macaroonAuthError = newMacaroonAuth(ctxt.srv.statePool.SystemState())
 
89
                ctxt._macaroonAuth, ctxt._macaroonAuthError = newExternalMacaroonAuth(ctxt.st)
82
90
        })
83
91
        if ctxt._macaroonAuth == nil {
84
92
                return nil, errors.Trace(ctxt._macaroonAuthError)
88
96
 
89
97
var errMacaroonAuthNotConfigured = errors.New("macaroon authentication is not configured")
90
98
 
91
 
// newMacaroonAuth returns an authenticator that can authenticate
92
 
// macaroon-based logins. This is just a helper function for authCtxt.macaroonAuth.
93
 
func newMacaroonAuth(st *state.State) (*authentication.MacaroonAuthenticator, error) {
 
99
// newExternalMacaroonAuth returns an authenticator that can authenticate
 
100
// macaroon-based logins for external users. This is just a helper function
 
101
// for authCtxt.macaroonAuth.
 
102
func newExternalMacaroonAuth(st *state.State) (*authentication.ExternalMacaroonAuthenticator, error) {
94
103
        envCfg, err := st.ModelConfig()
95
104
        if err != nil {
96
105
                return nil, errors.Annotate(err, "cannot get model config")
109
118
                        return nil, errors.Annotate(err, "cannot get identity public key")
110
119
                }
111
120
        }
112
 
        svc, err := bakery.NewService(
113
 
                bakery.NewServiceParams{
114
 
                        Location: "juju model " + st.ModelUUID(),
115
 
                        Locator: bakery.PublicKeyLocatorMap{
116
 
                                idURL: idPK,
117
 
                        },
118
 
                },
119
 
        )
 
121
        svc, err := newBakeryService(st, bakery.PublicKeyLocatorMap{
 
122
                idURL: idPK,
 
123
        })
120
124
        if err != nil {
121
125
                return nil, errors.Annotate(err, "cannot make bakery service")
122
126
        }
123
 
        var auth authentication.MacaroonAuthenticator
 
127
        var auth authentication.ExternalMacaroonAuthenticator
124
128
        auth.Service = svc
125
129
        auth.Macaroon, err = svc.NewMacaroon("api-login", nil, nil)
126
130
        if err != nil {
129
133
        auth.IdentityLocation = idURL
130
134
        return &auth, nil
131
135
}
 
136
 
 
137
// newBakeryService creates a new bakery.Service.
 
138
func newBakeryService(st *state.State, locator bakery.PublicKeyLocator) (*bakery.Service, error) {
 
139
        return bakery.NewService(bakery.NewServiceParams{
 
140
                Location: "juju model " + st.ModelUUID(),
 
141
                Locator:  locator,
 
142
        })
 
143
}