[gnome-maps/wip/osm-edit: 2/2] osmEdit: WIP, implement OAuth sign in support
- From: Marcus Lundblad <mlundblad src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-maps/wip/osm-edit: 2/2] osmEdit: WIP, implement OAuth sign in support
- Date: Wed, 11 Nov 2015 22:18:52 +0000 (UTC)
commit d35eaa60677df77e04f34f0f02354a18b25e16fa
Author: Marcus Lundblad <ml update uu se>
Date: Wed Nov 11 23:18:20 2015 +0100
osmEdit: WIP, implement OAuth sign in support
src/osmConnection.js | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++
src/osmEdit.js | 15 ++++++
2 files changed, 137 insertions(+), 0 deletions(-)
---
diff --git a/src/osmConnection.js b/src/osmConnection.js
index 34de7d6..06650e0 100644
--- a/src/osmConnection.js
+++ b/src/osmConnection.js
@@ -27,17 +27,26 @@ const Utils = imports.utils;
const Lang = imports.lang;
const GLib = imports.gi.GLib;
const Maps = imports.gi.GnomeMaps;
+const Rest = imports.gi.Rest;
const Soup = imports.gi.Soup;
const BASE_URL = 'https://api.openstreetmap.org/api';
const TEST_BASE_URL = 'http://api06.dev.openstreetmap.org/api';
const API_VERSION = '0.6';
+/* OAuth constants */
+const CONSUMER_KEY = '2lbpDoED0ZspGssTBAJ8zOCtrtmUoX4KnmZUIWIK';
+const CONSUMER_SECRET = 'AO9BhDl9sJ33DjaZgQmYcNIuM3ZSml4xtugai6gE';
+const OAUTH_ENDPOINT_URL = 'https://www.openstreetmap.org/oauth';
+const LOGIN_URL = 'https://www.openstreetmap.org/login';
+
const OSMConnection = new Lang.Class({
Name: 'OSMConnection',
_init: function(params) {
this._session = new Soup.Session();
+ this._oauthProxy = Rest.OAuthProxy.new(CONSUMER_KEY, CONSUMER_SECRET,
+ OAUTH_ENDPOINT_URL, false);
/* TODO: stopgap to supply username/password
to use with HTTP basic auth, should be
@@ -232,10 +241,123 @@ const OSMConnection = new Lang.Class({
},
_authenticate: function(session, msg, auth, retrying, user_data) {
+ Utils.debug('authenticate triggered');
if (retrying)
session.cancel_message(msg, Soup.Status.UNAUTHORIZED);
auth.authenticate(this._username, this._password);
+ },
+
+ requestOAuthToken: function(callback) {
+ this._oauthProxy.request_token_async('request_token', 'oob',
+ function(proxy, error, weakObject,
+ userData) {
+ this._onRequestOAuthToken(error, callback)}.bind(this),
+ this._oauthProxy, callback);
+ },
+
+ _onRequestOAuthToken: function(error, callback) {
+ Utils.debug('OAuth request token callback');
+ Utils.debug('callback: ' + callback);
+
+ if (error) {
+ Utils.debug('error message: ' + error.message);
+ callback(false);
+ }
+
+ Utils.debug('request token: ' + this._oauthProxy.get_token());
+ Utils.debug('request secret: ' + this._oauthProxy.get_token_secret());
+ this._oauthToken = this._oauthProxy.get_token();
+ this._oauthTokenSecret = this._oauthProxy.get_token_secret();
+ callback(true);
+ },
+
+ authorizeOAuthToken: function(username, password, callback) {
+ /* get login session ID */
+ let loginUrl = LOGIN_URL + '?cookie_test=true';
+ let uri = new Soup.URI(loginUrl);
+ let msg = new Soup.Message({method: 'GET', uri: uri});
+
+ Utils.debug('calling login form URL: ' + loginUrl);
+
+ this._session.queue_message(msg, (function(obj, message) {
+ this._onLoginFormReceived(message, callback);
+ }).bind(this));
+
+ let authorizeUrl =
+ OAUTH_ENDPOINT_URL + '/authorize?OAuth.OAUTH_TOKEN=' +
+ this._oauthToken;
+
+ },
+
+ _onLoginFormReceived: function(message, callback) {
+ Utils.debug('status: ' + message.status_code);
+
+ if (message.status_code !== Soup.Status.OK) {
+ Utils.debug('Failed to load login form');
+ callback(false);
+ return;
+ }
+
+ let osmSessionID =
+ this._extractOSMSessionID(message.response_headers);
+ let osmSessionToken =
+ this._extractToken(message.response_body.data);
+ Utils.debug('session ID: ' + osmSessionID);
+ Utils.debug('session token: ' + osmSessionToken);
+
+ if (osmSessionID === null || osmSessionToken === null) {
+ Utils.debug('Failed to extract OSM session');
+ callback(false);
+ return;
+ }
+ },
+
+ _login: function(username, password, callback) {
+ /* post login form */
+ },
+
+ /* extract the session ID from the login form response headers */
+ _extractOSMSessionID: function(responseHeaders) {
+ let cookie = responseHeaders.get('Set-Cookie');
+
+ Utils.debug('cookie: ' + cookie);
+
+ if (cookie === null)
+ return null;
+
+ let cookieParts = cookie.split(';');
+ for (let index in cookieParts) {
+ let kvPair = cookieParts[index].trim();
+ let kv = kvPair.split('=');
+
+ Utils.debug('kv: ' + kv);
+
+ if (kv.length !== 2) {
+ continue;
+ } else if (kv[0] === '_osm_session') {
+ return kv[1];
+ }
+ }
+
+ return null;
+ },
+
+ /* extract the authenticity token from the hidden input field of the login
+ form */
+ _extractToken: function(messageBody) {
+ let regex = /.*authenticity_token.*value=\"([^\"]+)\".*/;
+ let lines = messageBody.split('\n');
+
+ for (let i in lines) {
+ let line = lines[i];
+ let match = line.match(regex);
+
+ if (match && match.length === 2)
+ return match[1];
+ }
+
+ return null;
}
});
diff --git a/src/osmEdit.js b/src/osmEdit.js
index 723010f..ca50dd0 100644
--- a/src/osmEdit.js
+++ b/src/osmEdit.js
@@ -136,5 +136,20 @@ const OSMEdit = new Lang.Class({
_closeChangeset: function(changesetId, callback) {
this._osmConnection.closeChangeset(changesetId, callback);
+ },
+
+ performOAuthSignIn: function(username, password) {
+ this._osmConnection.requestOAuthToken(function(success) {
+ Utils.debug('requested token');
+ this._onOAuthTokenRequested(success, username, password)
+ }.bind(this));
+ },
+
+ _onOAuthTokenRequested: function(success, username, password) {
+ Utils.debug('about to authorize');
+ this._osmConnection.authorizeOAuthToken(username, password,
+ (function(success) {
+ Utils.debug('authorized, success: ' + success);
+ }).bind(this));
}
});
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]