Use chrome frame to support IE. Also rewired gdata authentication process to support IE.

git-svn-id: http://google-refine.googlecode.com/svn/trunk@2270 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
David Huynh 2011-10-05 04:39:42 +00:00
parent e7e9dbc74d
commit 765fb4ea8e
14 changed files with 170 additions and 250 deletions

View File

@ -44,8 +44,6 @@ function init() {
//Packages.java.lang.System.err.println(module.getMountPoint());
var RS = Packages.com.google.refine.RefineServlet;
RS.registerCommand(module, "authorize", Packages.com.google.refine.extension.gdata.AuthorizeCommand());
RS.registerCommand(module, "authorize2", Packages.com.google.refine.extension.gdata.AuthorizeCommand2());
RS.registerCommand(module, "deauthorize", Packages.com.google.refine.extension.gdata.DeAuthorizeCommand());
RS.registerCommand(module, "upload", Packages.com.google.refine.extension.gdata.UploadCommand());
@ -69,6 +67,7 @@ function init() {
"index/scripts",
module,
[
"scripts/gdata-extension.js",
"scripts/index/importing-controller.js",
"scripts/index/gdata-source-ui.js"
]
@ -87,6 +86,7 @@ function init() {
"project/scripts",
module,
[
"scripts/gdata-extension.js",
"scripts/project/exporters.js"
]
);
@ -97,24 +97,32 @@ function init() {
*/
function process(path, request, response) {
// Analyze path and handle this request yourself.
if (path == "authorized") {
if (path == "authorize") {
var context = {};
var params = new Packages.java.util.Properties();
context.params = params;
context.authorizationUrl = Packages.com.google.refine.extension.gdata.GDataExtension.getAuthorizationUrl(module, request);
send(request, response, "authorize.vt", context);
} else if (path == "authorized") {
var context = {};
context.winname = request.getParameter("winname");
context.callback = request.getParameter("callback");
(function() {
var queryString = request.getQueryString();
if (queryString != null) {
var AuthSubUtil = Packages.com.google.gdata.client.http.AuthSubUtil;
// FIXME(SM): can we safely assume UTF-8 encoding here?
var onetimeUseToken = AuthSubUtil.getTokenFromReply(
Packages.java.net.URLDecoder.decode(queryString,"UTF-8"));
Packages.java.net.URLDecoder.decode(queryString, "UTF-8"));
if (onetimeUseToken) {
var sessionToken = AuthSubUtil.exchangeForSessionToken(onetimeUseToken, null);
Packages.com.google.refine.extension.gdata.TokenCookie.setToken(request, response, sessionToken);
} else {
Packages.com.google.refine.extension.gdata.TokenCookie.deleteToken(request, response);
return;
}
}
Packages.com.google.refine.extension.gdata.TokenCookie.deleteToken(request, response);
})();
send(request, response, "authorized.vt", context);
}

View File

@ -1,6 +1,7 @@
/*
<!doctype html>
<!--
Copyright 2010, Google Inc.
Copyright 2011, Google Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -29,24 +30,17 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// Client side resources to be injected for gData extension
// Add items to the exporter menu
//ExportManager.MenuItems.append(
// [ "core/project", "core/export", "core/export-templating" ],
// [
// {
// "label":"Google Spreadsheet",
// "click": function() {}
// },
// {
// "label":"Google Data",
// "click": function() {}
// },
// {} // separator
// ]
//);
var gdataExtension = {};
-->
<html lang="en">
<head>
<meta charset="utf-8">
<title>Google Refine - Authorization</title>
</head>
<body>
<script>
window.setTimeout(function() {
document.location.href = "$authorizationUrl";
}, 100);
</script>
</body>
</html>

View File

@ -34,28 +34,27 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<html lang="en">
<head>
<meta charset="utf-8">
<title>Google Refine</title>
<title>Google Refine - Authorized</title>
</head>
<body>
Closing...
Authorization process completed. Close this window and return to Google Refine.
<script>
(function() {
var url = document.location.href;
var slash = url.indexOf('/', url.indexOf('//') + 2);
var origin = url.substring(0, slash);
var windowName = "$winname";
var callbackName = "$callback";
var pairs = document.cookie.split(';');
for (var i = 0; i < pairs.length; i++) {
var pair = pairs[i].replace(/^\s+/, '').replace(/\s+$/, '').split('=');
if (pair[0] == 'authsub_token' && pair[1].length > 0) {
window.opener.postMessage('gdata:' + pair.join('='), origin);
return;
var w = window.open("", windowName);
var callback = w[callbackName];
if (callback) {
try {
callback();
} catch (e) {
alert(e.message);
}
} else {
w.close();
}
window.opener.postMessage('gdata:authsub_token=', origin);
})();
window.setTimeout(function() { window.close(); }, 100);
window.close();
</script>
</body>
</html>

View File

@ -0,0 +1,62 @@
/*
Copyright 2010, Google Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
var GdataExtension = {};
GdataExtension.isAuthorized = function() {
return $.cookie('authsub_token') !== null;
};
GdataExtension.showAuthorizationDialog = function(onAuthorized, onNotAuthorized) {
if (window.name) {
var windowName = window.name;
} else {
var windowName = "googlerefine" + new Date().getTime();
window.name = windowName;
}
var callbackName = "cb" + new Date().getTime();
var callback = function(evt) {
delete window[callbackName];
if (GdataExtension.isAuthorized()) {
onAuthorized();
} else if (onNotAuthorized) {
onNotAuthorized();
}
window.setTimeout(function() { win.close(); }, 100);
};
window[callbackName] = callback;
var url = ModuleWirings['gdata'] + "authorize?winname=" + escape(windowName) + "&callback=" + escape(callbackName);
var win = window.open(url, "googlerefinegdataauth", "resizable=1,width=800,height=600");
};

View File

@ -33,19 +33,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Refine.GDataSourceUI = function(controller) {
this._controller = controller;
var self = this;
window.addEventListener(
"message",
function(evt) {
if ($.cookie('authsub_token')) {
self._listDocuments();
} else {
self._body.find('.gdata-page').hide();
self._elmts.signinPage.show();
}
},
false);
};
Refine.GDataSourceUI.prototype.attachUI = function(body) {
@ -54,18 +41,23 @@ Refine.GDataSourceUI.prototype.attachUI = function(body) {
this._body.html(DOM.loadHTML("gdata", "scripts/index/import-from-gdata-form.html"));
this._elmts = DOM.bind(this._body);
var self = this;
this._body.find('.gdata-signin.button').click(function() {
window.open(
"/command/gdata/authorize",
"google-refine-gdata-signin",
"resizable=1,width=600,height=450"
GdataExtension.showAuthorizationDialog(
function() {
self._listDocuments();
},
function() {
self._body.find('.gdata-page').hide();
self._elmts.signinPage.show();
}
);
});
this._body.find('.gdata-page').hide();
this._elmts.signinPage.show();
if ($.cookie('authsub_token')) {
if (GdataExtension.isAuthorized()) {
this._listDocuments();
}
};

View File

@ -61,25 +61,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
}
};
var messageListener = function(evt) {
window.removeEventListener("message", messageListener, false);
if ($.cookie('authsub_token')) {
if (GdataExtension.isAuthorized()) {
doUpload();
} else {
GdataExtension.showAuthorizationDialog(doUpload);
}
};
var authenticate = function() {
window.addEventListener("message", messageListener, false);
window.open(
"/command/gdata/authorize",
"google-refine-gdata-signin",
"resizable=1,width=600,height=450"
);
};
authenticate();
};
CustomTabularExporterDialog.uploadTargets.push({
id: 'gdata/google-spreadsheet',
label: 'A new Google spreadsheet',

View File

@ -1,69 +0,0 @@
/*
* Copyright (c) 2011, Thomas F. Morris
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of Google nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/package com.google.refine.extension.gdata;
import java.io.IOException;
import java.net.URL;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.gdata.client.http.AuthSubUtil;
import com.google.refine.commands.Command;
/**
* Command to allow user to authenticate themselves.
*
*/
public class AuthorizeCommand extends Command {
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
char[] mountPointChars = this.servlet.getModule("gdata")
.getMountPoint().getMountPoint().toCharArray();
StringBuffer sb = new StringBuffer();
sb.append(mountPointChars, 0, mountPointChars.length);
sb.append("authorized");
URL thisUrl = new URL(request.getRequestURL().toString());
URL authorizedUrl = new URL(thisUrl, sb.toString());
String requestUrl = AuthSubUtil.getRequestUrl(
authorizedUrl.toExternalForm(), // execution continues at authorized on redirect
"https://docs.google.com/feeds https://spreadsheets.google.com/feeds https://www.google.com/fusiontables/api/query",
false,
true);
response.sendRedirect(requestUrl);
}
}

View File

@ -1,89 +0,0 @@
/*
* Copyright (c) 2011, Thomas F. Morris
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of Google nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.google.refine.extension.gdata;
import java.io.IOException;
import java.net.URLDecoder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.gdata.client.http.AuthSubUtil;
import com.google.refine.commands.Command;
/**
* Second half of authentication sequence after Google has redirected back to us
*
*/
public class AuthorizeCommand2 extends Command {
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
String queryString = request.getQueryString();
if (queryString == null) {
respond(response, "401 Unauthorized", "Authentication failed.");
return;
}
String onetimeUseToken = AuthSubUtil.getTokenFromReply(URLDecoder.decode(queryString,"UTF-8"));
// FIXME(SM): can we safely assume UTF-8 encoding here?
String sessionToken = AuthSubUtil.exchangeForSessionToken(onetimeUseToken, null);
TokenCookie.setToken(request, response, sessionToken);
// FeedURLFactory factory = FeedURLFactory.getDefault();
// SpreadsheetService service = new SpreadsheetService(
// "Google-Refine-GData-Extension-0.2");
// service.setAuthSubToken(sessionToken);
//
// SpreadsheetFeed feed = service.getFeed(
// factory.getSpreadsheetsFeedUrl(), SpreadsheetFeed.class);
// List<SpreadsheetEntry> spreadsheets = feed.getEntries();
// for (int i = 0; i < spreadsheets.size(); i++) {
// SpreadsheetEntry entry = spreadsheets.get(i);
// System.out.println("\t" + entry.getTitle().getPlainText());
// }
respond(response, "200 OK", "");
// } catch (AuthenticationException e) {
// } catch (GeneralSecurityException e) {
} catch (Exception e) { // AuthenticationException
// GeneralSecurityException
e.printStackTrace();
TokenCookie.deleteToken(request, response);
respondException(response, e);
}
}
}

View File

@ -30,6 +30,7 @@ package com.google.refine.extension.gdata;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
@ -38,15 +39,22 @@ import java.util.Scanner;
import java.util.regex.MatchResult;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import com.google.gdata.client.GoogleService;
import com.google.gdata.client.Service.GDataRequest;
import com.google.gdata.client.Service.GDataRequest.RequestType;
import com.google.gdata.client.docs.DocsService;
import com.google.gdata.client.http.AuthSubUtil;
import com.google.gdata.client.spreadsheet.FeedURLFactory;
import com.google.gdata.client.spreadsheet.SpreadsheetService;
import com.google.gdata.util.ContentType;
import com.google.gdata.util.ServiceException;
import com.google.refine.util.ParsingUtilities;
import edu.mit.simile.butterfly.ButterflyModule;
/**
* @author Tom Morris <tfmorris@gmail.com>
* @copyright 2010 Thomas F. Morris
@ -55,6 +63,27 @@ import com.google.gdata.util.ServiceException;
abstract public class GDataExtension {
static final String SERVICE_APP_NAME = "Google-Refine-GData-Extension";
static public String getAuthorizationUrl(ButterflyModule module, HttpServletRequest request)
throws MalformedURLException {
char[] mountPointChars = module.getMountPoint().getMountPoint().toCharArray();
StringBuffer sb = new StringBuffer();
sb.append(mountPointChars, 0, mountPointChars.length);
sb.append("authorized?winname=");
sb.append(ParsingUtilities.encode(request.getParameter("winname")));
sb.append("&callback=");
sb.append(ParsingUtilities.encode(request.getParameter("callback")));
URL thisUrl = new URL(request.getRequestURL().toString());
URL authorizedUrl = new URL(thisUrl, sb.toString());
return AuthSubUtil.getRequestUrl(
authorizedUrl.toExternalForm(), // execution continues at authorized on redirect
"https://docs.google.com/feeds https://spreadsheets.google.com/feeds https://www.google.com/fusiontables/api/query",
false,
true);
}
static private FeedURLFactory factory;
static public FeedURLFactory getFeedUrlFactory() {
if (factory == null) {

View File

@ -33,6 +33,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome-1">
<title>About - Google Refine</title>
<link rel="icon" type="image/png" href="images/favicon.png">
<link rel="stylesheet" href="/styles/common.less" />

View File

@ -35,6 +35,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=8;IE=9;chrome=1;">
<title>Error - Google Refine</title>
<link rel="icon" type="image/png" href="images/favicon.png">
<link rel="stylesheet" href="/styles/common.less" />

View File

@ -34,6 +34,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=8;IE=9;chrome=1;">
<title>Google Refine</title>
<link rel="icon" type="image/png" href="images/favicon.png">
<script type="text/javascript" src="wirings.js"></script>

View File

@ -34,6 +34,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=8;IE=9;chrome=1;">
<title>Preferences - Google Refine</title>
<link rel="icon" type="image/png" href="images/favicon.png">
<script type="text/javascript" src="wirings.js"></script>

View File

@ -34,6 +34,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=8;IE=9;chrome=1;">
<title>Google Refine</title>
<script type="text/javascript">var theProject = { id : $projectID };</script>
<script type="text/javascript" src="wirings.js"></script>