I started poking around in the ejabberd source code to see what I could learn. I couldn't find much in the way of high level documentation that talks about how the various bits of ejabberd talk to each other, so I'm starting to piece it together myself.
After compiling ejabberd I made a php script I could use with the external authentication system. Here's a version that supports just two hardcoded users:
I stripped down the ejabberd config to just load what I considered the bare essentials. Here is the modules section I'm testing with:
mod_disco deals with discovery, so clients can find out what the server supports. modroster deals with rosters (buddy lists etc) using mnesia. modpubsub is enabled because I want to use User Tune, an extension that lets you broadcast the name of the song you are playing to all everyone in your roster. modcaps provides XEP-115 - an extension for broadcasting and dynamically discovering client, device, or generic entity capabilities. modcaps is a requirement of mod_pubsub.
I've removed the module that allows users to register, although I made a few accounts first whilst testing. The last two modules, modmnesiaweb and modthriftctl are modules I wrote.
To help figure out what's going on inside of ejabberd, it's useful to be able to easily browse the mnesia database. Yaws comes with an appmod that does this, called ymnesia. This ejabberd module will start yaws in embedded mode and run this appmod, enabling you to explore the mnesia database from a web browser.
Yaws observation: yaws didn't appear to build ymnesia by default, I edited the Makefile in src and added "ymnesia" to the module list. Also, if ./configure fails, the package you are probably missing is libpam0g-dev
To compile it:
where EJAB_SRC is the ejabberd-2.X.X/src directory, after you've compiled from source (so the beams are there too).
Copy the resulting mod_mnesiaweb.beam to /var/lib/ejabberd/ebin so ejabberd finds it, and it should work. Hit up http://localhost:8001/showdb/ in your browser and you can explore the mnesia database.
Use the match syntax to filter tables. For example to find everyone in my roster, I use this in the input box next to roster:
Not pretty, but it gets the job done. You can just view the entire table, copy a record then replace fields with '_' to build queries.
Next up I wanted to try the Erlang Thrift bindings (written by the folks at Amie St.), and expose some useful functionality for controlling the server.
If you aren't familiar with Thrift, I recommend reading about it first. In a nutshell, you write your API using an IDL (a .thrift file) and the thrift compiler creates client libraries, and server code in various different languages. It's an RPC mechanism, and useful in a mixed environment.
Run that .thrift file, and you get gen-php and gen-erl directories, with php client code, and erlang files needed to build a server.
Here's the ejabberd module, which starts a thrift server:
To build, first build the gen-erl code:
Where ERL_THRIFT is the lib/erl directory from the amiethrift code, git://repo.or.cz/amiethrift.git
Then compile the module:
To install, copy all the beam files to the ejabberd ebin dir:
This is inspired by mod_xmlrpc, which is in ejabberd-modules. As you can see from the start function, that's what it takes to start a thrift server. It's now trivial to call into ejabberd from other languages. For example, if you started listening to a song using a flash player on the website, a php webservice could make a user tune announcement on your behalf, or spoof messages from you boasting how much you love listening to Paris Hilton.
If anyone knows where I can read about the ejabberd architecture / design, so I don't have to piece it all together myself, please let me know.