urls.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. #!/usr/bin/env python
  2. # Licensed to Cloudera, Inc. under one
  3. # or more contributor license agreements. See the NOTICE file
  4. # distributed with this work for additional information
  5. # regarding copyright ownership. Cloudera, Inc. licenses this file
  6. # to you under the Apache License, Version 2.0 (the
  7. # "License"); you may not use this file except in compliance
  8. # with the License. You may obtain a copy of the License at
  9. #
  10. # http://www.apache.org/licenses/LICENSE-2.0
  11. #
  12. # Unless required by applicable law or agreed to in writing, software
  13. # distributed under the License is distributed on an "AS IS" BASIS,
  14. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. # See the License for the specific language governing permissions and
  16. # limitations under the License.
  17. from __future__ import absolute_import
  18. import logging
  19. import re
  20. import sys
  21. # FIXME: This could be replaced with hooking into the `AppConfig.ready()`
  22. # signal in Django 1.7:
  23. #
  24. # https://docs.djangoproject.com/en/1.7/ref/applications/#django.apps.AppConfig.ready
  25. #
  26. import debug_toolbar
  27. import desktop.lib.metrics.file_reporter
  28. desktop.lib.metrics.file_reporter.start_file_reporter()
  29. from django.conf import settings
  30. from django.views.static import serve
  31. from notebook import views as notebook_views
  32. from useradmin import views as useradmin_views
  33. from desktop import appmanager
  34. from desktop import views as desktop_views
  35. from desktop import api as desktop_api
  36. from desktop import api2 as desktop_api2
  37. from desktop.auth import views as desktop_auth_views
  38. from desktop.conf import METRICS, USE_NEW_EDITOR, ENABLE_DJANGO_DEBUG_TOOL, ANALYTICS, has_connectors, ENABLE_PROMETHEUS, SLACK
  39. from desktop.configuration import api as desktop_configuration_api
  40. from desktop.lib.vcs import api as desktop_lib_vcs_api
  41. from desktop.settings import is_oidc_configured
  42. if sys.version_info[0] > 2:
  43. from django.urls import include, re_path
  44. else:
  45. from django.conf.urls import include, url as re_path
  46. # Django expects handler404 and handler500 to be defined.
  47. # django.conf.urls provides them. But we want to override them.
  48. # Also see http://code.djangoproject.com/ticket/5350
  49. handler403 = 'desktop.views.serve_403_error'
  50. handler404 = 'desktop.views.serve_404_error'
  51. handler500 = 'desktop.views.serve_500_error'
  52. # Some django-wide URLs
  53. dynamic_patterns = [
  54. re_path(r'^hue/accounts/login', desktop_auth_views.dt_login, name='desktop_auth_views_dt_login'),
  55. re_path(r'^accounts/login/?$', desktop_auth_views.dt_login), # Deprecated
  56. re_path(r'^accounts/logout/?$', desktop_auth_views.dt_logout, {'next_page': '/'}),
  57. re_path(r'^profile$', desktop_auth_views.profile),
  58. re_path(r'^login/oauth/?$', desktop_auth_views.oauth_login),
  59. re_path(r'^login/oauth_authenticated/?$', desktop_auth_views.oauth_authenticated),
  60. re_path(r'^hue/oidc_failed', desktop_auth_views.oidc_failed),
  61. ]
  62. if USE_NEW_EDITOR.get():
  63. dynamic_patterns += [
  64. re_path(r'^home/?$', desktop_views.home2, name='desktop_views_home2'),
  65. re_path(r'^home2$', desktop_views.home, name='desktop_views_home'),
  66. re_path(r'^home_embeddable$', desktop_views.home_embeddable),
  67. ]
  68. else:
  69. dynamic_patterns += [
  70. re_path(r'^home$', desktop_views.home, name='desktop_views_home'),
  71. re_path(r'^home2$', desktop_views.home2, name='desktop_views_home2')
  72. ]
  73. dynamic_patterns += [
  74. re_path(r'^logs$', desktop_views.log_view, name="desktop.views.log_view"),
  75. re_path(r'^desktop/log_analytics$', desktop_views.log_analytics),
  76. re_path(r'^desktop/log_js_error$', desktop_views.log_js_error),
  77. re_path(r'^desktop/dump_config$', desktop_views.dump_config, name="desktop.views.dump_config"),
  78. re_path(r'^desktop/download_logs$', desktop_views.download_log_view),
  79. re_path(r'^desktop/get_debug_level', desktop_views.get_debug_level),
  80. re_path(r'^desktop/set_all_debug', desktop_views.set_all_debug),
  81. re_path(r'^desktop/reset_all_debug', desktop_views.reset_all_debug),
  82. re_path(r'^bootstrap.js$', desktop_views.bootstrap), # unused
  83. re_path(r'^desktop/status_bar/?$', desktop_views.status_bar),
  84. re_path(r'^desktop/debug/is_alive$', desktop_views.is_alive),
  85. re_path(r'^desktop/debug/is_idle$', desktop_views.is_idle),
  86. re_path(r'^desktop/debug/threads$', desktop_views.threads, name="desktop.views.threads"),
  87. re_path(r'^desktop/debug/memory$', desktop_views.memory),
  88. re_path(r'^desktop/debug/check_config$', desktop_views.check_config, name="desktop.views.check_config"),
  89. re_path(r'^desktop/debug/check_config_ajax$', desktop_views.check_config_ajax),
  90. re_path(r'^desktop/log_frontend_event$', desktop_views.log_frontend_event),
  91. # Catch-up gist
  92. re_path(r'^hue/gist/?$', desktop_api2.gist_get),
  93. # Mobile
  94. re_path(r'^assist_m', desktop_views.assist_m),
  95. # Hue 4
  96. re_path(r'^hue.*/?$', desktop_views.hue, name='desktop_views_hue'),
  97. re_path(r'^403$', desktop_views.path_forbidden),
  98. re_path(r'^404$', desktop_views.not_found),
  99. re_path(r'^500$', desktop_views.server_error),
  100. # KO components, change to doc?name=ko_editor or similar
  101. re_path(r'^ko_editor', desktop_views.ko_editor),
  102. re_path(r'^ko_metastore', desktop_views.ko_metastore),
  103. # JS that needs to be mako
  104. re_path(r'^desktop/globalJsConstants.js', desktop_views.global_js_constants),
  105. re_path(r'^desktop/topo/(?P<location>\w+)', desktop_views.topo),
  106. # Web workers
  107. re_path(r'^desktop/workers/aceSqlLocationWorker.js', desktop_views.ace_sql_location_worker),
  108. re_path(r'^desktop/workers/aceSqlSyntaxWorker.js', desktop_views.ace_sql_syntax_worker),
  109. re_path(r'^dynamic_bundle/(?P<config>\w+)/(?P<bundle_name>.+)', desktop_views.dynamic_bundle),
  110. # Unsupported browsers
  111. re_path(r'^boohoo$', desktop_views.unsupported, name='desktop_views_unsupported'),
  112. # Top level web page!
  113. re_path(r'^$', desktop_views.index, name="desktop_views.index"),
  114. ]
  115. dynamic_patterns += [
  116. # Tags
  117. re_path(r'^desktop/api/tag/add_tag$', desktop_api.add_tag),
  118. re_path(r'^desktop/api/tag/remove_tag$', desktop_api.remove_tag),
  119. re_path(r'^desktop/api/doc/tag$', desktop_api.tag),
  120. re_path(r'^desktop/api/doc/update_tags$', desktop_api.update_tags),
  121. re_path(r'^desktop/api/doc/get$', desktop_api.get_document),
  122. # Permissions
  123. re_path(r'^desktop/api/doc/update_permissions', desktop_api.update_permissions),
  124. ]
  125. dynamic_patterns += [
  126. re_path(r'^desktop/api2/doc/open?$', desktop_api2.open_document), # To keep before get_document
  127. re_path(r'^desktop/api2/docs/?$', desktop_api2.search_documents), # search documents for current user
  128. re_path(r'^desktop/api2/doc/?$', desktop_api2.get_document), # get doc/dir by path or UUID
  129. re_path(r'^desktop/api2/doc/move/?$', desktop_api2.move_document),
  130. re_path(r'^desktop/api2/doc/mkdir/?$', desktop_api2.create_directory),
  131. re_path(r'^desktop/api2/doc/update/?$', desktop_api2.update_document),
  132. re_path(r'^desktop/api2/doc/delete/?$', desktop_api2.delete_document),
  133. re_path(r'^desktop/api2/doc/copy/?$', desktop_api2.copy_document),
  134. re_path(r'^desktop/api2/doc/restore/?$', desktop_api2.restore_document),
  135. re_path(r'^desktop/api2/doc/share/link/?$', desktop_api2.share_document_link),
  136. re_path(r'^desktop/api2/doc/share/?$', desktop_api2.share_document),
  137. re_path(r'^desktop/api2/get_config/?$', desktop_api2.get_config),
  138. re_path(r'^desktop/api2/get_hue_config/?$', desktop_api2.get_hue_config),
  139. re_path(r'^desktop/api2/context/namespaces/(?P<interface>[\w\-]+)/?$', desktop_api2.get_context_namespaces),
  140. re_path(r'^desktop/api2/context/computes/(?P<interface>[\w\-]+)/?$', desktop_api2.get_context_computes),
  141. re_path(r'^desktop/api2/context/clusters/(?P<interface>[\w\-]+)/?$', desktop_api2.get_context_clusters),
  142. re_path(r'^desktop/api2/user_preferences(?:/(?P<key>\w+))?/?$', desktop_api2.user_preferences, name="desktop.api2.user_preferences"),
  143. re_path(r'^desktop/api2/doc/export/?$', desktop_api2.export_documents),
  144. re_path(r'^desktop/api2/doc/import/?$', desktop_api2.import_documents),
  145. re_path(r'^desktop/api2/gist/create/?$', desktop_api2.gist_create),
  146. re_path(r'^desktop/api2/gist/open/?$', desktop_api2.gist_get),
  147. re_path(r'^desktop/api/search/entities/?$', desktop_api2.search_entities),
  148. re_path(r'^desktop/api/search/entities_interactive/?$', desktop_api2.search_entities_interactive),
  149. ]
  150. dynamic_patterns += [
  151. re_path(r'^editor', notebook_views.editor),
  152. ]
  153. # Default Configurations
  154. dynamic_patterns += [
  155. re_path(r'^desktop/api/configurations/?$', desktop_configuration_api.default_configurations),
  156. re_path(r'^desktop/api/configurations/user/?$', desktop_configuration_api.app_configuration_for_user),
  157. re_path(r'^desktop/api/configurations/delete/?$', desktop_configuration_api.delete_default_configuration),
  158. ]
  159. dynamic_patterns += [
  160. re_path(r'^desktop/api/users/autocomplete', useradmin_views.list_for_autocomplete, name='useradmin_views_list_for_autocomplete'),
  161. re_path(r'^desktop/api/users/?$', useradmin_views.get_users_by_id)
  162. ]
  163. dynamic_patterns += [
  164. re_path(r'^desktop/api/vcs/contents/?$', desktop_lib_vcs_api.contents),
  165. re_path(r'^desktop/api/vcs/authorize/?$', desktop_lib_vcs_api.authorize),
  166. ]
  167. # Metrics specific
  168. if METRICS.ENABLE_WEB_METRICS.get():
  169. dynamic_patterns += [
  170. re_path(r'^desktop/metrics/?', include('desktop.lib.metrics.urls'))
  171. ]
  172. dynamic_patterns += [
  173. re_path(r'^desktop/connectors/?', include('desktop.lib.connectors.urls'))
  174. ]
  175. if ANALYTICS.IS_ENABLED.get():
  176. dynamic_patterns += [
  177. re_path(r'^desktop/analytics/?', include('desktop.lib.analytics.urls'))
  178. ]
  179. dynamic_patterns += [
  180. re_path(r'^scheduler/', include('desktop.lib.scheduler.urls'))
  181. ]
  182. if ENABLE_PROMETHEUS.get():
  183. dynamic_patterns += [
  184. re_path('', include('django_prometheus.urls')),
  185. ]
  186. static_patterns = []
  187. # SAML specific
  188. if settings.SAML_AUTHENTICATION:
  189. static_patterns.append(re_path(r'^saml2/', include('libsaml.urls')))
  190. if settings.OAUTH_AUTHENTICATION:
  191. static_patterns.append(re_path(r'^oauth/', include('liboauth.urls')))
  192. # Root each app at /appname if they have a "urls" module
  193. app_urls_patterns = []
  194. for app in appmanager.DESKTOP_MODULES:
  195. if app.urls:
  196. if app.is_url_namespaced:
  197. namespace = app.name
  198. else:
  199. namespace = None
  200. if namespace or app in appmanager.DESKTOP_APPS:
  201. app_urls_patterns.append(re_path('^' + re.escape(app.name) + '/', include((app.urls, app.name), namespace=namespace)))
  202. app.urls_imported = True
  203. static_patterns.append(
  204. re_path(r'^%s(?P<path>.*)$' % re.escape(settings.STATIC_URL.lstrip('/')),
  205. serve,
  206. {'document_root': settings.STATIC_ROOT})
  207. )
  208. urlpatterns = []
  209. urlpatterns.extend(dynamic_patterns)
  210. urlpatterns.extend(app_urls_patterns)
  211. urlpatterns.extend(static_patterns)
  212. if settings.DEBUG and ENABLE_DJANGO_DEBUG_TOOL.get():
  213. urlpatterns += [
  214. re_path(r'^__debug__/', include(debug_toolbar.urls)),
  215. ]
  216. if is_oidc_configured():
  217. urlpatterns += [
  218. re_path(r'^oidc/', include('mozilla_django_oidc.urls')),
  219. ]
  220. # Slack botserver URLs
  221. if SLACK.IS_ENABLED.get():
  222. urlpatterns += [
  223. re_path(r'^slack/', include('desktop.lib.botserver.urls')),
  224. ]