Repository: cloudflare/cloudflare-go (go)

Issue:
Access application custom attributes don't update when removed
### Confirmation

- [X] My issue isn't already found on the issue tracker.
- [X] I have replicated my issue using the latest version of the library and it is still present.

### cloudflare-go version

v0.101.0

### Go environment

```text
GO111MODULE=''
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/mprovost/Library/Caches/go-build'
GOENV='/Users/mprovost/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/mprovost/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/mprovost/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/opt/homebrew/Cellar/go/1.22.5/libexec'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/opt/homebrew/Cellar/go/1.22.5/libexec/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.22.5'
GCCGO='gccgo'
AR='ar'
CC='cc'
CXX='c++'
CGO_ENABLED='1'
GOMOD='/Users/mprovost/Projects/go-repro/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/zn/gmcgtk3s26xc8x7d4s2z43hw0000gn/T/go-build358138541=/tmp/go-build -gno-record-gcc-switches -fno-common'
```

### Expected output

Custom attributes should be removed when an empty list is passed as the custom attributes.

### Actual output

Nothing changes, since the attribute is omitted when empty:

https://github.com/cloudflare/cloudflare-go/blob/80d52bc4aa257a198d85177a11722407797c9705/access_application.go#L233

### Code demonstrating the issue

```go
package main

import (
	"context"
	"log"
	"os"

	"github.com/cloudflare/cloudflare-go"
)

func main() {
	api, err := cloudflare.New(os.Getenv("CLOUDFLARE_API_KEY"), os.Getenv("CLOUDFLARE_EMAIL"))
	if err != nil {
		log.Fatal(err)
	}

	ctx := context.Background()

	accountId := "<Account ID>"
	applicationId := "<Application ID>"

	account := cloudflare.AccountIdentifier(accountId)

	application := cloudflare.UpdateAccessApplicationParams{
		ID:   applicationId,
		Name: "TESTING",
		Type: "saas",
		SaasApplication: &cloudflare.SaasApplication{
			CustomAttributes: []cloudflare.SAMLAttributeConfig{},
		},
	}

	newApplication, err := api.UpdateAccessApplication(ctx, account, application)
	if err != nil {
		log.Fatal(err)
	}

	log.Print(newApplication)
}
```

### Steps to reproduce

1. Create an Access application
   - Saas type
   - SAML authentication (the application in this step doesn't matter)
   - Add a SAML attribute statement. It doesn't matter the contents, nor any other information in this step
   - The rest of the data is irrelevant and can be set to anything
2. Fill in the repro code with the proper account ID and application ID
3. Run the repro
4. Notice in the dashboard that the custom attribute statement wasn't removed

### References

_No response_

Pull request:
fix: enable removing access application custom attributes and claims
Removes the `omitempty` on Access application custom attributes. This allows an empty list to be passed to remove empty attributes, which would have otherwise been omitted.

closes #2837

## Description

Removes the `omitempty` on Access application custom attributes.

## Has your change been tested?

Using the script in #2837

## Types of changes

What sort of change does your code introduce/modify?

- [x] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)

## Checklist:

- [x] My code follows the code style of this project.
- [x] My change requires a change to the documentation.
- [x] I have updated the documentation accordingly.
- [x] I have added tests to cover my changes.
- [x] All new and existing tests passed.
- [x] This change is using publicly documented in [cloudflare/api-schemas](https://github.com/cloudflare/api-schemas) 
      and relies on stable APIs.

[1]: https://help.github.com/articles/closing-issues-using-keywords/


Patch:
diff --git a/.changelog/2838.txt b/.changelog/2838.txt
new file mode 100644
index 000000000..4a9c03ec0
--- /dev/null
+++ b/.changelog/2838.txt
@@ -0,0 +1,3 @@
+```release-notes:bug
+access_application: enable removing access application custom attributes and claims
+```
diff --git a/access_application.go b/access_application.go
index ec1dfcc62..def62c0b8 100644
--- a/access_application.go
+++ b/access_application.go
@@ -224,15 +224,15 @@ type SaasApplication struct {
 	AuthType  string     `json:"auth_type,omitempty"`
 
 	// SAML saas app
-	ConsumerServiceUrl            string                `json:"consumer_service_url,omitempty"`
-	SPEntityID                    string                `json:"sp_entity_id,omitempty"`
-	IDPEntityID                   string                `json:"idp_entity_id,omitempty"`
-	NameIDFormat                  string                `json:"name_id_format,omitempty"`
-	SSOEndpoint                   string                `json:"sso_endpoint,omitempty"`
-	DefaultRelayState             string                `json:"default_relay_state,omitempty"`
-	CustomAttributes              []SAMLAttributeConfig `json:"custom_attributes,omitempty"`
-	NameIDTransformJsonata        string                `json:"name_id_transform_jsonata,omitempty"`
-	SamlAttributeTransformJsonata string                `json:"saml_attribute_transform_jsonata"`
+	ConsumerServiceUrl            string                 `json:"consumer_service_url,omitempty"`
+	SPEntityID                    string                 `json:"sp_entity_id,omitempty"`
+	IDPEntityID                   string                 `json:"idp_entity_id,omitempty"`
+	NameIDFormat                  string                 `json:"name_id_format,omitempty"`
+	SSOEndpoint                   string                 `json:"sso_endpoint,omitempty"`
+	DefaultRelayState             string                 `json:"default_relay_state,omitempty"`
+	CustomAttributes              *[]SAMLAttributeConfig `json:"custom_attributes"`
+	NameIDTransformJsonata        string                 `json:"name_id_transform_jsonata,omitempty"`
+	SamlAttributeTransformJsonata string                 `json:"saml_attribute_transform_jsonata"`
 
 	// OIDC saas app
 	ClientID                     string                                     `json:"client_id,omitempty"`
@@ -242,7 +242,7 @@ type SaasApplication struct {
 	Scopes                       []string                                   `json:"scopes,omitempty"`
 	AppLauncherURL               string                                     `json:"app_launcher_url,omitempty"`
 	GroupFilterRegex             string                                     `json:"group_filter_regex,omitempty"`
-	CustomClaims                 []OIDCClaimConfig                          `json:"custom_claims,omitempty"`
+	CustomClaims                 *[]OIDCClaimConfig                         `json:"custom_claims"`
 	AllowPKCEWithoutClientSecret *bool                                      `json:"allow_pkce_without_client_secret,omitempty"`
 	RefreshTokenOptions          *RefreshTokenOptions                       `json:"refresh_token_options,omitempty"`
 	HybridAndImplicitOptions     *AccessApplicationHybridAndImplicitOptions `json:"hybrid_and_implicit_options,omitempty"`


Test patch:
diff --git a/access_application_test.go b/access_application_test.go
index d43085608..50f2c7e66 100644
--- a/access_application_test.go
+++ b/access_application_test.go
@@ -1011,7 +1011,7 @@ func TestCreateSAMLSaasAccessApplications(t *testing.T) {
 			SPEntityID:         "dash.example.com",
 			NameIDFormat:       "id",
 			DefaultRelayState:  "https://saas.example.com",
-			CustomAttributes: []SAMLAttributeConfig{
+			CustomAttributes: &[]SAMLAttributeConfig{
 				{
 					Name:       "test1",
 					NameFormat: "urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified",
@@ -1166,7 +1166,7 @@ func TestCreateOIDCSaasAccessApplications(t *testing.T) {
 			AppLauncherURL:               "https://saas.example.com",
 			GroupFilterRegex:             ".*",
 			AllowPKCEWithoutClientSecret: BoolPtr(false),
-			CustomClaims: []OIDCClaimConfig{
+			CustomClaims: &[]OIDCClaimConfig{
 				{
 					Name:     "test1",
 					Source:   SourceConfig{Name: "test1"},
@@ -1197,7 +1197,7 @@ func TestCreateOIDCSaasAccessApplications(t *testing.T) {
 			AppLauncherURL:               "https://saas.example.com",
 			GroupFilterRegex:             ".*",
 			AllowPKCEWithoutClientSecret: BoolPtr(false),
-			CustomClaims: []OIDCClaimConfig{
+			CustomClaims: &[]OIDCClaimConfig{
 				{
 					Name:     "test1",
 					Source:   SourceConfig{Name: "test1"},
@@ -1229,7 +1229,7 @@ func TestCreateOIDCSaasAccessApplications(t *testing.T) {
 			AppLauncherURL:               "https://saas.example.com",
 			GroupFilterRegex:             ".*",
 			AllowPKCEWithoutClientSecret: BoolPtr(false),
-			CustomClaims: []OIDCClaimConfig{
+			CustomClaims: &[]OIDCClaimConfig{
 				{
 					Name:     "test1",
 					Source:   SourceConfig{Name: "test1"},