From f98f52a50eddf0410de1689340eefa624c0db3cf Mon Sep 17 00:00:00 2001
From: Ivanq <imachug@yandex.ru>
Date: Fri, 22 Sep 2017 08:21:51 +0300
Subject: [PATCH 1/2] Allow siteClone not for admin sites

---
 src/Ui/UiWebsocket.py | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/src/Ui/UiWebsocket.py b/src/Ui/UiWebsocket.py
index 8ecdf7aa..32675e70 100644
--- a/src/Ui/UiWebsocket.py
+++ b/src/Ui/UiWebsocket.py
@@ -33,7 +33,7 @@ class UiWebsocket(object):
         self.sending = False  # Currently sending to client
         self.send_queue = []  # Messages to send to client
         self.admin_commands = (
-            "sitePause", "siteResume", "siteDelete", "siteList", "siteSetLimit", "siteClone",
+            "sitePause", "siteResume", "siteDelete", "siteList", "siteSetLimit",
             "channelJoinAllsite", "serverUpdate", "serverPortcheck", "serverShutdown", "serverShowdirectory",
             "certSet", "configSet", "permissionAdd", "permissionRemove"
         )
@@ -809,7 +809,7 @@ class UiWebsocket(object):
         else:
             self.response(to, {"error": "Unknown site: %s" % address})
 
-    def actionSiteClone(self, to, address, root_inner_path="", target_address=None):
+    def cbSiteClone(self, to, address, root_inner_path="", target_address=None):
         self.cmd("notification", ["info", _["Cloning site..."]])
         site = self.server.sites.get(address)
         if target_address:
@@ -827,6 +827,16 @@ class UiWebsocket(object):
             self.cmd("notification", ["done", _["Site cloned"] + "<script>window.top.location = '/%s'</script>" % new_address])
             gevent.spawn(new_site.announce)
 
+    def actionSiteClone(self, to, address, root_inner_path="", target_address=None):
+        if "ADMIN" in self.getPermissions(to):
+            self.cbSiteClone(to, address, root_inner_path, target_address)
+        else:
+            self.cmd(
+                "confirm",
+                [_["Clone site <b>%s</b>?"] % address, _["Clone"]],
+                lambda (res): self.cbSiteClone(to, address, root_inner_path, target_address)
+            )
+
     def actionSiteSetLimit(self, to, size_limit):
         self.site.settings["size_limit"] = int(size_limit)
         self.site.saveSettings()

From 7fa019321c12bfbb806d88fde3a7cdd04d5e59f6 Mon Sep 17 00:00:00 2001
From: Ivanq <imachug@yandex.ru>
Date: Fri, 22 Sep 2017 08:28:39 +0300
Subject: [PATCH 2/2] Check site before cloning

---
 src/Ui/UiWebsocket.py | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/Ui/UiWebsocket.py b/src/Ui/UiWebsocket.py
index 32675e70..07eadbd5 100644
--- a/src/Ui/UiWebsocket.py
+++ b/src/Ui/UiWebsocket.py
@@ -828,6 +828,14 @@ class UiWebsocket(object):
             gevent.spawn(new_site.announce)
 
     def actionSiteClone(self, to, address, root_inner_path="", target_address=None):
+        if not SiteManager.site_manager.isAddress(address):
+            self.response(to, {"error": "Not a site: %s" % address})
+            return
+
+        if not self.server.sites.get(address):
+            # Don't expose site existense
+            return
+
         if "ADMIN" in self.getPermissions(to):
             self.cbSiteClone(to, address, root_inner_path, target_address)
         else: