1
0
mirror of https://github.com/mayflower/docker-ls.git synced 2025-11-26 12:03:12 +03:00

Support authentification via basic auth.

This commit is contained in:
Christian Speckner
2016-02-26 13:25:34 +01:00
parent 17a44c1a20
commit 1eae834b66
6 changed files with 93 additions and 16 deletions

View File

@@ -33,6 +33,7 @@ type Config struct {
credentials RegistryCredentials
pageSize uint
maxConcurrentRequests uint
basicAuth bool
}
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.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.BoolVar(&c.basicAuth, "basic-auth", c.basicAuth, "use basic auth instead of token auth")
c.credentials.BindToFlags(flags)
}
@@ -62,5 +64,6 @@ func NewConfig() Config {
registryUrl: DEFAULT_REGISTRY_URL,
pageSize: 100,
maxConcurrentRequests: 5,
basicAuth: false,
}
}

View 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),
}
}

View 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))
}

View File

@@ -4,7 +4,7 @@ import (
"git.mayflower.de/vaillant-team/docker-ls/lib/auth"
)
type TokenAuthConfig interface {
type Config interface {
MaxConcurrentRequests() uint
Credentials() auth.RegistryCredentials
}

View File

@@ -1,6 +1,7 @@
package connector
import (
"errors"
"net/http"
"net/url"
"strings"
@@ -9,21 +10,12 @@ import (
)
type tokenAuthConnector struct {
cfg TokenAuthConfig
cfg Config
httpClient *http.Client
authenticator auth.Authenticator
semaphore chan int
semaphore semaphore
tokenCache *tokenCache
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) {
@@ -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) {
r.AquireLock()
defer r.ReleaseLock()
r.semaphore.Lock()
defer r.semaphore.Unlock()
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"))
if err != nil {
err = errors.New(err.Error() +
" Are you shure that you are using the correct (token) auth scheme?")
return
}
@@ -126,11 +121,11 @@ func (r *tokenAuthConnector) GetStatistics() Statistics {
return r.stat
}
func NewTokenAuthConnector(cfg TokenAuthConfig) *tokenAuthConnector {
func NewTokenAuthConnector(cfg Config) Connector {
connector := tokenAuthConnector{
cfg: cfg,
httpClient: http.DefaultClient,
semaphore: make(chan int, cfg.MaxConcurrentRequests()),
semaphore: newSemaphore(cfg.MaxConcurrentRequests()),
tokenCache: newTokenCache(),
stat: new(statistics),
}

View File

@@ -5,5 +5,8 @@ import (
)
func createConnector(cfg *Config) connector.Connector {
if cfg.basicAuth {
return connector.NewBasicAuthConnector(cfg)
}
return connector.NewTokenAuthConnector(cfg)
}