diff --git a/README.md b/README.md index 6ef89f6..d44a61f 100644 --- a/README.md +++ b/README.md @@ -763,6 +763,8 @@ Typically set your own id into it. `OWNERS_ONLY` is an optional variable once defined only the owners can operate the bot (this is a form of whitelisting) +`INVITE_WHITELIST` (default empty) is an optional comma-separated list of matrix id's to restrict the acceptance of invites into rooms of the bot to users or servers. It supports wild cards: Example value: `@user:matrix.org,@*:myserver.org` + `LEAVE_EMPTY_ROOMS` (default true) if this is set to false, the bot will stay in empty rooms __*ATTENTION:*__ Don't include bot itself in `BOT_OWNERS` if cron or any other module that can cause bot to send custom commands is used, as it could potentially be used to run owner commands as the bot itself. diff --git a/bot.py b/bot.py index edf0e46..2d04172 100755 --- a/bot.py +++ b/bot.py @@ -35,6 +35,7 @@ class Bot: self.version = '1.5' self.client = None self.join_on_invite = False + self.invite_whitelist = [] self.modules = dict() self.module_aliases = dict() self.leave_empty_rooms = True @@ -458,11 +459,25 @@ class Bot: def starts_with_command(body): """Checks if body starts with ! and has one or more letters after it""" return re.match(r"^!\w.*", body) is not None + + def on_invite_whitelist(self, sender): + for entry in self.invite_whitelist: + if entry == sender: + return True + controll_value = entry.split(':') + if controll_value[0] == '@*' and controll_value[1] == sender.split(':')[1]: + return True + return False + async def invite_cb(self, room, event): room: MatrixRoom event: InviteEvent + if len(self.invite_whitelist) > 0 and not self.on_invite_whitelist(event.sender): + self.logger.error(f'Cannot join room {room.display_name}, as {event.sender} is not whitelisted for invites!') + return + if self.join_on_invite or self.is_owner(event): for attempt in range(3): self.jointime = datetime.datetime.now() @@ -558,6 +573,7 @@ class Bot: bot_owners = os.getenv('BOT_OWNERS') access_token = os.getenv('MATRIX_ACCESS_TOKEN') join_on_invite = os.getenv('JOIN_ON_INVITE') + invite_whitelist = os.getenv('INVITE_WHITELIST') owners_only = os.getenv('OWNERS_ONLY') is not None leave_empty_rooms = os.getenv('LEAVE_EMPTY_ROOMS') @@ -565,6 +581,7 @@ class Bot: self.client = AsyncClient(matrix_server, self.matrix_user, ssl = matrix_server.startswith("https://")) self.client.access_token = access_token self.join_on_invite = (join_on_invite or '').lower() == 'true' + self.invite_whitelist = invite_whitelist.split(',') if invite_whitelist is not None else [] self.leave_empty_rooms = (leave_empty_rooms or 'true').lower() == 'true' self.owners = bot_owners.split(',') self.owners_only = owners_only @@ -616,6 +633,8 @@ class Bot: if self.join_on_invite: self.logger.info('Note: Bot will join rooms if invited') + if len(self.invite_whitelist) > 0: + self.logger.info(f'Note: Bot will only join rooms when the inviting user is contained in {self.invite_whitelist}') self.logger.info('Bot running as %s, owners %s', self.client.user, self.owners) self.bot_task = asyncio.create_task(self.client.sync_forever(timeout=30000)) await self.bot_task