dnscontrol/pkg/cloudflare-go/access_identity_provider.go
Tom Limoncelli 7fd6a74e0c
CLOUDFLAREAPI: CF_REDIRECT/CF_TEMP_REDIRECT should dtrt using Single Redirects (#3002)
Co-authored-by: Josh Zhang <jzhang1@stackoverflow.com>
2024-06-18 17:38:50 -04:00

306 lines
12 KiB
Go

package cloudflare
import (
"context"
"fmt"
"net/http"
"github.com/goccy/go-json"
)
// AccessIdentityProvider is the structure of the provider object.
type AccessIdentityProvider struct {
ID string `json:"id,omitempty"`
Name string `json:"name"`
Type string `json:"type"`
Config AccessIdentityProviderConfiguration `json:"config"`
ScimConfig AccessIdentityProviderScimConfiguration `json:"scim_config"`
}
// AccessIdentityProviderConfiguration is the combined structure of *all*
// identity provider configuration fields. This is done to simplify the use of
// Access products and their relationship to each other.
//
// API reference: https://developers.cloudflare.com/access/configuring-identity-providers/
type AccessIdentityProviderConfiguration struct {
APIToken string `json:"api_token,omitempty"`
AppsDomain string `json:"apps_domain,omitempty"`
Attributes []string `json:"attributes,omitempty"`
AuthURL string `json:"auth_url,omitempty"`
CentrifyAccount string `json:"centrify_account,omitempty"`
CentrifyAppID string `json:"centrify_app_id,omitempty"`
CertsURL string `json:"certs_url,omitempty"`
ClientID string `json:"client_id,omitempty"`
ClientSecret string `json:"client_secret,omitempty"`
Claims []string `json:"claims,omitempty"`
Scopes []string `json:"scopes,omitempty"`
DirectoryID string `json:"directory_id,omitempty"`
EmailAttributeName string `json:"email_attribute_name,omitempty"`
EmailClaimName string `json:"email_claim_name,omitempty"`
IdpPublicCert string `json:"idp_public_cert,omitempty"`
IssuerURL string `json:"issuer_url,omitempty"`
OktaAccount string `json:"okta_account,omitempty"`
OktaAuthorizationServerID string `json:"authorization_server_id,omitempty"`
OneloginAccount string `json:"onelogin_account,omitempty"`
PingEnvID string `json:"ping_env_id,omitempty"`
RedirectURL string `json:"redirect_url,omitempty"`
SignRequest bool `json:"sign_request,omitempty"`
SsoTargetURL string `json:"sso_target_url,omitempty"`
SupportGroups bool `json:"support_groups,omitempty"`
TokenURL string `json:"token_url,omitempty"`
PKCEEnabled *bool `json:"pkce_enabled,omitempty"`
ConditionalAccessEnabled bool `json:"conditional_access_enabled,omitempty"`
}
type AccessIdentityProviderScimConfiguration struct {
Enabled bool `json:"enabled,omitempty"`
Secret string `json:"secret,omitempty"`
UserDeprovision bool `json:"user_deprovision,omitempty"`
SeatDeprovision bool `json:"seat_deprovision,omitempty"`
GroupMemberDeprovision bool `json:"group_member_deprovision,omitempty"`
}
// AccessIdentityProvidersListResponse is the API response for multiple
// Access Identity Providers.
type AccessIdentityProvidersListResponse struct {
Response
Result []AccessIdentityProvider `json:"result"`
ResultInfo `json:"result_info"`
}
// AccessIdentityProviderResponse is the API response for a single
// Access Identity Provider.
type AccessIdentityProviderResponse struct {
Response
Result AccessIdentityProvider `json:"result"`
}
type ListAccessIdentityProvidersParams struct {
ResultInfo
}
type CreateAccessIdentityProviderParams struct {
Name string `json:"name"`
Type string `json:"type"`
Config AccessIdentityProviderConfiguration `json:"config"`
ScimConfig AccessIdentityProviderScimConfiguration `json:"scim_config"`
}
type UpdateAccessIdentityProviderParams struct {
ID string `json:"-"`
Name string `json:"name"`
Type string `json:"type"`
Config AccessIdentityProviderConfiguration `json:"config"`
ScimConfig AccessIdentityProviderScimConfiguration `json:"scim_config"`
}
// AccessAuthContext represents an Access Azure Identity Provider Auth Context.
type AccessAuthContext struct {
ID string `json:"id"`
UID string `json:"uid"`
ACID string `json:"ac_id"`
DisplayName string `json:"display_name"`
Description string `json:"description"`
}
// AccessAuthContextsListResponse represents the response from the list
// Access Auth Contexts endpoint.
type AccessAuthContextsListResponse struct {
Result []AccessAuthContext `json:"result"`
Response
}
// ListAccessIdentityProviders returns all Access Identity Providers for an
// account or zone.
//
// Account API Reference: https://developers.cloudflare.com/api/operations/access-identity-providers-list-access-identity-providers
// Zone API Reference: https://developers.cloudflare.com/api/operations/zone-level-access-identity-providers-list-access-identity-providers
func (api *API) ListAccessIdentityProviders(ctx context.Context, rc *ResourceContainer, params ListAccessIdentityProvidersParams) ([]AccessIdentityProvider, *ResultInfo, error) {
baseURL := fmt.Sprintf("/%s/%s/access/identity_providers", rc.Level, rc.Identifier)
autoPaginate := true
if params.PerPage >= 1 || params.Page >= 1 {
autoPaginate = false
}
if params.PerPage < 1 {
params.PerPage = 25
}
if params.Page < 1 {
params.Page = 1
}
var accessProviders []AccessIdentityProvider
var r AccessIdentityProvidersListResponse
for {
uri := buildURI(baseURL, params)
res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
if err != nil {
return []AccessIdentityProvider{}, &ResultInfo{}, fmt.Errorf("%s: %w", errMakeRequestError, err)
}
err = json.Unmarshal(res, &r)
if err != nil {
return []AccessIdentityProvider{}, &ResultInfo{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
}
accessProviders = append(accessProviders, r.Result...)
params.ResultInfo = r.ResultInfo.Next()
if params.ResultInfo.Done() || !autoPaginate {
break
}
}
return accessProviders, &r.ResultInfo, nil
}
// GetAccessIdentityProvider returns a single Access Identity
// Provider for an account or zone.
//
// Account API Reference: https://developers.cloudflare.com/api/operations/access-identity-providers-get-an-access-identity-provider
// Zone API Reference: https://developers.cloudflare.com/api/operations/zone-level-access-identity-providers-get-an-access-identity-provider
func (api *API) GetAccessIdentityProvider(ctx context.Context, rc *ResourceContainer, identityProviderID string) (AccessIdentityProvider, error) {
uri := fmt.Sprintf(
"/%s/%s/access/identity_providers/%s",
rc.Level,
rc.Identifier,
identityProviderID,
)
res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
if err != nil {
return AccessIdentityProvider{}, fmt.Errorf("%s: %w", errMakeRequestError, err)
}
var accessIdentityProviderResponse AccessIdentityProviderResponse
err = json.Unmarshal(res, &accessIdentityProviderResponse)
if err != nil {
return AccessIdentityProvider{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
}
return accessIdentityProviderResponse.Result, nil
}
// CreateAccessIdentityProvider creates a new Access Identity Provider.
//
// Account API Reference: https://developers.cloudflare.com/api/operations/access-identity-providers-add-an-access-identity-provider
// Zone API Reference: https://developers.cloudflare.com/api/operations/zone-level-access-identity-providers-add-an-access-identity-provider
func (api *API) CreateAccessIdentityProvider(ctx context.Context, rc *ResourceContainer, params CreateAccessIdentityProviderParams) (AccessIdentityProvider, error) {
uri := fmt.Sprintf("/%s/%s/access/identity_providers", rc.Level, rc.Identifier)
res, err := api.makeRequestContext(ctx, http.MethodPost, uri, params)
if err != nil {
return AccessIdentityProvider{}, fmt.Errorf("%s: %w", errMakeRequestError, err)
}
var accessIdentityProviderResponse AccessIdentityProviderResponse
err = json.Unmarshal(res, &accessIdentityProviderResponse)
if err != nil {
return AccessIdentityProvider{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
}
return accessIdentityProviderResponse.Result, nil
}
// UpdateAccessIdentityProvider updates an existing Access Identity
// Provider.
//
// Account API Reference: https://developers.cloudflare.com/api/operations/access-identity-providers-update-an-access-identity-provider
// Zone API Reference: https://developers.cloudflare.com/api/operations/zone-level-access-identity-providers-update-an-access-identity-provider
func (api *API) UpdateAccessIdentityProvider(ctx context.Context, rc *ResourceContainer, params UpdateAccessIdentityProviderParams) (AccessIdentityProvider, error) {
uri := fmt.Sprintf(
"/%s/%s/access/identity_providers/%s",
rc.Level,
rc.Identifier,
params.ID,
)
res, err := api.makeRequestContext(ctx, http.MethodPut, uri, params)
if err != nil {
return AccessIdentityProvider{}, err
}
var accessIdentityProviderResponse AccessIdentityProviderResponse
err = json.Unmarshal(res, &accessIdentityProviderResponse)
if err != nil {
return AccessIdentityProvider{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
}
return accessIdentityProviderResponse.Result, nil
}
// DeleteAccessIdentityProvider deletes an Access Identity Provider.
//
// Account API Reference: https://developers.cloudflare.com/api/operations/access-identity-providers-delete-an-access-identity-provider
// Zone API Reference: https://developers.cloudflare.com/api/operations/zone-level-access-identity-providers-delete-an-access-identity-provider
func (api *API) DeleteAccessIdentityProvider(ctx context.Context, rc *ResourceContainer, identityProviderUUID string) (AccessIdentityProvider, error) {
uri := fmt.Sprintf(
"/%s/%s/access/identity_providers/%s",
rc.Level,
rc.Identifier,
identityProviderUUID,
)
res, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil)
if err != nil {
return AccessIdentityProvider{}, fmt.Errorf("%s: %w", errMakeRequestError, err)
}
var accessIdentityProviderResponse AccessIdentityProviderResponse
err = json.Unmarshal(res, &accessIdentityProviderResponse)
if err != nil {
return AccessIdentityProvider{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
}
return accessIdentityProviderResponse.Result, nil
}
// ListAccessIdentityProviderAuthContexts returns an identity provider's auth contexts
// AzureAD only
// Account API Reference: https://developers.cloudflare.com/api/operations/access-identity-providers-get-an-access-identity-provider
// Zone API Reference: https://developers.cloudflare.com/api/operations/zone-level-access-identity-providers-get-an-access-identity-provider
func (api *API) ListAccessIdentityProviderAuthContexts(ctx context.Context, rc *ResourceContainer, identityProviderID string) ([]AccessAuthContext, error) {
uri := fmt.Sprintf("/%s/%s/access/identity_providers/%s/auth_context", rc.Level, rc.Identifier, identityProviderID)
res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
if err != nil {
return []AccessAuthContext{}, err
}
var accessAuthContextListResponse AccessAuthContextsListResponse
err = json.Unmarshal(res, &accessAuthContextListResponse)
if err != nil {
return []AccessAuthContext{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
}
return accessAuthContextListResponse.Result, nil
}
// UpdateAccessIdentityProviderAuthContexts updates an existing Access Identity
// Provider.
// AzureAD only
// Account API Reference: https://developers.cloudflare.com/api/operations/access-identity-providers-refresh-an-access-identity-provider-auth-contexts
// Zone API Reference: https://developers.cloudflare.com/api/operations/zone-level-access-identity-providers-update-an-access-identity-provider
func (api *API) UpdateAccessIdentityProviderAuthContexts(ctx context.Context, rc *ResourceContainer, identityProviderID string) (AccessIdentityProvider, error) {
uri := fmt.Sprintf(
"/%s/%s/access/identity_providers/%s/auth_context",
rc.Level,
rc.Identifier,
identityProviderID,
)
res, err := api.makeRequestContext(ctx, http.MethodPut, uri, nil)
if err != nil {
return AccessIdentityProvider{}, err
}
var accessIdentityProviderResponse AccessIdentityProviderResponse
err = json.Unmarshal(res, &accessIdentityProviderResponse)
if err != nil {
return AccessIdentityProvider{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
}
return accessIdentityProviderResponse.Result, nil
}