I’ve had a few requests for the slides from my WordPress APIs talk at WordCamp San Francisco last weekend. A few minutes on SlideShare and here they are:
It’s very brief, time was limited.
WordPress 2.6 has been released.
For those of you interested in keeping up with XML-RPC & AtomPub changes in WordPress, here’s what has changed from 2.5.1 to 2.6:
Since the story around disabling XML-RPC & AtomPub by default has gone through a few twists, I’ll re-state the current situation: new installs of WordPress will have XML-RPC and AtomPub access disabled by default, upgrades of WordPress to version 2.6 from previous versions will not have XML-RPC and AtomPub disabled as part of the upgrade process. There is no check box for enabling these services during the install or upgrade. The process for turning them back on are simple check boxes in wp-admin under Settings -> Writing.
On the security front, there are no known security issues in XML-RPC or AtomPub. If you think you’ve discovered one please email the details to firstname.lastname@example.org.
Another point that I’ve seen a few folks bring up is the feeling that this is just the first step in removing XML-RPC and/or AtomPub entirely or that they’ll stop getting new features. These features are not going away and as for continued development and new features, go back and read the top of this post. That said, we can definitely use more people looking at the XML-RPC and AtomPub code.
If you are interested in XML-RPC/AtomPub, please come join us on the wp-xmlrpc email list.
As westi has already noted, the next version of WordPress will have XML-RPC and AtomPub disabled by default. It’s easily turned on via an option in wp-admin, and can be enabled during installation as well.
This reduces the number of potential ways an attacker can break in. To be clear though, I’m not aware of any current security issues with XML-RPC or AtomPub in WordPress.
If you’ve done any sort of work with XML-RPC blog APIs on WordPress you’ve come across blog_id. What blog_id does and does not do in WordPress can be a bit confusing though.
Lets look at the metaWeblog.* XML-RPC methods to get an idea of what the problem looks like. Here’s the metaWeblog.newPost method:
metaWeblog.newPost( blog_id, username, password, struct, publish )
The WordPress implementation of this method doesn’t use the blog_id value at all. For all intents and purposes it is thrown away, only using the last four parameters. It’s kept in the parameter list though in an effort to be compatible with other implementations of metaWeblog.newPost.
For regular WordPress installs that isn’t too confusing. There is some very limited internal use of blog_id, just none at the XML-RPC level. Where things go a little side ways is with WordPress MU (WPMU), which is what WordPress.com uses. WPMU uses the blog_id value quite a bit, since it has to manage multiple blogs.
One reason for including the blod_id in method calls like metaWeblog.newPost is because other services only have one XML-RPC end point (end point is just a URL). One example is TypePad, whose XML-RPC end point is http://www.typepad.com/t/api. This allows them to figure which blog the new post is being assigned to. For WPMU there is a unique XML-RPC end point for each blog, instead of just one for the whole WPMU install. Because of this WPMU doesn’t need the blog_id value to figure out which blog the new post is for because it can figure that out from the XML-RPC end point being used.
But wait, there’s more. Here’s metaWeblog.editPost:
metaWeblog.editPost( post_id, username, password, struct, publish )
You’ll notice that there’s no blog_id in the parameter list. For other services this isn’t an issue because they’ll generate unique post_id values not for just one blog, but for their whole service. WPMU doesn’t do that, post_id’s are only unique in each blog. A given WPMU install could have as many posts with a post_id of 1 as there are blogs setup.
So far all of these examples can be addressed by making sure that you point to the correct XML-RPC end point. But the metaWeblog.* methods aren’t the only APIs WordPress makes available, there’s also a subset of the blogger.* methods. One that really causes grief is blogger.getUsersBlogs:
blogger.getUsersBlogs( app_key, username, password )
Ignore the app_key parameter, WordPress does. The intent of this method was to let clients know what blogs a given user had access to. Once the user provided a username and password a client could then just ask the service for a list of all the blogs that the user had access to. Unfortunately for WPMU, clients would make certain incorrect assumptions once they’d asked blogger.getUsersBlogs for information.
Let’s use example.com has an example of a multi-blog site. I’ve got blogs at joseph.example.com, josephscott.example.com and helloworld.example.com. A blog client comes along and asks example.com/xmlrpc.php for a list of blogs that I have access to. They get a list back that looks something like:
blogName: "Joseph Scott"
blogName: "Hello World"
Nothing wrong so far, but it’s what I see blog clients do next that breaks things. Instead of querying each blog URL to find out what the XML-RPC end point is for each one, they assume that the end point that provided this data will work for all three. I’ve found this to be a very common assumption in blog clients. In this case it means that they send metaWeblog.newPost requests to example.com/xmlrpc.php. For services that have one global end point for all of their blogs this works fine, which works because they send along the unique blog_id value. This doesn’t work for WPMU because it throws away those blog_id values sent to it via XML-RPC methods.
At this point you might be thinking, well, gee, why don’t you just fix WordPress/WPMU to respect the blog_id and then everything will be fine. That was what I thought the first time I ran into this. I started digging through code, and then I ran into metaWeblog.editPost (and others) that don’t require a blog_id value. That’s when I realized that it wasn’t realistic to try and fix this. It would require WPMU to generate unique post_id values across all blogs, something that it does not do, and isn’t likely to be doing in the near future.
In order to minimize the confusion I changed the behavior of the blogger.getUsersBlogs method in WordPress. Instead of sending details for all the blogs that the user had access to, it only sent info for the one blog that it was talking to. Continuing with the example above, lets say the client had sent a blogger.getUsersBlogs request to josephscott.example.com/xmlrpc.php. The response would only contain data about josephscott.example.com. This effectively prevents the client from getting confused about example.com supporting blog_id and only using one global XML-RPC end point. The down side to this approach is that instead of the client being able to discover all of the other blogs that I have access to on example.com, I have to configure each one in the client.
Well, that isn’t completely true. If a client makes a blogger.getUsersBlogs to the master blog in an WPMU install it will still get a list of all the blogs that user has access to. In the example above that would be example.com/xmlrpc.php. This was necessary because some services querying WordPress.com depended on this. Those changes were generalized and are included as part of WPMU.
For blog clients that wanted access to a user blog list but don’t make the single end point assumption I added a new method, wp.getUsersBlogs:
wp.getUsersBlogs( username, password )
It returns the same data that blogger.getUsersBlogs does, with one additional field for each blog: xmlrpc. The xmlrpc field is the XML-RPC end point for each blog. This saves the client from having to go out and detect the end point for each blog. My hope was that if a client knew enough to ask for wp.getUsersBlogs it also knew enough not to make incorrect assumptions about what to do with that data.
Right now the wp.getUsersBlogs is only available on WordPress.com, but it will be hitting WordPress and WordPressMU soon.
It’s still possible that at some point we’ll do enough low level work in WordPress/WPMU to make things work in a manner similar to what others do with blog_id and post_id, but for now this is where things stand. If you are making use of the XML-RPC APIs in WordPress and wondered what the story was with blog_id’s, now you know.
WordPress 2.5 is officially out the door. Matt hits the long list of highlights of what is new in the release announcement. This coincides with the new layout at WordPress.rog. Peter Westwood (one of the WordPress core developers) put together a tag cloud of people who contributed to this release.
For the XML-RPC blog client developers out there 2.5 adds four new methods:
To go along with the new status methods, you can now explicitly set the post and page status using the post_status and page_status fields. Like wise the status is also exposed via the various get* methods. One note about future posts, for the purposes of XML-RPC clients we set the post_status to publish when the actual database value is future.
The wp.suggestCategories method has been fixed to return data in the same format that it did originally. I never heard anyone complain about this though, so I guess it isn’t getting much use.
Custom fields for posts and pages are now exposed and manageable from metaWeblog.getPost/newPost/editPost, wp.getPage/newPage/editPage via the custom_fields field. I was really happy to get this in, I think there is a lot of potential in being able to manage custom fields externally.
The mt_allow_comments field now understands the value of 2 to be the same as the value of zero. This was done because other platforms expect to be able use the value 2, so some clients assume that we support it. Now we do, but from the WordPress point of view is does exactly the same thing as zero.
If the field date_created_gmt is provided in metaWeblog.newPost/editPost, wp.newPage/editPage then it is used instead of the dateCreated field. This same field was already exposed via metaWeblog.getPost, wp.getPage. By definition the date_created_gmt field is always GMT, even if you don’t provide a time zone offset or a trailing Z. I’m hoping this will help ease the many headaches that have been brought on by trying to deal with date/time issues in the XML-RPC blog APIs.
If you are a developer that makes use of the WordPress XML-RPC interface, or are interested in doing development work on the WordPress XML-RPC code please subscribe to the wp-xmlrpc email list. Along with various tickets in Trac this is where we discuss ideas and issues for the XML-RPC APIs that WordPress supports.
scot hacker?s foobar blog > Notes on a Massive WordPress Migration – Lots of details on how they moved CDT from MovableType to WordPress.
Tags: movabletype wordpress
PHP mail() and The Path of No Return ? All in the head – If you are using PHP’s mail() function then make sure that Sendmail is happy with the From address on the envelope.
Tags: php mail sendmail