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 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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_SALT = ['salt1', 'salt2']
  25. COOKIE_SESSION_HASH_ALGO = hashlib.sha512
  26. ##@brief Return a salted hash of a cookie
  27. def cookie_hash(token):
  28. token = str(token)
  29. return COOKIE_SESSION_HASH_ALGO(token.encode()).hexdigest()
  30. return COOKIE_SESSION_HASH_ALGO(
  31. (COOKIE_SESSION_HASH_SALT[0]+token+COOKIE_SESSION_HASH_SALT[1]).encode()).hexdigest()
  32. ##@brief Load cookie from request
  33. #@note Can produce security warning logs
  34. #@param request
  35. #@return None or a session token
  36. def load_cookie(request):
  37. token = request.cookies.get(COOKIE_SESSION_ID)
  38. if token is None or len(token) == 0:
  39. return None
  40. token=token.encode()
  41. hashtok = request.cookies.get(COOKIE_SESSION_HASH)
  42. if hashtok is None:
  43. raise ClientAuthenticationFailure(
  44. WebUiClient, 'Bad cookies : no hash provided')
  45. if cookie_hash(token) != hashtok:
  46. raise ClientAuthenticationFailure(
  47. WebUiClient, 'Bad cookies : hash mismatch')
  48. return token
  49. ##@brief Properly set cookies and hash given a token
  50. #@param response
  51. #@param token str : the session token
  52. def save_cookie(response, token):
  53. response.set_cookie(COOKIE_SESSION_ID, token)
  54. response.set_cookie(COOKIE_SESSION_HASH, cookie_hash(token))
  55. def empty_cookie(response):
  56. response.set_cookie(COOKIE_SESSION_ID, '')
  57. response.set_cookie(COOKIE_SESSION_HASH, '')
  58. #Starting instance
  59. loader.start()
  60. #providing access to dyncode
  61. import lodel
  62. import leapi_dyncode as dyncode
  63. lodel.dyncode = dyncode
  64. # TODO déplacer dans un module "sessions.py"
  65. def delete_old_session_files(timestamp_now):
  66. session_files_path = os.path.abspath(session_store.path)
  67. session_files = [os.path.join(session_files_path, file_object) for file_object in os.listdir(session_files_path)
  68. if os.path.isfile(os.path.join(session_files_path, file_object))]
  69. for session_file in session_files:
  70. last_modified = os.stat(session_file).st_mtime
  71. expiration_timestamp = last_modified + SESSION_EXPIRATION_LIMIT
  72. if timestamp_now > expiration_timestamp:
  73. os.unlink(session_file)
  74. def is_session_file_expired(timestamp_now, sid):
  75. session_file = session_store.get_session_filename(sid)
  76. expiration_timestamp = os.stat(session_file).st_mtime + SESSION_EXPIRATION_LIMIT
  77. if timestamp_now < expiration_timestamp:
  78. return False
  79. return True
  80. # WSGI Application
  81. def application(env, start_response):
  82. request = LodelRequest(env)
  83. session_token = None
  84. try:
  85. #We have to create the client before restoring cookie in order to be able
  86. #to log messages with client infos
  87. client = WebUiClient(env['REMOTE_ADDR'], env['HTTP_USER_AGENT'], None)
  88. session_token = load_cookie(request)
  89. if session_token is not None:
  90. WebUiClient.restore_session(session_token)
  91. #next line is for testing purpose
  92. print("ACCESS DATAS : ", WebUiClient['last_request'])
  93. session_token = None
  94. #next line is for testing purpose
  95. WebUiClient['last_request'] = time.time()
  96. try:
  97. controller = get_controller(request)
  98. response = controller(request)
  99. except HttpException as e:
  100. try:
  101. response = e.render(request)
  102. except Exception as eb:
  103. raise eb
  104. res = Response()
  105. res.status_code = 500
  106. return res
  107. session_token = WebUiClient.session_token()
  108. if session_token is not None:
  109. save_cookie(response,session_token)
  110. session_token = None
  111. except (ClientError, ClientAuthenticationError):
  112. response = HttpException(200).render(request)
  113. empty_cookie(response)
  114. except ClientAuthenticationFailure:
  115. response = HttpException(200).render(request)
  116. empty_cookie(response)
  117. except Exception as e:
  118. raise e
  119. res = response(env, start_response)
  120. WebUiClient.clean()
  121. return res