mirror of
https://github.com/pomerium/pomerium.git
synced 2025-05-02 20:06:03 +02:00
116 lines
2.8 KiB
Go
116 lines
2.8 KiB
Go
package ping
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
"strings"
|
|
|
|
"github.com/rs/zerolog"
|
|
|
|
"github.com/pomerium/pomerium/internal/encoding"
|
|
"github.com/pomerium/pomerium/internal/httputil"
|
|
)
|
|
|
|
type config struct {
|
|
authURL *url.URL
|
|
apiURL *url.URL
|
|
serviceAccount *ServiceAccount
|
|
httpClient *http.Client
|
|
environmentID string
|
|
}
|
|
|
|
// An Option updates the Ping configuration.
|
|
type Option func(*config)
|
|
|
|
// WithAPIURL sets the api url in the config.
|
|
func WithAPIURL(apiURL *url.URL) Option {
|
|
return func(cfg *config) {
|
|
cfg.apiURL = apiURL
|
|
}
|
|
}
|
|
|
|
// WithAuthURL sets the auth url in the config.
|
|
func WithAuthURL(authURL *url.URL) Option {
|
|
return func(cfg *config) {
|
|
cfg.authURL = authURL
|
|
}
|
|
}
|
|
|
|
// WithEnvironmentID sets the environment ID in the config.
|
|
func WithEnvironmentID(environmentID string) Option {
|
|
return func(cfg *config) {
|
|
cfg.environmentID = environmentID
|
|
}
|
|
}
|
|
|
|
// WithHTTPClient sets the http client option.
|
|
func WithHTTPClient(httpClient *http.Client) Option {
|
|
return func(cfg *config) {
|
|
cfg.httpClient = httputil.NewLoggingClient(httpClient, "ping_idp_client",
|
|
func(evt *zerolog.Event) *zerolog.Event {
|
|
return evt.Str("provider", "ping")
|
|
})
|
|
}
|
|
}
|
|
|
|
// WithProviderURL sets the environment ID from the provider URL set in the config.
|
|
func WithProviderURL(providerURL *url.URL) Option {
|
|
// provider URL will be https://auth.pingone.com/{ENVIRONMENT_ID}/as
|
|
if providerURL == nil {
|
|
return func(cfg *config) {}
|
|
}
|
|
parts := strings.Split(providerURL.Path, "/")
|
|
if len(parts) < 1 {
|
|
return func(cfg *config) {}
|
|
}
|
|
return WithEnvironmentID(parts[1])
|
|
}
|
|
|
|
// WithServiceAccount sets the service account in the config.
|
|
func WithServiceAccount(serviceAccount *ServiceAccount) Option {
|
|
return func(cfg *config) {
|
|
cfg.serviceAccount = serviceAccount
|
|
}
|
|
}
|
|
|
|
func getConfig(options ...Option) *config {
|
|
cfg := new(config)
|
|
WithHTTPClient(http.DefaultClient)(cfg)
|
|
WithAuthURL(&url.URL{
|
|
Scheme: "https",
|
|
Host: "auth.pingone.com",
|
|
})(cfg)
|
|
WithAPIURL(&url.URL{
|
|
Scheme: "https",
|
|
Host: "api.pingone.com",
|
|
})(cfg)
|
|
for _, option := range options {
|
|
option(cfg)
|
|
}
|
|
return cfg
|
|
}
|
|
|
|
// A ServiceAccount is used by the Ping provider to query the API.
|
|
type ServiceAccount struct {
|
|
ClientID string `json:"client_id"`
|
|
ClientSecret string `json:"client_secret"`
|
|
EnvironmentID string `json:"environment_id"`
|
|
}
|
|
|
|
// ParseServiceAccount parses the service account in the config options.
|
|
func ParseServiceAccount(rawServiceAccount string) (*ServiceAccount, error) {
|
|
var serviceAccount ServiceAccount
|
|
if err := encoding.DecodeBase64OrJSON(rawServiceAccount, &serviceAccount); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if serviceAccount.ClientID == "" {
|
|
return nil, fmt.Errorf("client_id is required")
|
|
}
|
|
if serviceAccount.ClientSecret == "" {
|
|
return nil, fmt.Errorf("client_secret is required")
|
|
}
|
|
|
|
return &serviceAccount, nil
|
|
}
|