def handle(bot: Bot, event: events.TextMessage, match: typing.Match): try: account = fetch_api("account", api_key=match.group(1)) server = enums.World(account.get("world")) guilds = ( bot.session.query(models.Guild) .filter(models.Guild.guid.in_(account.get("guilds", []))) .filter(models.Guild.group_id.isnot(None)) .options(load_only(models.Guild.name)) ) bot.send_message( event.id, "info_world", user=account.get("name"), world=server.proper_name, guilds=", ".join([_.name for _ in guilds]), ) except InvalidKeyException: logging.info("This seems to be an invalid API key.") bot.send_message(event.id, "invalid_token") except (requests.RequestException, RateLimitException, ApiErrBadData): logging.exception("Error during API call") bot.send_message(event.id, "error_api")
def handle(bot: Bot, event: events.TextMessage, match: typing.Match): if event.uid not in Config.whitelist_admin: return try: json = fetch_api("account", api_key=match.group(1)) account = models.Account.get_by_api_info( bot.session, guid=json.get("id"), name=json.get("name") ) # Account does not exist if not account: logging.info("User was not registered.") bot.send_message(event.id, "account_unknown", account=json.get("name")) return # Get previous identity previous_identity: typing.Optional[ models.LinkAccountIdentity ] = account.valid_identities.one_or_none() # Remove previous links account.invalidate(bot.session) if previous_identity: # Get cldbid and sync groups try: cldbid = bot.exec_( "clientgetdbidfromuid", cluid=previous_identity.identity.guid )[0]["cldbid"] result = sync_groups(bot, cldbid, account, remove_all=True) logging.info( "%s (%s) marked previous links of %s as ignored", event.name, event.uid, account.name, ) bot.send_message( event.id, "groups_revoked", amount="1", groups=result["removed"], ) except ts3.TS3Error: # User might not exist in the db logging.info("Failed to remove groups from user", exc_info=True) else: bot.send_message(event.id, "groups_revoked", amount="0", groups=[]) except InvalidKeyException: logging.info("This seems to be an invalid API key.") bot.send_message(event.id, "invalid_token") except ApiErrBadData: bot.send_message(event.id, "error_api")
def create(guid: str, group_id: int = None): """ Retrieves guild details from the API and returns an instance or None if the guild was not found :exception NotFoundException :exception RateLimitException :exception requests.RequestException """ data = ts3bot.fetch_api(f"guild/{guid}") return Guild( guid=guid, name=data.get("name", "undefined"), tag=data.get("tag", "undefined"), group_id=group_id, )
def handle(bot: Bot, event: events.TextMessage, match: typing.Match): if event.uid not in Config.whitelist_admin: return # Grab client_uid try: user = bot.exec_("clientgetnamefromdbid", cldbid=match.group(1)) client_uid = user[0]["cluid"] except ts3.query.TS3QueryError: bot.send_message(event.id, "user_not_found") return try: json = fetch_api("account", api_key=match.group(2)) account = models.Account.get_or_create(bot.session, json, match.group(2)) identity: models.Identity = models.Identity.get_or_create( bot.session, client_uid) # Save api key in account account.api_key = match.group(2) account.is_valid = True bot.session.commit() transfer_registration( bot, account, event, is_admin=True, target_identity=identity, target_dbid=match.group(1), ) except InvalidKeyException: logging.info("This seems to be an invalid API key.") bot.send_message(event.id, "invalid_token") return except (RateLimitException, RequestException, ApiErrBadData): bot.send_message(event.id, "error_api")
def handle(bot: Bot, event: events.TextMessage, match: Match) -> None: key = match.group(1) # Check with ArenaNet's API try: account_info = fetch_api("account", api_key=key) # Check if one of the guilds is in the alliance is_part_of_alliance = (bot.session.query(models.Guild).filter( models.Guild.guid.in_(account_info.get("guilds", []))).filter( models.Guild.is_part_of_alliance.is_(True)).count() > 0) # One of the guilds is in the alliance if is_part_of_alliance: account: models.Account = models.Account.get_or_create( bot.session, account_info, key) identity: models.Identity = models.Identity.get_or_create( bot.session, event.uid) # Check if account is registered to anyone linked_identity: Optional[ models. LinkAccountIdentity] = account.valid_identities.one_or_none() # Account is already linked if linked_identity: # Account is linked to another guid if linked_identity.identity.guid != event.uid: try: # Get user's DB id cldbid: str = bot.exec_("clientgetdbidfromuid", cluid=event.uid)[0]["cldbid"] except ts3.TS3Error: LOG.error("Failed to get user's dbid", exc_info=True) bot.send_message(event.id, "error_critical") return force_key_name = f"ts3bot-{cldbid}" # Fetch token info token_info = fetch_api("tokeninfo", api_key=key) # Override registration, same as !register if token_info.get("name", "") == force_key_name: ts3bot.transfer_registration(bot, account, event) LOG.info( "%s (%s) transferred permissions of %s onto themselves.", event.name, event.uid, account_info.get("name"), ) return LOG.warning( "%s (%s) tried to use an already registered API key/account. (%s)", event.name, event.uid, account_info.get("name"), ) bot.send_message(event.id, "token_in_use", api_name=force_key_name) else: # Account is linked to current guid LOG.info( "User %s (%s) tried to register a second time for whatever reason using %s", event.name, event.uid, account_info.get("name", "Unknown account"), ) # Save new API key if account.api_key != key: account.api_key = key account.is_valid = True bot.session.commit() bot.send_message(event.id, "registration_exists") return # Same API key supplied, last check was over 12 minutes ago if (ts3bot.timedelta_hours(datetime.datetime.today() - account.last_check) >= 0.2): # Update saved account info if same API key was posted again with a reasonable time frame account.update(bot.session) try: # Get user's DB id cldbid = bot.exec_("clientgetdbidfromuid", cluid=event.uid)[0]["cldbid"] # Sync groups ts3bot.sync_groups(bot, cldbid, account) bot.send_message(event.id, "registration_details_updated") except ts3.TS3Error: # User might not exist in the db LOG.error("Failed to sync user", exc_info=True) else: # Too early bot.send_message(event.id, "registration_too_early") else: # Otherwise account is not yet linked and can be used # Save API key account.api_key = key account.is_valid = True bot.session.commit() # Get user's DB id cldbid = bot.exec_("clientgetdbidfromuid", cluid=event.uid)[0]["cldbid"] # Unlink previous account from identity current_account = models.Account.get_by_identity( bot.session, event.uid) if current_account: LOG.info("Delinking %s from cldbid:%s", current_account, cldbid) current_account.invalidate(bot.session) # Register link between models bot.session.add( models.LinkAccountIdentity(account=account, identity=identity)) bot.session.commit() # Add all known guilds to user if enabled if Config.getboolean( "guild", "assign_on_register") and Config.getboolean( "guild", "allow_multiple_guilds"): cast(AppenderQuery, account.guilds).filter( models.LinkAccountGuild.id.in_( bot.session.query(models.LinkAccountGuild.id).join( models.Guild).filter( models.Guild.group_id.isnot( None)).subquery())).update( {"is_active": True}, synchronize_session="fetch") bot.session.commit() # Sync groups sync_groups(bot, cldbid, account) LOG.info( "Assigned alliance permissions to %s (%s) using %s", event.name, event.uid, account_info.get("name", "Unknown account"), ) # Was registered with other account previously if current_account: bot.send_message(event.id, "registration_update", account=account.name) else: bot.send_message(event.id, "welcome_registered") # Tell user about !guild if it's enabled if Config.getboolean("commands", "guild"): if Config.getboolean( "guild", "assign_on_register") and Config.getboolean( "guild", "allow_multiple_guilds"): bot.send_message(event.id, "welcome_registered_3") else: bot.send_message(event.id, "welcome_registered_2") else: bot.send_message( event.id, "invalid_world", world=enums.World(account_info.get("world")).proper_name, ) except InvalidKeyException: LOG.info("This seems to be an invalid API key.") bot.send_message(event.id, "invalid_token_retry") except (RateLimitException, RequestException, ApiErrBadData): bot.send_message(event.id, "error_api")