CorsPlugin.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import re
  2. import cgi
  3. import copy
  4. from Plugin import PluginManager
  5. from Translate import Translate
  6. if "_" not in locals():
  7. _ = Translate("plugins/Cors/languages/")
  8. def getCorsPath(site, inner_path):
  9. match = re.match("^cors-([A-Za-z0-9]{26,35})/(.*)", inner_path)
  10. if not match:
  11. raise Exception("Invalid cors path: %s" % inner_path)
  12. cors_address = match.group(1)
  13. cors_inner_path = match.group(2)
  14. if not "Cors:%s" % cors_address in site.settings["permissions"]:
  15. raise Exception("This site has no permission to access site %s" % cors_address)
  16. return cors_address, cors_inner_path
  17. @PluginManager.registerTo("UiWebsocket")
  18. class UiWebsocketPlugin(object):
  19. def hasSitePermission(self, address, cmd=None):
  20. if super(UiWebsocketPlugin, self).hasSitePermission(address, cmd=cmd):
  21. return True
  22. if not "Cors:%s" % address in self.site.settings["permissions"] or cmd not in ["fileGet", "fileList", "dirList", "fileRules", "optionalFileInfo", "fileQuery", "dbQuery", "userGetSettings", "siteInfo"]:
  23. return False
  24. else:
  25. return True
  26. # Add cors support for file commands
  27. def corsFuncWrapper(self, func_name, to, inner_path, *args, **kwargs):
  28. if inner_path.startswith("cors-"):
  29. cors_address, cors_inner_path = getCorsPath(self.site, inner_path)
  30. req_self = copy.copy(self)
  31. req_self.site = self.server.sites.get(cors_address) # Change the site to the merged one
  32. if not req_self.site:
  33. return {"error": "No site found"}
  34. func = getattr(super(UiWebsocketPlugin, req_self), func_name)
  35. back = func(to, cors_inner_path, *args, **kwargs)
  36. return back
  37. else:
  38. func = getattr(super(UiWebsocketPlugin, self), func_name)
  39. return func(to, inner_path, *args, **kwargs)
  40. def actionFileGet(self, to, inner_path, *args, **kwargs):
  41. return self.corsFuncWrapper("actionFileGet", to, inner_path, *args, **kwargs)
  42. def actionFileList(self, to, inner_path, *args, **kwargs):
  43. return self.corsFuncWrapper("actionFileList", to, inner_path, *args, **kwargs)
  44. def actionDirList(self, to, inner_path, *args, **kwargs):
  45. return self.corsFuncWrapper("actionDirList", to, inner_path, *args, **kwargs)
  46. def actionFileRules(self, to, inner_path, *args, **kwargs):
  47. return self.corsFuncWrapper("actionFileRules", to, inner_path, *args, **kwargs)
  48. def actionOptionalFileInfo(self, to, inner_path, *args, **kwargs):
  49. return self.corsFuncWrapper("actionOptionalFileInfo", to, inner_path, *args, **kwargs)
  50. def actionCorsPermission(self, to, address):
  51. site = self.server.sites.get(address)
  52. if site:
  53. site_name = site.content_manager.contents.get("content.json", {}).get("title")
  54. button_title = _["Grant"]
  55. else:
  56. site_name = address
  57. button_title = _["Grant & Add"]
  58. if site and "Cors:" + address in self.permissions:
  59. return "ignored"
  60. self.cmd(
  61. "confirm",
  62. [_["This site requests <b>read</b> permission to: <b>%s</b>"] % cgi.escape(site_name), button_title],
  63. lambda (res): self.cbCorsPermission(to, address)
  64. )
  65. def cbCorsPermission(self, to, address):
  66. self.actionPermissionAdd(to, "Cors:" + address)
  67. site = self.server.sites.get(address)
  68. if not site:
  69. self.server.site_manager.need(address)
  70. @PluginManager.registerTo("UiRequest")
  71. class UiRequestPlugin(object):
  72. # Allow to load cross origin files using /cors-address/file.jpg
  73. def parsePath(self, path):
  74. path_parts = super(UiRequestPlugin, self).parsePath(path)
  75. if "cors-" not in path: # Optimization
  76. return path_parts
  77. site = self.server.sites[path_parts["address"]]
  78. try:
  79. path_parts["address"], path_parts["inner_path"] = getCorsPath(site, path_parts["inner_path"])
  80. except:
  81. return None
  82. return path_parts