Пример #1
0
    async def get_user_details(self, args):
        username, platform_id = (None,) * 2

        if not args:
            raise InvalidCommandError("Username is required")

        if args[-1] == "-platform":
            raise InvalidCommandError(
                f"Platform must be specified like `-platform {list(constants.PLATFORM_EMOJI_MAP.keys())}`"
            )

        if "-platform" in args:
            platform_name = args[-1].lower()
            username = "******".join(args[0:-2])
            platform_id = constants.PLATFORM_MAP.get(platform_name)
            if not platform_id:
                raise InvalidCommandError(
                    f"Invalid platform `{platform_name}` was specified"
                )
        else:
            username = "******".join(args)

        if not username:
            raise InvalidCommandError("Username is required")

        return username, platform_id
Пример #2
0
    async def get_bungie_details(self,
                                 username,
                                 bungie_id=None,
                                 platform_id=None):
        membership_id = None
        username_lower = username.lower()

        if bungie_id:
            try:
                player = await execute_pydest(
                    self.bot.destiny.api.get_membership_data_by_id(bungie_id),
                    self.bot.redis)
            except pydest.PydestException as e:
                log_message = f"Could not find Destiny player for {username}"
                log.error(f"{log_message}\n\n{e}\n\n{player}")
                raise InvalidCommandError(log_message)

            for membership in player['Response']['destinyMemberships']:
                if membership['membershipType'] != constants.PLATFORM_BUNGIE:
                    membership_id = membership['membershipId']
                    platform_id = membership['membershipType']
                    break
        else:
            try:
                player = await execute_pydest(
                    self.bot.destiny.api.search_destiny_player(
                        platform_id, username), self.bot.redis)
            except pydest.PydestException as e:
                log_message = f"Could not find Destiny player for {username}"
                log.error(f"{log_message}\n\n{e}\n\n{player}")
                raise InvalidCommandError(log_message)

            if len(player['Response']) == 1:
                membership = player['Response'][0]
                if membership['displayName'].lower() == username_lower:
                    membership_id = membership['membershipId']
                    platform_id = membership['membershipType']
            else:
                for membership in player['Response']:
                    display_name = membership['displayName'].lower()
                    membership_type = membership['membershipType']
                    if membership_type == platform_id and display_name == username_lower:
                        membership_id = membership['membershipId']
                        platform_id = membership['membershipType']
                        break

        return membership_id, platform_id
Пример #3
0
    async def invite(self, ctx, *args):
        """Invite a member by username (Admin only, requires registration)"""
        manager = MessageManager(ctx)
        username, platform_id = await self.get_user_details(args)

        member_db = await self.get_member_db(ctx, username)
        admin_db = await self.bot.database.get_member_by_discord_id(
            ctx.author.id)
        clan_db = await self.get_admin_group(ctx)

        if not platform_id and clan_db.platform:
            platform_id = clan_db.platform
        else:
            raise InvalidCommandError(
                "Platform was not specified and clan default platform is not set"
            )

        bungie_id = None
        if member_db:
            bungie_id = member_db.bungie_id

        membership_id, platform_id = await self.get_bungie_details(
            username, bungie_id, platform_id)

        res = None
        try:
            res = await execute_pydest(
                self.bot.destiny.api.group_invite_member(
                    group_id=clan_db.clan_id,
                    membership_type=platform_id,
                    membership_id=membership_id,
                    message=f"Join my clan {clan_db.name}!",
                    access_token=admin_db.bungie_access_token), self.bot.redis)
        except pydest.PydestTokenException:
            tokens = await self.refresh_admin_tokens(manager, admin_db)
            res = await execute_pydest(
                self.bot.destiny.api.group_invite_member(
                    group_id=clan_db.clan_id,
                    membership_type=platform_id,
                    membership_id=membership_id,
                    message=f"Join my clan {clan_db.name}!",
                    access_token=tokens['access_token']), self.bot.redis)
            admin_db.bungie_access_token = tokens['access_token']
            admin_db.bungie_refresh_token = tokens['refresh_token']
            await self.bot.database.update(admin_db)

        if not res:
            raise RuntimeError("Unexpected empty response from the Bungie API")

        if res['ErrorStatus'] == 'ClanTargetDisallowsInvites':
            message = f"User **{username}** has disabled clan invites"
        elif res['ErrorStatus'] != 'Success':
            message = f"Could not invite **{username}**"
            log.info(f"Could not invite '{username}': {res}")
        else:
            message = f"Invited **{username}** to clan **{clan_db.name}**"

        return await manager.send_message(message, mention=False, clean=False)
Пример #4
0
 def predicate(ctx):
     try:
         game_mode = ctx.message.content.split()[2]
     except IndexError:
         raise InvalidCommandError(
             f"Missing game mode, supported are `{', '.join(SUPPORTED_GAME_MODES.keys())}`")
     if game_mode in SUPPORTED_GAME_MODES.keys():
         return True
     raise InvalidGameModeError(game_mode, SUPPORTED_GAME_MODES.keys())
Пример #5
0
    async def invite(self, ctx, *args):
        """Invite a member by username (Admin only, requires registration)"""
        manager = MessageManager(ctx)
        username, platform_id = await self.get_user_details(args)

        member_db = await self.get_member_db(ctx, username)
        admin_db = await self.bot.database.get_member_by_discord_id(
            ctx.author.id, include_clan=False
        )
        clan_db = await self.get_admin_group(ctx)

        if not platform_id and clan_db.platform:
            platform_id = clan_db.platform
        else:
            raise InvalidCommandError(
                "Platform was not specified and clan default platform is not set"
            )

        bungie_id = None
        if member_db:
            bungie_id = member_db.bungie_id

        membership_id, platform_id = await self.get_bungie_details(
            username, bungie_id, platform_id
        )

        res = await execute_pydest_auth(
            self.bot.ext_conns,
            self.bot.destiny.api.group_invite_member,
            admin_db,
            manager,
            group_id=clan_db.clan_id,
            membership_type=platform_id,
            membership_id=membership_id,
            message=f"Join my clan {clan_db.name}!",
            access_token=admin_db.bungie_access_token,
        )

        if res.error_status == "ClanTargetDisallowsInvites":
            message = f"User **{username}** has disabled clan invites"
        elif res.error_status == "ClanMaximumMembershipReached":
            message = f"Could not invite **{username}**, clan is full"
        elif res.error_status != "Success":
            message = f"Could not invite **{username}**"
            log.info(f"Could not invite '{username}': {res}")
        else:
            message = f"Invited **{username}** to clan **{clan_db.name}**"

        return await manager.send_message(message, mention=False, clean=False)
Пример #6
0
    async def approve(self, ctx, *args):
        """Approve a pending member (Admin only, requires registration)"""
        manager = MessageManager(ctx)
        username, platform_id = await self.get_user_details(args)

        member_db = await self.get_member_db(ctx, username)
        admin_db = await self.bot.database.get_member_by_discord_id(
            ctx.author.id, include_clan=False
        )
        clan_db = await self.get_admin_group(ctx)

        if clan_db.platform:
            platform_id = clan_db.platform
        elif not platform_id:
            raise InvalidCommandError(
                "Platform was not specified and clan default platform is not set"
            )

        bungie_id = None
        if member_db:
            bungie_id = member_db.bungie_id

        membership_id, platform_id = await self.get_bungie_details(
            username, bungie_id, platform_id
        )

        res = await execute_pydest_auth(
            self.bot.ext_conns,
            self.bot.destiny.api.group_approve_pending_member,
            admin_db,
            manager,
            group_id=clan_db.clan_id,
            membership_type=platform_id,
            membership_id=membership_id,
            message=f"Welcome to {clan_db.name}!",
            access_token=admin_db.bungie_access_token,
        )

        if res.error_status != "Success":
            message = f"Could not approve **{username}**"
            log.info(f"Could not approve '{username}': {res}")
        else:
            message = f"Approved **{username}** as a member of clan **{clan_db.name}**"

        return await manager.send_message(message, mention=False, clean=False)
Пример #7
0
async def refresh_user_tokens(ctx, manager, auth_user_db):
    tokens = await execute_pydest(ctx['destiny'].api.refresh_oauth_token,
                                  auth_user_db.bungie_refresh_token,
                                  return_type=DestinyTokenResponse)

    if tokens.error:
        log.warning(f"{tokens.error_description} Registration is needed")
        user_info = await register(
            manager,
            "Your registration token has expired and re-registration is needed."
        )
        if not user_info:
            raise InvalidCommandError(
                "I'm not sure where you went. We can try this again later.")
        tokens = {
            token: user_info.get(token)
            for token in [tokens.access_token, tokens.refresh_token]
        }

    return tokens
Пример #8
0
    async def refresh_admin_tokens(self, manager, admin_db):
        tokens = await execute_pydest(
            self.bot.destiny.api.refresh_oauth_token(
                admin_db.bungie_refresh_token), self.bot.redis)

        if 'error' in tokens:
            log.warning(
                f"{tokens['error_description']} Registration is needed")
            user_info = await register(
                manager,
                "Your registration token has expired and re-registration is needed."
            )
            if not user_info:
                raise InvalidCommandError(
                    "I'm not sure where you went. We can try this again later."
                )
            tokens = {
                token: user_info.get(token)
                for token in ['access_token', 'refresh_token']
            }

        return tokens
Пример #9
0
    async def get_bungie_details(self, username, bungie_id=None, platform_id=None):
        membership_id = None
        username_lower = username.lower()

        if bungie_id:
            try:
                player = await execute_pydest(
                    self.bot.destiny.api.get_membership_data_by_id,
                    bungie_id,
                    return_type=DestinyMembershipResponse,
                )
            except pydest.PydestException as e:
                log_message = f"Could not find Destiny player for {username}"
                log.error(f"{log_message}\n\n{e}\n\n{username}")
                raise InvalidCommandError(log_message)

            for membership in player.response.destiny_memberships:
                if membership.membership_type != constants.PLATFORM_BUNGIE:
                    membership_id = membership.membership_id
                    platform_id = membership.membership_type
                    break
        else:
            player = await execute_pydest(
                self.bot.destiny.api.search_destiny_player,
                platform_id,
                username,
                return_type=DestinySearchPlayerResponse,
            )
            if not player.response:
                log_message = f"Could not find Destiny player for {username}"
                log.error(f"{log_message}\n\n{player}")
                raise InvalidCommandError(log_message)

            if len(player.response) == 1:
                membership = player.response[0]
                if (
                    membership.display_name.lower() == username_lower
                    and membership.membership_type == platform_id
                ):
                    membership_id = membership.membership_id
                    platform_id = membership.membership_type
                else:
                    membership_orig = membership
                    profile = await execute_pydest(
                        self.bot.destiny.api.get_membership_data_by_id,
                        membership.membership_id,
                        return_type=DestinyMembershipResponse,
                    )
                    for membership in profile.response.destiny_memberships:
                        if membership.display_name.lower() == username_lower:
                            user_matches = True
                            break
                    if user_matches:
                        membership_id = membership_orig.membership_id
                        platform_id = membership_orig.membership_type
            else:
                for membership in player.response:
                    display_name = membership.display_name.lower()
                    membership_type = membership.membership_type
                    if (
                        membership_type == platform_id
                        and display_name == username_lower
                    ):
                        membership_id = membership.membership_id
                        platform_id = membership.membership_type
                        break
        return membership_id, platform_id