No Description

responses.py 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. # IRIS Source Code
  2. # Copyright (C) 2024 - DFIR-IRIS
  3. # contact@dfir-iris.org
  4. #
  5. # This program is free software; you can redistribute it and/or
  6. # modify it under the terms of the GNU Lesser General Public
  7. # License as published by the Free Software Foundation; either
  8. # version 3 of the License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. # Lesser General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU Lesser General Public License
  16. # along with this program; if not, write to the Free Software Foundation,
  17. # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. import datetime
  19. import decimal
  20. import json
  21. import pickle
  22. import uuid
  23. from flask import render_template
  24. from flask import request
  25. from sqlalchemy.orm import DeclarativeMeta
  26. from app import TEMPLATE_PATH
  27. from app import app
  28. # Set basic 404
  29. @app.errorhandler(404)
  30. def page_not_found(e):
  31. # note that we set the 404 status explicitly
  32. if request.content_type and 'application/json' in request.content_type:
  33. return response_error("Resource not found", status=404)
  34. return render_template('pages/error-404.html', template_folder=TEMPLATE_PATH), 404
  35. def response(status, data=None):
  36. if data is not None:
  37. data = json.dumps(data, cls=AlchemyEncoder)
  38. return app.response_class(response=data, status=status, mimetype='application/json')
  39. def response_error(msg, data=None, status=400):
  40. content = {
  41. 'status': 'error',
  42. 'message': msg,
  43. 'data': data if data is not None else []
  44. }
  45. return response(status, data=content)
  46. def response_success(msg='', data=None):
  47. content = {
  48. "status": "success",
  49. "message": msg,
  50. "data": data if data is not None else []
  51. }
  52. return response(200, data=content)
  53. class AlchemyEncoder(json.JSONEncoder):
  54. def default(self, obj):
  55. if isinstance(obj.__class__, DeclarativeMeta):
  56. # an SQLAlchemy class
  57. fields = {}
  58. for field in [x for x in dir(obj) if not x.startswith('_') and x != 'metadata'
  59. and x != 'query' and x != 'query_class']:
  60. data = obj.__getattribute__(field)
  61. try:
  62. json.dumps(data) # this will fail on non-encodable values, like other classes
  63. fields[field] = data
  64. except TypeError:
  65. fields[field] = None
  66. # a json-encodable dict
  67. return fields
  68. if isinstance(obj, decimal.Decimal):
  69. return str(obj)
  70. if isinstance(obj, datetime.datetime) or isinstance(obj, datetime.date):
  71. return obj.isoformat()
  72. if isinstance(obj, uuid.UUID):
  73. return str(obj)
  74. else:
  75. if obj.__class__ == bytes:
  76. try:
  77. return pickle.load(obj)
  78. except Exception:
  79. return str(obj)
  80. return json.JSONEncoder.default(self, obj)