Development of an internal social media platform with personalised dashboards for students
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.

mockSync.py 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. """
  2. """
  3. # Created on 2014.11.17
  4. #
  5. # Author: Giovanni Cannata
  6. #
  7. # Copyright 2014 - 2018 Giovanni Cannata
  8. #
  9. # This file is part of ldap3.
  10. #
  11. # ldap3 is free software: you can redistribute it and/or modify
  12. # it under the terms of the GNU Lesser General Public License as published
  13. # by the Free Software Foundation, either version 3 of the License, or
  14. # (at your option) any later version.
  15. #
  16. # ldap3 is distributed in the hope that it will be useful,
  17. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. # GNU Lesser General Public License for more details.
  20. #
  21. # You should have received a copy of the GNU Lesser General Public License
  22. # along with ldap3 in the COPYING and COPYING.LESSER files.
  23. # If not, see <http://www.gnu.org/licenses/>.
  24. from ..core.results import DO_NOT_RAISE_EXCEPTIONS
  25. from .mockBase import MockBaseStrategy
  26. from .. import ALL_ATTRIBUTES, ALL_OPERATIONAL_ATTRIBUTES, NO_ATTRIBUTES
  27. from .sync import SyncStrategy
  28. from ..operation.bind import bind_response_to_dict
  29. from ..operation.delete import delete_response_to_dict
  30. from ..operation.add import add_response_to_dict
  31. from ..operation.compare import compare_response_to_dict
  32. from ..operation.modifyDn import modify_dn_response_to_dict
  33. from ..operation.modify import modify_response_to_dict
  34. from ..operation.search import search_result_done_response_to_dict, search_result_entry_response_to_dict
  35. from ..operation.extended import extended_response_to_dict
  36. from ..core.exceptions import LDAPSocketOpenError, LDAPOperationResult
  37. from ..utils.log import log, log_enabled, ERROR, PROTOCOL
  38. class MockSyncStrategy(MockBaseStrategy, SyncStrategy): # class inheritance sequence is important, MockBaseStrategy must be the first one
  39. """
  40. This strategy create a mock LDAP server, with synchronous access
  41. It can be useful to test LDAP without accessing a real Server
  42. """
  43. def __init__(self, ldap_connection):
  44. SyncStrategy.__init__(self, ldap_connection)
  45. MockBaseStrategy.__init__(self)
  46. def post_send_search(self, payload):
  47. message_id, message_type, request, controls = payload
  48. self.connection.response = []
  49. self.connection.result = dict()
  50. if message_type == 'searchRequest':
  51. responses, result = self.mock_search(request, controls)
  52. for entry in responses:
  53. response = search_result_entry_response_to_dict(entry, self.connection.server.schema, self.connection.server.custom_formatter, self.connection.check_names)
  54. response['type'] = 'searchResEntry'
  55. ###
  56. if self.connection.empty_attributes:
  57. for attribute_type in request['attributes']:
  58. attribute_name = str(attribute_type)
  59. if attribute_name not in response['raw_attributes'] and attribute_name not in (ALL_ATTRIBUTES, ALL_OPERATIONAL_ATTRIBUTES, NO_ATTRIBUTES):
  60. response['raw_attributes'][attribute_name] = list()
  61. response['attributes'][attribute_name] = list()
  62. if log_enabled(PROTOCOL):
  63. log(PROTOCOL, 'attribute set to empty list for missing attribute <%s> in <%s>',
  64. attribute_type, self)
  65. if not self.connection.auto_range:
  66. attrs_to_remove = []
  67. # removes original empty attribute in case a range tag is returned
  68. for attribute_type in response['attributes']:
  69. attribute_name = str(attribute_type)
  70. if ';range' in attribute_name.lower():
  71. orig_attr, _, _ = attribute_name.partition(';')
  72. attrs_to_remove.append(orig_attr)
  73. for attribute_type in attrs_to_remove:
  74. if log_enabled(PROTOCOL):
  75. log(PROTOCOL,
  76. 'attribute type <%s> removed in response because of same attribute returned as range by the server in <%s>',
  77. attribute_type, self)
  78. del response['raw_attributes'][attribute_type]
  79. del response['attributes'][attribute_type]
  80. ###
  81. self.connection.response.append(response)
  82. result = search_result_done_response_to_dict(result)
  83. result['type'] = 'searchResDone'
  84. self.connection.result = result
  85. if self.connection.raise_exceptions and result and result['result'] not in DO_NOT_RAISE_EXCEPTIONS:
  86. if log_enabled(PROTOCOL):
  87. log(PROTOCOL, 'operation result <%s> for <%s>', result, self.connection)
  88. raise LDAPOperationResult(result=result['result'], description=result['description'], dn=result['dn'], message=result['message'], response_type=result['type'])
  89. return self.connection.response
  90. def post_send_single_response(self, payload): # payload is a tuple sent by self.send() made of message_type, request, controls
  91. message_id, message_type, request, controls = payload
  92. responses = []
  93. result = None
  94. if message_type == 'bindRequest':
  95. result = bind_response_to_dict(self.mock_bind(request, controls))
  96. result['type'] = 'bindResponse'
  97. elif message_type == 'unbindRequest':
  98. self.bound = None
  99. elif message_type == 'abandonRequest':
  100. pass
  101. elif message_type == 'delRequest':
  102. result = delete_response_to_dict(self.mock_delete(request, controls))
  103. result['type'] = 'delResponse'
  104. elif message_type == 'addRequest':
  105. result = add_response_to_dict(self.mock_add(request, controls))
  106. result['type'] = 'addResponse'
  107. elif message_type == 'compareRequest':
  108. result = compare_response_to_dict(self.mock_compare(request, controls))
  109. result['type'] = 'compareResponse'
  110. elif message_type == 'modDNRequest':
  111. result = modify_dn_response_to_dict(self.mock_modify_dn(request, controls))
  112. result['type'] = 'modDNResponse'
  113. elif message_type == 'modifyRequest':
  114. result = modify_response_to_dict(self.mock_modify(request, controls))
  115. result['type'] = 'modifyResponse'
  116. elif message_type == 'extendedReq':
  117. result = extended_response_to_dict(self.mock_extended(request, controls))
  118. result['type'] = 'extendedResp'
  119. self.connection.result = result
  120. responses.append(result)
  121. if self.connection.raise_exceptions and result and result['result'] not in DO_NOT_RAISE_EXCEPTIONS:
  122. if log_enabled(PROTOCOL):
  123. log(PROTOCOL, 'operation result <%s> for <%s>', result, self.connection)
  124. raise LDAPOperationResult(result=result['result'], description=result['description'], dn=result['dn'], message=result['message'], response_type=result['type'])
  125. return responses