def test_save_enterprise_user(self, mock_client_put): workspace_key = ds_util.client.key('SlackWorkspace', 'enterprise_id-NONE') store = DatastoreInstallationStore(ds_util.client) installation = Installation(app_id='app_id', enterprise_id='enterprise_id', user_id='user_id') store.save(installation) workspace_entity = mock_client_put.call_args_list[0][0][0] self.assertEqual(workspace_entity.key, workspace_key) bot_latest_entity = mock_client_put.call_args_list[1][0][0] self.assertEqual(bot_latest_entity.key.parent, workspace_key) self.assertEqual( bot_latest_entity.key, ds_util.client.key('SlackBot', 'bot-latest', parent=workspace_key), ) installer_latest_entity = mock_client_put.call_args_list[2][0][0] self.assertEqual( installer_latest_entity.key, ds_util.client.key('SlackInstaller', 'installer-latest', parent=workspace_key), ) installer_user_latest_entity = mock_client_put.call_args_list[3][0][0] self.assertEqual( installer_user_latest_entity.key, ds_util.client.key('SlackInstaller', 'installer-user_id-latest', parent=workspace_key), )
def test_find_installation(self, mock_client_get): workspace_key = ds_util.client.key('SlackWorkspace', 'enterprise_id-team_id') store = DatastoreInstallationStore(ds_util.client) installation_entity = Entity( ds_util.client.key('SlackInstaller', 'installer-latest', parent=workspace_key)) installation_entity.update( Installation( app_id='app_id', enterprise_id='enterprise_id', team_id='team_id', user_id='user_id', ).__dict__) mock_client_get.return_value = installation_entity found_installation = store.find_installation( enterprise_id='enterprise_id', team_id='team_id') self.assertIsNotNone(found_installation) self.assertIsInstance(found_installation, Installation) # Make sure we searched for the right key. key = mock_client_get.call_args[0][0] self.assertEqual( key, ds_util.client.key('SlackInstaller', 'installer-latest', parent=workspace_key), )
def test_find_bot(self, mock_client_get): workspace_key = ds_util.client.key('SlackWorkspace', 'enterprise_id-team_id') store = DatastoreInstallationStore(ds_util.client) bot_entity = Entity( ds_util.client.key('SlackBot', 'bot-latest', parent=workspace_key)) bot_entity.update( Bot( app_id='app_id', bot_id='bot_id', bot_token='bot_token', bot_user_id='bot_user_id', installed_at=55.00, ).__dict__) mock_client_get.return_value = bot_entity found_bot = store.find_bot(enterprise_id='enterprise_id', team_id='team_id') self.assertIsNotNone(found_bot) self.assertIsInstance(found_bot, Bot) # Make sure we searched for the right key. key = mock_client_get.call_args[0][0] self.assertEqual( key, ds_util.client.key('SlackBot', 'bot-latest', parent=workspace_key))
def _create_slack_client_for_team(team_id): slack_service = Service.get('slack', parent=Bot.key()) installation_store = DatastoreInstallationStore(ds_util.client, parent=slack_service.key) slack_bot = installation_store.find_bot( enterprise_id=None, team_id=team_id, is_enterprise_install=False, ) return WebClient(slack_bot.bot_token)
def _create_slack_client(event): slack_service = Service.get('slack', parent=Bot.key()) installation_store = DatastoreInstallationStore(ds_util.client, parent=slack_service.key) slack_bot = installation_store.find_bot( enterprise_id=event.get('authorizations', [{}])[0].get('enterprise_id'), team_id=event.get('authorizations', [{}])[0].get('team_id'), is_enterprise_install=event.get('authorizations', [{}])[0].get('is_enterprise_install'), ) return WebClient(slack_bot.bot_token)
def _oauth(request: flask.Request, session: dict, user: Entity, dest: str, redirect_uri: str): # Retrieve the auth code and state from the request params if 'code' not in request.args: error = request.args["error"] if "error" in request.args else "" return flask.make_response( f"Something is wrong with the installation (error: {error})", 400) code = request.args['code'] # Verify the state parameter state_store = DatastoreOAuthStateStore(ds_util.client, STATE_EXPIRATION_SECONDS) if not state_store.consume(request.args["state"]): return flask.make_response( "Try the installation again (the state value is already expired)", 400) # Verify the state parameter # Complete the installation by calling oauth.v2.access API method client = WebClient() oauth_response = client.oauth_v2_access( client_id=config.slack_creds['client_id'], client_secret=config.slack_creds['client_secret'], redirect_uri=redirect_uri, code=code, ) # These seem to sometimes return None rather than being unset, so for maps, return {} installed_enterprise = oauth_response.get("enterprise", {}) or {} is_enterprise_install = oauth_response.get("is_enterprise_install") installed_team = oauth_response.get("team", {}) or {} installer = oauth_response.get("authed_user", {}) or {} incoming_webhook = oauth_response.get("incoming_webhook", {}) or {} bot_token = oauth_response.get("access_token") # NOTE: oauth.v2.access doesn't include bot_id in response bot_id = None enterprise_url = None if bot_token is not None: auth_test = client.auth_test(token=bot_token) bot_id = auth_test["bot_id"] if is_enterprise_install is True: enterprise_url = auth_test.get("url") installation = Installation( app_id=oauth_response.get("app_id"), enterprise_id=installed_enterprise.get("id"), enterprise_name=installed_enterprise.get("name"), enterprise_url=enterprise_url, team_id=installed_team.get("id"), team_name=installed_team.get("name"), bot_token=bot_token, bot_id=bot_id, bot_user_id=oauth_response.get("bot_user_id"), bot_scopes=oauth_response.get("scope"), # comma-separated string user_id=installer.get("id"), user_token=installer.get("access_token"), user_scopes=installer.get("scope"), # comma-separated string incoming_webhook_url=incoming_webhook.get("url"), incoming_webhook_channel=incoming_webhook.get("channel"), incoming_webhook_channel_id=incoming_webhook.get("channel_id"), incoming_webhook_configuration_url=incoming_webhook.get( "configuration_url"), is_enterprise_install=is_enterprise_install, token_type=oauth_response.get("token_type"), ) # Store the installation service = Service.get(SERVICE_NAME, parent=user.key) store = DatastoreInstallationStore(ds_util.client, parent=service.key) store.save(installation) task_util.sync_service(Service.get(SERVICE_NAME, parent=user.key)) return flask.redirect(config.devserver_url + dest)