Skip to content

Instantly share code, notes, and snippets.

@slaporte
Created March 22, 2015 07:45
Show Gist options
  • Select an option

  • Save slaporte/9fced3a40510376d5906 to your computer and use it in GitHub Desktop.

Select an option

Save slaporte/9fced3a40510376d5906 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# MediaWiki OAuth connector for Flask
#
# Requires flask-oauth
#
# (C) 2013 Merlijn van Deen <valhallasw@arctus.nl>
# Licensed under the MIT License // http://opensource.org/licenses/MIT
#
__version__ = '0.1.14'
import urllib
from flask import request, session, redirect, url_for, flash, Blueprint
from flask_oauth import OAuth, OAuthRemoteApp, OAuthException, parse_response
class MWOAuthRemoteApp(OAuthRemoteApp):
def handle_oauth1_response(self):
"""Handles an oauth1 authorization response. The return value of
this method is forwarded as first argument to the handling view
function.
"""
client = self.make_client()
resp, content = client.request('%s&oauth_verifier=%s' % (
self.expand_url(self.access_token_url),
request.args['oauth_verifier'],
), self.access_token_method)
print resp, content
data = parse_response(resp, content)
if not self.status_okay(resp):
raise OAuthException('Invalid response from ' + self.name,
type='invalid_response', data=data)
return data
class MWOAuth(object):
def __init__(self,
base_url='https://www.mediawiki.org/w',
clean_url='https://www.mediawiki.org/wiki',
default_return_to='index',
consumer_key=None, consumer_secret=None):
if not consumer_key or not consumer_secret:
raise Exception('MWOAuthBlueprintFactory needs consumer key and secret')
self.base_url = base_url
self.default_return_to = default_return_to
self.oauth = OAuth()
self.mwoauth = MWOAuthRemoteApp(self.oauth, 'mw.org',
base_url = base_url + "/index.php",
request_token_url=base_url + "/index.php",
request_token_params = {'title': 'Special:OAuth/initiate',
'oauth_callback': 'oob'},
access_token_url=base_url + "/index.php?title=Special:OAuth/token",
authorize_url=clean_url + '/Special:OAuth/authorize',
consumer_key=consumer_key,
consumer_secret=consumer_secret,
)
self.oauth.remote_apps['mw.org'] = self.mwoauth
@self.mwoauth.tokengetter
def get_mwo_token(token=None):
return session.get('mwo_token')
self.bp = Blueprint('mwoauth', __name__)
@self.bp.route('/logout')
def logout():
session['mwo_token'] = None
session['username'] = None
return "Logged out!"
@self.bp.route('/login')
def login():
redirector = self.mwoauth.authorize()
redirector.headers['Location'] += "&oauth_consumer_key=" + self.mwoauth.consumer_key
return redirector
@self.bp.route('/auth/callback')
@self.mwoauth.authorized_handler
def oauth_authorized(resp):
#import pdb; pdb.set_trace()
next_url = request.args.get('next') or url_for(self.default_return_to)
if resp is None:
flash(u'You denied the request to sign in.')
return redirect(next_url)
session['mwo_token'] = (
resp['oauth_token'],
resp['oauth_token_secret']
)
username = self.get_current_user(False)
flash('You were signed in, %s!' % username)
return redirect(next_url)
def request(self, api_query):
""" e.g. {'action': 'query', 'meta': 'userinfo'}. format=json not required
function returns a python dict that resembles the api's json response
"""
api_query['format'] = 'json'
ret = self.mwoauth.post(self.base_url + "/api.php?" + urllib.urlencode(api_query),
content_type="text/plain")
return ret.data
def post(self, get_params, post_body):
get_params['format'] = 'json'
ret = self.mwoauth.post(self.base_url + "/api.php?" + urllib.urlencode(get_params),
data=urllib.urlencode(post_body),
content_type='text/plain')
import pdb; pdb.set_trace()
return ret.data
def get_current_user(self, cached=True):
if cached:
return session.get('username')
try:
data = self.request({'action': 'query', 'meta': 'userinfo'})
session['username'] = data['query']['userinfo']['name']
except KeyError:
session['username'] = None
if data['error']['code'] == "mwoauth-invalid-authorization":
flash(u'Access to this application was revoked. Please re-login!')
else:
raise
except OAuthException:
session['username'] = None
return session['username']
def get_csrftoken(self):
try:
#https://en.wikipedia.org/w/api.php?action=query&meta=tokens&type=csrf
data = self.request({'action': 'query', 'meta': 'tokens', 'type': 'csrf'})
session['csrftoken'] = data['query']['tokens']['csrftoken']
except KeyError:
import pdb; pdb.set_trace()
return session['csrftoken']
def thank(self, revisionid):
token = self.get_csrftoken()
#api.php?action=thank&revid=456&source=diff&token=123ABC
ret = self.post({'action': 'thank', 'rev': int(revisionid), 'source': 'barnsworth'}, {'token': token})
import pdb; pdb.set_trace()
return revisionid
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment