As I said in the last post, an API would be required to make the system more testable and more consistent.
I started straight away and wrote up something quickly. Over the next week, it solidified into something that appears to cover any needs that I have.
So here’s how the API works:
Requests are sent to a URL which is generated like this:
The plugin name is optional. Leaving it out means you want to call a core function.
Parameters can be added by adding
/key=value pairs to the URL.
An example URL might be this:
Sending that, with a POST parameter for the password, will log me in.
To log out, I can use this URL:
mod_rewrite is used to direct a request through a script which tears the URL apart into parameters.
p parameter is given, the function is named after the plugin, rewritten to match the WebME coding standard.
For example, if the URL is
/a/p=comments/f=editComment, then the “comments” part is rewritten as Comments, and ‘_’ and “editComment” are appended to form the function name “Comments_editComment”, which is called and the result returned to the browser.
For double-barrel plugin names, such as “image-gallery”, the name is rewritten to “ImageGallery”.
p parameter is given, then the request is a core function, and “Core_” is prepended to the function name.
For example, the login URL above,
/a/p=login calls the function
If a function name begins with “admin”, it is an admin function (see below for more on this).
If no plugin name is supplied, then the core API file, /ww.incs/api-funcs.php is loaded. This contained common API functions that might be used by any core script or plugin.
If a plugin name is supplied, then the API file is expected to be located at /ww.plugins/plugin-name/api.php for common functions, and /ww.plugins/plugin-name/api-admin.php for admin functions.
For core functions, common functions are at /ww.incs/api-funcs.php and admin functions are at /ww.incs/api-admin.php
Having a central point for RPC means that we can apply security rules in one place and know that they cover all scripts. Before-hand, I would sometimes come across scripts and realise that they were open for abuse if someone knows that magic URL incantation. I would silently curse myself or whoever had written the script and fix it up. Now, though, having one single point of entry means I can secure everything at once.
If a function name starts with “admin”, then the script checks to see if the user is logged in and is a member of the administrators group. If not, the API will return an error. It’s as simple as that!
Of course, this doesn’t stop abuse by people that are logged in as admins or who are victims of XSS, but it helps stop a few problems caused by developers not noticing their scripts were open to use by anyone at all.
So now, when people are creating new plugins for WebME, the following could be used as a bare-bones directory structure:
/ww.plugins/plugin-name/plugin.php details, server-side functions
/ww.plugins/plugin-name/api.php common RPC functions
/ww.plugins/plugin-name/api-admin.php admin RPC functions
/ww.plugins/plugin-name/admin.js admin scripts in JS