mirror of
https://github.com/mayflower/docker-ls.git
synced 2025-11-28 00:01:09 +03:00
Support authentification via basic auth.
This commit is contained in:
@@ -33,6 +33,7 @@ type Config struct {
|
|||||||
credentials RegistryCredentials
|
credentials RegistryCredentials
|
||||||
pageSize uint
|
pageSize uint
|
||||||
maxConcurrentRequests uint
|
maxConcurrentRequests uint
|
||||||
|
basicAuth bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *urlValue) String() string {
|
func (u *urlValue) String() string {
|
||||||
@@ -45,6 +46,7 @@ func (c *Config) BindToFlags(flags *flag.FlagSet) {
|
|||||||
flags.Var((*urlValue)(&c.registryUrl), "registry", "registry URL")
|
flags.Var((*urlValue)(&c.registryUrl), "registry", "registry URL")
|
||||||
flags.UintVar(&c.pageSize, "page-size", c.pageSize, "page size for paginated requests")
|
flags.UintVar(&c.pageSize, "page-size", c.pageSize, "page size for paginated requests")
|
||||||
flags.UintVar(&c.maxConcurrentRequests, "max-requests", c.maxConcurrentRequests, "concurrent API request limit")
|
flags.UintVar(&c.maxConcurrentRequests, "max-requests", c.maxConcurrentRequests, "concurrent API request limit")
|
||||||
|
flags.BoolVar(&c.basicAuth, "basic-auth", c.basicAuth, "use basic auth instead of token auth")
|
||||||
|
|
||||||
c.credentials.BindToFlags(flags)
|
c.credentials.BindToFlags(flags)
|
||||||
}
|
}
|
||||||
@@ -62,5 +64,6 @@ func NewConfig() Config {
|
|||||||
registryUrl: DEFAULT_REGISTRY_URL,
|
registryUrl: DEFAULT_REGISTRY_URL,
|
||||||
pageSize: 100,
|
pageSize: 100,
|
||||||
maxConcurrentRequests: 5,
|
maxConcurrentRequests: 5,
|
||||||
|
basicAuth: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
57
lib/connector/basic_auth_connector.go
Normal file
57
lib/connector/basic_auth_connector.go
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
package connector
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type basicAuthConnector struct {
|
||||||
|
cfg Config
|
||||||
|
httpClient *http.Client
|
||||||
|
semaphore semaphore
|
||||||
|
stat *statistics
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *basicAuthConnector) Delete(url *url.URL, hint string) (*http.Response, error) {
|
||||||
|
return r.Request("DELETE", url, hint)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *basicAuthConnector) Get(url *url.URL, hint string) (*http.Response, error) {
|
||||||
|
return r.Request("GET", url, hint)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *basicAuthConnector) GetStatistics() Statistics {
|
||||||
|
return r.stat
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *basicAuthConnector) Request(method string, url *url.URL, hint string) (response *http.Response, err error) {
|
||||||
|
r.semaphore.Lock()
|
||||||
|
defer r.semaphore.Unlock()
|
||||||
|
|
||||||
|
r.stat.Request()
|
||||||
|
|
||||||
|
request, err := http.NewRequest(method, url.String(), strings.NewReader(""))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
credentials := r.cfg.Credentials()
|
||||||
|
if credentials.Password() != "" || credentials.User() != "" {
|
||||||
|
request.SetBasicAuth(credentials.User(), credentials.Password())
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err = r.httpClient.Do(request)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBasicAuthConnector(cfg Config) Connector {
|
||||||
|
return &basicAuthConnector{
|
||||||
|
cfg: cfg,
|
||||||
|
httpClient: http.DefaultClient,
|
||||||
|
semaphore: newSemaphore(cfg.MaxConcurrentRequests()),
|
||||||
|
stat: new(statistics),
|
||||||
|
}
|
||||||
|
}
|
||||||
19
lib/connector/semaphore.go
Normal file
19
lib/connector/semaphore.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package connector
|
||||||
|
|
||||||
|
type semaphore chan int
|
||||||
|
|
||||||
|
func (s semaphore) Lock() {
|
||||||
|
s <- 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s semaphore) Unlock() {
|
||||||
|
_ = <-s
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSemaphore(limit uint) semaphore {
|
||||||
|
if limit == 0 {
|
||||||
|
limit = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return semaphore(make(chan int, limit))
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"git.mayflower.de/vaillant-team/docker-ls/lib/auth"
|
"git.mayflower.de/vaillant-team/docker-ls/lib/auth"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TokenAuthConfig interface {
|
type Config interface {
|
||||||
MaxConcurrentRequests() uint
|
MaxConcurrentRequests() uint
|
||||||
Credentials() auth.RegistryCredentials
|
Credentials() auth.RegistryCredentials
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package connector
|
package connector
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -9,21 +10,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type tokenAuthConnector struct {
|
type tokenAuthConnector struct {
|
||||||
cfg TokenAuthConfig
|
cfg Config
|
||||||
httpClient *http.Client
|
httpClient *http.Client
|
||||||
authenticator auth.Authenticator
|
authenticator auth.Authenticator
|
||||||
semaphore chan int
|
semaphore semaphore
|
||||||
tokenCache *tokenCache
|
tokenCache *tokenCache
|
||||||
stat *statistics
|
stat *statistics
|
||||||
basicAuth bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *tokenAuthConnector) AquireLock() {
|
|
||||||
r.semaphore <- 1
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *tokenAuthConnector) ReleaseLock() {
|
|
||||||
_ = <-r.semaphore
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *tokenAuthConnector) Delete(url *url.URL, hint string) (*http.Response, error) {
|
func (r *tokenAuthConnector) Delete(url *url.URL, hint string) (*http.Response, error) {
|
||||||
@@ -35,8 +27,8 @@ func (r *tokenAuthConnector) Get(url *url.URL, hint string) (*http.Response, err
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *tokenAuthConnector) Request(method string, url *url.URL, hint string) (response *http.Response, err error) {
|
func (r *tokenAuthConnector) Request(method string, url *url.URL, hint string) (response *http.Response, err error) {
|
||||||
r.AquireLock()
|
r.semaphore.Lock()
|
||||||
defer r.ReleaseLock()
|
defer r.semaphore.Unlock()
|
||||||
|
|
||||||
r.stat.Request()
|
r.stat.Request()
|
||||||
|
|
||||||
@@ -73,6 +65,9 @@ func (r *tokenAuthConnector) Request(method string, url *url.URL, hint string) (
|
|||||||
challenge, err := auth.ParseChallenge(resp.Header.Get("www-authenticate"))
|
challenge, err := auth.ParseChallenge(resp.Header.Get("www-authenticate"))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
err = errors.New(err.Error() +
|
||||||
|
" Are you shure that you are using the correct (token) auth scheme?")
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,11 +121,11 @@ func (r *tokenAuthConnector) GetStatistics() Statistics {
|
|||||||
return r.stat
|
return r.stat
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTokenAuthConnector(cfg TokenAuthConfig) *tokenAuthConnector {
|
func NewTokenAuthConnector(cfg Config) Connector {
|
||||||
connector := tokenAuthConnector{
|
connector := tokenAuthConnector{
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
httpClient: http.DefaultClient,
|
httpClient: http.DefaultClient,
|
||||||
semaphore: make(chan int, cfg.MaxConcurrentRequests()),
|
semaphore: newSemaphore(cfg.MaxConcurrentRequests()),
|
||||||
tokenCache: newTokenCache(),
|
tokenCache: newTokenCache(),
|
||||||
stat: new(statistics),
|
stat: new(statistics),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,5 +5,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func createConnector(cfg *Config) connector.Connector {
|
func createConnector(cfg *Config) connector.Connector {
|
||||||
|
if cfg.basicAuth {
|
||||||
|
return connector.NewBasicAuthConnector(cfg)
|
||||||
|
}
|
||||||
return connector.NewTokenAuthConnector(cfg)
|
return connector.NewTokenAuthConnector(cfg)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user