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.

116 lines
3.7 KiB

  1. # Copyright 2016-2017 Versada <https://versada.eu/>
  2. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
  3. import os.path
  4. import urllib.parse
  5. from .processor import SanitizePasswordsProcessor
  6. from .generalutils import get_environ
  7. from sentry_sdk._compat import text_type
  8. from werkzeug import datastructures
  9. def get_request_info(request):
  10. """ Returns context data extracted from :param:`request`.
  11. Heavily based on flask integration for Sentry: https://git.io/vP4i9.
  12. """
  13. urlparts = urllib.parse.urlsplit(request.url)
  14. return {
  15. 'url': '%s://%s%s' % (urlparts.scheme, urlparts.netloc, urlparts.path),
  16. 'query_string': urlparts.query,
  17. 'method': request.method,
  18. 'headers': dict(datastructures.EnvironHeaders(request.environ)),
  19. 'env': dict(get_environ(request.environ)),
  20. }
  21. def get_extra_context(request):
  22. """ Extracts additional context from the current request
  23. (if such is set).
  24. """
  25. try:
  26. session = getattr(request, 'session', {})
  27. except RuntimeError:
  28. ctx = {}
  29. else:
  30. ctx = {
  31. 'tags': {
  32. 'database': session.get('db', None),
  33. },
  34. 'user': {
  35. 'email': session.get('login', None),
  36. 'id': session.get('uid', None),
  37. },
  38. 'extra': {
  39. 'context': session.get('context', {}),
  40. },
  41. }
  42. if request.httprequest:
  43. ctx.update({
  44. 'request': get_request_info(request.httprequest),
  45. })
  46. return ctx
  47. class SanitizeOdooCookiesProcessor(SanitizePasswordsProcessor):
  48. """ Custom :class:`raven.processors.Processor`.
  49. Allows to sanitize sensitive Odoo cookies, namely the "session_id" cookie.
  50. """
  51. KEYS = frozenset([
  52. 'session_id',
  53. ])
  54. class InvalidGitRepository(Exception):
  55. pass
  56. def fetch_git_sha(path, head=None):
  57. """ >>> fetch_git_sha(os.path.dirname(__file__))
  58. Taken from https://git.io/JITmC
  59. """
  60. if not head:
  61. head_path = os.path.join(path, '.git', 'HEAD')
  62. if not os.path.exists(head_path):
  63. raise InvalidGitRepository(
  64. 'Cannot identify HEAD for git repository at %s' % (path,))
  65. with open(head_path, 'r') as fp:
  66. head = text_type(fp.read()).strip()
  67. if head.startswith('ref: '):
  68. head = head[5:]
  69. revision_file = os.path.join(
  70. path, '.git', *head.split('/')
  71. )
  72. else:
  73. return head
  74. else:
  75. revision_file = os.path.join(path, '.git', 'refs', 'heads', head)
  76. if not os.path.exists(revision_file):
  77. if not os.path.exists(os.path.join(path, '.git')):
  78. raise InvalidGitRepository(
  79. '%s does not seem to be the root of a git repository' % (path,))
  80. # Check for our .git/packed-refs' file since a `git gc` may have run
  81. # https://git-scm.com/book/en/v2/Git-Internals-Maintenance-and-Data-Recovery
  82. packed_file = os.path.join(path, '.git', 'packed-refs')
  83. if os.path.exists(packed_file):
  84. with open(packed_file) as fh:
  85. for line in fh:
  86. line = line.rstrip()
  87. if line and line[:1] not in ('#', '^'):
  88. try:
  89. revision, ref = line.split(' ', 1)
  90. except ValueError:
  91. continue
  92. if ref == head:
  93. return text_type(revision)
  94. raise InvalidGitRepository(
  95. 'Unable to find ref to head "%s" in repository' % (head,))
  96. with open(revision_file) as fh:
  97. return text_type(fh.read()).strip()