From 939f869bbc3b8609ec5ba8a00d21b12e9f03b570 Mon Sep 17 00:00:00 2001 From: Nick Booth Date: Fri, 11 Sep 2020 11:59:32 +0100 Subject: [PATCH] Fix plamere/spotipy#560 --- spotipy/oauth2.py | 70 +++++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/spotipy/oauth2.py b/spotipy/oauth2.py index 8a37774..96303a5 100644 --- a/spotipy/oauth2.py +++ b/spotipy/oauth2.py @@ -234,18 +234,19 @@ class SpotifyOAuth(SpotifyAuthBase): OAUTH_TOKEN_URL = "https://accounts.spotify.com/api/token" def __init__( - self, - client_id=None, - client_secret=None, - redirect_uri=None, - state=None, - scope=None, - cache_path=None, - username=None, - proxies=None, - show_dialog=False, - requests_session=True, - requests_timeout=None + self, + client_id=None, + client_secret=None, + redirect_uri=None, + state=None, + scope=None, + cache_path=None, + username=None, + proxies=None, + show_dialog=False, + requests_session=True, + requests_timeout=None, + open_browser=True ): """ Creates a SpotifyOAuth object @@ -264,6 +265,7 @@ class SpotifyOAuth(SpotifyAuthBase): * show_dialog: Interpreted as boolean * requests_timeout: Tell Requests to stop waiting for a response after a given number of seconds + * open_browser: Whether or not the web browser should be opened to authorize a user """ super(SpotifyOAuth, self).__init__(requests_session) @@ -280,6 +282,7 @@ class SpotifyOAuth(SpotifyAuthBase): self.proxies = proxies self.requests_timeout = requests_timeout self.show_dialog = show_dialog + self.open_browser = open_browser def get_cached_token(self): """ Gets a cached auth token @@ -294,7 +297,7 @@ class SpotifyOAuth(SpotifyAuthBase): # if scopes don't match, then bail if "scope" not in token_info or not self._is_scope_subset( - self.scope, token_info["scope"] + self.scope, token_info["scope"] ): return None @@ -382,8 +385,8 @@ class SpotifyOAuth(SpotifyAuthBase): except webbrowser.Error: logger.error("Please navigate here: %s", auth_url) - def _get_auth_response_interactive(self, open_browser=True): - if open_browser: + def _get_auth_response_interactive(self, open_browser=False): + if open_browser or self.open_browser: self._open_auth_url() prompt = "Enter the URL you were redirected to: " else: @@ -413,7 +416,7 @@ class SpotifyOAuth(SpotifyAuthBase): else: raise SpotifyOauthError("Server listening on localhost has not been accessed") - def get_auth_response(self, open_browser=True): + def get_auth_response(self, open_browser=False): logger.info('User authentication requires interaction with your ' 'web browser. Once you enter your credentials and ' 'give authorization, you will be redirected to ' @@ -424,9 +427,9 @@ class SpotifyOAuth(SpotifyAuthBase): redirect_host, redirect_port = get_host_port(redirect_info.netloc) if ( - open_browser - and redirect_host in ("127.0.0.1", "localhost") - and redirect_info.scheme == "http" + (open_browser or self.open_browser) + and redirect_host in ("127.0.0.1", "localhost") + and redirect_info.scheme == "http" ): # Only start a local http server if a port is specified if redirect_port: @@ -584,7 +587,8 @@ class SpotifyPKCE(SpotifyAuthBase): username=None, proxies=None, requests_timeout=None, - requests_session=True,): + requests_session=True, + open_browser=True): """ Creates Auth Manager with the PKCE Auth flow. @@ -602,6 +606,7 @@ class SpotifyPKCE(SpotifyAuthBase): * proxies: Proxy for the requests library to route through * requests_timeout: Tell Requests to stop waiting for a response after a given number of seconds + * open_browser: Whether or not the web browser should be opened to authorize a user """ super(SpotifyPKCE, self).__init__(requests_session) @@ -620,6 +625,7 @@ class SpotifyPKCE(SpotifyAuthBase): self.code_verifier = None self.code_challenge = None self.authorization_code = None + self.open_browser = open_browser def _normalize_scope(self, scope): if scope: @@ -642,7 +648,7 @@ class SpotifyPKCE(SpotifyAuthBase): try: import secrets verifier = secrets.token_urlsafe(length) - except ImportError: # For python 3.5 support + except ImportError: # For python 3.5 support import os import base64 rand_bytes = os.urandom(length) @@ -688,7 +694,7 @@ class SpotifyPKCE(SpotifyAuthBase): except webbrowser.Error: logger.error("Please navigate here: %s", auth_url) - def _get_auth_response(self, open_browser=True): + def _get_auth_response(self, open_browser=False): logger.info('User authentication requires interaction with your ' 'web browser. Once you enter your credentials and ' 'give authorization, you will be redirected to ' @@ -699,9 +705,9 @@ class SpotifyPKCE(SpotifyAuthBase): redirect_host, redirect_port = get_host_port(redirect_info.netloc) if ( - open_browser - and redirect_host in ("127.0.0.1", "localhost") - and redirect_info.scheme == "http" + (open_browser or self.open_browser) + and redirect_host in ("127.0.0.1", "localhost") + and redirect_info.scheme == "http" ): # Only start a local http server if a port is specified if redirect_port: @@ -730,8 +736,8 @@ class SpotifyPKCE(SpotifyAuthBase): else: raise SpotifyOauthError("Server listening on localhost has not been accessed") - def _get_auth_response_interactive(self, open_browser=True): - if open_browser: + def _get_auth_response_interactive(self, open_browser=False): + if open_browser or self.open_browser: self._open_auth_url() prompt = "Enter the URL you were redirected to: " else: @@ -764,7 +770,7 @@ class SpotifyPKCE(SpotifyAuthBase): # if scopes don't match, then bail if "scope" not in token_info or not self._is_scope_subset( - self.scope, token_info["scope"] + self.scope, token_info["scope"] ): return None @@ -858,9 +864,9 @@ class SpotifyPKCE(SpotifyAuthBase): raise SpotifyOauthError('error: {0}, error_descr: {1}'.format(error_payload['error'], error_payload[ 'error_description' - ]), - error=error_payload['error'], - error_description=error_payload['error_description']) + ]), + error=error_payload['error'], + error_description=error_payload['error_description']) token_info = response.json() token_info = self._add_custom_values_to_token_info(token_info) self._save_token_info(token_info) @@ -1011,7 +1017,7 @@ class SpotifyImplicitGrant(SpotifyAuthBase): # if scopes don't match, then bail if "scope" not in token_info or not self._is_scope_subset( - self.scope, token_info["scope"] + self.scope, token_info["scope"] ): return None