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
else:
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))
# Legend

View file

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

View file

@ -96,4 +96,5 @@
/* Globe */
.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

@ -150,4 +150,5 @@
/* Globe */
.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() {
return wrapper.ws.cmd("sidebarGetPeers", [], (function(_this) {
return function(globe_data) {
var e;
if (_this.globe) {
_this.globe.scene.remove(_this.globe.points);
_this.globe.addData(globe_data, {
@ -530,15 +531,20 @@ window.initScrollable = function () {
});
_this.globe.createPoints();
} else {
_this.globe = new DAT.Globe(_this.tag.find(".globe")[0], {
"imgDir": "/uimedia/globe/"
});
_this.globe.addData(globe_data, {
format: 'magnitude',
name: "hello"
});
_this.globe.createPoints();
_this.globe.animate();
try {
_this.globe = new DAT.Globe(_this.tag.find(".globe")[0], {
"imgDir": "/uimedia/globe/"
});
_this.globe.addData(globe_data, {
format: 'magnitude',
name: "hello"
});
_this.globe.createPoints();
_this.globe.animate();
} catch (_error) {
e = _error;
_this.tag.find(".globe").addClass("error").text("WebGL not supported");
}
}
return _this.tag.find(".globe").removeClass("loading");
};
@ -557,7 +563,9 @@ window.initScrollable = function () {
})(Class);
window.sidebar = new Sidebar();
setTimeout((function() {
return window.sidebar = new Sidebar();
}), 500);
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):
self.version = "0.3.6"
self.rev = 889
self.rev = 900
self.argv = argv
self.action = None
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_dict, content, flags=re.DOTALL)
# Remove end of line whitespace
content = re.sub("(?m)[ ]+$", "", content)
# Write to disk
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()
def testHomepage(self, browser, site_url):
browser.get("%s" % site_url)
browser.get("%s/1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr" % site_url)
assert browser.title == "ZeroHello - ZeroNet"
def testLinkSecurity(self, browser, site_url):

View file

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

View file

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

View file

@ -1,11 +1,6 @@
class Wrapper
constructor: (ws_url) ->
@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()
@notifications = new Notifications($(".notifications"))
@ -73,6 +68,11 @@ class Wrapper
# Incoming message from inner frame
onMessageInner: (e) =>
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
if cmd == "innerReady"
@inner_ready = true
@ -383,4 +383,23 @@ else
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);
}
/* 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 */
.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 }

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) ;
}
/* 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 */
.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 }

View file

@ -762,12 +762,6 @@ jQuery.extend( jQuery.easing,
this.onMessageInner = __bind(this.onMessageInner, this);
this.onMessageWebsocket = __bind(this.onMessageWebsocket, this);
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.notifications = new Notifications($(".notifications"));
this.fixbutton = new Fixbutton();
@ -842,6 +836,14 @@ jQuery.extend( jQuery.easing,
Wrapper.prototype.onMessageInner = function(e) {
var cmd, message, query;
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;
if (cmd === "innerReady") {
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;
window.wrapper = new Wrapper(ws_url);
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);
}
}).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 && document.execCommand) document.execCommand("Stop", false)
// Dont allow site to load in a popup
/*
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 = "{file_url}{query_string}"
address = "{address}"
wrapper_nonce = "{wrapper_nonce}"
wrapper_key = "{wrapper_key}"
postmessage_nonce_security = {postmessage_nonce_security}
file_inner_path = "{file_inner_path}"
permissions = {permissions}
show_loadingscreen = {show_loadingscreen}

View file

@ -47,7 +47,8 @@ class WorkerManager:
tasks = self.tasks[:] # Copy it so removing elements wont cause any problem
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)
# Skip to next file workers
workers = self.findWorkers(task)
@ -56,17 +57,17 @@ class WorkerManager:
worker.skip()
else:
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)
# Remove task
self.failTask(task)
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)
self.log.debug(
"Task taking more than 15 secs, workers: %s find more peers: %s" %
(len(workers), task["inner_path"])
"Task taking more than 15+%s secs, workers: %s find more peers: %s" %
(size_extra_time, len(workers), task["inner_path"])
)
task["site"].announce(mode="more") # Find more peers
if task["optional_hash_id"]:
@ -326,9 +327,13 @@ class WorkerManager:
optional_hash_id = helper.toHashId(file_info["sha512"])
else:
optional_hash_id = None
if file_info:
size = file_info.get("size", 0)
else:
size = 0
task = {
"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)