github.com/demonoid81/moby@v0.0.0-20200517203328-62dd8e17c460/pkg/authorization/plugin.go (about) 1 package authorization // import "github.com/demonoid81/moby/pkg/authorization" 2 3 import ( 4 "sync" 5 6 "github.com/demonoid81/moby/pkg/plugingetter" 7 "github.com/demonoid81/moby/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 initErr error 52 plugin *plugins.Client 53 name string 54 once sync.Once 55 } 56 57 func newAuthorizationPlugin(name string) Plugin { 58 return &authorizationPlugin{name: name} 59 } 60 61 func (a *authorizationPlugin) Name() string { 62 return a.name 63 } 64 65 // Set the remote for an authz pluginv2 66 func (a *authorizationPlugin) SetName(remote string) { 67 a.name = remote 68 } 69 70 func (a *authorizationPlugin) AuthZRequest(authReq *Request) (*Response, error) { 71 if err := a.initPlugin(); err != nil { 72 return nil, err 73 } 74 75 authRes := &Response{} 76 if err := a.plugin.Call(AuthZApiRequest, authReq, authRes); err != nil { 77 return nil, err 78 } 79 80 return authRes, nil 81 } 82 83 func (a *authorizationPlugin) AuthZResponse(authReq *Request) (*Response, error) { 84 if err := a.initPlugin(); err != nil { 85 return nil, err 86 } 87 88 authRes := &Response{} 89 if err := a.plugin.Call(AuthZApiResponse, authReq, authRes); err != nil { 90 return nil, err 91 } 92 93 return authRes, nil 94 } 95 96 // initPlugin initializes the authorization plugin if needed 97 func (a *authorizationPlugin) initPlugin() error { 98 // Lazy loading of plugins 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 a.initErr = e 112 return 113 } 114 a.plugin = plugin.Client() 115 } 116 }) 117 return a.initErr 118 }