From 61cfb8aa2ff222b9a92e466dddf59c8d92f8e772 Mon Sep 17 00:00:00 2001 From: HelloZeroNet Date: Wed, 10 Feb 2016 02:30:04 +0100 Subject: [PATCH] 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 --- plugins/Sidebar/SidebarPlugin.py | 1 + plugins/Sidebar/media/Sidebar.coffee | 16 +++++++++---- plugins/Sidebar/media/Sidebar.css | 3 ++- plugins/Sidebar/media/all.css | 3 ++- plugins/Sidebar/media/all.js | 28 ++++++++++++++-------- plugins/Trayicon/trayicon.ico | Bin 1150 -> 1150 bytes src/Config.py | 2 +- src/Site/SiteStorage.py | 4 ++++ src/Test/TestWeb.py | 2 +- src/Ui/UiRequest.py | 6 +++++ src/Ui/UiWebsocket.py | 2 +- src/Ui/media/Wrapper.coffee | 31 +++++++++++++++++++----- src/Ui/media/Wrapper.css | 4 ++++ src/Ui/media/all.css | 4 ++++ src/Ui/media/all.js | 34 +++++++++++++++++++++------ src/Ui/template/wrapper.html | 3 +++ src/Worker/WorkerManager.py | 17 +++++++++----- 17 files changed, 121 insertions(+), 39 deletions(-) diff --git a/plugins/Sidebar/SidebarPlugin.py b/plugins/Sidebar/SidebarPlugin.py index b22ddc17..0450b22d 100644 --- a/plugins/Sidebar/SidebarPlugin.py +++ b/plugins/Sidebar/SidebarPlugin.py @@ -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"
  • " % (percent, extension, color, extension)) # Legend diff --git a/plugins/Sidebar/media/Sidebar.coffee b/plugins/Sidebar/media/Sidebar.coffee index 68a0f68a..ae09755a 100644 --- a/plugins/Sidebar/media/Sidebar.coffee +++ b/plugins/Sidebar/media/Sidebar.coffee @@ -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' diff --git a/plugins/Sidebar/media/Sidebar.css b/plugins/Sidebar/media/Sidebar.css index 6593d4cc..b43c99b0 100644 --- a/plugins/Sidebar/media/Sidebar.css +++ b/plugins/Sidebar/media/Sidebar.css @@ -96,4 +96,5 @@ /* Globe */ .globe { width: 360px; height: 360px } -.globe.loading { background: url(/uimedia/img/loading-circle.gif) center center no-repeat } \ No newline at end of file +.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; } \ No newline at end of file diff --git a/plugins/Sidebar/media/all.css b/plugins/Sidebar/media/all.css index 68552d50..6398f3d0 100644 --- a/plugins/Sidebar/media/all.css +++ b/plugins/Sidebar/media/all.css @@ -150,4 +150,5 @@ /* Globe */ .globe { width: 360px; height: 360px } -.globe.loading { background: url(/uimedia/img/loading-circle.gif) center center no-repeat } \ No newline at end of file +.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; } \ No newline at end of file diff --git a/plugins/Sidebar/media/all.js b/plugins/Sidebar/media/all.js index 61eb5f29..a1bf185b 100644 --- a/plugins/Sidebar/media/all.js +++ b/plugins/Sidebar/media/all.js @@ -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'; diff --git a/plugins/Trayicon/trayicon.ico b/plugins/Trayicon/trayicon.ico index 8e1a528501aeda828ca283d01c3203c4a5c0b55f..086172254e3534b532ddc8a82c49c60bc6e036f2 100644 GIT binary patch literal 1150 zcmb7DziV1i6h3JS5!yl^kTt~+)5VgKq3i3~KOi6!iqN5UkU;HFDKwjOjEfCsaENq} z7D|hwNU13lM+9qEv<2`OW)pA&%fMCbmc!wA7>Pt)G@H$QtycRM3Wc6S>;i7i z3Bv5w0)c?HR4RR#UN*B>EXMtQ{}XVW0Q0k(E1S)}8;{55O4@F>OTAuCSN>=;`khLp z_8?>~R%1L(@j9JOHJMDlb-UeJRn&c(zgdD9&D+qenP#abMJ{t9aCOyWLae^KR1VbeLQUY<3;KlW(+8C>-*vN{6qR z&*u*<@AsNbYjxQp>+Bi4hwOj!k2MCz>{<5i-2R&D-~`<9zPOWyG0zUQ3hIp@4zA|ZaOtHS>|xw9m) zE+XdvE&o$EFaQJOJ9v>K+m{X}# zphm2qUh{#ghBq3GelVWJVzKMVWb#J0+kGF*t6bHX9P|2qzn@nv{%vp;SdB*GjmeKa zqt`t6F2d<)kMO+7WYVVYhfF53M=V?{79aY0PxYp@`QqDQz29xyb_RpNS5u38zuA{p zrBdk;d(p%{nb%_({ z=l0G&gApOG*=!Do?VO~q)oL%`n7!L%eucYKG`(QY>>u_~|H{#`avbL)<7Og}*ro5+ z^iV%e@2|nqx@i9xo@zkF*m^eAYV|qwX6}!#KaD@Eca$~nYa2$V^H!_1AGp7#g6j{? z$*}^q^v!UOa*Mv7U=F{ZHS*}&J@Nfcry|~C5qCr6=dwuUsmQ@+<~G @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 = $("
    You have opened this page by clicking on a link. Please, confirm if you want to load this site.Open site
    ") + 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) \ No newline at end of file diff --git a/src/Ui/media/Wrapper.css b/src/Ui/media/Wrapper.css index 5c91e88e..6d4f550c 100644 --- a/src/Ui/media/Wrapper.css +++ b/src/Ui/media/Wrapper.css @@ -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 } diff --git a/src/Ui/media/all.css b/src/Ui/media/all.css index bcf20b3a..4f4a5b14 100644 --- a/src/Ui/media/all.css +++ b/src/Ui/media/all.css @@ -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 } diff --git a/src/Ui/media/all.js b/src/Ui/media/all.js index 436e2e9e..60925cc8 100644 --- a/src/Ui/media/all.js +++ b/src/Ui/media/all.js @@ -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 = $("
    You have opened this page by clicking on a link. Please, confirm if you want to load this site.Open site
    "); + 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); diff --git a/src/Ui/template/wrapper.html b/src/Ui/template/wrapper.html index 8989c240..6dbb0c2f 100644 --- a/src/Ui/template/wrapper.html +++ b/src/Ui/template/wrapper.html @@ -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} diff --git a/src/Worker/WorkerManager.py b/src/Worker/WorkerManager.py index c4da30ff..9819ad64 100644 --- a/src/Worker/WorkerManager.py +++ b/src/Worker/WorkerManager.py @@ -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)