There is the server tag qdlConfigName that is used to designate the active QDL configuration. This does mean you may have several in the configuration as needed.
A great place to start is in the base system's configuration documentation. All of that is supported as well as extensions specific to OA4MP, which are documented here.
These are in the <qdl> tag in additional to the standard attributes:
Name | Default | Description |
strict_acls | false | Enabled/disable enforcing strict access control for scripts. If this is set true, then every script must have permission granted to execute. Corollary: You must set permissions for every script to run or you will get errors if set to true. |
In the standard QDL configuration there are two parameters that bear special mention here.
If there is a single configuration, that may be named anything you like and it will be used. If there are multiple configurations, then you should set the attribute for qdlConfigName to be whatever the active configuration is. If it is omitted, the default name of qdl-default will be used.
Scripts at the server level are run for every client in the specified phase -- they are just standard script elements like in the client configuration. The following contract for server scripts holds for client scripts: Server script are run first, creating/updating the workspace, then the client scripts are run in the workspace.
This allows an administrator to set up state across the entire service. For instance, OA4MP has almost no concept of a user natively, since the idea is to use whatever infrastructure you have. A server script that grabs a user record and populates some data structures would allow extending OA4MP without having to alter the base server itself. Adding, say, a User and all supporting code is possible and CILogon does that, but it is a very major piece of coding and then you have to maintain it vis-a-vis OA4MP updates. QDL is much more straightforward and insulates you from server code changes.
If you give a script a specific exec_phase, the server scripts are run before any other scripts. This may take a bit of planning. If you want to so something in the post_auth phase after all clients have run their handlers, then you should actually set the script for the pre_token phase to run before any other processing in the next round.
Clients may skip server scripts if their skipServerScripts flag is set.
To add a script, put it in script tags. This uses QDL anaphors (aka scriptlets). You should read that in conjunction with the OA4MP scripting document, which is the complete documentation. server scripts
<scripts> <script> {qdl:... </script> <script> {qdl:... </script> ... </scripts>
You can either have one script per tag or have a single tag with an array of scripts. These are not in token handlers, but are at the top level. See the example below. There are many reasons to have scripts on the server:
(Is it ugly to have JSON inside XML? Sure. But it's consistent with client configurations. shrug.)
Here is a full example taken from my testing system:
<qdl name="qdl-test" enabled="true" debug="info" skipBadModulesOnLoad="true" restricted_io="false" strict_acls = "false" server_mode_on="true" script_path="vfs#/scripts/"> <virtual_file_systems> <vfs type="pass_through" access="rw"> <root_dir>/home/ncsa/dev/ncsa-git/oa4mp/server-admin/src/main/resources/qdl</root_dir> <scheme><![CDATA[vfs]]></scheme> <mount_point>/scripts</mount_point> </vfs> </virtual_file_systems> <modules> <module type="java" import_on_start="true"> <class_name>edu.uiuc.ncsa.myproxy.oa4mp.qdl.OA2QDLLoader</class_name> </module> </modules> <modules> <module type="java" import_on_start="true"> <class_name>edu.uiuc.ncsa.myproxy.oa4mp.qdl.claims.TokenHandlerLoader</class_name> </module> </modules> <scripts> <script> {"qdl":{"code":[ "x:='my_custom_claim';", "say('*** IN SERVER SCRIPT');", "claims.'my_claim':=x;", "access_token.'my_at_claim':='my_at_claim';", "refresh_token.'my_rt_claim':='my_rt_claim';" ], "xmd":{"exec_phase":"post_token"} } } </script> <script> {"qdl": { "load":"ws_init.qdl", "xmd":{"exec_phase":"pre_auth","token_type":"access"}, "args":[4,true,{"server":"localhost","port":443}] } } </script> </scripts> </qdl>
The configuration sets the runtime environment for every QDL workspace. The script path is set, the virtual file system mounted and a couple of modules are loaded into every workspace. The two specified scripts run resp. a block of code which just sets a couple of attributes in the access and refresh token (to show it can be done), and run a script called ws_init.qdl (resolved against the script path) in the pre_auth phase, so that the workspace is set up for all clients. They are in separate script elements, though you could just run them together as elements in an array, though that gets pretty hard to parse manually. One point is that while the server has server_mode_on="true", server scripts are still allowed to run code blocks. This is because clients have no access to them. The standard caveat applies to code blocks. Keep them very simple or just run a script.
Finally, clients may be configured individually to not have these scripts run.
The module system was revised and in proved in QDL 1.5. The major innovation is that before, modules