No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

run.py 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. # -*- coding: utf-8 -*-
  2. import loader # Lodel2 loader
  3. import os
  4. import hashlib
  5. import time
  6. from werkzeug.contrib.sessions import FilesystemSessionStore
  7. from werkzeug.wrappers import Response
  8. from werkzeug.contrib.securecookie import SecureCookie
  9. from lodel.settings import Settings
  10. from .interface.router import get_controller
  11. from .interface.lodelrequest import LodelRequest
  12. from .exceptions import *
  13. from .client import WebUiClient
  14. from lodel.auth.exceptions import *
  15. from lodel.utils.datetime import get_utc_timestamp
  16. from lodel.plugin.hooks import LodelHook
  17. SESSION_FILES_BASE_DIR = Settings.webui.sessions.directory
  18. SESSION_FILES_TEMPLATE = Settings.webui.sessions.file_template
  19. SESSION_EXPIRATION_LIMIT = Settings.webui.sessions.expiration
  20. session_store = FilesystemSessionStore(path=SESSION_FILES_BASE_DIR, filename_template=SESSION_FILES_TEMPLATE)
  21. COOKIE_SESSION_ID = 'toktoken'
  22. COOKIE_SESSION_HASH = 'nekotkot'
  23. COOKIE_SESSION_HASH_SALT = [ os.urandom(32) for _ in range(2) ] #Before and after salt (maybe useless)
  24. COOKIE_SESSION_HASH_ALGO = hashlib.sha512
  25. ##@brief Return a salted hash of a cookie
  26. def cookie_hash(token):
  27. return COOKIE_SESSION_HASH_ALGO(
  28. COOKIE_SESSION_HASH_SALT[0]+token+COOKIE_SESSION_HASH_SALT[1]).hexdigest()
  29. ##@brief Load cookie from request
  30. #@note Can produce security warning logs
  31. #@param request
  32. #@return None or a session token
  33. def load_cookie(request):
  34. token = request.cookies.get(COOKIE_SESSION_ID)
  35. if token is None and token != '':
  36. return None
  37. token = bytes(token, 'utf-8')
  38. hashtok = request.cookies.get(COOKIE_SESSION_HASH)
  39. if hashtok is None:
  40. raise ClientAuthenticationFailure(
  41. WebUiClient, 'Bad cookies : no hash provided')
  42. if cookie_hash(token) != hashtok:
  43. raise ClientAuthenticationFailure(
  44. WebUiClient, 'Bad cookies : hash mismatch')
  45. return token
  46. ##@brief Properly set cookies and hash given a token
  47. #@param response
  48. #@param token str : the session token
  49. def save_cookie(response, token):
  50. response.set_cookie(COOKIE_SESSION_ID, token)
  51. response.set_cookie(COOKIE_SESSION_HASH, cookie_hash(token))
  52. def empty_cookie(response):
  53. response.set_cookie(COOKIE_SESSION_ID, '')
  54. response.set_cookie(COOKIE_SESSION_HASH, '')
  55. #Starting instance
  56. loader.start()
  57. #providing access to dyncode
  58. import lodel
  59. import leapi_dyncode as dyncode
  60. lodel.dyncode = dyncode
  61. # TODO déplacer dans un module "sessions.py"
  62. def delete_old_session_files(timestamp_now):
  63. session_files_path = os.path.abspath(session_store.path)
  64. session_files = [os.path.join(session_files_path, file_object) for file_object in os.listdir(session_files_path)
  65. if os.path.isfile(os.path.join(session_files_path, file_object))]
  66. for session_file in session_files:
  67. last_modified = os.stat(session_file).st_mtime
  68. expiration_timestamp = last_modified + SESSION_EXPIRATION_LIMIT
  69. if timestamp_now > expiration_timestamp:
  70. os.unlink(session_file)
  71. def is_session_file_expired(timestamp_now, sid):
  72. session_file = session_store.get_session_filename(sid)
  73. expiration_timestamp = os.stat(session_file).st_mtime + SESSION_EXPIRATION_LIMIT
  74. if timestamp_now < expiration_timestamp:
  75. return False
  76. return True
  77. # WSGI Application
  78. def application(env, start_response):
  79. request = LodelRequest(env)
  80. session_token = None
  81. try:
  82. #We have to create the client before restoring cookie in order to be able
  83. #to log messages with client infos
  84. client = WebUiClient(env['REMOTE_ADDR'], env['HTTP_USER_AGENT'], None)
  85. session_token = load_cookie(request)
  86. if session_token is not None:
  87. WebClient.restore_session(token)
  88. session_token = None
  89. #test
  90. WebUiClient['last_request'] = time.time()
  91. try:
  92. controller = get_controller(request)
  93. response = controller(request)
  94. except HttpException as e:
  95. try:
  96. response = e.render(request)
  97. except Exception as eb:
  98. raise eb
  99. res = Response()
  100. res.status_code = 500
  101. return res
  102. session_token = WebUiClient.session_token()
  103. if session_token is not None:
  104. save_cookie(response,session_token)
  105. session_token = None
  106. except (ClientError, ClientAuthenticationError):
  107. response = HttpException(400).render(request)
  108. empty_cookie(response)
  109. except ClientAuthenticationFailure:
  110. response = HttpException(401).render(request)
  111. empty_cookie(response)
  112. except Exception as e:
  113. raise e
  114. res = response(env, start_response)
  115. WebUiClient.destroy()
  116. return res