github.com/gdevillele/moby@v1.13.0/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  func (a *authorizationPlugin) AuthZRequest(authReq *Request) (*Response, error) {
    65  	if err := a.initPlugin(); err != nil {
    66  		return nil, err
    67  	}
    68  
    69  	authRes := &Response{}
    70  	if err := a.plugin.Call(AuthZApiRequest, authReq, authRes); err != nil {
    71  		return nil, err
    72  	}
    73  
    74  	return authRes, nil
    75  }
    76  
    77  func (a *authorizationPlugin) AuthZResponse(authReq *Request) (*Response, error) {
    78  	if err := a.initPlugin(); err != nil {
    79  		return nil, err
    80  	}
    81  
    82  	authRes := &Response{}
    83  	if err := a.plugin.Call(AuthZApiResponse, authReq, authRes); err != nil {
    84  		return nil, err
    85  	}
    86  
    87  	return authRes, nil
    88  }
    89  
    90  // initPlugin initializes the authorization plugin if needed
    91  func (a *authorizationPlugin) initPlugin() error {
    92  	// Lazy loading of plugins
    93  	var err error
    94  	a.once.Do(func() {
    95  		if a.plugin == nil {
    96  			var plugin plugingetter.CompatPlugin
    97  			var e error
    98  
    99  			if pg := GetPluginGetter(); pg != nil {
   100  				plugin, e = pg.Get(a.name, AuthZApiImplements, plugingetter.LOOKUP)
   101  			} else {
   102  				plugin, e = plugins.Get(a.name, AuthZApiImplements)
   103  			}
   104  			if e != nil {
   105  				err = e
   106  				return
   107  			}
   108  			a.plugin = plugin.Client()
   109  		}
   110  	})
   111  	return err
   112  }