github.com/gdevillele/moby@v1.13.0/pkg/authorization/middleware.go (about) 1 package authorization 2 3 import ( 4 "net/http" 5 "sync" 6 7 "github.com/Sirupsen/logrus" 8 "github.com/docker/docker/pkg/plugingetter" 9 "golang.org/x/net/context" 10 ) 11 12 // Middleware uses a list of plugins to 13 // handle authorization in the API requests. 14 type Middleware struct { 15 mu sync.Mutex 16 plugins []Plugin 17 } 18 19 // NewMiddleware creates a new Middleware 20 // with a slice of plugins names. 21 func NewMiddleware(names []string, pg plugingetter.PluginGetter) *Middleware { 22 SetPluginGetter(pg) 23 return &Middleware{ 24 plugins: newPlugins(names), 25 } 26 } 27 28 // SetPlugins sets the plugin used for authorization 29 func (m *Middleware) SetPlugins(names []string) { 30 m.mu.Lock() 31 m.plugins = newPlugins(names) 32 m.mu.Unlock() 33 } 34 35 // WrapHandler returns a new handler function wrapping the previous one in the request chain. 36 func (m *Middleware) WrapHandler(handler func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error) func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 37 return func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 38 39 m.mu.Lock() 40 plugins := m.plugins 41 m.mu.Unlock() 42 if len(plugins) == 0 { 43 return handler(ctx, w, r, vars) 44 } 45 46 user := "" 47 userAuthNMethod := "" 48 49 // Default authorization using existing TLS connection credentials 50 // FIXME: Non trivial authorization mechanisms (such as advanced certificate validations, kerberos support 51 // and ldap) will be extracted using AuthN feature, which is tracked under: 52 // https://github.com/docker/docker/pull/20883 53 if r.TLS != nil && len(r.TLS.PeerCertificates) > 0 { 54 user = r.TLS.PeerCertificates[0].Subject.CommonName 55 userAuthNMethod = "TLS" 56 } 57 58 authCtx := NewCtx(plugins, user, userAuthNMethod, r.Method, r.RequestURI) 59 60 if err := authCtx.AuthZRequest(w, r); err != nil { 61 logrus.Errorf("AuthZRequest for %s %s returned error: %s", r.Method, r.RequestURI, err) 62 return err 63 } 64 65 rw := NewResponseModifier(w) 66 67 var errD error 68 69 if errD = handler(ctx, rw, r, vars); errD != nil { 70 logrus.Errorf("Handler for %s %s returned error: %s", r.Method, r.RequestURI, errD) 71 } 72 73 if err := authCtx.AuthZResponse(rw, r); errD == nil && err != nil { 74 logrus.Errorf("AuthZResponse for %s %s returned error: %s", r.Method, r.RequestURI, err) 75 return err 76 } 77 78 if errD != nil { 79 return errD 80 } 81 82 return nil 83 } 84 }