directory.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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. try:
  68. yield self._simple_insert(
  69. "room_aliases",
  70. {
  71. "room_alias": room_alias.to_string(),
  72. "room_id": room_id,
  73. "creator": creator,
  74. },
  75. desc="create_room_alias_association",
  76. )
  77. except self.database_engine.module.IntegrityError:
  78. raise SynapseError(
  79. 409, "Room alias %s already exists" % room_alias.to_string()
  80. )
  81. for server in servers:
  82. # TODO(erikj): Fix this to bulk insert
  83. yield self._simple_insert(
  84. "room_alias_servers",
  85. {
  86. "room_alias": room_alias.to_string(),
  87. "server": server,
  88. },
  89. desc="create_room_alias_association",
  90. )
  91. self.get_aliases_for_room.invalidate((room_id,))
  92. def get_room_alias_creator(self, room_alias):
  93. return self._simple_select_one_onecol(
  94. table="room_aliases",
  95. keyvalues={
  96. "room_alias": room_alias,
  97. },
  98. retcol="creator",
  99. desc="get_room_alias_creator",
  100. allow_none=True
  101. )
  102. @defer.inlineCallbacks
  103. def delete_room_alias(self, room_alias):
  104. room_id = yield self.runInteraction(
  105. "delete_room_alias",
  106. self._delete_room_alias_txn,
  107. room_alias,
  108. )
  109. self.get_aliases_for_room.invalidate((room_id,))
  110. defer.returnValue(room_id)
  111. def _delete_room_alias_txn(self, txn, room_alias):
  112. txn.execute(
  113. "SELECT room_id FROM room_aliases WHERE room_alias = ?",
  114. (room_alias.to_string(),)
  115. )
  116. res = txn.fetchone()
  117. if res:
  118. room_id = res[0]
  119. else:
  120. return None
  121. txn.execute(
  122. "DELETE FROM room_aliases WHERE room_alias = ?",
  123. (room_alias.to_string(),)
  124. )
  125. txn.execute(
  126. "DELETE FROM room_alias_servers WHERE room_alias = ?",
  127. (room_alias.to_string(),)
  128. )
  129. return room_id
  130. @cached(max_entries=5000)
  131. def get_aliases_for_room(self, room_id):
  132. return self._simple_select_onecol(
  133. "room_aliases",
  134. {"room_id": room_id},
  135. "room_alias",
  136. desc="get_aliases_for_room",
  137. )