third_party_rules.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. # -*- coding: utf-8 -*-
  2. # Copyright 2019 The Matrix.org Foundation C.I.C.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. from twisted.internet import defer
  16. class ThirdPartyEventRules(object):
  17. """Allows server admins to provide a Python module implementing an extra
  18. set of rules to apply when processing events.
  19. This is designed to help admins of closed federations with enforcing custom
  20. behaviours.
  21. """
  22. def __init__(self, hs):
  23. self.third_party_rules = None
  24. self.store = hs.get_datastore()
  25. module = None
  26. config = None
  27. if hs.config.third_party_event_rules:
  28. module, config = hs.config.third_party_event_rules
  29. if module is not None:
  30. self.third_party_rules = module(
  31. config=config, http_client=hs.get_simple_http_client()
  32. )
  33. @defer.inlineCallbacks
  34. def check_event_allowed(self, event, context):
  35. """Check if a provided event should be allowed in the given context.
  36. Args:
  37. event (synapse.events.EventBase): The event to be checked.
  38. context (synapse.events.snapshot.EventContext): The context of the event.
  39. Returns:
  40. defer.Deferred[bool]: True if the event should be allowed, False if not.
  41. """
  42. if self.third_party_rules is None:
  43. return True
  44. prev_state_ids = yield context.get_prev_state_ids(self.store)
  45. # Retrieve the state events from the database.
  46. state_events = {}
  47. for key, event_id in prev_state_ids.items():
  48. state_events[key] = yield self.store.get_event(event_id, allow_none=True)
  49. ret = yield self.third_party_rules.check_event_allowed(event, state_events)
  50. return ret
  51. @defer.inlineCallbacks
  52. def on_create_room(self, requester, config, is_requester_admin):
  53. """Intercept requests to create room to allow, deny or update the
  54. request config.
  55. Args:
  56. requester (Requester)
  57. config (dict): The creation config from the client.
  58. is_requester_admin (bool): If the requester is an admin
  59. Returns:
  60. defer.Deferred
  61. """
  62. if self.third_party_rules is None:
  63. return
  64. yield self.third_party_rules.on_create_room(
  65. requester, config, is_requester_admin
  66. )
  67. @defer.inlineCallbacks
  68. def check_threepid_can_be_invited(self, medium, address, room_id):
  69. """Check if a provided 3PID can be invited in the given room.
  70. Args:
  71. medium (str): The 3PID's medium.
  72. address (str): The 3PID's address.
  73. room_id (str): The room we want to invite the threepid to.
  74. Returns:
  75. defer.Deferred[bool], True if the 3PID can be invited, False if not.
  76. """
  77. if self.third_party_rules is None:
  78. return True
  79. state_ids = yield self.store.get_filtered_current_state_ids(room_id)
  80. room_state_events = yield self.store.get_events(state_ids.values())
  81. state_events = {}
  82. for key, event_id in state_ids.items():
  83. state_events[key] = room_state_events[event_id]
  84. ret = yield self.third_party_rules.check_threepid_can_be_invited(
  85. medium, address, state_events
  86. )
  87. return ret