utils.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. """A module with various utility methods for authorization in Jupyter Server."""
  2. # Copyright (c) Jupyter Development Team.
  3. # Distributed under the terms of the Modified BSD License.
  4. import importlib
  5. import random
  6. import re
  7. import warnings
  8. def warn_disabled_authorization():
  9. """DEPRECATED, does nothing"""
  10. warnings.warn(
  11. "jupyter_server.auth.utils.warn_disabled_authorization is deprecated",
  12. DeprecationWarning,
  13. stacklevel=2,
  14. )
  15. HTTP_METHOD_TO_AUTH_ACTION = {
  16. "GET": "read",
  17. "HEAD": "read",
  18. "OPTIONS": "read",
  19. "POST": "write",
  20. "PUT": "write",
  21. "PATCH": "write",
  22. "DELETE": "write",
  23. "WEBSOCKET": "execute",
  24. }
  25. def get_regex_to_resource_map():
  26. """Returns a dictionary with all of Jupyter Server's
  27. request handler URL regex patterns mapped to
  28. their resource name.
  29. e.g.
  30. { "/api/contents/<regex_pattern>": "contents", ...}
  31. """
  32. from jupyter_server.serverapp import JUPYTER_SERVICE_HANDLERS
  33. modules = []
  34. for mod_name in JUPYTER_SERVICE_HANDLERS.values():
  35. if mod_name:
  36. modules.extend(mod_name)
  37. resource_map = {}
  38. for handler_module in modules:
  39. mod = importlib.import_module(handler_module)
  40. name = mod.AUTH_RESOURCE
  41. for handler in mod.default_handlers:
  42. url_regex = handler[0]
  43. resource_map[url_regex] = name
  44. # terminal plugin doesn't have importable url patterns
  45. # get these from terminal/__init__.py
  46. for url_regex in [
  47. r"/terminals/websocket/(\w+)",
  48. "/api/terminals",
  49. r"/api/terminals/(\w+)",
  50. ]:
  51. resource_map[url_regex] = "terminals"
  52. return resource_map
  53. def match_url_to_resource(url, regex_mapping=None):
  54. """Finds the JupyterHandler regex pattern that would
  55. match the given URL and returns the resource name (str)
  56. of that handler.
  57. e.g.
  58. /api/contents/... returns "contents"
  59. """
  60. if not regex_mapping:
  61. regex_mapping = get_regex_to_resource_map()
  62. for regex, auth_resource in regex_mapping.items():
  63. pattern = re.compile(regex)
  64. if pattern.fullmatch(url):
  65. return auth_resource
  66. # From https://en.wikipedia.org/wiki/Moons_of_Jupiter
  67. moons_of_jupyter = [
  68. "Metis",
  69. "Adrastea",
  70. "Amalthea",
  71. "Thebe",
  72. "Io",
  73. "Europa",
  74. "Ganymede",
  75. "Callisto",
  76. "Themisto",
  77. "Leda",
  78. "Ersa",
  79. "Pandia",
  80. "Himalia",
  81. "Lysithea",
  82. "Elara",
  83. "Dia",
  84. "Carpo",
  85. "Valetudo",
  86. "Euporie",
  87. "Eupheme",
  88. # 'S/2003 J 18',
  89. # 'S/2010 J 2',
  90. "Helike",
  91. # 'S/2003 J 16',
  92. # 'S/2003 J 2',
  93. "Euanthe",
  94. # 'S/2017 J 7',
  95. "Hermippe",
  96. "Praxidike",
  97. "Thyone",
  98. "Thelxinoe",
  99. # 'S/2017 J 3',
  100. "Ananke",
  101. "Mneme",
  102. # 'S/2016 J 1',
  103. "Orthosie",
  104. "Harpalyke",
  105. "Iocaste",
  106. # 'S/2017 J 9',
  107. # 'S/2003 J 12',
  108. # 'S/2003 J 4',
  109. "Erinome",
  110. "Aitne",
  111. "Herse",
  112. "Taygete",
  113. # 'S/2017 J 2',
  114. # 'S/2017 J 6',
  115. "Eukelade",
  116. "Carme",
  117. # 'S/2003 J 19',
  118. "Isonoe",
  119. # 'S/2003 J 10',
  120. "Autonoe",
  121. "Philophrosyne",
  122. "Cyllene",
  123. "Pasithee",
  124. # 'S/2010 J 1',
  125. "Pasiphae",
  126. "Sponde",
  127. # 'S/2017 J 8',
  128. "Eurydome",
  129. # 'S/2017 J 5',
  130. "Kalyke",
  131. "Hegemone",
  132. "Kale",
  133. "Kallichore",
  134. # 'S/2011 J 1',
  135. # 'S/2017 J 1',
  136. "Chaldene",
  137. "Arche",
  138. "Eirene",
  139. "Kore",
  140. # 'S/2011 J 2',
  141. # 'S/2003 J 9',
  142. "Megaclite",
  143. "Aoede",
  144. # 'S/2003 J 23',
  145. "Callirrhoe",
  146. "Sinope",
  147. ]
  148. def get_anonymous_username() -> str:
  149. """
  150. Get a random user-name based on the moons of Jupyter.
  151. This function returns names like "Anonymous Io" or "Anonymous Metis".
  152. """
  153. return moons_of_jupyter[random.randint(0, len(moons_of_jupyter) - 1)] # noqa: S311