rest modules JSON replies format and types
Hello all, I am having a bit of fun playing around with the rest module in 3.0.10 to replace a custom coded perl module. I got it working and everything seem to work nicely but for one thing. The documentation says that the JSON payload in the request and in the reply should be in the same format. I have no problem with the request (since FR is encoding it anyway), and I have been able to hack a reply in the right format which is accepted by the module and sets the attributes I want, but I must concede that I am cheating a little at this point. I am returning every attribute with the type set to “string”. That is to say, if I get a request that looks like the following: { "Called-Station-SSID": { "value": [ "IofStuff" ], "type": "string" }, "EAP-Type": { "value": [ 26 ], "type": "integer" }, "FreeRADIUS-Proxied-To": { "value": [ "127.0.0.1" ], "type": "ipaddr" }, "Location-Capable": { "value": [ 1 ], "type": "integer" }, "Tunnel-Medium-Type": { "value": [ "IEEE-802" ], "type": "integer" }, } My reply will actually look like: { "Tunnel-Medium-Type": { "type": "string", "value": [ 6 ] }, "Tunnel-Type": { "type": "string", "value": [ 13 ] }, "Tunnel-Private-Group-ID": { "type": "string", "value": [ 2 ] } } And yet it seems to work. So, does FreeRADIUS actually look at those types in the JSON reply? Should I be looking into parsing the dictionary files in my REST service to populate the reply with the correct types? Not that it would be that hard, but if it does not matter I can find better ways of keeping myself entertained... Much obliged for any help, -- Louis Munro lmunro@inverse.ca :: www.inverse.ca +1.514.447.4918 x125 :: +1 (866) 353-6153 x125 Inverse inc. :: Leaders behind SOGo (www.sogo.nu) and PacketFence (www.packetfence.org)
So, does FreeRADIUS actually look at those types in the JSON reply?
No, the types are more to let the REST server know what dictionary types the attributes are. JSON types are a subset of the datatypes we have in the server. Reading through the code it looks like the un-martialing function is quite lazy and is just calls json_object_get_string to get a string representation of the type and then fr_pair_value_from_str to convert that to a proper C type. I suppose if json_object_get_string didn't like being called on integer types it could cause issues. Try with with compact version: { "Tunnel-Private-Group-ID": 2 } and then if that doesn't work: { "Tunnel-Private-Group-ID": "2" } If the first works, it points to an issues in json_pair_make/leaf, if the second works then it's an issue with json_object_get_string, which would be an easy fix. Run with -Xx to get extra info.
Should I be looking into parsing the dictionary files in my REST service to populate the reply with the correct types? Not that it would be that hard, but if it does not matter I can find better ways of keeping myself entertained...
Nah. -Arran Ignore the bit about recursing. It'll work some day, just not right now... /** Processes JSON response and converts it into multiple VALUE_PAIRs * * Processes JSON attribute declarations in the format below. Will recurse when * processing nested attributes. When processing nested attributes flags and * operators from previous attributes are not inherited. * * JSON response format is: @verbatim { "<attribute0>":{ "do_xlat":<bool>, "is_json":<bool>, "op":"<operator>", "value":[<value0>,<value1>,<valueN>] }, "<attribute1>":{ "value":{ "<nested-attribute0>":{ "op":"<operator>", "value":<value0> } } }, "<attribute2>":"<value0>", "<attributeN>":[<value0>,<value1>,<valueN>] } @endverbatim * * JSON valuepair flags: * - do_xlat (optional) Controls xlat expansion of values. Defaults to true. * - is_json (optional) If true, any nested JSON data will be copied to the * VALUE_PAIR in string form. Defaults to true. * - op (optional) Controls how the attribute is inserted into * the target list. Defaults to ':=' (T_OP_SET). * * If "op" is ':=' or '=', it will be automagically changed to '+=' for the * second and subsequent values in multivalued attributes. This does not work * between multiple attribute declarations. * * @see fr_tokens_table * * @param[in] instance configuration data. * @param[in] section configuration data. * @param[in] request Current request. * @param[in] object containing root node, or parent node. * @param[in] level Current nesting level. * @param[in] max counter, decremented after each VALUE_PAIR is created, * when 0 no more attributes will be processed. * @return * - Number of attributes created. * - < 0 on error. */ static int json_pair_make(rlm_rest_t const *instance, rlm_rest_section_t *section, REQUEST *request, json_object *object, UNUSED int level, int max) { Arran Cudbard-Bell <a.cudbardb@freeradius.org> FreeRADIUS development team FD31 3077 42EC 7FCD 32FE 5EE2 56CF 27F9 30A8 CAA2
On Feb 3, 2016, at 16:45 , Arran Cudbard-Bell <a.cudbardb@freeradius.org> wrote:
Try with with compact version:
{ "Tunnel-Private-Group-ID": 2 }
and then if that doesn't work:
{ "Tunnel-Private-Group-ID": "2" }
The first works for me. The (perl) module I use to serialize to JSON automatically quotes strings and leaves integers as is. So { "Airespace-ACL-Name": "registration", "Tunnel-Medium-Type": 6, "Tunnel-Type": 13, "Tunnel-Private-Group-ID": 2 } Seems to work just fine and results in (8) Sent Access-Accept Id 200 from 172.20.20.96:1812 to 172.20.110.250:32769 length 0 (8) User-Name = "joetester" (8) Tunnel-Private-Group-Id = "2" (8) Tunnel-Type = VLAN (8) Tunnel-Medium-Type = IEEE-802 (8) Airespace-ACL-Name = "registration" (8) MS-MPPE-Recv-Key = 0xb20b4de20b6a2dad2adcbdc6e895133bd1b9bc332ff0abe58095c6da1926517b (8) MS-MPPE-Send-Key = 0x179b0a6f723109bf0708039c6dd04ae4353eadd9ef95652bc93d748785b77acb (8) EAP-Message = 0x03090004 (8) Message-Authenticator = 0x00000000000000000000000000000000 (8) Finished request
Run with -Xx to get extra info.
Should I be looking into parsing the dictionary files in my REST service to populate the reply with the correct types? Not that it would be that hard, but if it does not matter I can find better ways of keeping myself entertained...
Nah.
Thank you for setting me straight. I was making this more complicated than it deserved. I’ll go and shave some other yak now. Regards, -- Louis Munro lmunro@inverse.ca :: www.inverse.ca +1.514.447.4918 x125 :: +1 (866) 353-6153 x125 Inverse inc. :: Leaders behind SOGo (www.sogo.nu) and PacketFence (www.packetfence.org)
On 4 Feb 2016, at 07:26, Louis Munro <lmunro@inverse.ca> wrote:
On Feb 3, 2016, at 16:45 , Arran Cudbard-Bell <a.cudbardb@freeradius.org> wrote:
Try with with compact version:
{ "Tunnel-Private-Group-ID": 2 }
and then if that doesn't work:
{ "Tunnel-Private-Group-ID": "2" }
The first works for me. The (perl) module I use to serialize to JSON automatically quotes strings and leaves integers as is. So
{ "Airespace-ACL-Name": "registration", "Tunnel-Medium-Type": 6, "Tunnel-Type": 13, "Tunnel-Private-Group-ID": 2 }
Ok, thanks. Could you open an issue ticket, and i'll figure out whatever the problem is with the expanded reply. -Arran Arran Cudbard-Bell <a.cudbardb@freeradius.org> FreeRADIUS development team FD31 3077 42EC 7FCD 32FE 5EE2 56CF 27F9 30A8 CAA2
On Feb 4, 2016, at 15:03 , Arran Cudbard-Bell <a.cudbardb@freeradius.org> wrote:
Ok, thanks. Could you open an issue ticket, and i'll figure out whatever the problem is with the expanded reply.
-Arran
Done: https://github.com/FreeRADIUS/freeradius-server/issues/1525 Feel free to let me know if I was not clear enough in the description or if I misunderstood what you wrote. Regards, -- Louis Munro lmunro@inverse.ca :: www.inverse.ca +1.514.447.4918 x125 :: +1 (866) 353-6153 x125 Inverse inc. :: Leaders behind SOGo (www.sogo.nu) and PacketFence (www.packetfence.org)
On 4 Feb 2016, at 12:33, Louis Munro <lmunro@inverse.ca> wrote:
On Feb 4, 2016, at 15:03 , Arran Cudbard-Bell <a.cudbardb@freeradius.org> wrote:
Ok, thanks. Could you open an issue ticket, and i'll figure out whatever the problem is with the expanded reply.
-Arran
Done: https://github.com/FreeRADIUS/freeradius-server/issues/1525
Feel free to let me know if I was not clear enough in the description or if I misunderstood what you wrote.
That's fine. Hopefully have time to look at this tomorrow. In v3.1.x we have a rlm_json module which implements a jpath style query syntax for extracting JSON nodes. You might want to check it out if you're returning complex data structures. -Arran Arran Cudbard-Bell <a.cudbardb@freeradius.org> FreeRADIUS development team FD31 3077 42EC 7FCD 32FE 5EE2 56CF 27F9 30A8 CAA2
participants (2)
-
Arran Cudbard-Bell -
Louis Munro