__main__.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. # mautrix-signal - A Matrix-Signal puppeting bridge
  2. # Copyright (C) 2020 Tulir Asokan
  3. #
  4. # This program is free software: you can redistribute it and/or modify
  5. # it under the terms of the GNU Affero General Public License as published by
  6. # the Free Software Foundation, either version 3 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU Affero General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU Affero General Public License
  15. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  16. from mautrix.bridge import Bridge
  17. from mautrix.bridge.state_store.asyncpg import PgBridgeStateStore
  18. from mautrix.types import RoomID, UserID
  19. from mautrix.util.async_db import Database
  20. from .version import version, linkified_version
  21. from .config import Config
  22. from .db import upgrade_table, init as init_db
  23. from .matrix import MatrixHandler
  24. from .signal import SignalHandler
  25. from .user import User
  26. from .portal import Portal
  27. from .puppet import Puppet
  28. from .web import ProvisioningAPI
  29. class SignalBridge(Bridge):
  30. module = "mautrix_signal"
  31. name = "mautrix-signal"
  32. command = "python -m mautrix-signal"
  33. description = "A Matrix-Signal puppeting bridge."
  34. repo_url = "https://github.com/tulir/mautrix-signal"
  35. real_user_content_key = "net.maunium.signal.puppet"
  36. version = version
  37. markdown_version = linkified_version
  38. config_class = Config
  39. matrix_class = MatrixHandler
  40. db: Database
  41. matrix: MatrixHandler
  42. signal: SignalHandler
  43. config: Config
  44. state_store: PgBridgeStateStore
  45. provisioning_api: ProvisioningAPI
  46. def make_state_store(self) -> None:
  47. self.state_store = PgBridgeStateStore(self.db, self.get_puppet, self.get_double_puppet)
  48. def prepare_db(self) -> None:
  49. self.db = Database(self.config["appservice.database"], upgrade_table=upgrade_table,
  50. loop=self.loop)
  51. init_db(self.db)
  52. def prepare_bridge(self) -> None:
  53. self.signal = SignalHandler(self)
  54. super().prepare_bridge()
  55. cfg = self.config["appservice.provisioning"]
  56. # self.provisioning_api = ProvisioningAPI(cfg["shared_secret"])
  57. # self.az.app.add_subapp(cfg["prefix"], self.provisioning_api.app)
  58. async def start(self) -> None:
  59. await self.db.start()
  60. await self.state_store.upgrade_table.upgrade(self.db.pool)
  61. User.init_cls(self)
  62. self.add_startup_actions(Puppet.init_cls(self))
  63. Portal.init_cls(self)
  64. if self.config["bridge.resend_bridge_info"]:
  65. self.add_startup_actions(self.resend_bridge_info())
  66. self.add_startup_actions(self.signal.start())
  67. await super().start()
  68. def prepare_stop(self) -> None:
  69. self.add_shutdown_actions(self.signal.stop())
  70. for puppet in Puppet.by_custom_mxid.values():
  71. puppet.stop()
  72. async def resend_bridge_info(self) -> None:
  73. self.config["bridge.resend_bridge_info"] = False
  74. self.config.save()
  75. self.log.info("Re-sending bridge info state event to all portals")
  76. async for portal in Portal.all_with_room():
  77. await portal.update_bridge_info()
  78. self.log.info("Finished re-sending bridge info state events")
  79. async def get_user(self, user_id: UserID) -> User:
  80. return await User.get_by_mxid(user_id)
  81. async def get_portal(self, room_id: RoomID) -> Portal:
  82. return await Portal.get_by_mxid(room_id)
  83. async def get_puppet(self, user_id: UserID, create: bool = False) -> Puppet:
  84. return await Puppet.get_by_mxid(user_id, create=create)
  85. async def get_double_puppet(self, user_id: UserID) -> Puppet:
  86. return await Puppet.get_by_custom_mxid(user_id)
  87. def is_bridge_ghost(self, user_id: UserID) -> bool:
  88. return bool(Puppet.get_id_from_mxid(user_id))
  89. SignalBridge().run()