references #831, transparent EZProxy support

changes default behavior. transparent redirection is now enabled by default, and a caution dialog appears when proxies are first accessed. when transparent redirection is turned off, no dialog appears, and proxies get saved automatically. when the user switches transparent redirection on, there is a warning that s/he should check that there are only trusted proxies in the list. i'm not sure how well i've worded the messages, so feel free to suggest better alternatives.
also, a bit of jsdoc cleanup on proxy.js
This commit is contained in:
Simon Kornblith 2008-08-21 05:46:54 +00:00
parent 4c0523fbda
commit c77fe5462a
6 changed files with 99 additions and 36 deletions

View file

@ -1127,6 +1127,16 @@ function refreshProxyList() {
*/
function updateProxyPrefs() {
Zotero.Prefs.set("proxies.autoRecognize", document.getElementById('zotero-proxies-autoRecognize').checked);
Zotero.Prefs.set("proxies.transparent", document.getElementById('zotero-proxies-transparent').checked);
var oldTransparent = Zotero.Prefs.get("proxies.transparent");
var newTransparent = document.getElementById('zotero-proxies-transparent').checked;
if(!oldTransparent && newTransparent) {
Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Components.interfaces.nsIPromptService).alert(window,
Zotero.getString("proxies.enableTransparentWarning.title"),
Zotero.getString("proxies.enableTransparentWarning.description"));
}
Zotero.Prefs.set("proxies.transparent", newTransparent);
Zotero.Proxies.init()
}

View file

@ -26,6 +26,7 @@
/**
* A singleton to handle URL rewriting proxies
* @namespace
*/
Zotero.Proxies = new function() {
var on = false;
@ -38,6 +39,9 @@ Zotero.Proxies = new function() {
var lastRecognizedURI = false;
var lastButton = false;
/**
* Initializes http-on-examine-response observer to intercept page loads and gets preferences
*/
this.init = function() {
if(!on) {
var observerService = Components.classes["@mozilla.org/observer-service;1"]
@ -52,7 +56,11 @@ Zotero.Proxies = new function() {
}
/**
* Observe method to capture page loads
* Observe method to capture page loads and determine if they're going through an EZProxy.
* At the moment, also clears Content-Disposition header on requests for EndNote files so we
* can capture them instead of letting them get saved as attachments
*
* @param {nsIChannel} channel
*/
this.observe = function(channel) {
channel.QueryInterface(Components.interfaces.nsIHttpChannel);
@ -106,28 +114,21 @@ Zotero.Proxies = new function() {
Components.utils.reportError(e);
}
if(proxy) {
var checkState = {value:false};
var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Components.interfaces.nsIPromptService);
if(!transparent) {
// if transparent is turned off, just save the proxy
proxy.save();
} else if(proxy) {
// otherwise, make sure we want it
var io = {site:proxy.hosts[0], proxy:channel.URI.hostPort};
var window = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator)
.getMostRecentWindow("navigator:browser");
window.openDialog('chrome://zotero/content/proxy.xul', '', 'chrome,modal', io);
if(!lastRecognizedURI || !channel.originalURI || !channel.originalURI.equals(lastRecognizedURI)) {
lastButton = ps.confirmEx(window,
Zotero.getString("proxies.recognized"),
Zotero.getString("proxies.recognized.message"),
((proxies.length ? 0 : ps.BUTTON_DELAY_ENABLE) + ps.BUTTON_POS_0 * ps.BUTTON_TITLE_OK +
ps.BUTTON_POS_1 * ps.BUTTON_TITLE_CANCEL + ps.BUTTON_POS_1_DEFAULT),
null, null, null, Zotero.getString("proxies.recognized.disable"), checkState);
lastRecognizedURI = channel.originalURI ? channel.originalURI : channel.URI;
}
if(lastButton == 0) proxy.save();
if(checkState.value) {
autoRecognize = false;
Zotero.Prefs.set("proxies.autoRecognize", false);
if(io.add) proxy.save();
if(io.disable) {
transparent = false;
Zotero.Prefs.set("proxies.transparent", false);
}
break;
@ -154,6 +155,7 @@ Zotero.Proxies = new function() {
/**
* Gets all proxy objects
* @type Zotero.Proxy[]
*/
this.get = function() {
if(!proxies) {
@ -166,6 +168,7 @@ Zotero.Proxies = new function() {
/**
* Removes a proxy object from the list of proxy objects
* @returns {Boolean} True if the proxy was in the list, false if it was not
*/
this.remove = function(proxy) {
var index = proxies.indexOf(proxy);
@ -176,7 +179,7 @@ Zotero.Proxies = new function() {
}
/**
* Saves a proxy object not previously in the proxy list
* Inserts a proxy into the host map; necessary when proxies are added
*/
this.save = function(proxy) {
proxies.push(proxy);
@ -185,11 +188,10 @@ Zotero.Proxies = new function() {
hosts[host] = proxy;
}
}
return proxy;
}
/**
* Refreshes host map; necessary when proxies are added, changed, or deleted
* Refreshes host map; necessary when proxies are changed or deleted
*/
this.refreshHostMap = function() {
hosts = {};
@ -203,7 +205,12 @@ Zotero.Proxies = new function() {
}
/**
* Returns a page's proper url, adjusting for proxying
* Returns a page's proper URL from a proxied URL
* @param {String} url
* @param {Boolean} onlyReturnIfProxied Controls behavior if the given URL is not proxied. If
* it is false or unspecified, unproxied URLs are returned verbatim. If it is true, the
* function will return "false" if the given URL is unproxied.
* @type String
*/
this.proxyToProper = function(url, onlyReturnIfProxied) {
for each(var proxy in proxies) {
@ -220,7 +227,12 @@ Zotero.Proxies = new function() {
}
/**
* Returns a page's proxied url from the proper url
* Returns a page's proxied URL from the proper URL
* @param {String} url
* @param {Boolean} onlyReturnIfProxied Controls behavior if the given URL is not proxied. If
* it is false or unspecified, unproxied URLs are returned verbatim. If it is true, the
* function will return "false" if the given URL is unproxied.
* @type String
*/
this.properToProxy = function(url, onlyReturnIfProxied) {
var uri = ioService.newURI(url, null, null);
@ -234,9 +246,10 @@ Zotero.Proxies = new function() {
}
/**
* A class to handle individual proxy servers
* Creates a Zotero.Proxy object from a DB row
*
* @constructor
* @class Represents an individual proxy server
*/
Zotero.Proxy = function(row) {
if(row) {
@ -247,21 +260,32 @@ Zotero.Proxy = function(row) {
}
}
/**
* Regexps to match the URL contents corresponding to proxy scheme parameters
* @const
*/
const Zotero_Proxy_schemeParameters = {
"%p":"(.*?)", // path
"%d":"(.*?)", // directory
"%f":"(.*?)", // filename
"%a":"(.*?)" // filename
};
/**
* Regexps to match proxy scheme parameters in the proxy scheme URL
* @const
*/
const Zotero_Proxy_schemeParameterRegexps = {
"%p":/([^%])%p/,
"%d":/([^%])%d/,
"%f":/([^%])%f/,
"%h":/([^%])%h/,
"%a":/([^%])%a/
}
};
/**
* Compiles the regular expression against which we match URLs for this proxy
* Compiles the regular expression against which we match URLs to determine if this proxy is in use
* and saves it in this.regexp
*/
Zotero.Proxy.prototype.compileRegexp = function() {
const metaRe = /[-[\]{}()*+?.\\^$|,#\s]/g;
@ -304,6 +328,9 @@ Zotero.Proxy.prototype.compileRegexp = function() {
/**
* Ensures that the proxy scheme and host settings are valid for this proxy type
*
* @returns {String|Boolean} An error type if a validation error occurred, or "false" if there was
* no error.
*/
Zotero.Proxy.prototype.validate = function() {
if(this.scheme.length < 8 || (this.scheme.substr(0, 7) != "http://" && this.scheme.substr(0, 8) != "https://")) {
@ -399,6 +426,7 @@ Zotero.Proxy.prototype.erase = function() {
* Converts a proxied URL to an unproxied URL using this proxy
*
* @param m {Array} The match from running this proxy's regexp against a URL spec
* @type String
*/
Zotero.Proxy.prototype.toProper = function(m) {
if(this.multiHost) {
@ -423,6 +451,7 @@ Zotero.Proxy.prototype.toProper = function(m) {
* Converts an unproxied URL to a proxied URL using this proxy
*
* @param {nsIURI} uri The nsIURI corresponding to the unproxied URL
* @type String
*/
Zotero.Proxy.prototype.toProxy = function(uri) {
proxyURL = this.scheme;
@ -448,6 +477,7 @@ Zotero.Proxy.prototype.toProxy = function(uri) {
/**
* Loads a proxy object from a DB row
* @private
*/
Zotero.Proxy.prototype._loadFromRow = function(row) {
this.proxyID = row.proxyID;
@ -458,10 +488,16 @@ Zotero.Proxy.prototype._loadFromRow = function(row) {
this.compileRegexp();
}
/**
* Detectors for various proxy systems
* @namespace
*/
Zotero.Proxies.Detectors = new Object();
/**
* Detector for OCLC EZProxy
* @param {nsIChannel} channel
* @type Boolean|Zotero.Proxy
*/
Zotero.Proxies.Detectors.EZProxy = function(channel) {
const ezProxyRe = /\?(?:.+&)?(url|qurl)=([^&]+)/i;
@ -556,7 +592,8 @@ Zotero.Proxies.Detectors.EZProxy.obs = Components.classes["@mozilla.org/observer
.getService(Components.interfaces.nsIObserverService);
/**
* Do-nothing stream listener
* @class Do-nothing stream listener
* @private
*/
Zotero.Proxies.Detectors.EZProxy.DummyStreamListener = function() {}
Zotero.Proxies.Detectors.EZProxy.DummyStreamListener.prototype.onDataAvailable = function(request,
@ -565,7 +602,8 @@ Zotero.Proxies.Detectors.EZProxy.DummyStreamListener.prototype.onStartRequest =
Zotero.Proxies.Detectors.EZProxy.DummyStreamListener.prototype.onStopRequest = function(request, context, status) {}
/**
* Observer to clear cookies on an HTTP request, then remove itself
* @class Observer to clear cookies on an HTTP request, then remove itself
* @private
*/
Zotero.Proxies.Detectors.EZProxy.Observer = function(newChannel) {
this.channel = newChannel;
@ -584,6 +622,8 @@ Zotero.Proxies.Detectors.EZProxy.Observer.prototype.QueryInterface = function(aI
/**
* Detector for Juniper Networks WebVPN
* @param {nsIChannel} channel
* @type Boolean|Zotero.Proxy
*/
Zotero.Proxies.Detectors.Juniper = function(channel) {
const juniperRe = /^(https?:\/\/[^\/:]+(?:\:[0-9]+)?)\/(.*),DanaInfo=([^+,]*)([^+]*)(?:\+(.*))?$/;

View file

@ -155,3 +155,9 @@
<!ENTITY zotero.integration.prefs.bookmarks.caption "Bookmarks are preserved across Microsoft Word and OpenOffice.org, but may be accidentally modified.">
<!ENTITY zotero.integration.references.label "References in Bibliography">
<!ENTITY zotero.proxy.recognized.title "Proxy Recognized">
<!ENTITY zotero.proxy.recognized.warning "Only add proxies linked from your library, school, or corporate website">
<!ENTITY zotero.proxy.recognized.warning.secondary "Adding other proxies allows malicious sites to masquerade as sites you trust.">
<!ENTITY zotero.proxy.recognized.disable.label "Do not automatically redirect requests through previously recognized proxies">
<!ENTITY zotero.proxy.recognized.ignore.label "Ignore">

View file

@ -505,6 +505,7 @@ proxies.error.scheme.noHTTP = Valid proxy schemes must start with "http://" or
proxies.error.host.invalid = You must enter a full hostname for the site served by this proxy (e.g., jstor.org).
proxies.error.scheme.noHost = A multi-site proxy scheme must contain the host variable (%h).
proxies.error.scheme.noPath = A valid proxy scheme must contain either the path variable (%p) or the directory and filename variables (%d and %f).
proxies.recognized = Proxy Recognized
proxies.recognized.message = Would you like Zotero to store information about this proxy server to enable saving of references accessed through it?\n\nWARNING: Only click "OK" below if you have accessed this site through your library or another institution you trust.
proxies.recognized.disable = Disable automatic recognition of proxy systems
proxies.recognized.message = Adding this proxy will allow Zotero to recognize items from its pages and will automatically redirect future requests to %1$S through %2$S.
proxies.recognized.add = Add Proxy
proxies.enableTransparentWarning.title = Warning
proxies.enableTransparentWarning.description = Please ensure that the proxies listed below belong to a library, school, or other institution with which you are affiliated. A malicious proxy could pose a security risk when transparent redirection is enabled.

View file

@ -206,3 +206,9 @@ zoteromergepane {
{
list-style-image: url('chrome://zotero/skin/treesource-collection.png');
}
.zotero-warning {
font-weight: bold;
font-size: 1.25em;
margin-bottom: 1em;
}

View file

@ -89,4 +89,4 @@ pref("extensions.zotero.sync.server.compressData", true);
// Proxy
pref("extensions.zotero.proxies.autoRecognize", true);
pref("extensions.zotero.proxies.transparent", false);
pref("extensions.zotero.proxies.transparent", true);