Devise Omniauth OAuth Strategy for MediaWiki (Wikipedia, WikiMedia Commons)

Authentication of MediaWiki users with a Rails Application using Devise and Omniauth

Wikimaps is a Wikimedia Commons project to georeference/georectify historical maps. Read the wikimaps blog here. It is using a customised version of the Mapwarper open source map georectification software as seen on http://mapwarper.net to speak with the Commons infrastructure and running on Wikimedia Foundations Labs servers. We needed a way to allow Commons users to log in easily.  And so I developed the omniauth-mediakwiki strategy gem so your Ruby applications can authenticate on WikiMedia wikis, like Wikipedia.org and Wikimedia Commons.

e0974880-2ef0-11e4-9b51-e96f339fe90c

The Wikimaps Warper application uses Devise – it works very nicely with Omniauth. The above image shows traditional login with username and password and, using OmniAuth, to Wikimedia Commons, GitHub and OpenStreetMap.

After clicking the Wikimedia Commons button the user is presented with this:oauth

It may not be that pretty, but the user allowing this will redirect back to our app and the user will be logged in.

This library used the omniauth-osm library as an initial framework for building upon.

The code is on github here:   https://github.com/timwaters/omniauth-mediawiki

The gem on RubyGems is here: https://rubygems.org/gems/omniauth-mediawiki

And you can install it by including it in your Gemfile or by doing:

gem install omniauth-mediakwiki

Create new registration

The mediawiki.org registration page is where you would create an OAuth consumer registration for your application. You can specify all wikimedia wikis or a specific one to work with. Registrations will create a key and secret which will work with your user so you can start developing straight away although currently a wiki admin has to approve each registration before other wiki users can use it.  Hopefully they will change this as more applications move away from HTTP Basic to more secure authentication and authorization strategies in the future!

Screenshot from 2014-09-03 21:08:33

Usage

Usage is as per any other OmniAuth 1.0 strategy. So let’s say you’re using Rails, you need to add the strategy to your `Gemfile` alongside omniauth:

gem 'omniauth'
gem 'omniauth-mediawiki'

Once these are in, you need to add the following to your `config/initializers/omniauth.rb`:

Rails.application.config.middleware.use OmniAuth::Builder do
 provider :mediawiki, "consumer_key", "consumer_secret"
end

If you are using devise, this is how it looks like in your `config/initializers/devise.rb`:

config.omniauth :mediawiki, "consumer_key", "consumer_secret", 
    {:client_options => {:site => 'http://commons.wikimedia.org' }}

If you would like to use this plugin against a wiki you should pass this you can use the environment variable WIKI_AUTH_SITE to set the server to connect to. Alternatively you can pass the site as a client_option to the omniauth config as seen above. If no site is specified the http://www.mediawiki.org wiki will be used.

Notes

In general see the pages around https://www.mediawiki.org/wiki/OAuth/For_Developers for more information

When registering for a new OAuth consumer registration you need to specify the callback url properly. e.g. for development:

http://localhost:3000/u/auth/mediawiki/callback

http://localhost:3000/users/auth/mediawiki/callback

This is different from many other OAuth authentication providers which allow the consumer applications to specify what the callback should be. Here we have to define the URL when we register the application. It’s not possible to alter the URL after the registration has been made.

Internally the strategy library has to use `/w/index.php?title=` paths in a few places, like so:

:authorize_path => '/wiki/Special:Oauth/authorize',
:access_token_path => '/w/index.php?title=Special:OAuth/token',
:request_token_path => '/w/index.php?title=Special:OAuth/initiate',

This could be due to a bug in the OAuth extension, or due to how the wiki redirects from /wiki/Special pages to /w/index.php pages….. I suspect this may change in the future.

Another thing to note is that the mediawiki OAuth implementation uses a cool but non standard way of identifying the user.  Omiauth and Devise needs a way to get the identity of the user. Calling '/w/index.php?title=Special:OAuth/identify' it returns a JSON Web Token (JWT). The JWT is signed using the OAuth secret and so the library decodes that and gets the user information.

Calling the MediaWIki API

Omniauth is mainly about authentication – it’s not really about using OAuth to do things on their behalf – but it’s relatively easy to do so if you want to do that. They recommend using it in conjunction with other libraries, for example, if you are using omniauth-twitter, you should use the Twitter gem to use the OAuth authentication variables to post tweets. There is no such gem for MediaWiki which uses OAuth. Existing  Ruby libraries such as MediaWiki Gateway and MediaWIki Ruby API currently only use usernames and passwords - but they should be looked at for help in crafting the necessary requests though.

So we will have to use the OAuth library and call the MediaWiki API directly:

In this example we’ll call the Wikimedia Commons API

Within a Devise / Omniauth setup, in the callback method, you can directly get an OAuth::AccessToken via request.env["omniauth.auth"]["extra"]["access_token"] or you can get the token and secret from request.env["omniauth.auth"]["credentials"]["token"] and request.env["omniauth.auth"]["credentials"]["secret"]

Assuming the authentication token and secret are stored in the user model, the following could be used to query the mediawiki API at a later date.

@consumer = OAuth::Consumer.new "consumer_key", "consumer_secret",
            {:site=>"https://commons.wikimedia.org"}
@access_token = OAuth::AccessToken.new(@consumer, user.auth_token, user.auth_secret)
uri = 'https://commons.wikimedia.org/w/api.php?action=query&meta=userinfo&uiprop=rights|editcount&format=json'
resp = @access_token.get(URI.encode(uri))
logger.debug resp.body.inspect
# {"query":{"userinfo":{"id":12345,"name":"WikiUser",
# "rights":["read","writeapi","purge","autoconfirmed","editsemiprotected","skipcaptcha"],
# "editcount":2323}}}

Here we called the Query action for userinfo asking for rights and editcount infomation.

Mapwarper.net running on a faster, newer server!

Mapwarper.net has finished maintenance work – I really should get rid of the beta sign now. Anyhow its running on a much faster site, courtesy of Topomancy.com. So performance should be better now. All user accounts and maps and points should have been transferred seamlessly.

mapwarper.net georectify maps georeferencing fun!

I’m still configuring the mail server, so if new users when signing up are seeing mail in spam boxes, let me know!

Cheers!

Haiti #2

Almost exactly a year ago, I finished the import of a large amount of road data for Haiti. This was the result of the mapping community responding to the devastating storms and flooding that shook the country, and the need for good quality data for people to share.  Now the country is struck by another disaster.

The main page coordinating efforts from OSM is here:

http://wiki.openstreetmap.org/wiki/WikiProject_Haiti#2010_Earthquake_Response

We’ve set up a special Map Warper instance at  http://maps.nypl.org/relief/maps has a number of public domain maps that you can warp. Please come along and rectify these maps. OSM volunteers will then trace over the top and add these onto the map.

Where 2.0 & Free our old maps!

Well over a month ago I went over to the Bay area for Where2.0 and Wherecamp 2009.

Presented at the Ignite Where on the Thursday evening, after the workshops, about Map Warper.

Map Warper Ignite Slides on slideshare.

Video is here!

I’m near the end at 34:15 minutes in.

In fact, http://where.blip.tv is where to go for all the presentations.

Ignite format was fun, the lights were quite bright on stage so it appeared that I was scowling!

Scowling, and not from slagging off the Ordnance Survey too. Rather I think the OS deserves the love that it’s maps generate – it’s the people who use them that deserve the criticism.

I gave the example of an anti-pattern used in local governments in the UK:

  • Councils have old map archives.
  • Councils have Ordnance Survey mapping.
  • Councils have statutory obligation to look at contaminated land, and the history of land for planning and development etc.
  • Councils use OS mapping to georeference and rectify old maps using OS mapping. Often at great expense, sometimes outsourcing to other countries.
  • Resulting rectified maps are derivative works from the OS, and cannot be shared, or given away for free because of this.

As a response to this, and knowing that all the councils probably had digital collections of (unrectified) out of copyright maps, I am proposing “Free our Old Maps” project.

Lets use crowd sourcing techiques to free these old maps get layers and layers of old historical maps for the UK.

The rest of the conference was good.

Michal Migurski had a nice slot entitled “Flea Market Mapping” where he  showed off his own attempts at a map warper, but was mainly highlighting the love of old maps. He was unaware of and didn’t see Map Warper or my talk before at the very same conference! (But liked it when he did see it later)

Wearabale Haptics talk captured my imagination.

The horizonless map from Autodesk was v. cool too. Can’t find the relevant link though…

Ugotrade writes up a nice review: http://www.ugotrade.com/2009/06/02/location-becomes-oxygen-at-where-20-wherecamp/

OpenStreetMap was a given, no longer a new thing that people didnt know about, it was pretty much mentioned casually throughout. The Stamen fellas did a nice workshop with mapnik, cascadenik and OSM data, which was very well attended.

Also over from Leeds was my buddy Mohsin, fresh out of Leeds Met, and presenting at Wherefaire his Snapture project. Using Leodis images, location on a mobile app, we can view Leeds through time. V. cool project.

Private Maps Now Available in the Warper

Added the ability to make your uploaded maps private in the Map Warper – only you will be able to see and edit these maps, they won’t show up on the lists.
You can also delete maps too.
Access to both these features are via the map’s edit tab.

maynooth map warper

Other bit of news is that I’ve disabled anonymous uploads, so sign up if you haven’t already.