diff --git a/synapse-auth-module/README.md b/synapse-auth-module/README.md index 1459ed6..782d527 100644 --- a/synapse-auth-module/README.md +++ b/synapse-auth-module/README.md @@ -1,6 +1,7 @@ # ppfun-auth-module for matrix-synapse Allows pixelplanet users to login with their credentials on matrix. +Required synapse version is 1.69+ ## Installation @@ -16,8 +17,11 @@ modules: ppfunurl: "http://local.pixelplanet.url:port" # if true, only mail-verified users can log in verified: true - # rooms that will be automatically joined on login + # rooms that will be automatically joined on login, must be a list autojoin_rooms: ['#pp_en:pixelplanet.fun', '#pp_int:pixelplanet.fun'] + # dont notify users in pp_ channels + # when true, it triggers a monkeypatch that blocks notifications in bridged channels in order to avoid flooding the synapse database with push_actions + block_notify: false ``` ## References diff --git a/synapse-auth-module/ppfun_auth.py b/synapse-auth-module/ppfun_auth.py index e73a1d0..45ce1e2 100644 --- a/synapse-auth-module/ppfun_auth.py +++ b/synapse-auth-module/ppfun_auth.py @@ -10,23 +10,62 @@ import logging import synapse from synapse import module_api from synapse.types import RoomAlias +from synapse.push.bulk_push_rule_evaluator import BulkPushRuleEvaluator +from synapse.api.constants import EventTypes, Membership logger = logging.getLogger(__name__) +def monkeyPatchPushRules(store): + """Monkey patching BulkPushRuleEvaluator to not + send notifications if message is in pp_ channel, + otherwise event_push_actions will get filled up with unread + notification for pp_ users, creating and infinite growing database + """ + originalFunction = BulkPushRuleEvaluator.action_for_event_by_user + # cache for whether room is bridge room that gets notifications blocked or not + room_block_notif = {} + + async def monkeyPatch(self, event, context): + # always notify on invites + if event.type != EventTypes.Member or event.membership != Membership.INVITE: + room_id = event.room_id + if room_id in room_block_notif: + if room_block_notif[room_id]: + return + else: + aliases = await store.get_aliases_for_room(room_id) + for alias in aliases: + if alias.startswith('#pp_'): + room_block_notif[room_id] = True + return + room_block_notif[room_id] = False + return await originalFunction(self, event, context) + + BulkPushRuleEvaluator.action_for_event_by_user = monkeyPatch + logger.info('Monkey patched BulkPushRuleEvaluator') + class PPfunAuthProvider: def __init__(self, config: dict, api: module_api): self.api = api + if 'ppfunurl' not in config: raise Exception('Pixelplanet ppfunurl not configured') self.ppfunurl = config["ppfunurl"] + if 'apisocketkey' not in config: raise Exception('Pixelplanet apisocketkey not configured') self.apisocketkey = config["apisocketkey"] + if 'verified' in config: self.check_verified = config['verified'] else: self.check_verified = False + + if 'block_notify' in config and config['block_notify']: + monkeyPatchPushRules(api._store) + + self.autojoin_rooms = [] if 'autojoin_rooms' in config: self.parsed_rooms = False self.autojoin_rooms = config["autojoin_rooms"] @@ -38,19 +77,21 @@ class PPfunAuthProvider: }, ) - # resolve room_aliases to room_ids async def translate_room_aliases_to_ids( self, room_aliases: List[str], ) -> List[str]: + """Resole list of room_aliases to room_ids + """ room_ids = [] logger.info('Translating room_aliases to ids') for alias in room_aliases: - aliasObject = RoomAlias.from_string(alias) - room = await self.api._store.get_association_from_room_alias(aliasObject) - if room is not None: - logger.info('Map alias %s to room %s', alias, room.room_id) - room_ids.append(room.room_id) + try: + (room_id, hosts) = await self.api.lookup_room_alias(alias) + logger.info('Map alias %s to room %s', alias, room_id) + room_ids.append(room_id) + except: + logger.warning('Could not resolve room %s', alias) return room_ids; async def check_credentials( @@ -79,12 +120,13 @@ class PPfunAuthProvider: logger.warning('Could not login via ppfun: %s', e) return None - # Make sure that email is set correctly when logging in async def set_email( self, user_id: str, email: str ) -> bool: + """making sure that email is the same between ppfun and matrix user + """ threepid_dict_list = await self.api.get_threepids_for_user(user_id) for threepid_dict in threepid_dict_list: if threepid_dict['address'] == email: @@ -105,6 +147,8 @@ class PPfunAuthProvider: self, user_id: str, ) -> None: + if not self.autojoin_rooms: + return if not self.parsed_rooms: self.autojoin_rooms = await self.translate_room_aliases_to_ids(self.autojoin_rooms) self.parsed_rooms = True