-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(api/v1): Add new Docker registry client
- Loading branch information
Showing
14 changed files
with
608 additions
and
496 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package none | ||
|
||
// Token implementation for None authentication | ||
type Token struct { | ||
} | ||
|
||
// Method is set to "None" | ||
func (tk Token) Method() string { | ||
return "None" | ||
} | ||
|
||
// String is empty (no token here) | ||
func (tk Token) String() string { | ||
return "" | ||
} | ||
|
||
// ExpiresIn is set to 0 for None authentication | ||
func (tk Token) ExpiresIn() int { | ||
return 0 | ||
} | ||
|
||
// RequestToken does pretty little here... | ||
func RequestToken() (*Token, error) { | ||
return &Token{}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package auth | ||
|
||
import ( | ||
"errors" | ||
"net/http" | ||
"strings" | ||
|
||
log "github.com/sirupsen/logrus" | ||
|
||
"github.com/ivanilves/lstags/api/v1/registry/client/auth/basic" | ||
"github.com/ivanilves/lstags/api/v1/registry/client/auth/bearer" | ||
"github.com/ivanilves/lstags/api/v1/registry/client/auth/none" | ||
) | ||
|
||
// Token is an abstraction for aggregated token-related information we get from authentication services | ||
type Token interface { | ||
Method() string | ||
String() string | ||
ExpiresIn() int | ||
} | ||
|
||
type authHeader string | ||
|
||
func extractAuthHeader(hh []string) (authHeader, error) { | ||
if len(hh) == 0 { | ||
return "None realm=none", nil | ||
} | ||
|
||
h := hh[0] | ||
|
||
if len(strings.SplitN(h, " ", 2)) != 2 { | ||
return "", errors.New("Unexpected 'Www-Authenticate' header: " + h) | ||
} | ||
|
||
return authHeader(h), nil | ||
} | ||
|
||
func getAuthMethod(h authHeader) string { | ||
return strings.SplitN(string(h), " ", 2)[0] | ||
} | ||
|
||
func getAuthParams(h authHeader) map[string]string { | ||
params := make(map[string]string) | ||
|
||
paramString := strings.SplitN(string(h), " ", 2)[1] | ||
|
||
for _, keyValueString := range strings.Split(paramString, ",") { | ||
kv := strings.Split(keyValueString, "=") | ||
if len(kv) == 2 { | ||
params[kv[0]] = strings.Trim(kv[1], "\"") | ||
} | ||
} | ||
|
||
return params | ||
} | ||
|
||
// NewToken creates a new instance of Token in two steps: | ||
// * detects authentication type ("Bearer", "Basic" or "None") | ||
// * delegates actual authentication to the type-specific implementation | ||
func NewToken(url, username, password, scope string) (Token, error) { | ||
resp, err := http.Get(url) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
authHeader, err := extractAuthHeader(resp.Header["Www-Authenticate"]) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
method := getAuthMethod(authHeader) | ||
params := getAuthParams(authHeader) | ||
|
||
switch method { | ||
case "None": | ||
return none.RequestToken() | ||
case "Basic": | ||
t, err := basic.RequestToken(url, username, password) | ||
if err != nil { | ||
log.Debug(err.Error()) | ||
|
||
return none.RequestToken() | ||
} | ||
|
||
return t, nil | ||
case "Bearer": | ||
params["scope"] = scope | ||
return bearer.RequestToken(username, password, params) | ||
default: | ||
return nil, errors.New("Unknown authentication method: " + method) | ||
} | ||
} |
Oops, something went wrong.