github.com/jiasir/docker@v1.3.3-0.20170609024000-252e610103e7/pkg/authorization/plugin.go (about) 1 package authorization 2 3 import ( 4 "sync" 5 6 "github.com/docker/docker/pkg/plugingetter" 7 "github.com/docker/docker/pkg/plugins" 8 ) 9 10 // Plugin allows third party plugins to authorize requests and responses 11 // in the context of docker API 12 type Plugin interface { 13 // Name returns the registered plugin name 14 Name() string 15 16 // AuthZRequest authorizes the request from the client to the daemon 17 AuthZRequest(*Request) (*Response, error) 18 19 // AuthZResponse authorizes the response from the daemon to the client 20 AuthZResponse(*Request) (*Response, error) 21 } 22 23 // newPlugins constructs and initializes the authorization plugins based on plugin names 24 func newPlugins(names []string) []Plugin { 25 plugins := []Plugin{} 26 pluginsMap := make(map[string]struct{}) 27 for _, name := range names { 28 if _, ok := pluginsMap[name]; ok { 29 continue 30 } 31 pluginsMap[name] = struct{}{} 32 plugins = append(plugins, newAuthorizationPlugin(name)) 33 } 34 return plugins 35 } 36 37 var getter plugingetter.PluginGetter 38 39 // SetPluginGetter sets the plugingetter 40 func SetPluginGetter(pg plugingetter.PluginGetter) { 41 getter = pg 42 } 43 44 // GetPluginGetter gets the plugingetter 45 func GetPluginGetter() plugingetter.PluginGetter { 46 return getter 47 } 48 49 // authorizationPlugin is an internal adapter to docker plugin system 50 type authorizationPlugin struct { 51 plugin *plugins.Client 52 name string 53 once sync.Once 54 } 55 56 func newAuthorizationPlugin(name string) Plugin { 57 return &authorizationPlugin{name: name} 58 } 59 60 func (a *authorizationPlugin) Name() string { 61 return a.name 62 } 63 64 // Set the remote for an authz pluginv2 65 func (a *authorizationPlugin) SetName(remote string) { 66 a.name = remote 67 } 68 69 func (a *authorizationPlugin) AuthZRequest(authReq *Request) (*Response, error) { 70 if err := a.initPlugin(); err != nil { 71 return nil, err 72 } 73 74 authRes := &Response{} 75 if err := a.plugin.Call(AuthZApiRequest, authReq, authRes); err != nil { 76 return nil, err 77 } 78 79 return authRes, nil 80 } 81 82 func (a *authorizationPlugin) AuthZResponse(authReq *Request) (*Response, error) { 83 if err := a.initPlugin(); err != nil { 84 return nil, err 85 } 86 87 authRes := &Response{} 88 if err := a.plugin.Call(AuthZApiResponse, authReq, authRes); err != nil { 89 return nil, err 90 } 91 92 return authRes, nil 93 } 94 95 // initPlugin initializes the authorization plugin if needed 96 func (a *authorizationPlugin) initPlugin() error { 97 // Lazy loading of plugins 98 var err error 99 a.once.Do(func() { 100 if a.plugin == nil { 101 var plugin plugingetter.CompatPlugin 102 var e error 103 104 if pg := GetPluginGetter(); pg != nil { 105 plugin, e = pg.Get(a.name, AuthZApiImplements, plugingetter.Lookup) 106 a.SetName(plugin.Name()) 107 } else { 108 plugin, e = plugins.Get(a.name, AuthZApiImplements) 109 } 110 if e != nil { 111 err = e 112 return 113 } 114 a.plugin = plugin.Client() 115 } 116 }) 117 return err 118 }