mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 16:33:21 +01:00
116 lines
2.4 KiB
Go
116 lines
2.4 KiB
Go
package anchore
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"path"
|
|
"strings"
|
|
"unicode"
|
|
|
|
"github.com/anchore/client-go/pkg/external"
|
|
"github.com/anchore/syft/internal"
|
|
"github.com/anchore/syft/internal/version"
|
|
)
|
|
|
|
type Configuration struct {
|
|
BaseURL string
|
|
Username string
|
|
Password string
|
|
UserAgent string
|
|
}
|
|
|
|
type Client struct {
|
|
config Configuration
|
|
client *external.APIClient
|
|
}
|
|
|
|
func NewClient(cfg Configuration) (*Client, error) {
|
|
if cfg.UserAgent == "" {
|
|
versionInfo := version.FromBuild()
|
|
// format: product / product-version comment
|
|
cfg.UserAgent = fmt.Sprintf("%s / %s %s", internal.ApplicationName, versionInfo.Version, versionInfo.Platform)
|
|
}
|
|
|
|
baseURL, err := prepareBaseURLForClient(cfg.BaseURL)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("unable to create client: %w", err)
|
|
}
|
|
|
|
return &Client{
|
|
config: cfg,
|
|
client: external.NewAPIClient(&external.Configuration{
|
|
BasePath: baseURL,
|
|
UserAgent: cfg.UserAgent,
|
|
}),
|
|
}, nil
|
|
}
|
|
|
|
func (c *Client) newRequestContext(parentContext context.Context) context.Context {
|
|
if parentContext == nil {
|
|
parentContext = context.Background()
|
|
}
|
|
return context.WithValue(
|
|
parentContext,
|
|
external.ContextBasicAuth,
|
|
external.BasicAuth{
|
|
UserName: c.config.Username,
|
|
Password: c.config.Password,
|
|
},
|
|
)
|
|
}
|
|
|
|
var ErrInvalidBaseURLInput = errors.New("invalid base URL input")
|
|
|
|
func prepareBaseURLForClient(baseURL string) (string, error) {
|
|
if err := checkBaseURLInput(baseURL); err != nil {
|
|
return "", err
|
|
}
|
|
|
|
scheme, urlWithoutScheme := splitSchemeFromURL(baseURL)
|
|
|
|
if scheme == "" {
|
|
scheme = "http"
|
|
}
|
|
|
|
urlWithoutScheme = path.Clean(urlWithoutScheme)
|
|
|
|
const requiredSuffix = "v1"
|
|
if path.Base(urlWithoutScheme) != requiredSuffix {
|
|
urlWithoutScheme = path.Join(urlWithoutScheme, requiredSuffix)
|
|
}
|
|
|
|
preparedBaseURL := scheme + "://" + urlWithoutScheme
|
|
return preparedBaseURL, nil
|
|
}
|
|
|
|
func checkBaseURLInput(url string) error {
|
|
if url == "" {
|
|
return ErrInvalidBaseURLInput
|
|
}
|
|
|
|
firstCharacter := rune(url[0])
|
|
if !(unicode.IsLetter(firstCharacter)) {
|
|
return ErrInvalidBaseURLInput
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func splitSchemeFromURL(url string) (scheme, urlWithoutScheme string) {
|
|
if hasScheme(url) {
|
|
urlParts := strings.SplitN(url, "://", 2)
|
|
scheme = urlParts[0]
|
|
urlWithoutScheme = urlParts[1]
|
|
return
|
|
}
|
|
|
|
return "", url
|
|
}
|
|
|
|
func hasScheme(url string) bool {
|
|
parts := strings.Split(url, "://")
|
|
|
|
return len(parts) > 1
|
|
}
|