Use context for auth access controllers
The auth package has been updated to use "golang.org/x/net/context" for passing information between the application and the auth backend. AccessControllers should now set a "auth.user" context value to a AuthUser struct containing a single "Name" field for now with possible, optional, values in the future. The "silly" auth backend always sets the name to "silly", while the "token" auth backend will set the name to match the "subject" claim of the JWT. Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)
This commit is contained in:
parent
1089cae282
commit
904b35a24f
2 changed files with 18 additions and 5 deletions
19
docs/app.go
19
docs/app.go
|
@ -16,6 +16,7 @@ import (
|
||||||
"github.com/docker/distribution/storagedriver"
|
"github.com/docker/distribution/storagedriver"
|
||||||
"github.com/docker/distribution/storagedriver/factory"
|
"github.com/docker/distribution/storagedriver/factory"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
// App is a global registry application object. Shared resources can be placed
|
// App is a global registry application object. Shared resources can be placed
|
||||||
|
@ -189,6 +190,12 @@ func (ssrw *singleStatusResponseWriter) WriteHeader(status int) {
|
||||||
ssrw.ResponseWriter.WriteHeader(status)
|
ssrw.ResponseWriter.WriteHeader(status)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithRequest adds an http request to the given context and requents
|
||||||
|
// a new context with an "http.request" value.
|
||||||
|
func WithRequest(ctx context.Context, r *http.Request) context.Context {
|
||||||
|
return context.WithValue(ctx, "http.request", r)
|
||||||
|
}
|
||||||
|
|
||||||
// dispatcher returns a handler that constructs a request specific context and
|
// dispatcher returns a handler that constructs a request specific context and
|
||||||
// handler, using the dispatch factory function.
|
// handler, using the dispatch factory function.
|
||||||
func (app *App) dispatcher(dispatch dispatchFunc) http.Handler {
|
func (app *App) dispatcher(dispatch dispatchFunc) http.Handler {
|
||||||
|
@ -301,7 +308,8 @@ func (app *App) authorized(w http.ResponseWriter, r *http.Request, context *Cont
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := app.accessController.Authorized(r, accessRecords...); err != nil {
|
authCtx, err := app.accessController.Authorized(WithRequest(nil, r), accessRecords...)
|
||||||
|
if err != nil {
|
||||||
switch err := err.(type) {
|
switch err := err.(type) {
|
||||||
case auth.Challenge:
|
case auth.Challenge:
|
||||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
|
@ -322,6 +330,10 @@ func (app *App) authorized(w http.ResponseWriter, r *http.Request, context *Cont
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The authorized context should contain an auth.UserInfo
|
||||||
|
// object. If it doesn't, just use the zero value for now.
|
||||||
|
context.AuthUserInfo, _ = authCtx.Value("auth.user").(auth.UserInfo)
|
||||||
|
|
||||||
// At this point, the request should have access to the repository under
|
// At this point, the request should have access to the repository under
|
||||||
// the requested operation. Make is available on the context.
|
// the requested operation. Make is available on the context.
|
||||||
context.Repository = app.registry.Repository(repo)
|
context.Repository = app.registry.Repository(repo)
|
||||||
|
@ -332,11 +344,8 @@ func (app *App) authorized(w http.ResponseWriter, r *http.Request, context *Cont
|
||||||
// eventBridge returns a bridge for the current request, configured with the
|
// eventBridge returns a bridge for the current request, configured with the
|
||||||
// correct actor and source.
|
// correct actor and source.
|
||||||
func (app *App) eventBridge(ctx *Context, r *http.Request) notifications.Listener {
|
func (app *App) eventBridge(ctx *Context, r *http.Request) notifications.Listener {
|
||||||
// TODO(stevvooe): Need to extract user data from request context using
|
|
||||||
// auth system. Would prefer to do this during logging refactor and
|
|
||||||
// addition of user and google context type.
|
|
||||||
actor := notifications.ActorRecord{
|
actor := notifications.ActorRecord{
|
||||||
Name: "--todo--",
|
Name: ctx.AuthUserInfo.Name,
|
||||||
}
|
}
|
||||||
request := notifications.NewRequestRecord(ctx.RequestID, r)
|
request := notifications.NewRequestRecord(ctx.RequestID, r)
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package registry
|
||||||
import (
|
import (
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/docker/distribution/api/v2"
|
"github.com/docker/distribution/api/v2"
|
||||||
|
"github.com/docker/distribution/auth"
|
||||||
"github.com/docker/distribution/storage"
|
"github.com/docker/distribution/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -25,6 +26,9 @@ type Context struct {
|
||||||
// handler *must not* start the response via http.ResponseWriter.
|
// handler *must not* start the response via http.ResponseWriter.
|
||||||
Errors v2.Errors
|
Errors v2.Errors
|
||||||
|
|
||||||
|
// AuthUserInfo contains information about an authorized client.
|
||||||
|
AuthUserInfo auth.UserInfo
|
||||||
|
|
||||||
// vars contains the extracted gorilla/mux variables that can be used for
|
// vars contains the extracted gorilla/mux variables that can be used for
|
||||||
// assignment.
|
// assignment.
|
||||||
vars map[string]string
|
vars map[string]string
|
||||||
|
|
Loading…
Reference in a new issue