Rev900, Sidebar filestats bar width round fix, Sidebar WebGL not supported error, Sidebar optimalizations, Trayicon gray shadow, Trim end of line whitespace from json files, Fix testweb testcase, Implement experimental postMessage nonce security, Return None when testing external ip, Window opener security check and message, Increase timeout for large files

This commit is contained in:
HelloZeroNet 2016-02-10 02:30:04 +01:00
parent 018c6f7075
commit 61cfb8aa2f
17 changed files with 121 additions and 39 deletions

View file

@ -148,6 +148,7 @@ class UiWebsocketPlugin(object):
percent = 0 percent = 0
else: else:
percent = 100 * (float(size) / size_total) percent = 100 * (float(size) / size_total)
percent = math.floor(percent*100)/100 # Floor to 2 digits
body.append(u"<li style='width: %.2f%%' class='%s back-%s' title='%s'></li>" % (percent, extension, color, extension)) body.append(u"<li style='width: %.2f%%' class='%s back-%s' title='%s'></li>" % (percent, extension, color, extension))
# Legend # Legend

View file

@ -320,10 +320,14 @@ class Sidebar extends Class
@globe.addData( globe_data, {format: 'magnitude', name: "hello", animated: false} ) @globe.addData( globe_data, {format: 'magnitude', name: "hello", animated: false} )
@globe.createPoints() @globe.createPoints()
else else
try
@globe = new DAT.Globe( @tag.find(".globe")[0], {"imgDir": "/uimedia/globe/"} ) @globe = new DAT.Globe( @tag.find(".globe")[0], {"imgDir": "/uimedia/globe/"} )
@globe.addData( globe_data, {format: 'magnitude', name: "hello"} ) @globe.addData( globe_data, {format: 'magnitude', name: "hello"} )
@globe.createPoints() @globe.createPoints()
@globe.animate() @globe.animate()
catch e
@tag.find(".globe").addClass("error").text("WebGL not supported")
@tag.find(".globe").removeClass("loading") @tag.find(".globe").removeClass("loading")
@ -334,5 +338,7 @@ class Sidebar extends Class
@globe = null @globe = null
window.sidebar = new Sidebar() setTimeout ( ->
window.sidebar = new Sidebar()
), 500
window.transitionEnd = 'transitionend webkitTransitionEnd oTransitionEnd otransitionend' window.transitionEnd = 'transitionend webkitTransitionEnd oTransitionEnd otransitionend'

View file

@ -97,3 +97,4 @@
/* Globe */ /* Globe */
.globe { width: 360px; height: 360px } .globe { width: 360px; height: 360px }
.globe.loading { background: url(/uimedia/img/loading-circle.gif) center center no-repeat } .globe.loading { background: url(/uimedia/img/loading-circle.gif) center center no-repeat }
.globe.error { text-align: center; padding-top: 156px; box-sizing: border-box; opacity: 0.2; }

View file

@ -151,3 +151,4 @@
/* Globe */ /* Globe */
.globe { width: 360px; height: 360px } .globe { width: 360px; height: 360px }
.globe.loading { background: url(/uimedia/img/loading-circle.gif) center center no-repeat } .globe.loading { background: url(/uimedia/img/loading-circle.gif) center center no-repeat }
.globe.error { text-align: center; padding-top: 156px; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -o-box-sizing: border-box; -ms-box-sizing: border-box; box-sizing: border-box ; opacity: 0.2; }

View file

@ -521,6 +521,7 @@ window.initScrollable = function () {
Sidebar.prototype.displayGlobe = function() { Sidebar.prototype.displayGlobe = function() {
return wrapper.ws.cmd("sidebarGetPeers", [], (function(_this) { return wrapper.ws.cmd("sidebarGetPeers", [], (function(_this) {
return function(globe_data) { return function(globe_data) {
var e;
if (_this.globe) { if (_this.globe) {
_this.globe.scene.remove(_this.globe.points); _this.globe.scene.remove(_this.globe.points);
_this.globe.addData(globe_data, { _this.globe.addData(globe_data, {
@ -530,6 +531,7 @@ window.initScrollable = function () {
}); });
_this.globe.createPoints(); _this.globe.createPoints();
} else { } else {
try {
_this.globe = new DAT.Globe(_this.tag.find(".globe")[0], { _this.globe = new DAT.Globe(_this.tag.find(".globe")[0], {
"imgDir": "/uimedia/globe/" "imgDir": "/uimedia/globe/"
}); });
@ -539,6 +541,10 @@ window.initScrollable = function () {
}); });
_this.globe.createPoints(); _this.globe.createPoints();
_this.globe.animate(); _this.globe.animate();
} catch (_error) {
e = _error;
_this.tag.find(".globe").addClass("error").text("WebGL not supported");
}
} }
return _this.tag.find(".globe").removeClass("loading"); return _this.tag.find(".globe").removeClass("loading");
}; };
@ -557,7 +563,9 @@ window.initScrollable = function () {
})(Class); })(Class);
window.sidebar = new Sidebar(); setTimeout((function() {
return window.sidebar = new Sidebar();
}), 500);
window.transitionEnd = 'transitionend webkitTransitionEnd oTransitionEnd otransitionend'; window.transitionEnd = 'transitionend webkitTransitionEnd oTransitionEnd otransitionend';

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -8,7 +8,7 @@ class Config(object):
def __init__(self, argv): def __init__(self, argv):
self.version = "0.3.6" self.version = "0.3.6"
self.rev = 889 self.rev = 900
self.argv = argv self.argv = argv
self.action = None self.action = None
self.config_file = "zeronet.conf" self.config_file = "zeronet.conf"

View file

@ -206,6 +206,10 @@ class SiteStorage:
content = re.sub("\[([^,\{\[]{10,100}?)\]", compact_list, content, flags=re.DOTALL) content = re.sub("\[([^,\{\[]{10,100}?)\]", compact_list, content, flags=re.DOTALL)
content = re.sub("\{([^,\[\{]{10,100}?)\}", compact_dict, content, flags=re.DOTALL) content = re.sub("\{([^,\[\{]{10,100}?)\}", compact_dict, content, flags=re.DOTALL)
# Remove end of line whitespace
content = re.sub("(?m)[ ]+$", "", content)
# Write to disk # Write to disk
self.write(inner_path, content) self.write(inner_path, content)

View file

@ -35,7 +35,7 @@ class TestWeb:
assert "Forbidden" in urllib.urlopen("%s/1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr/../../zeronet.py" % site_url).read() assert "Forbidden" in urllib.urlopen("%s/1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr/../../zeronet.py" % site_url).read()
def testHomepage(self, browser, site_url): def testHomepage(self, browser, site_url):
browser.get("%s" % site_url) browser.get("%s/1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr" % site_url)
assert browser.title == "ZeroHello - ZeroNet" assert browser.title == "ZeroHello - ZeroNet"
def testLinkSecurity(self, browser, site_url): def testLinkSecurity(self, browser, site_url):

View file

@ -229,6 +229,7 @@ class UiRequest(object):
query_string = "" query_string = ""
body_style = "" body_style = ""
meta_tags = "" meta_tags = ""
postmessage_nonce_security = "false"
wrapper_nonce = self.getWrapperNonce() wrapper_nonce = self.getWrapperNonce()
@ -254,6 +255,9 @@ class UiRequest(object):
cgi.escape(site.content_manager.contents["content.json"]["background-color"], True) cgi.escape(site.content_manager.contents["content.json"]["background-color"], True)
if content.get("viewport"): if content.get("viewport"):
meta_tags += '<meta name="viewport" id="viewport" content="%s">' % cgi.escape(content["viewport"], True) meta_tags += '<meta name="viewport" id="viewport" content="%s">' % cgi.escape(content["viewport"], True)
if content.get("postmessage_nonce_security"):
postmessage_nonce_security = "true"
if site.settings.get("own"): if site.settings.get("own"):
sandbox_permissions = "allow-modals" # For coffeescript compile errors sandbox_permissions = "allow-modals" # For coffeescript compile errors
@ -272,6 +276,8 @@ class UiRequest(object):
meta_tags=meta_tags, meta_tags=meta_tags,
query_string=query_string, query_string=query_string,
wrapper_key=site.settings["wrapper_key"], wrapper_key=site.settings["wrapper_key"],
wrapper_nonce=wrapper_nonce,
postmessage_nonce_security=postmessage_nonce_security,
permissions=json.dumps(site.settings["permissions"]), permissions=json.dumps(site.settings["permissions"]),
show_loadingscreen=json.dumps(not site.storage.isFile(file_inner_path)), show_loadingscreen=json.dumps(not site.storage.isFile(file_inner_path)),
sandbox_permissions=sandbox_permissions, sandbox_permissions=sandbox_permissions,

View file

@ -222,7 +222,7 @@ class UiWebsocket(object):
def formatServerInfo(self): def formatServerInfo(self):
return { return {
"ip_external": bool(sys.modules["main"].file_server.port_opened), "ip_external": sys.modules["main"].file_server.port_opened,
"platform": sys.platform, "platform": sys.platform,
"fileserver_ip": config.fileserver_ip, "fileserver_ip": config.fileserver_ip,
"fileserver_port": config.fileserver_port, "fileserver_port": config.fileserver_port,

View file

@ -1,11 +1,6 @@
class Wrapper class Wrapper
constructor: (ws_url) -> constructor: (ws_url) ->
@log "Created!" @log "Created!"
if window.opener
@log "Security error: Opener present, exiting..."
document.write("Forbidden: Opener present.")
document.body.innerHTML = "Forbidden: Opener present."
return
@loading = new Loading() @loading = new Loading()
@notifications = new Notifications($(".notifications")) @notifications = new Notifications($(".notifications"))
@ -73,6 +68,11 @@ class Wrapper
# Incoming message from inner frame # Incoming message from inner frame
onMessageInner: (e) => onMessageInner: (e) =>
message = e.data message = e.data
if window.postmessage_nonce_security and message.wrapper_nonce != window.wrapper_nonce
@log "Message nonce error:", message.wrapper_nonce, '!=', window.wrapper_nonce
@actionNotification({"params": ["error", "Message wrapper_nonce error, please report!"]})
window.removeEventListener("message", @onMessageInner)
return
cmd = message.cmd cmd = message.cmd
if cmd == "innerReady" if cmd == "innerReady"
@inner_ready = true @inner_ready = true
@ -383,4 +383,23 @@ else
ws_url = proto.ws + ":" + origin.replace(proto.http+":", "") + "/Websocket?wrapper_key=" + window.wrapper_key ws_url = proto.ws + ":" + origin.replace(proto.http+":", "") + "/Websocket?wrapper_key=" + window.wrapper_key
window.wrapper = new Wrapper(ws_url)
if window.opener
# Window opener security problem workaround: Open a new window, close this one
console.log "Opener present:", window.opener
setTimeout ( -> # Wait 200ms to parent tab closing
if window.opener
# Opener still present, display message
elem = $("<div class='opener-overlay'><div class='dialog'>You have opened this page by clicking on a link. Please, confirm if you want to load this site.<a href='?' target='_blank' class='button'>Open site</a></div></div>")
elem.find('a').on "click", ->
window.open("?", "_blank")
window.close()
return false
$("body").prepend(elem)
else
window.location.reload()
# Opener gone, continue init
# window.wrapper = new Wrapper(ws_url)
), 100
else
window.wrapper = new Wrapper(ws_url)

View file

@ -130,6 +130,10 @@ a { color: black }
box-shadow: 0 0 10px #AF3BFF, 0 0 5px #29d; opacity: 1.0; transform: rotate(3deg) translate(0px, -4px); box-shadow: 0 0 10px #AF3BFF, 0 0 5px #29d; opacity: 1.0; transform: rotate(3deg) translate(0px, -4px);
} }
/* Opener overlay */
.opener-overlay { position: fixed; z-index: 9999; width: 100%; text-align: center; background-color: rgba(100,100,100,0.5); height: 100%; vertical-align: middle; }
.opener-overlay .dialog { background-color: white; padding: 40px; display: inline-block; color: #4F4F4F; font-family: 'Lucida Grande', 'Segoe UI', Helvetica, Arial, sans-serif; font-size: 14px; }
/* Icons */ /* Icons */
.icon-profile { font-size: 6px; top: 0em; border-radius: 0.7em 0.7em 0 0; background: #FFFFFF; width: 1.5em; height: 0.7em; position: relative; display: inline-block; margin-right: 4px } .icon-profile { font-size: 6px; top: 0em; border-radius: 0.7em 0.7em 0 0; background: #FFFFFF; width: 1.5em; height: 0.7em; position: relative; display: inline-block; margin-right: 4px }
.icon-profile::before { position: absolute; content: ""; top: -1em; left: 0.38em; width: 0.8em; height: 0.85em; border-radius: 50%; background: #FFFFFF } .icon-profile::before { position: absolute; content: ""; top: -1em; left: 0.38em; width: 0.8em; height: 0.85em; border-radius: 50%; background: #FFFFFF }

View file

@ -135,6 +135,10 @@ a { color: black }
-webkit-box-shadow: 0 0 10px #AF3BFF, 0 0 5px #29d; -moz-box-shadow: 0 0 10px #AF3BFF, 0 0 5px #29d; -o-box-shadow: 0 0 10px #AF3BFF, 0 0 5px #29d; -ms-box-shadow: 0 0 10px #AF3BFF, 0 0 5px #29d; box-shadow: 0 0 10px #AF3BFF, 0 0 5px #29d ; opacity: 1.0; -webkit-transform: rotate(3deg) translate(0px, -4px); -moz-transform: rotate(3deg) translate(0px, -4px); -o-transform: rotate(3deg) translate(0px, -4px); -ms-transform: rotate(3deg) translate(0px, -4px); transform: rotate(3deg) translate(0px, -4px) ; -webkit-box-shadow: 0 0 10px #AF3BFF, 0 0 5px #29d; -moz-box-shadow: 0 0 10px #AF3BFF, 0 0 5px #29d; -o-box-shadow: 0 0 10px #AF3BFF, 0 0 5px #29d; -ms-box-shadow: 0 0 10px #AF3BFF, 0 0 5px #29d; box-shadow: 0 0 10px #AF3BFF, 0 0 5px #29d ; opacity: 1.0; -webkit-transform: rotate(3deg) translate(0px, -4px); -moz-transform: rotate(3deg) translate(0px, -4px); -o-transform: rotate(3deg) translate(0px, -4px); -ms-transform: rotate(3deg) translate(0px, -4px); transform: rotate(3deg) translate(0px, -4px) ;
} }
/* Opener overlay */
.opener-overlay { position: fixed; z-index: 9999; width: 100%; text-align: center; background-color: rgba(100,100,100,0.5); height: 100%; vertical-align: middle; }
.opener-overlay .dialog { background-color: white; padding: 40px; display: inline-block; color: #4F4F4F; font-family: 'Lucida Grande', 'Segoe UI', Helvetica, Arial, sans-serif; font-size: 14px; }
/* Icons */ /* Icons */
.icon-profile { font-size: 6px; top: 0em; -webkit-border-radius: 0.7em 0.7em 0 0; -moz-border-radius: 0.7em 0.7em 0 0; -o-border-radius: 0.7em 0.7em 0 0; -ms-border-radius: 0.7em 0.7em 0 0; border-radius: 0.7em 0.7em 0 0 ; background: #FFFFFF; width: 1.5em; height: 0.7em; position: relative; display: inline-block; margin-right: 4px } .icon-profile { font-size: 6px; top: 0em; -webkit-border-radius: 0.7em 0.7em 0 0; -moz-border-radius: 0.7em 0.7em 0 0; -o-border-radius: 0.7em 0.7em 0 0; -ms-border-radius: 0.7em 0.7em 0 0; border-radius: 0.7em 0.7em 0 0 ; background: #FFFFFF; width: 1.5em; height: 0.7em; position: relative; display: inline-block; margin-right: 4px }
.icon-profile::before { position: absolute; content: ""; top: -1em; left: 0.38em; width: 0.8em; height: 0.85em; -webkit-border-radius: 50%; -moz-border-radius: 50%; -o-border-radius: 50%; -ms-border-radius: 50%; border-radius: 50% ; background: #FFFFFF } .icon-profile::before { position: absolute; content: ""; top: -1em; left: 0.38em; width: 0.8em; height: 0.85em; -webkit-border-radius: 50%; -moz-border-radius: 50%; -o-border-radius: 50%; -ms-border-radius: 50%; border-radius: 50% ; background: #FFFFFF }

View file

@ -762,12 +762,6 @@ jQuery.extend( jQuery.easing,
this.onMessageInner = __bind(this.onMessageInner, this); this.onMessageInner = __bind(this.onMessageInner, this);
this.onMessageWebsocket = __bind(this.onMessageWebsocket, this); this.onMessageWebsocket = __bind(this.onMessageWebsocket, this);
this.log("Created!"); this.log("Created!");
if (window.opener) {
this.log("Security error: Opener present, exiting...");
document.write("Forbidden: Opener present.");
document.body.innerHTML = "Forbidden: Opener present.";
return;
}
this.loading = new Loading(); this.loading = new Loading();
this.notifications = new Notifications($(".notifications")); this.notifications = new Notifications($(".notifications"));
this.fixbutton = new Fixbutton(); this.fixbutton = new Fixbutton();
@ -842,6 +836,14 @@ jQuery.extend( jQuery.easing,
Wrapper.prototype.onMessageInner = function(e) { Wrapper.prototype.onMessageInner = function(e) {
var cmd, message, query; var cmd, message, query;
message = e.data; message = e.data;
if (window.postmessage_nonce_security && message.wrapper_nonce !== window.wrapper_nonce) {
this.log("Message nonce error:", message.wrapper_nonce, '!=', window.wrapper_nonce);
this.actionNotification({
"params": ["error", "Message wrapper_nonce error, please report!"]
});
window.removeEventListener("message", this.onMessageInner);
return;
}
cmd = message.cmd; cmd = message.cmd;
if (cmd === "innerReady") { if (cmd === "innerReady") {
this.inner_ready = true; this.inner_ready = true;
@ -1264,6 +1266,24 @@ jQuery.extend( jQuery.easing,
ws_url = proto.ws + ":" + origin.replace(proto.http + ":", "") + "/Websocket?wrapper_key=" + window.wrapper_key; ws_url = proto.ws + ":" + origin.replace(proto.http + ":", "") + "/Websocket?wrapper_key=" + window.wrapper_key;
if (window.opener) {
console.log("Opener present:", window.opener);
setTimeout((function() {
var elem;
if (window.opener) {
elem = $("<div class='opener-overlay'><div class='dialog'>You have opened this page by clicking on a link. Please, confirm if you want to load this site.<a href='?' target='_blank' class='button'>Open site</a></div></div>");
elem.find('a').on("click", function() {
window.open("?", "_blank");
window.close();
return false;
});
return $("body").prepend(elem);
} else {
return window.location.reload();
}
}), 100);
} else {
window.wrapper = new Wrapper(ws_url); window.wrapper = new Wrapper(ws_url);
}
}).call(this); }).call(this);

View file

@ -17,6 +17,7 @@ if (window.self !== window.top) window.open(window.location.toString(), "_top");
if (window.self !== window.top) window.stop(); if (window.self !== window.top) window.stop();
if (window.self !== window.top && document.execCommand) document.execCommand("Stop", false) if (window.self !== window.top && document.execCommand) document.execCommand("Stop", false)
// Dont allow site to load in a popup // Dont allow site to load in a popup
/* /*
if (window.opener) document.write("Opener not allowed") if (window.opener) document.write("Opener not allowed")
@ -61,7 +62,9 @@ if (window.opener && window.stop) window.stop()
document.getElementById("inner-iframe").src = "about:blank" document.getElementById("inner-iframe").src = "about:blank"
document.getElementById("inner-iframe").src = "{file_url}{query_string}" document.getElementById("inner-iframe").src = "{file_url}{query_string}"
address = "{address}" address = "{address}"
wrapper_nonce = "{wrapper_nonce}"
wrapper_key = "{wrapper_key}" wrapper_key = "{wrapper_key}"
postmessage_nonce_security = {postmessage_nonce_security}
file_inner_path = "{file_inner_path}" file_inner_path = "{file_inner_path}"
permissions = {permissions} permissions = {permissions}
show_loadingscreen = {show_loadingscreen} show_loadingscreen = {show_loadingscreen}

View file

@ -47,7 +47,8 @@ class WorkerManager:
tasks = self.tasks[:] # Copy it so removing elements wont cause any problem tasks = self.tasks[:] # Copy it so removing elements wont cause any problem
for task in tasks: for task in tasks:
if task["time_started"] and time.time() >= task["time_started"] + 60: # Task taking too long time, skip it size_extra_time = task["size"] / (1024*100) # 1 second for every 100k
if task["time_started"] and time.time() >= task["time_started"] + 60 + size_extra_time: # Task taking too long time, skip it
self.log.debug("Timeout, Skipping: %s" % task) self.log.debug("Timeout, Skipping: %s" % task)
# Skip to next file workers # Skip to next file workers
workers = self.findWorkers(task) workers = self.findWorkers(task)
@ -56,17 +57,17 @@ class WorkerManager:
worker.skip() worker.skip()
else: else:
self.failTask(task) self.failTask(task)
elif time.time() >= task["time_added"] + 60 and not self.workers: # No workers left elif time.time() >= task["time_added"] + 60 + size_extra_time and not self.workers: # No workers left
self.log.debug("Timeout, Cleanup task: %s" % task) self.log.debug("Timeout, Cleanup task: %s" % task)
# Remove task # Remove task
self.failTask(task) self.failTask(task)
elif (task["time_started"] and time.time() >= task["time_started"] + 15) or not self.workers: elif (task["time_started"] and time.time() >= task["time_started"] + 15) or not self.workers:
# Task started more than 15 sec ago or no workers # Find more workers: Task started more than 15 sec ago or no workers
workers = self.findWorkers(task) workers = self.findWorkers(task)
self.log.debug( self.log.debug(
"Task taking more than 15 secs, workers: %s find more peers: %s" % "Task taking more than 15+%s secs, workers: %s find more peers: %s" %
(len(workers), task["inner_path"]) (size_extra_time, len(workers), task["inner_path"])
) )
task["site"].announce(mode="more") # Find more peers task["site"].announce(mode="more") # Find more peers
if task["optional_hash_id"]: if task["optional_hash_id"]:
@ -326,9 +327,13 @@ class WorkerManager:
optional_hash_id = helper.toHashId(file_info["sha512"]) optional_hash_id = helper.toHashId(file_info["sha512"])
else: else:
optional_hash_id = None optional_hash_id = None
if file_info:
size = file_info.get("size", 0)
else:
size = 0
task = { task = {
"evt": evt, "workers_num": 0, "site": self.site, "inner_path": inner_path, "done": False, "optional_hash_id": optional_hash_id, "evt": evt, "workers_num": 0, "site": self.site, "inner_path": inner_path, "done": False, "optional_hash_id": optional_hash_id,
"time_added": time.time(), "time_started": None, "time_action": None, "peers": peers, "priority": priority, "failed": [] "time_added": time.time(), "time_started": None, "time_action": None, "peers": peers, "priority": priority, "failed": [], "size": size
} }
self.tasks.append(task) self.tasks.append(task)