1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
|
# -*- text -*-
#
#
# $Id$
#######################################################################
#
# = JSON Module
#
# The `json` module provides the `json_encode` XLAT, which may be
# used to encode a given list of attributes into different
# formats of JSON object.
#
#
# ## Configuration Settings
#
json {
#
# The only options for the JSON module are to control the output
# format of the `json_encode` xlat.
#
encode {
#
# output_mode:: set the format of JSON documenta
# that should be created. This may be one of:
#
# - object
# - object_simple
# - array
# - array_of_names
# - array_of_values
#
# Examples of each format are given below.
#
# output_mode = object
#
# ### Formatting options for attribute names
#
attribute {
#
# prefix:: Add a colon-delimited prefix to all
# attribute names in the output document. For example,
# with a prefix of "foo", `User-Name` will be output as
# `foo:User-Name`.
#
# prefix =
}
#
# ### Formatting options for attribute values
#
value {
#
# single_value_as_array:: always put values in an array
#
# Output formats will by default put single values as a
# JSON object (string, integer, etc). More than one
# value will, depending on the output format, be added
# as an array.
#
# When this option is enabled, values will always be
# added as an array.
#
# single_value_as_array = no
#
# enum_as_integer:: output the integer value of
# enumerated attributes
#
# Where an attribute has enum values, the textual
# representation of the value will normally be output.
# Enable this option to force the numeric value
# instead.
#
# enum_as_integer = no
#
# always_string:: force all values to be strings
#
# Integer values are normally written to the JSON
# document as numbers (i.e. without quotes). Enable
# this option to force all values to be as quoted
# strings.
#
# always_string = no
}
}
}
#
# ## Expansions
#
# rlm_json provides the below xlat function.
#
# ### %{json_encode:...}
#
# Generates a JSON document from a given list of attribute templates. The
# format of document generated can be controlled with the 'encode' section in
# the module configuration. Attribute values will automatically be escaped so
# they are JSON-safe.
#
# NOTE: The name of the xlat is based on the instance name of this module. If
# the module was defined as `json jdoc {...}`, then the xlat name will be
# `jdoc_encode`.
#
# The xlat should be passed a list of attributes to encode. Each attribute
# (after template expansion) will be added to a list of attributes to include
# in the JSON document. If any of the attributes given are preceeded with a `!`
# then they are removed from the list. Once all attributes have been processed,
# the JSON document will be created using this list.
#
# For example, the following will produce a JSON document with two attributes in
# it, `User-Name` and `Calling-Station-Id`, from the RADIUS request:
#
# .Example
#
# ```
# %{json_encode:&User-Name &Calling-Station-Id}
# ```
#
# The following will include all attributes in the RADIUS request, except for
# `User-Password`:
#
# .Example
#
# ```
# %{json_encode:&request[*] !&User-Password}
# ```
#
# In another (contrived) example, all the attributes in the RADIUS request will
# be included in the document, _except_ any attributes in the RADIUS reply.
# `&User-Name` will be included from the control list, too, if it exists:
#
# .Example
#
# ```
# %{json_encode:&request[*] !&reply[*] &control:User-Name}
# ```
#
# #### Output format modes
#
# There are a number of output modes, each generating a different format of
# JSON document.
#
# NOTE: In the JSON document, "type" is the type of the _attribute_, which is
# not necessarily the same as the type of the "value" in the document. See e.g.
# `Login-Service` above, an enumerated value.
#
# The following examples assume the three attributes are being added to the
# JSON document:
#
# ```
# User-Name = bob
# Filter-Id = ab
# Filter-Id += cd
# ```
#
# #### Object output mode examples
#
# These modes output a JSON object.
#
# .Output mode "object"
#
# [source,json]
# ----
# {
# "User-Name": {
# "type": "string",
# "value": "bob"
# },
# "Filter-Id": {
# "type": "string",
# "value": ["ab","cd"]
# }
# }
# ----
#
# .Output mode "object_simple"
#
# [source,json]
# ----
# {
# "User-Name": "bob",
# "Filter-Id": ["ab","cd"]
# }
# ----
#
# #### Array output mode examples
#
# The "array" mode is a list of objects, each containing an attribute. If the
# "single_value_as_array" value option is set then each attribute will only
# appear once in the array, and "value" will be a list of all the values from
# the same attribute.
#
# .Output mode "array"
#
# [source,json]
# ----
# [
# {
# "name": "User-Name",
# "type": "string",
# "value": "bob"
# },
# {
# "name": "Filter-Id",
# "type": "string",
# "value": "ab"
# },
# {
# "name": "Filter-Id",
# "type": "string",
# "value": "cd"
# }
# ]
# ----
#
# .Output mode "array" when "single_value_as_array" is also set
#
# [source,json]
# ----
# [
# {
# "name": "User-Name",
# "type": "string",
# "value": ["bob"]
# },
# {
# "name": "Filter-Id",
# "type": "string",
# "value": ["ab","cd"]
# }
# ]
# ----
#
# The following output modes either do not include the attribute names or
# values. They are likely to be useful only when the attributes are
# individually specified and _guaranteed to exist_. In this case the attribute
# names in `array_of_names` will have corresponding indexes to the values in
# `array_of_values`.
#
# .Output mode "array_of_names"
#
# [source,json]
# ----
# [
# "User-Name",
# "Filter-Id",
# "Filter-Id"
# ]
# ----
#
# .Output mode "array_of_values"
#
# [source,json]
# ----
# [
# "bob",
# "ab",
# "cd"
# ]
# ----
#
|