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