diff --git a/slack/web/base_client.py b/slack/web/base_client.py index 207a3cee9..01f946d95 100644 --- a/slack/web/base_client.py +++ b/slack/web/base_client.py @@ -7,7 +7,6 @@ import logging import asyncio from typing import Optional, Union -import inspect import hashlib import hmac @@ -171,20 +170,6 @@ def api_call( return self._event_loop.run_until_complete(future) - def _validate_xoxp_token(self): - """Ensures that an xoxp token is used when the specified method is called. - - Raises: - BotUserAccessError: If the API method is called with a Bot User OAuth Access Token. - """ - - if self.token.startswith("xoxb"): - method_name = inspect.stack()[1][3] - msg = "The method '{}' cannot be called with a Bot Token.".format( - method_name - ) - raise err.BotUserAccessError(msg) - def _get_url(self, api_method): """Joins the base Slack URL and an API method to form an absolute URL. diff --git a/slack/web/client.py b/slack/web/client.py index 94a6ff17f..800c8faa6 100644 --- a/slack/web/client.py +++ b/slack/web/client.py @@ -81,8 +81,6 @@ def admin_apps_approve( Raises: SlackRequestError: If niether or both the `app_id` and `request_id` args are specified. """ - self._validate_xoxp_token() - if app_id: kwargs.update({"app_id": app_id}) elif request_id: @@ -96,12 +94,10 @@ def admin_apps_approve( def admin_apps_requests_list(self, **kwargs) -> Union[Future, SlackResponse]: """List app requests for a team/workspace.""" - self._validate_xoxp_token() return self.api_call("admin.apps.requests.list", http_verb="GET", params=kwargs) def admin_apps_restrict(self, **kwargs) -> Union[Future, SlackResponse]: """Restrict an app for installation on a workspace.""" - self._validate_xoxp_token() return self.api_call("admin.apps.restrict", json=kwargs) def admin_users_session_reset( @@ -112,7 +108,6 @@ def admin_users_session_reset( Args: user_id (str): The ID of the user to wipe sessions for. e.g. 'W12345678' """ - self._validate_xoxp_token() kwargs.update({"user_id": user_id}) return self.api_call("admin.users.session.reset", json=kwargs) @@ -140,7 +135,6 @@ def channels_archive( Args: channel (str): The channel id. e.g. 'C1234567890' """ - self._validate_xoxp_token() kwargs.update({"channel": channel}) return self.api_call("channels.archive", json=kwargs) @@ -150,7 +144,6 @@ def channels_create(self, *, name: str, **kwargs) -> Union[Future, SlackResponse Args: name (str): The name of the channel. e.g. 'mychannel' """ - self._validate_xoxp_token() kwargs.update({"name": name}) return self.api_call("channels.create", json=kwargs) @@ -183,7 +176,6 @@ def channels_invite( channel (str): The channel id. e.g. 'C1234567890' user (str): The user id. e.g. 'U1234567890' """ - self._validate_xoxp_token() kwargs.update({"channel": channel, "user": user}) return self.api_call("channels.invite", json=kwargs) @@ -193,7 +185,6 @@ def channels_join(self, *, name: str, **kwargs) -> Union[Future, SlackResponse]: Args: name (str): The channel name. e.g. '#general' """ - self._validate_xoxp_token() kwargs.update({"name": name}) return self.api_call("channels.join", json=kwargs) @@ -206,7 +197,6 @@ def channels_kick( channel (str): The channel id. e.g. 'C1234567890' user (str): The user id. e.g. 'U1234567890' """ - self._validate_xoxp_token() kwargs.update({"channel": channel, "user": user}) return self.api_call("channels.kick", json=kwargs) @@ -216,7 +206,6 @@ def channels_leave(self, *, channel: str, **kwargs) -> Union[Future, SlackRespon Args: channel (str): The channel id. e.g. 'C1234567890' """ - self._validate_xoxp_token() kwargs.update({"channel": channel}) return self.api_call("channels.leave", json=kwargs) @@ -245,7 +234,6 @@ def channels_rename( channel (str): The channel id. e.g. 'C1234567890' name (str): The new channel name. e.g. 'newchannel' """ - self._validate_xoxp_token() kwargs.update({"channel": channel, "name": name}) return self.api_call("channels.rename", json=kwargs) @@ -294,7 +282,6 @@ def channels_unarchive( Args: channel (str): The channel id. e.g. 'C1234567890' """ - self._validate_xoxp_token() kwargs.update({"channel": channel}) return self.api_call("channels.unarchive", json=kwargs) @@ -405,7 +392,6 @@ def chat_unfurl( unfurls (dict): a dict of the specific URLs you're offering an unfurl for. e.g. {"https://example.com/": {"text": "Every day is the test."}} """ - self._validate_xoxp_token() kwargs.update({"channel": channel, "ts": ts, "unfurls": unfurls}) return self.api_call("chat.unfurl", json=kwargs) @@ -438,7 +424,6 @@ def conversations_archive( Args: channel (str): The channel id. e.g. 'C1234567890' """ - self._validate_xoxp_token() kwargs.update({"channel": channel}) return self.api_call("conversations.archive", json=kwargs) @@ -461,7 +446,6 @@ def conversations_create( Args: name (str): The name of the channel. e.g. 'mychannel' """ - self._validate_xoxp_token() kwargs.update({"name": name}) return self.api_call("conversations.create", json=kwargs) @@ -496,7 +480,6 @@ def conversations_invite( channel (str): The channel id. e.g. 'C1234567890' users (list): An list of user id's to invite. e.g. ['U2345678901', 'U3456789012'] """ - self._validate_xoxp_token() kwargs.update({"channel": channel, "users": users}) return self.api_call("conversations.invite", json=kwargs) @@ -508,7 +491,6 @@ def conversations_join( Args: channel (str): The channel id. e.g. 'C1234567890' """ - self._validate_xoxp_token() kwargs.update({"channel": channel}) return self.api_call("conversations.join", json=kwargs) @@ -521,7 +503,6 @@ def conversations_kick( channel (str): The channel id. e.g. 'C1234567890' user (str): The id of the user to kick. e.g. 'U2345678901' """ - self._validate_xoxp_token() kwargs.update({"channel": channel, "user": user}) return self.api_call("conversations.kick", json=kwargs) @@ -533,7 +514,6 @@ def conversations_leave( Args: channel (str): The channel id. e.g. 'C1234567890' """ - self._validate_xoxp_token() kwargs.update({"channel": channel}) return self.api_call("conversations.leave", json=kwargs) @@ -565,7 +545,6 @@ def conversations_rename( channel (str): The channel id. e.g. 'C1234567890' name (str): The new channel name. e.g. 'newchannel' """ - self._validate_xoxp_token() kwargs.update({"channel": channel, "name": name}) return self.api_call("conversations.rename", json=kwargs) @@ -613,7 +592,6 @@ def conversations_unarchive( Args: channel (str): The channel id. e.g. 'C1234567890' """ - self._validate_xoxp_token() kwargs.update({"channel": channel}) return self.api_call("conversations.unarchive", json=kwargs) @@ -650,12 +628,10 @@ def dialog_open( def dnd_endDnd(self, **kwargs) -> Union[Future, SlackResponse]: """Ends the current user's Do Not Disturb session immediately.""" - self._validate_xoxp_token() return self.api_call("dnd.endDnd", json=kwargs) def dnd_endSnooze(self, **kwargs) -> Union[Future, SlackResponse]: """Ends the current user's snooze mode immediately.""" - self._validate_xoxp_token() return self.api_call("dnd.endSnooze", json=kwargs) def dnd_info(self, **kwargs) -> Union[Future, SlackResponse]: @@ -670,7 +646,6 @@ def dnd_setSnooze( Args: num_minutes (int): The snooze duration. e.g. 60 """ - self._validate_xoxp_token() kwargs.update({"num_minutes": num_minutes}) return self.api_call("dnd.setSnooze", http_verb="GET", params=kwargs) @@ -714,7 +689,6 @@ def files_info(self, *, file: str, **kwargs) -> Union[Future, SlackResponse]: def files_list(self, **kwargs) -> Union[Future, SlackResponse]: """Lists & filters team files.""" - self._validate_xoxp_token() return self.api_call("files.list", http_verb="GET", params=kwargs) def files_remote_info(self, **kwargs) -> Union[Future, SlackResponse]: @@ -768,7 +742,6 @@ def files_revokePublicURL( Args: file (str): The file id. e.g. 'F1234467890' """ - self._validate_xoxp_token() kwargs.update({"file": file}) return self.api_call("files.revokePublicURL", json=kwargs) @@ -780,7 +753,6 @@ def files_sharedPublicURL( Args: file (str): The file id. e.g. 'F1234467890' """ - self._validate_xoxp_token() kwargs.update({"file": file}) return self.api_call("files.sharedPublicURL", json=kwargs) @@ -816,7 +788,6 @@ def groups_archive(self, *, channel: str, **kwargs) -> Union[Future, SlackRespon Args: channel (str): The channel id. e.g. 'C1234567890' """ - self._validate_xoxp_token() kwargs.update({"channel": channel}) return self.api_call("groups.archive", json=kwargs) @@ -826,7 +797,6 @@ def groups_create(self, *, name: str, **kwargs) -> Union[Future, SlackResponse]: Args: name (str): The name of the private group. e.g. 'mychannel' """ - self._validate_xoxp_token() kwargs.update({"name": name}) return self.api_call("groups.create", json=kwargs) @@ -838,7 +808,6 @@ def groups_createChild( Args: channel (str): The group id. e.g. 'G1234567890' """ - self._validate_xoxp_token() kwargs.update({"channel": channel}) return self.api_call("groups.createChild", http_verb="GET", params=kwargs) @@ -869,7 +838,6 @@ def groups_invite( channel (str): The group id. e.g. 'G1234567890' user (str): The user id. e.g. 'U1234567890' """ - self._validate_xoxp_token() kwargs.update({"channel": channel, "user": user}) return self.api_call("groups.invite", json=kwargs) @@ -882,7 +850,6 @@ def groups_kick( channel (str): The group id. e.g. 'G1234567890' user (str): The user id. e.g. 'U1234567890' """ - self._validate_xoxp_token() kwargs.update({"channel": channel, "user": user}) return self.api_call("groups.kick", json=kwargs) @@ -892,7 +859,6 @@ def groups_leave(self, *, channel: str, **kwargs) -> Union[Future, SlackResponse Args: channel (str): The group id. e.g. 'G1234567890' """ - self._validate_xoxp_token() kwargs.update({"channel": channel}) return self.api_call("groups.leave", json=kwargs) @@ -930,7 +896,6 @@ def groups_rename( channel (str): The channel id. e.g. 'C1234567890' name (str): The new channel name. e.g. 'newchannel' """ - self._validate_xoxp_token() kwargs.update({"channel": channel, "name": name}) return self.api_call("groups.rename", json=kwargs) @@ -944,7 +909,6 @@ def groups_replies( thread_ts (str): The timestamp of an existing message with 0 or more replies. e.g. '1234567890.123456' """ - self._validate_xoxp_token() kwargs.update({"channel": channel, "thread_ts": thread_ts}) return self.api_call("groups.replies", http_verb="GET", params=kwargs) @@ -980,7 +944,6 @@ def groups_unarchive( Args: channel (str): The channel id. e.g. 'G1234567890' """ - self._validate_xoxp_token() kwargs.update({"channel": channel}) return self.api_call("groups.unarchive", json=kwargs) @@ -1205,7 +1168,6 @@ def reminders_add( the number of seconds until the reminder (if within 24 hours), or a natural language description (Ex. 'in 15 minutes' or 'every Thursday') """ - self._validate_xoxp_token() kwargs.update({"text": text, "time": time}) return self.api_call("reminders.add", json=kwargs) @@ -1218,7 +1180,6 @@ def reminders_complete( reminder (str): The ID of the reminder to be marked as complete. e.g. 'Rm12345678' """ - self._validate_xoxp_token() kwargs.update({"reminder": reminder}) return self.api_call("reminders.complete", json=kwargs) @@ -1230,7 +1191,6 @@ def reminders_delete( Args: reminder (str): The ID of the reminder. e.g. 'Rm12345678' """ - self._validate_xoxp_token() kwargs.update({"reminder": reminder}) return self.api_call("reminders.delete", json=kwargs) @@ -1242,13 +1202,11 @@ def reminders_info( Args: reminder (str): The ID of the reminder. e.g. 'Rm12345678' """ - self._validate_xoxp_token() kwargs.update({"reminder": reminder}) return self.api_call("reminders.info", http_verb="GET", params=kwargs) def reminders_list(self, **kwargs) -> Union[Future, SlackResponse]: """Lists all reminders created by or for a given user.""" - self._validate_xoxp_token() return self.api_call("reminders.list", http_verb="GET", params=kwargs) def rtm_connect(self, **kwargs) -> Union[Future, SlackResponse]: @@ -1266,7 +1224,6 @@ def search_all(self, *, query: str, **kwargs) -> Union[Future, SlackResponse]: query (str): Search query. May contains booleans, etc. e.g. 'pickleface' """ - self._validate_xoxp_token() kwargs.update({"query": query}) return self.api_call("search.all", http_verb="GET", params=kwargs) @@ -1277,7 +1234,6 @@ def search_files(self, *, query: str, **kwargs) -> Union[Future, SlackResponse]: query (str): Search query. May contains booleans, etc. e.g. 'pickleface' """ - self._validate_xoxp_token() kwargs.update({"query": query}) return self.api_call("search.files", http_verb="GET", params=kwargs) @@ -1288,7 +1244,6 @@ def search_messages(self, *, query: str, **kwargs) -> Union[Future, SlackRespons query (str): Search query. May contains booleans, etc. e.g. 'pickleface' """ - self._validate_xoxp_token() kwargs.update({"query": query}) return self.api_call("search.messages", http_verb="GET", params=kwargs) @@ -1306,7 +1261,6 @@ def stars_add(self, **kwargs) -> Union[Future, SlackResponse]: def stars_list(self, **kwargs) -> Union[Future, SlackResponse]: """Lists stars for a user.""" - self._validate_xoxp_token() return self.api_call("stars.list", http_verb="GET", params=kwargs) def stars_remove(self, **kwargs) -> Union[Future, SlackResponse]: @@ -1323,12 +1277,10 @@ def stars_remove(self, **kwargs) -> Union[Future, SlackResponse]: def team_accessLogs(self, **kwargs) -> Union[Future, SlackResponse]: """Gets the access logs for the current team.""" - self._validate_xoxp_token() return self.api_call("team.accessLogs", http_verb="GET", params=kwargs) def team_billableInfo(self, **kwargs) -> Union[Future, SlackResponse]: """Gets billable users information for the current team.""" - self._validate_xoxp_token() return self.api_call("team.billableInfo", http_verb="GET", params=kwargs) def team_info(self, **kwargs) -> Union[Future, SlackResponse]: @@ -1337,12 +1289,10 @@ def team_info(self, **kwargs) -> Union[Future, SlackResponse]: def team_integrationLogs(self, **kwargs) -> Union[Future, SlackResponse]: """Gets the integration logs for the current team.""" - self._validate_xoxp_token() return self.api_call("team.integrationLogs", http_verb="GET", params=kwargs) def team_profile_get(self, **kwargs) -> Union[Future, SlackResponse]: """Retrieve a team's profile.""" - self._validate_xoxp_token() return self.api_call("team.profile.get", http_verb="GET", params=kwargs) def usergroups_create(self, *, name: str, **kwargs) -> Union[Future, SlackResponse]: @@ -1352,7 +1302,6 @@ def usergroups_create(self, *, name: str, **kwargs) -> Union[Future, SlackRespon name (str): A name for the User Group. Must be unique among User Groups. e.g. 'My Test Team' """ - self._validate_xoxp_token() kwargs.update({"name": name}) return self.api_call("usergroups.create", json=kwargs) @@ -1365,7 +1314,6 @@ def usergroups_disable( usergroup (str): The encoded ID of the User Group to disable. e.g. 'S0604QSJC' """ - self._validate_xoxp_token() kwargs.update({"usergroup": usergroup}) return self.api_call("usergroups.disable", json=kwargs) @@ -1378,13 +1326,11 @@ def usergroups_enable( usergroup (str): The encoded ID of the User Group to enable. e.g. 'S0604QSJC' """ - self._validate_xoxp_token() kwargs.update({"usergroup": usergroup}) return self.api_call("usergroups.enable", json=kwargs) def usergroups_list(self, **kwargs) -> Union[Future, SlackResponse]: """List all User Groups for a team""" - self._validate_xoxp_token() return self.api_call("usergroups.list", http_verb="GET", params=kwargs) def usergroups_update( @@ -1396,7 +1342,6 @@ def usergroups_update( usergroup (str): The encoded ID of the User Group to update. e.g. 'S0604QSJC' """ - self._validate_xoxp_token() kwargs.update({"usergroup": usergroup}) return self.api_call("usergroups.update", json=kwargs) @@ -1409,7 +1354,6 @@ def usergroups_users_list( usergroup (str): The encoded ID of the User Group to update. e.g. 'S0604QSJC' """ - self._validate_xoxp_token() kwargs.update({"usergroup": usergroup}) return self.api_call("usergroups.users.list", http_verb="GET", params=kwargs) @@ -1424,7 +1368,6 @@ def usergroups_users_update( users (list): A list user IDs that represent the entire list of users for the User Group. e.g. ['U060R4BJ4', 'U060RNRCZ'] """ - self._validate_xoxp_token() kwargs.update({"usergroup": usergroup, "users": users}) return self.api_call("usergroups.users.update", json=kwargs) @@ -1434,7 +1377,6 @@ def users_conversations(self, **kwargs) -> Union[Future, SlackResponse]: def users_deletePhoto(self, **kwargs) -> Union[Future, SlackResponse]: """Delete the user profile photo""" - self._validate_xoxp_token() return self.api_call("users.deletePhoto", http_verb="GET", params=kwargs) def users_getPresence(self, *, user: str, **kwargs) -> Union[Future, SlackResponse]: @@ -1449,7 +1391,6 @@ def users_getPresence(self, *, user: str, **kwargs) -> Union[Future, SlackRespon def users_identity(self, **kwargs) -> Union[Future, SlackResponse]: """Get a user's identity.""" - self._validate_xoxp_token() return self.api_call("users.identity", http_verb="GET", params=kwargs) def users_info(self, *, user: str, **kwargs) -> Union[Future, SlackResponse]: @@ -1487,7 +1428,6 @@ def users_setPhoto( image (str): Supply the path of the image you'd like to upload. e.g. 'myimage.png' """ - self._validate_xoxp_token() return self.api_call("users.setPhoto", files={"image": image}, data=kwargs) def users_setPresence( @@ -1503,12 +1443,10 @@ def users_setPresence( def users_profile_get(self, **kwargs) -> Union[Future, SlackResponse]: """Retrieves a user's profile information.""" - self._validate_xoxp_token() return self.api_call("users.profile.get", http_verb="GET", params=kwargs) def users_profile_set(self, **kwargs) -> Union[Future, SlackResponse]: """Set the profile information for a user.""" - self._validate_xoxp_token() return self.api_call("users.profile.set", json=kwargs) def views_open( diff --git a/tests/web/test_web_client.py b/tests/web/test_web_client.py index c901c27a4..4709d8cc2 100644 --- a/tests/web/test_web_client.py +++ b/tests/web/test_web_client.py @@ -151,11 +151,6 @@ def test_request_pagination_stops_when_next_cursor_is_missing(self, mock_request req_args=fake_req_args(params={"limit": 2}), ) - def test_xoxb_token_validation(self, mock_request): - with self.assertRaises(err.BotUserAccessError): - # Channels can only be created with xoxa tokens. - self.client.channels_create(name="test") - def test_json_can_only_be_sent_with_post_requests(self, mock_request): with self.assertRaises(err.SlackRequestError): self.client.api_call("fake.method", http_verb="GET", json={})