directory.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. # -*- coding: utf-8 -*-
  2. # Copyright 2014-2016 OpenMarket Ltd
  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 ._base import SQLBaseStore
  16. from synapse.util.caches.descriptors import cached
  17. from synapse.api.errors import SynapseError
  18. from twisted.internet import defer
  19. from collections import namedtuple
  20. RoomAliasMapping = namedtuple(
  21. "RoomAliasMapping",
  22. ("room_id", "room_alias", "servers",)
  23. )
  24. class DirectoryStore(SQLBaseStore):
  25. @defer.inlineCallbacks
  26. def get_association_from_room_alias(self, room_alias):
  27. """ Get's the room_id and server list for a given room_alias
  28. Args:
  29. room_alias (RoomAlias)
  30. Returns:
  31. Deferred: results in namedtuple with keys "room_id" and
  32. "servers" or None if no association can be found
  33. """
  34. room_id = yield self._simple_select_one_onecol(
  35. "room_aliases",
  36. {"room_alias": room_alias.to_string()},
  37. "room_id",
  38. allow_none=True,
  39. desc="get_association_from_room_alias",
  40. )
  41. if not room_id:
  42. defer.returnValue(None)
  43. return
  44. servers = yield self._simple_select_onecol(
  45. "room_alias_servers",
  46. {"room_alias": room_alias.to_string()},
  47. "server",
  48. desc="get_association_from_room_alias",
  49. )
  50. if not servers:
  51. defer.returnValue(None)
  52. return
  53. defer.returnValue(
  54. RoomAliasMapping(room_id, room_alias.to_string(), servers)
  55. )
  56. @defer.inlineCallbacks
  57. def create_room_alias_association(self, room_alias, room_id, servers, creator=None):
  58. """ Creates an associatin between a room alias and room_id/servers
  59. Args:
  60. room_alias (RoomAlias)
  61. room_id (str)
  62. servers (list)
  63. creator (str): Optional user_id of creator.
  64. Returns:
  65. Deferred
  66. """
  67. def alias_txn(txn):
  68. self._simple_insert_txn(
  69. txn,
  70. "room_aliases",
  71. {
  72. "room_alias": room_alias.to_string(),
  73. "room_id": room_id,
  74. "creator": creator,
  75. },
  76. )
  77. self._simple_insert_many_txn(
  78. txn,
  79. table="room_alias_servers",
  80. values=[{
  81. "room_alias": room_alias.to_string(),
  82. "server": server,
  83. } for server in servers],
  84. )
  85. self._invalidate_cache_and_stream(
  86. txn, self.get_aliases_for_room, (room_id,)
  87. )
  88. try:
  89. ret = yield self.runInteraction(
  90. "create_room_alias_association", alias_txn
  91. )
  92. except self.database_engine.module.IntegrityError:
  93. raise SynapseError(
  94. 409, "Room alias %s already exists" % room_alias.to_string()
  95. )
  96. defer.returnValue(ret)
  97. def get_room_alias_creator(self, room_alias):
  98. return self._simple_select_one_onecol(
  99. table="room_aliases",
  100. keyvalues={
  101. "room_alias": room_alias,
  102. },
  103. retcol="creator",
  104. desc="get_room_alias_creator",
  105. allow_none=True
  106. )
  107. @defer.inlineCallbacks
  108. def delete_room_alias(self, room_alias):
  109. room_id = yield self.runInteraction(
  110. "delete_room_alias",
  111. self._delete_room_alias_txn,
  112. room_alias,
  113. )
  114. self.get_aliases_for_room.invalidate((room_id,))
  115. defer.returnValue(room_id)
  116. def _delete_room_alias_txn(self, txn, room_alias):
  117. txn.execute(
  118. "SELECT room_id FROM room_aliases WHERE room_alias = ?",
  119. (room_alias.to_string(),)
  120. )
  121. res = txn.fetchone()
  122. if res:
  123. room_id = res[0]
  124. else:
  125. return None
  126. txn.execute(
  127. "DELETE FROM room_aliases WHERE room_alias = ?",
  128. (room_alias.to_string(),)
  129. )
  130. txn.execute(
  131. "DELETE FROM room_alias_servers WHERE room_alias = ?",
  132. (room_alias.to_string(),)
  133. )
  134. return room_id
  135. @cached(max_entries=5000)
  136. def get_aliases_for_room(self, room_id):
  137. return self._simple_select_onecol(
  138. "room_aliases",
  139. {"room_id": room_id},
  140. "room_alias",
  141. desc="get_aliases_for_room",
  142. )