Repository: Nerzal/gocloak
Pull request #138 (2020-01-31 07:27:00)

New method UpdateClientProtocolMapper (Feature request #137)
Added new method UpdateClientProtocolMapper which updates a protocol mapper in client scope regarding to feature request #137.
Renamed test TestGocloak_CreateDeleteClientProtocolMapper to TestGocloak_CreateUpdateDeleteClientProtocolMapper for testing the new method.

Regards
Thomas


Patch:
diff --git a/README.md b/README.md
index bc37e23..9cda086 100644
--- a/README.md
+++ b/README.md
@@ -161,6 +161,7 @@ type GoCloak interface {
 	GetUsersByClientRoleName(token string, realm string, clientID string, roleName string, params GetUsersByRoleParams) ([]*User, error)
 	UserAttributeContains(attributes map[string][]string, attribute string, value string) bool
 	CreateClientProtocolMapper(token, realm, clientID string, mapper ProtocolMapperRepresentation) error
+	UpdateClientProtocolMapper(token, realm, clientID string, mapperID string, mapper ProtocolMapperRepresentation) error
 	DeleteClientProtocolMapper(token, realm, clientID, mapperID string) error
 
 	// *** Realm Roles ***
diff --git a/client.go b/client.go
index 817264a..564cda2 100644
--- a/client.go
+++ b/client.go
@@ -744,6 +744,15 @@ func (client *gocloak) CreateClientProtocolMapper(token, realm, clientID string,
 	return getID(resp), nil
 }
 
+// UpdateClientProtocolMapper updates a protocol mapper in client scope
+func (client *gocloak) UpdateClientProtocolMapper(token, realm, clientID string, mapperID string, mapper ProtocolMapperRepresentation) error {
+	resp, err := client.getRequestWithBearerAuth(token).
+		SetBody(mapper).
+		Put(client.getAdminRealmURL(realm, "clients", clientID, "protocol-mappers", "models", mapperID))
+
+	return checkForError(resp, err)
+}
+
 // DeleteClientProtocolMapper deletes a protocol mapper in client scope
 func (client *gocloak) DeleteClientProtocolMapper(token, realm, clientID, mapperID string) error {
 	resp, err := client.getRequestWithBearerAuth(token).
diff --git a/gocloak.go b/gocloak.go
index 0acccd3..f3a4f48 100644
--- a/gocloak.go
+++ b/gocloak.go
@@ -125,6 +125,8 @@ type GoCloak interface {
 	GetClientUserSessions(token, realm, clientID string) ([]*UserSessionRepresentation, error)
 	// CreateClientProtocolMapper creates a protocol mapper in client scope
 	CreateClientProtocolMapper(token, realm, clientID string, mapper ProtocolMapperRepresentation) (string, error)
+	// CreateClientProtocolMapper updates a protocol mapper in client scope
+	UpdateClientProtocolMapper(token, realm, clientID string, mapperID string, mapper ProtocolMapperRepresentation) error
 	// DeleteClientProtocolMapper deletes a protocol mapper in client scope
 	DeleteClientProtocolMapper(token, realm, clientID, mapperID string) error
 


Test patch:
diff --git a/client_test.go b/client_test.go
index 86c4bdc..f38c14e 100644
--- a/client_test.go
+++ b/client_test.go
@@ -2131,7 +2131,7 @@ func findProtocolMapperByID(client *Client, id string) *ProtocolMapperRepresenta
 	return nil
 }
 
-func TestGocloak_CreateDeleteClientProtocolMapper(t *testing.T) {
+func TestGocloak_CreateUpdateDeleteClientProtocolMapper(t *testing.T) {
 	t.Parallel()
 	cfg := GetConfig(t)
 	client := NewClientWithDebug(t)
@@ -2175,6 +2175,38 @@ func TestGocloak_CreateDeleteClientProtocolMapper(t *testing.T) {
 		findProtocolMapperByID(testClientAfter, id),
 		"protocol mapper has not been created",
 	)
+
+	err = client.UpdateClientProtocolMapper(
+		token.AccessToken,
+		cfg.GoCloak.Realm,
+		*(testClient.ID),
+		createdID,
+		ProtocolMapperRepresentation{
+			ID:             &id,
+			Name:           StringP("test"),
+			Protocol:       StringP("openid-connect"),
+			ProtocolMapper: StringP("oidc-usermodel-attribute-mapper"),
+			Config: map[string]string{
+				"access.token.claim":   "true",
+				"aggregate.attrs":      "",
+				"claim.name":           "testUpdated",
+				"id.token.claim":       "true",
+				"jsonType.label":       "String",
+				"multivalued":          "",
+				"user.attribute":       "test",
+				"userinfo.token.claim": "true",
+			},
+		},
+	)
+	assert.NoError(t, err, "UpdateClientProtocolMapper failed")
+
+	testClientAfterUpdate := GetClientByClientID(t, client, cfg.GoCloak.ClientID)
+	assert.Equal(
+		t,
+		findProtocolMapperByID(testClientAfterUpdate, id).Config["claim.name"],
+		"testUpdated",
+	)
+
 	err = client.DeleteClientProtocolMapper(
 		token.AccessToken,
 		cfg.GoCloak.Realm,