Skip to content

Commit

Permalink
AUTH-5403 added access custom pages
Browse files Browse the repository at this point in the history
  • Loading branch information
rkernscloudflaretest committed Aug 1, 2023
1 parent c6d8f5a commit 816fc65
Show file tree
Hide file tree
Showing 6 changed files with 312 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .changelog/1343.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
access_custom_page: Add support for custom pages
```
3 changes: 3 additions & 0 deletions access_application.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ type AccessApplication struct {
HttpOnlyCookieAttribute *bool `json:"http_only_cookie_attribute,omitempty"`
ServiceAuth401Redirect *bool `json:"service_auth_401_redirect,omitempty"`
PathCookieAttribute *bool `json:"path_cookie_attribute,omitempty"`
CustomPages []string `json:"custom_pages,omitempty"`
}

type AccessApplicationGatewayRule struct {
Expand Down Expand Up @@ -139,6 +140,7 @@ type CreateAccessApplicationParams struct {
SessionDuration string `json:"session_duration,omitempty"`
SkipInterstitial *bool `json:"skip_interstitial,omitempty"`
Type AccessApplicationType `json:"type,omitempty"`
CustomPages []string `json:"custom_pages,omitempty"`
}

type UpdateAccessApplicationParams struct {
Expand All @@ -165,6 +167,7 @@ type UpdateAccessApplicationParams struct {
SessionDuration string `json:"session_duration,omitempty"`
SkipInterstitial *bool `json:"skip_interstitial,omitempty"`
Type AccessApplicationType `json:"type,omitempty"`
CustomPages []string `json:"custom_pages,omitempty"`
}

// ListAccessApplications returns all applications within an account or zone.
Expand Down
4 changes: 3 additions & 1 deletion access_application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ func TestAccessApplications(t *testing.T) {
"skip_interstitial": true,
"app_launcher_visible": true,
"service_auth_401_redirect": true,
"path_cookie_attribute": true
"path_cookie_attribute": true,
"custom_pages": ["480f4f69-1a28-4fdd-9240-1ed29f0ac1dc"]
}
],
"result_info": {
Expand Down Expand Up @@ -83,6 +84,7 @@ func TestAccessApplications(t *testing.T) {
LogoURL: "https://www.example.com/example.png",
SkipInterstitial: BoolPtr(true),
PathCookieAttribute: BoolPtr(true),
CustomPages: []string{"480f4f69-1a28-4fdd-9240-1ed29f0ac1dc"},
}}

mux.HandleFunc("/accounts/"+testAccountID+"/access/apps", handler)
Expand Down
104 changes: 104 additions & 0 deletions access_custom_page.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package cloudflare

import (
"context"
"encoding/json"
"fmt"
"net/http"
)

type AccessCustomPageType string

const (
Forbidden AccessCustomPageType = "forbidden"
IdentityDenied AccessCustomPageType = "identity_denied"
)

type AccessCustomPage struct {
// The HTML content of the custom page.
CustomHTML string `json:"custom_html,omitempty"`
Name string `json:"name,omitempty"`
AppCount int `json:"app_count,omitempty"`
Type AccessCustomPageType `json:"type,omitempty"`
UID string `json:"uid,omitempty"`
}

type AccessCustomPageListResponse struct {
Response
Result []AccessCustomPage `json:"result"`
ResultInfo `json:"result_info"`
}

type AccessCustomPageResponse struct {
Response
Result AccessCustomPage `json:"result"`
}

func (api *API) AccessCustomPages(ctx context.Context, rc *ResourceContainer, pageOpts PaginationOptions) ([]AccessCustomPage, error) {
uri := buildURI(fmt.Sprintf("/%s/%s/access/custom_pages", rc.Level, rc.Identifier), pageOpts)
res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
if err != nil {
return []AccessCustomPage{}, err
}

var customPagesResponse AccessCustomPageListResponse
err = json.Unmarshal(res, &customPagesResponse)
if err != nil {
return []AccessCustomPage{}, err
}
return customPagesResponse.Result, nil
}

func (api *API) AccessCustomPage(ctx context.Context, rc *ResourceContainer, customPageID string) (AccessCustomPage, error) {
uri := fmt.Sprintf("/%s/%s/access/custom_pages/%s", rc.Level, rc.Identifier, customPageID)
res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
if err != nil {
return AccessCustomPage{}, err
}

var customPageResponse AccessCustomPageResponse
err = json.Unmarshal(res, &customPageResponse)
if err != nil {
return AccessCustomPage{}, err
}
return customPageResponse.Result, nil
}

func (api *API) CreateAccessCustomPage(ctx context.Context, rc *ResourceContainer, customPage AccessCustomPage) (AccessCustomPage, error) {
uri := fmt.Sprintf("/%s/%s/access/custom_pages", rc.Level, rc.Identifier)
res, err := api.makeRequestContext(ctx, http.MethodPost, uri, customPage)
if err != nil {
return AccessCustomPage{}, err
}

var customPageResponse AccessCustomPageResponse
err = json.Unmarshal(res, &customPageResponse)
if err != nil {
return AccessCustomPage{}, err
}
return customPageResponse.Result, nil
}

func (api *API) DeleteAccessCustomPage(ctx context.Context, rc *ResourceContainer, customPageID string) error {
uri := fmt.Sprintf("/%s/%s/access/custom_pages/%s", rc.Level, rc.Identifier, customPageID)
_, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil)
if err != nil {
return err
}
return nil
}

func (api *API) UpdateAccessCustomPage(ctx context.Context, rc *ResourceContainer, customPageID string, customPage AccessCustomPage) (AccessCustomPage, error) {
uri := fmt.Sprintf("/%s/%s/access/custom_pages/%s", rc.Level, rc.Identifier, customPageID)
res, err := api.makeRequestContext(ctx, http.MethodPut, uri, customPage)
if err != nil {
return AccessCustomPage{}, err
}

var customPageResponse AccessCustomPageResponse
err = json.Unmarshal(res, &customPageResponse)
if err != nil {
return AccessCustomPage{}, err
}
return customPageResponse.Result, nil
}
191 changes: 191 additions & 0 deletions access_custom_page_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
package cloudflare

import (
"context"
"fmt"
"net/http"
"testing"

"github.com/stretchr/testify/assert"
)

func TestAccessCustomPages(t *testing.T) {
setup()
defer teardown()

handler := func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, r.Method, http.MethodGet, "HTTP method")
w.Header().Set("content-type", "application/json")
fmt.Fprintf(w, `{
"success": true,
"errors": [],
"messages": [],
"result": [
{
"name": "Forbidden",
"app_count": 0,
"type": "forbidden",
"uid": "480f4f69-1a28-4fdd-9240-1ed29f0ac1dc"
}
],
"result_info": {
"page": 1,
"per_page": 20,
"count": 1,
"total_count": 1
}
}`)
}

want := []AccessCustomPage{
{
Name: "Forbidden",
AppCount: 0,
Type: Forbidden,
UID: "480f4f69-1a28-4fdd-9240-1ed29f0ac1dc",
},
}
mux.HandleFunc("/accounts/"+testAccountID+"/access/custom_pages", handler)
actual, err := client.AccessCustomPages(context.Background(), AccountIdentifier(testAccountID), PaginationOptions{})

if assert.NoError(t, err) {
assert.Equal(t, want, actual)
}
}

func TestAccessCustomPage(t *testing.T) {
setup()
defer teardown()

handler := func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, r.Method, http.MethodGet, "HTTP method")
w.Header().Set("Content-Type", "application/json")
fmt.Fprintf(w, `{
"success": true,
"errors": [],
"messages": [],
"result": {
"custom_html": "<html><body><h1>Forbidden</h1></body></html>",
"name": "Forbidden",
"app_count": 0,
"type": "forbidden",
"uid": "480f4f69-1a28-4fdd-9240-1ed29f0ac1dc"
}
}`)
}

want := AccessCustomPage{
Name: "Forbidden",
AppCount: 0,
Type: Forbidden,
UID: "480f4f69-1a28-4fdd-9240-1ed29f0ac1dc",
CustomHTML: "<html><body><h1>Forbidden</h1></body></html>",
}
mux.HandleFunc("/accounts/"+testAccountID+"/access/custom_pages/480f4f69-1a28-4fdd-9240-1ed29f0ac1dc", handler)
actual, err := client.AccessCustomPage(context.Background(), AccountIdentifier(testAccountID), "480f4f69-1a28-4fdd-9240-1ed29f0ac1dc")

if assert.NoError(t, err) {
assert.Equal(t, want, actual)
}
}

func TestCreateAccessCustomPage(t *testing.T) {
setup()
defer teardown()

handler := func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, r.Method, http.MethodPost, "HTTP method")
w.Header().Set("Content-Type", "application/json")
fmt.Fprintf(w, `{
"success": true,
"errors": [],
"messages": [],
"result": {
"custom_html": "<html><body><h1>Forbidden</h1></body></html>",
"name": "Forbidden",
"app_count": 0,
"type": "forbidden",
"uid": "480f4f69-1a28-4fdd-9240-1ed29f0ac1dc"
}
}`)
}

customPage := AccessCustomPage{
Name: "Forbidden",
AppCount: 0,
Type: Forbidden,
UID: "480f4f69-1a28-4fdd-9240-1ed29f0ac1dc",
CustomHTML: "<html><body><h1>Forbidden</h1></body></html>",
}

mux.HandleFunc("/accounts/"+testAccountID+"/access/custom_pages", handler)
actual, err := client.CreateAccessCustomPage(context.Background(), AccountIdentifier(testAccountID), AccessCustomPage{
Name: "Forbidden",
Type: Forbidden,
CustomHTML: "<html><body><h1>Forbidden</h1></body></html>",
})

if assert.NoError(t, err) {
assert.Equal(t, customPage, actual)
}
}

func TestUpdateAccessCustomPage(t *testing.T) {
setup()
defer teardown()

handler := func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, r.Method, http.MethodPut, "HTTP method")
w.Header().Set("Content-Type", "application/json")
fmt.Fprintf(w, `{
"success": true,
"errors": [],
"messages": [],
"result": {
"custom_html": "<html><body><h1>Forbidden</h1></body></html>",
"name": "Forbidden",
"app_count": 0,
"type": "forbidden",
"uid": "480f4f69-1a28-4fdd-9240-1ed29f0ac1dc"
}
}`)
}

customPage := AccessCustomPage{
Name: "Forbidden",
AppCount: 0,
Type: Forbidden,
UID: "480f4f69-1a28-4fdd-9240-1ed29f0ac1dc",
CustomHTML: "<html><body><h1>Forbidden</h1></body></html>",
}

mux.HandleFunc("/accounts/"+testAccountID+"/access/custom_pages/480f4f69-1a28-4fdd-9240-1ed29f0ac1dc", handler)
actual, err := client.UpdateAccessCustomPage(context.Background(), AccountIdentifier(testAccountID), "480f4f69-1a28-4fdd-9240-1ed29f0ac1dc", customPage)

if assert.NoError(t, err) {
assert.Equal(t, customPage, actual)
}
}

func TestDeleteAccessCustomPage(t *testing.T) {
setup()
defer teardown()

handler := func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, r.Method, http.MethodDelete, "HTTP method")
w.Header().Set("Content-Type", "application/json")
fmt.Fprintf(w, `{
"success": true,
"errors": [],
"messages": [],
result: {
"id": "480f4f69-1a28-4fdd-9240-1ed29f0ac1dc"
}
}`)
}

mux.HandleFunc("/accounts/"+testAccountID+"/access/custom_pages/480f4f69-1a28-4fdd-9240-1ed29f0ac1dc", handler)
err := client.DeleteAccessCustomPage(context.Background(), AccountIdentifier(testAccountID), "480f4f69-1a28-4fdd-9240-1ed29f0ac1dc")

assert.NoError(t, err)
}
8 changes: 8 additions & 0 deletions access_organization.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type AccessOrganization struct {
UIReadOnlyToggleReason string `json:"ui_read_only_toggle_reason,omitempty"`
UserSeatExpirationInactiveTime string `json:"user_seat_expiration_inactive_time,omitempty"`
AutoRedirectToIdentity *bool `json:"auto_redirect_to_identity,omitempty"`
CustomPages AccessOrganizationCustomPages `json:"custom_pages,omitempty"`
}

// AccessOrganizationLoginDesign represents the login design options.
Expand All @@ -30,6 +31,11 @@ type AccessOrganizationLoginDesign struct {
FooterText string `json:"footer_text"`
}

type AccessOrganizationCustomPages struct {
Forbidden AccessCustomPageType `json:"forbidden,omitempty"`
IdentityDenied AccessCustomPageType `json:"identity_denied,omitempty"`
}

// AccessOrganizationListResponse represents the response from the list
// access organization endpoint.
type AccessOrganizationListResponse struct {
Expand Down Expand Up @@ -57,6 +63,7 @@ type CreateAccessOrganizationParams struct {
UIReadOnlyToggleReason string `json:"ui_read_only_toggle_reason,omitempty"`
UserSeatExpirationInactiveTime string `json:"user_seat_expiration_inactive_time,omitempty"`
AutoRedirectToIdentity *bool `json:"auto_redirect_to_identity,omitempty"`
CustomPages AccessOrganizationCustomPages `json:"custom_pages,omitempty"`
}

type UpdateAccessOrganizationParams struct {
Expand All @@ -67,6 +74,7 @@ type UpdateAccessOrganizationParams struct {
UIReadOnlyToggleReason string `json:"ui_read_only_toggle_reason,omitempty"`
UserSeatExpirationInactiveTime string `json:"user_seat_expiration_inactive_time,omitempty"`
AutoRedirectToIdentity *bool `json:"auto_redirect_to_identity,omitempty"`
CustomPages AccessOrganizationCustomPages `json:"custom_pages,omitempty"`
}

func (api *API) GetAccessOrganization(ctx context.Context, rc *ResourceContainer, params GetAccessOrganizationParams) (AccessOrganization, ResultInfo, error) {
Expand Down

0 comments on commit 816fc65

Please sign in to comment.