Skip to content

Commit

Permalink
resolve protocol mapper types and builtin protocol mappers on server …
Browse files Browse the repository at this point in the history
…info
  • Loading branch information
dmnkdmnt committed May 18, 2022
1 parent 04f3ff4 commit bde6014
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 9 deletions.
47 changes: 46 additions & 1 deletion model_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,55 @@ func TestStringOrArray_Marshal(t *testing.T) {

dataArray := gocloak.StringOrArray{"1", "2", "3"}
jsonArray, err := json.Marshal(&dataArray)
assert.NoError(t, err, "Marshaling failed for array of strings: %s", dataString)
assert.NoError(t, err, "Marshaling failed for array of strings: %s", dataArray)
assert.Equal(t, "[\"1\",\"2\",\"3\"]", string(jsonArray))
}

func TestEnforcedString_UnmarshalJSON(t *testing.T) {
t.Parallel()

type testData struct {
In []byte
Out gocloak.EnforcedString
}

data := []testData{{
In: []byte(`"string value"`),
Out: "string value",
}, {
In: []byte(`"\"quoted string value\""`),
Out: `"quoted string value"`,
}, {
In: []byte(`true`),
Out: "true",
}, {
In: []byte(`42`),
Out: "42",
}, {
In: []byte(`{"foo": "bar"}`),
Out: `{"foo": "bar"}`,
}, {
In: []byte(`["foo"]`),
Out: `["foo"]`,
}}

for _, d := range data {
var val gocloak.EnforcedString
err := json.Unmarshal(d.In, &val)
assert.NoErrorf(t, err, "Unmarshalling failed with data: %v", d.In)
assert.Equal(t, d.Out, val)
}
}

func TestEnforcedString_MarshalJSON(t *testing.T) {
t.Parallel()

data := gocloak.EnforcedString("foo")
jsonString, err := json.Marshal(&data)
assert.NoErrorf(t, err, "Unmarshalling failed with data: %v", data)
assert.Equal(t, `"foo"`, string(jsonString))
}

func TestGetQueryParams(t *testing.T) {
t.Parallel()

Expand Down
81 changes: 73 additions & 8 deletions models.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gocloak

import (
"bytes"
"encoding/json"
"strings"

Expand Down Expand Up @@ -60,6 +61,32 @@ func (s *StringOrArray) MarshalJSON() ([]byte, error) {
return json.Marshal([]string(*s))
}

// EnforcedString can be used when the expected value is string but Keycloak in some cases gives you mixed types
type EnforcedString string

// UnmarshalJSON modify data as string before json unmarshal
func (s *EnforcedString) UnmarshalJSON(data []byte) error {
if data[0] != '"' {
// Escape unescaped quotes
data = bytes.ReplaceAll(data, []byte(`"`), []byte(`\"`))
data = bytes.ReplaceAll(data, []byte(`\\"`), []byte(`\"`))

// Wrap data in quotes
data = append([]byte(`"`), data...)
data = append(data, []byte(`"`)...)
}

var val string
err := json.Unmarshal(data, &val)
*s = EnforcedString(val)
return err
}

// MarshalJSON return json marshal
func (s *EnforcedString) MarshalJSON() ([]byte, error) {
return json.Marshal(*s)
}

// APIErrType is a field containing more specific API error types
// that may be checked by the receiver.
type APIErrType string
Expand Down Expand Up @@ -610,11 +637,12 @@ type ScopeRepresentation struct {

// ProtocolMapperRepresentation represents....
type ProtocolMapperRepresentation struct {
Config *map[string]string `json:"config,omitempty"`
ID *string `json:"id,omitempty"`
Name *string `json:"name,omitempty"`
Protocol *string `json:"protocol,omitempty"`
ProtocolMapper *string `json:"protocolMapper,omitempty"`
Config *map[string]string `json:"config,omitempty"`
ID *string `json:"id,omitempty"`
Name *string `json:"name,omitempty"`
Protocol *string `json:"protocol,omitempty"`
ProtocolMapper *string `json:"protocolMapper,omitempty"`
ConsentRequired *bool `json:"consentRequired,omitempty"`
}

// GetClientsParams represents the query parameters
Expand Down Expand Up @@ -964,11 +992,48 @@ type PasswordPolicy struct {
MultipleSupported bool `json:"multipleSupported,omitempty"`
}

// ProtocolMapperTypeProperty represents a property of a ProtocolMapperType
type ProtocolMapperTypeProperty struct {
Name string `json:"name,omitempty"`
Label string `json:"label,omitempty"`
HelpText string `json:"helpText,omitempty"`
Type string `json:"type,omitempty"`
Options []string `json:"options,omitempty"`
DefaultValue EnforcedString `json:"defaultValue,omitempty"`
Secret bool `json:"secret,omitempty"`
ReadOnly bool `json:"readOnly,omitempty"`
}

// ProtocolMapperType represents a type of protocol mapper
type ProtocolMapperType struct {
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Category string `json:"category,omitempty"`
HelpText string `json:"helpText,omitempty"`
Priority int `json:"priority,omitempty"`
Properties []ProtocolMapperTypeProperty `json:"properties,omitempty"`
}

// ProtocolMapperTypes holds the currently available ProtocolMapperType-s grouped by protocol
type ProtocolMapperTypes struct {
DockerV2 []ProtocolMapperType `json:"docker-v2,omitempty"`
SAML []ProtocolMapperType `json:"saml,omitempty"`
OpenIDConnect []ProtocolMapperType `json:"openid-connect,omitempty"`
}

// BuiltinProtocolMappers holds the currently available built-in blueprints of ProtocolMapper-s grouped by protocol
type BuiltinProtocolMappers struct {
SAML []ProtocolMapperRepresentation `json:"saml,omitempty"`
OpenIDConnect []ProtocolMapperRepresentation `json:"openid-connect,omitempty"`
}

// ServerInfoRepesentation represents a server info
type ServerInfoRepesentation struct {
SystemInfo *SystemInfoRepresentation `json:"systemInfo,omitempty"`
MemoryInfo *MemoryInfoRepresentation `json:"memoryInfo,omitempty"`
PasswordPolicies []*PasswordPolicy `json:"passwordPolicies,omitempty"`
SystemInfo *SystemInfoRepresentation `json:"systemInfo,omitempty"`
MemoryInfo *MemoryInfoRepresentation `json:"memoryInfo,omitempty"`
PasswordPolicies []*PasswordPolicy `json:"passwordPolicies,omitempty"`
ProtocolMapperTypes *ProtocolMapperTypes `json:"protocolMapperTypes,omitempty"`
BuiltinProtocolMappers *BuiltinProtocolMappers `json:"builtinProtocolMappers,omitempty"`
}

// FederatedIdentityRepresentation represents an user federated identity
Expand Down

0 comments on commit bde6014

Please sign in to comment.