mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2025-10-06 11:56:50 +08:00
238 lines
7.4 KiB
Go
238 lines
7.4 KiB
Go
package cloudflare
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/goccy/go-json"
|
|
)
|
|
|
|
// APIToken is the full API token.
|
|
type APIToken struct {
|
|
ID string `json:"id,omitempty"`
|
|
Name string `json:"name,omitempty"`
|
|
Status string `json:"status,omitempty"`
|
|
IssuedOn *time.Time `json:"issued_on,omitempty"`
|
|
ModifiedOn *time.Time `json:"modified_on,omitempty"`
|
|
NotBefore *time.Time `json:"not_before,omitempty"`
|
|
ExpiresOn *time.Time `json:"expires_on,omitempty"`
|
|
Policies []APITokenPolicies `json:"policies,omitempty"`
|
|
Condition *APITokenCondition `json:"condition,omitempty"`
|
|
Value string `json:"value,omitempty"`
|
|
}
|
|
|
|
// APITokenPermissionGroups is the permission groups associated with API tokens.
|
|
type APITokenPermissionGroups struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name,omitempty"`
|
|
Scopes []string `json:"scopes,omitempty"`
|
|
}
|
|
|
|
// APITokenPolicies are policies attached to an API token.
|
|
type APITokenPolicies struct {
|
|
ID string `json:"id,omitempty"`
|
|
Effect string `json:"effect"`
|
|
Resources map[string]interface{} `json:"resources"`
|
|
PermissionGroups []APITokenPermissionGroups `json:"permission_groups"`
|
|
}
|
|
|
|
// APITokenRequestIPCondition is the struct for adding an IP restriction to an
|
|
// API token.
|
|
type APITokenRequestIPCondition struct {
|
|
In []string `json:"in,omitempty"`
|
|
NotIn []string `json:"not_in,omitempty"`
|
|
}
|
|
|
|
// APITokenCondition is the outer structure for request conditions (currently
|
|
// only IPs).
|
|
type APITokenCondition struct {
|
|
RequestIP *APITokenRequestIPCondition `json:"request.ip,omitempty"`
|
|
}
|
|
|
|
// APITokenResponse is the API response for a single API token.
|
|
type APITokenResponse struct {
|
|
Response
|
|
Result APIToken `json:"result"`
|
|
}
|
|
|
|
// APITokenListResponse is the API response for multiple API tokens.
|
|
type APITokenListResponse struct {
|
|
Response
|
|
Result []APIToken `json:"result"`
|
|
}
|
|
|
|
// APITokenRollResponse is the API response when rolling the token.
|
|
type APITokenRollResponse struct {
|
|
Response
|
|
Result string `json:"result"`
|
|
}
|
|
|
|
// APITokenVerifyResponse is the API response for verifying a token.
|
|
type APITokenVerifyResponse struct {
|
|
Response
|
|
Result APITokenVerifyBody `json:"result"`
|
|
}
|
|
|
|
// APITokenPermissionGroupsResponse is the API response for the available
|
|
// permission groups.
|
|
type APITokenPermissionGroupsResponse struct {
|
|
Response
|
|
Result []APITokenPermissionGroups `json:"result"`
|
|
}
|
|
|
|
// APITokenVerifyBody is the API body for verifying a token.
|
|
type APITokenVerifyBody struct {
|
|
ID string `json:"id"`
|
|
Status string `json:"status"`
|
|
NotBefore time.Time `json:"not_before"`
|
|
ExpiresOn time.Time `json:"expires_on"`
|
|
}
|
|
|
|
// GetAPIToken returns a single API token based on the ID.
|
|
//
|
|
// API reference: https://api.cloudflare.com/#user-api-tokens-token-details
|
|
func (api *API) GetAPIToken(ctx context.Context, tokenID string) (APIToken, error) {
|
|
uri := fmt.Sprintf("/user/tokens/%s", tokenID)
|
|
|
|
res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
|
|
if err != nil {
|
|
return APIToken{}, err
|
|
}
|
|
|
|
var apiTokenResponse APITokenResponse
|
|
err = json.Unmarshal(res, &apiTokenResponse)
|
|
if err != nil {
|
|
return APIToken{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
|
|
}
|
|
|
|
return apiTokenResponse.Result, nil
|
|
}
|
|
|
|
// APITokens returns all available API tokens.
|
|
//
|
|
// API reference: https://api.cloudflare.com/#user-api-tokens-list-tokens
|
|
func (api *API) APITokens(ctx context.Context) ([]APIToken, error) {
|
|
res, err := api.makeRequestContext(ctx, http.MethodGet, "/user/tokens", nil)
|
|
if err != nil {
|
|
return []APIToken{}, err
|
|
}
|
|
|
|
var apiTokenListResponse APITokenListResponse
|
|
err = json.Unmarshal(res, &apiTokenListResponse)
|
|
if err != nil {
|
|
return []APIToken{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
|
|
}
|
|
|
|
return apiTokenListResponse.Result, nil
|
|
}
|
|
|
|
// CreateAPIToken creates a new token. Returns the API token that has been
|
|
// generated.
|
|
//
|
|
// The token value itself is only shown once (post create) and will present as
|
|
// `Value` from this method. If you fail to capture it at this point, you will
|
|
// need to roll the token in order to get a new value.
|
|
//
|
|
// API reference: https://api.cloudflare.com/#user-api-tokens-create-token
|
|
func (api *API) CreateAPIToken(ctx context.Context, token APIToken) (APIToken, error) {
|
|
res, err := api.makeRequestContext(ctx, http.MethodPost, "/user/tokens", token)
|
|
if err != nil {
|
|
return APIToken{}, err
|
|
}
|
|
|
|
var createTokenAPIResponse APITokenResponse
|
|
err = json.Unmarshal(res, &createTokenAPIResponse)
|
|
if err != nil {
|
|
return APIToken{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
|
|
}
|
|
|
|
return createTokenAPIResponse.Result, nil
|
|
}
|
|
|
|
// UpdateAPIToken updates an existing API token.
|
|
//
|
|
// API reference: https://api.cloudflare.com/#user-api-tokens-update-token
|
|
func (api *API) UpdateAPIToken(ctx context.Context, tokenID string, token APIToken) (APIToken, error) {
|
|
res, err := api.makeRequestContext(ctx, http.MethodPut, "/user/tokens/"+tokenID, token)
|
|
if err != nil {
|
|
return APIToken{}, err
|
|
}
|
|
|
|
var updatedTokenResponse APITokenResponse
|
|
err = json.Unmarshal(res, &updatedTokenResponse)
|
|
if err != nil {
|
|
return APIToken{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
|
|
}
|
|
|
|
return updatedTokenResponse.Result, nil
|
|
}
|
|
|
|
// RollAPIToken rolls the credential associated with the token.
|
|
//
|
|
// API reference: https://api.cloudflare.com/#user-api-tokens-roll-token
|
|
func (api *API) RollAPIToken(ctx context.Context, tokenID string) (string, error) {
|
|
uri := fmt.Sprintf("/user/tokens/%s/value", tokenID)
|
|
|
|
res, err := api.makeRequestContext(ctx, http.MethodPut, uri, nil)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
var apiTokenRollResponse APITokenRollResponse
|
|
err = json.Unmarshal(res, &apiTokenRollResponse)
|
|
if err != nil {
|
|
return "", fmt.Errorf("%s: %w", errUnmarshalError, err)
|
|
}
|
|
|
|
return apiTokenRollResponse.Result, nil
|
|
}
|
|
|
|
// VerifyAPIToken tests the validity of the token.
|
|
//
|
|
// API reference: https://api.cloudflare.com/#user-api-tokens-verify-token
|
|
func (api *API) VerifyAPIToken(ctx context.Context) (APITokenVerifyBody, error) {
|
|
res, err := api.makeRequestContext(ctx, http.MethodGet, "/user/tokens/verify", nil)
|
|
if err != nil {
|
|
return APITokenVerifyBody{}, err
|
|
}
|
|
|
|
var apiTokenVerifyResponse APITokenVerifyResponse
|
|
err = json.Unmarshal(res, &apiTokenVerifyResponse)
|
|
if err != nil {
|
|
return APITokenVerifyBody{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
|
|
}
|
|
|
|
return apiTokenVerifyResponse.Result, nil
|
|
}
|
|
|
|
// DeleteAPIToken deletes a single API token.
|
|
//
|
|
// API reference: https://api.cloudflare.com/#user-api-tokens-delete-token
|
|
func (api *API) DeleteAPIToken(ctx context.Context, tokenID string) error {
|
|
_, err := api.makeRequestContext(ctx, http.MethodDelete, "/user/tokens/"+tokenID, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// ListAPITokensPermissionGroups returns all available API token permission groups.
|
|
//
|
|
// API reference: https://api.cloudflare.com/#permission-groups-list-permission-groups
|
|
func (api *API) ListAPITokensPermissionGroups(ctx context.Context) ([]APITokenPermissionGroups, error) {
|
|
var r APITokenPermissionGroupsResponse
|
|
res, err := api.makeRequestContext(ctx, http.MethodGet, "/user/tokens/permission_groups", nil)
|
|
if err != nil {
|
|
return []APITokenPermissionGroups{}, err
|
|
}
|
|
|
|
err = json.Unmarshal(res, &r)
|
|
if err != nil {
|
|
return []APITokenPermissionGroups{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
|
|
}
|
|
|
|
return r.Result, nil
|
|
}
|