예제 #1
0
 def __init__(self, bridge: 'Bridge', homeserver_address: str, user_id_prefix: str,
              user_id_suffix: str, db_url: str, key_sharing_config: Dict[str, bool] = None
              ) -> None:
     self.loop = bridge.loop or asyncio.get_event_loop()
     self.bridge = bridge
     self.az = bridge.az
     self.device_name = bridge.name
     self._id_prefix = user_id_prefix
     self._id_suffix = user_id_suffix
     self._share_session_events = {}
     self.key_sharing_config = key_sharing_config or {}
     pickle_key = "mautrix.bridge.e2ee"
     if db_url.startswith("postgres://"):
         if not PgCryptoStore or not PgCryptoStateStore:
             raise RuntimeError("Database URL is set to postgres, but asyncpg is not installed")
         self.crypto_db = Database(url=db_url, upgrade_table=PgCryptoStore.upgrade_table,
                                   log=logging.getLogger("mau.crypto.db"), loop=self.loop)
         self.crypto_store = PgCryptoStore("", pickle_key, self.crypto_db)
         self.state_store = PgCryptoStateStore(self.crypto_db, bridge.get_portal)
     elif db_url.startswith("pickle:///"):
         self.crypto_db = None
         self.crypto_store = PickleCryptoStore("", pickle_key, db_url[len("pickle:///"):])
         self.state_store = SQLCryptoStateStore(bridge.get_portal)
     else:
         raise RuntimeError("Unsupported database scheme")
     self.client = Client(base_url=homeserver_address, mxid=self.az.bot_mxid, loop=self.loop,
                          sync_store=self.crypto_store)
     self.crypto = OlmMachine(self.client, self.crypto_store, self.state_store)
     self.crypto.allow_key_share = self.allow_key_share
예제 #2
0
파일: instance.py 프로젝트: rrosajp/maubot
 async def start_database(
     self, upgrade_table: UpgradeTable | None = None, actually_start: bool = True
 ) -> None:
     if self.loader.meta.database_type == DatabaseType.SQLALCHEMY:
         self.inst_db = sql.create_engine(f"sqlite:///{self._sqlite_db_path}")
     elif self.loader.meta.database_type == DatabaseType.ASYNCPG:
         instance_db_log = db_log.getChild(self.id)
         # TODO should there be a way to choose between SQLite and Postgres
         #      for individual instances? Maybe checking the existence of the SQLite file.
         if self.maubot.plugin_postgres_db:
             self.inst_db = ProxyPostgresDatabase(
                 pool=self.maubot.plugin_postgres_db,
                 instance_id=self.id,
                 max_conns=self.maubot.config["plugin_databases.postgres_max_conns_per_plugin"],
                 upgrade_table=upgrade_table,
                 log=instance_db_log,
             )
         else:
             self.inst_db = Database.create(
                 f"sqlite:///{self._sqlite_db_path}",
                 upgrade_table=upgrade_table,
                 log=instance_db_log,
             )
         if actually_start:
             await self.inst_db.start()
     else:
         raise RuntimeError(f"Unrecognized database type {self.loader.meta.database_type}")
예제 #3
0
    def prepare_db(self) -> None:
        self.db = Database.create(
            self.config["database"],
            upgrade_table=upgrade_table,
            db_args=self.config["database_opts"],
            owner_name=self.name,
            ignore_foreign_tables=self.args.ignore_foreign_tables,
        )
        init_db(self.db)

        if PgCryptoStore:
            if self.config["crypto_database"] == "default":
                self.crypto_db = self.db
            else:
                self.crypto_db = Database.create(
                    self.config["crypto_database"],
                    upgrade_table=PgCryptoStore.upgrade_table,
                    ignore_foreign_tables=self.args.ignore_foreign_tables,
                )
        else:
            self.crypto_db = None

        if self.config["plugin_databases.postgres"] == "default":
            if self.db.scheme != Scheme.POSTGRES:
                self.log.critical(
                    'Using "default" as the postgres plugin database URL is only allowed if '
                    "the default database is postgres.")
                sys.exit(24)
            assert isinstance(self.db, PostgresDatabase)
            self.plugin_postgres_db = self.db
        elif self.config["plugin_databases.postgres"]:
            plugin_db = Database.create(
                self.config["plugin_databases.postgres"],
                db_args={
                    **self.config["database_opts"],
                    **self.config["plugin_databases.postgres_opts"],
                },
            )
            if plugin_db.scheme != Scheme.POSTGRES:
                self.log.critical(
                    "The plugin postgres database URL must be a postgres database"
                )
                sys.exit(24)
            assert isinstance(plugin_db, PostgresDatabase)
            self.plugin_postgres_db = plugin_db
        else:
            self.plugin_postgres_db = None
예제 #4
0
 def prepare_db(self) -> None:
     if not hasattr(self, "upgrade_table") or not self.upgrade_table:
         raise RuntimeError("upgrade_table is not set")
     self.db = Database.create(
         self.config["appservice.database"],
         upgrade_table=self.upgrade_table,
         db_args=self.config["appservice.database_opts"],
         owner_name=self.name,
         ignore_foreign_tables=self.args.ignore_foreign_tables,
     )
예제 #5
0
    async def start(self) -> None:
        self.database = Database(url=self.config["server.database"],
                                 upgrade_table=upgrade_table)
        Base.db = self.database
        init_mixpanel(self.config)
        self.server = Server(self.config)

        await self.database.start()
        await self.server.start()

        await super().start()
예제 #6
0
 def __init__(
     self,
     bridge: br.Bridge,
     homeserver_address: str,
     user_id_prefix: str,
     user_id_suffix: str,
     db_url: str,
     key_sharing_config: dict[str, bool] = None,
 ) -> None:
     self.loop = bridge.loop or asyncio.get_event_loop()
     self.bridge = bridge
     self.az = bridge.az
     self.device_name = bridge.name
     self._id_prefix = user_id_prefix
     self._id_suffix = user_id_suffix
     self._share_session_events = {}
     self.key_sharing_config = key_sharing_config or {}
     pickle_key = "mautrix.bridge.e2ee"
     self.crypto_db = Database.create(
         url=db_url,
         upgrade_table=PgCryptoStore.upgrade_table,
         log=logging.getLogger("mau.crypto.db"),
     )
     self.crypto_store = PgCryptoStore("", pickle_key, self.crypto_db)
     self.state_store = PgCryptoStateStore(self.crypto_db,
                                           bridge.get_portal)
     default_http_retry_count = bridge.config.get(
         "homeserver.http_retry_count", None)
     self.client = Client(
         base_url=homeserver_address,
         mxid=self.az.bot_mxid,
         loop=self.loop,
         sync_store=self.crypto_store,
         log=self.log.getChild("client"),
         default_retry_count=default_http_retry_count,
     )
     self.crypto = OlmMachine(self.client, self.crypto_store,
                              self.state_store)
     self.client.add_event_handler(InternalEventType.SYNC_STOPPED,
                                   self._exit_on_sync_fail)
     self.crypto.allow_key_share = self.allow_key_share
예제 #7
0
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
from typing import Dict, Optional, TYPE_CHECKING, ClassVar

from asyncpg import Record
from attr import dataclass

from mautrix.util.async_db import Database

fake_db = Database("") if TYPE_CHECKING else None


@dataclass
class UserPortal:
    db: ClassVar[Database] = fake_db

    user: int
    portal: int
    portal_receiver: int
    in_community: bool

    @classmethod
    def _from_row(cls, row: Optional[Record]) -> Optional['UserPortal']:
        if row is None:
            return None
예제 #8
0
 def prepare_db(self) -> None:
     self.db = Database(self.config["appservice.database"],
                        upgrade_table=upgrade_table,
                        loop=self.loop,
                        db_args=self.config["appservice.database_opts"])
     init_db(self.db)
예제 #9
0
파일: __main__.py 프로젝트: rrosajp/maubot
    module, main_class = meta.main_class.split("/", 1)
else:
    module = meta.modules[0]
    main_class = meta.main_class
bot_module = importlib.import_module(module)
plugin: type[Plugin] = getattr(bot_module, main_class)
loader = FileSystemLoader(os.path.dirname(args.meta))

log.info(
    f"Initializing standalone {meta.id} v{meta.version} on maubot {__version__}"
)

db = Database.create(
    config["database"],
    db_args=config.get("database_opts", {}),
    ignore_foreign_tables=True,
    log=logging.getLogger("maubot.db.standalone.upgrade"),
    upgrade_table=upgrade_table,
)

user_id = config["user.credentials.id"]
device_id = config["user.credentials.device_id"]
homeserver = config["user.credentials.homeserver"]
access_token = config["user.credentials.access_token"]

crypto_store = state_store = None
if device_id and not OlmMachine:
    log.warning(
        "device_id set in config, but encryption dependencies not installed",
        exc_info=crypto_import_error,
    )