This commit is contained in:
Nick Booth 2020-09-11 11:59:32 +01:00
parent a42f2ccd0f
commit 939f869bbc

View File

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