コード例 #1
0
ファイル: credentials.py プロジェクト: BenMcGrory/tekore
def prompt_for_user_token(client_id: str,
                          client_secret: str,
                          redirect_uri: str,
                          scope=None) -> RefreshingToken:
    """
    Prompt for manual authentication.

    Open a web browser for the user to log in with Spotify.
    Prompt to paste the URL after logging in to parse the `code` URL parameter.

    Parameters
    ----------
    client_id
        client ID
    client_secret
        client secret
    redirect_uri
        whitelisted redirect URI
    scope
        access rights as a space-separated list

    Returns
    -------
    RefreshingToken
        automatically refreshing user token
    """
    cred = RefreshingCredentials(client_id, client_secret, redirect_uri)
    url = cred.user_authorisation_url(scope, show_dialog=True)

    print('Opening browser for Spotify login...')
    webbrowser.open(url)
    redirected = input('Please paste redirect URL: ').strip()
    code = parse_code_from_url(redirected)
    return cred.request_user_token(code)
コード例 #2
0
ファイル: credentials.py プロジェクト: BenMcGrory/tekore
def request_client_token(client_id: str,
                         client_secret: str) -> RefreshingToken:
    """
    Request for client credentials.

    Parameters
    ----------
    client_id
        client ID
    client_secret
        client secret

    Returns
    -------
    RefreshingToken
        automatically refreshing client token
    """
    cred = RefreshingCredentials(client_id, client_secret)
    return cred.request_client_token()
コード例 #3
0
ファイル: credentials.py プロジェクト: BenMcGrory/tekore
def refresh_user_token(client_id: str, client_secret: str,
                       refresh_token: str) -> RefreshingToken:
    """
    Request a refreshed user token.

    Parameters
    ----------
    client_id
        client ID
    client_secret
        client secret
    refresh_token
        refresh token

    Returns
    -------
    RefreshingToken
        automatically refreshing user token
    """
    cred = RefreshingCredentials(client_id, client_secret)
    return cred.refresh_user_token(refresh_token)
コード例 #4
0
    def on_submit_creds(self) -> None:
        """
        Checking if the submitted credentials were correct, and starting the
        logging-in step.
        """

        # Obtaining the input data
        form_client_id = self.web_form.client_id
        form_client_secret = self.web_form.client_secret
        logging.info("Input creds: '%s' & '%s'", form_client_id,
                     form_client_secret)

        # Checking that the data isn't empty
        empty_field = False
        if form_client_id == '':
            self.web_form.input_client_id.highlight()
            empty_field = True
        else:
            self.web_form.input_client_id.undo_highlight()

        if form_client_secret == '':
            self.web_form.input_client_secret.highlight()
            empty_field = True
        else:
            self.web_form.input_client_secret.undo_highlight()

        if empty_field:
            return

        # Hiding the form and showing the web browser for the next step
        self.web_form.hide()
        self.browser.show()

        # Creating the request URL to obtain the authorization token
        self.creds = RefreshingCredentials(
            form_client_id, form_client_secret, self.redirect_uri)
        self.scope = scopes.user_read_currently_playing
        url = self.creds.user_authorisation_url(self.scope)
        self.browser.url = url
コード例 #5
0
class SpotifyWebPrompt(QWidget):
    """
    This widget handles all the interaction with the user to obtain the
    credentials for the Spotify Web API.
    """

    done = Signal(RefreshingToken)

    def __init__(self, client_id: str, client_secret: str, redirect_uri: str,
                 *args) -> None:
        """
        Starts the API initialization flow, which is the following:
            1. The user inputs the credentials.
            ** self.on_submit_creds is called **
            2. The user logs in.
            ** self.on_login is called **
            3. If the credentials were correct, the Web API is set up and
               started from outside this widget. Otherwise, go back to step 1.
            ** self.done is emitted **
        """

        super().__init__(*args)

        logging.info("Initializing the Spotify Web API prompt interface")
        self.redirect_uri = redirect_uri

        # Creating the layout
        self.layout = QHBoxLayout(self)
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.layout.setSpacing(0)

        # The web form for the user to input the credentials.
        self.web_form = SpotifyWebForm(client_id=client_id,
                                       client_secret=client_secret)
        # on_submit_spotify_web creds will be called once the credentials have
        # been input.
        self.web_form.button.clicked.connect(self.on_submit_creds)
        self.layout.addWidget(self.web_form)

        # The web browser for the user to login and grant access.
        # It's hidden at the beggining and will appear once the credentials
        # are input.
        self.browser = WebBrowser()
        self.browser.hide()
        # The initial screen with the web form will be shown if the user
        # clicks on the Go Back button.
        self.browser.go_back_button.pressed.connect(
            lambda: (self.browser.hide(), self.web_form.show()))
        # Any change in the browser URL will redirect to on__login to check if
        # the login was succesful.
        self.browser.web_view.urlChanged.connect(self.on_login)
        self.layout.addWidget(self.browser)

    @property
    def client_id(self) -> str:
        return self.web_form.client_id

    @property
    def client_secret(self) -> str:
        return self.web_form.client_secret

    @Slot()
    def on_submit_creds(self) -> None:
        """
        Checking if the submitted credentials were correct, and starting the
        logging-in step.
        """

        # Obtaining the input data
        form_client_id = self.web_form.client_id
        form_client_secret = self.web_form.client_secret
        logging.info("Input creds: '%s' & '%s'", form_client_id,
                     form_client_secret)

        # Checking that the data isn't empty
        empty_field = False
        if form_client_id == '':
            self.web_form.input_client_id.highlight()
            empty_field = True
        else:
            self.web_form.input_client_id.undo_highlight()

        if form_client_secret == '':
            self.web_form.input_client_secret.highlight()
            empty_field = True
        else:
            self.web_form.input_client_secret.undo_highlight()

        if empty_field:
            return

        # Hiding the form and showing the web browser for the next step
        self.web_form.hide()
        self.browser.show()

        # Creating the request URL to obtain the authorization token
        self.creds = RefreshingCredentials(
            form_client_id, form_client_secret, self.redirect_uri)
        self.scope = scopes.user_read_currently_playing
        url = self.creds.user_authorisation_url(self.scope)
        self.browser.url = url

    @Slot()
    def on_login(self) -> None:
        """
        This function is called once the user has logged into Spotify to
        obtain the access token.

        Part of this function is a reimplementation of
        `tekore.prompt_user_token`. It does the same thing but in a more
        automatized way, because Qt has access over the web browser too.
        """

        url = self.browser.url
        logging.info("Now at: %s", url)

        # If the URL isn't the Spotify response URI (localhost), do nothing
        if url.find(self.redirect_uri) == -1:
            return

        # Trying to get the auth token from the URL with Tekore's
        # parse_code_from_url(), which throws a KeyError if the URL doesn't
        # contain an auth token or if it contains more than one.
        try:
            code = parse_code_from_url(url)
        except KeyError as e:
            logging.info("ERROR: %s", str(e))
            return

        # Now the user token has to be requested to Spotify, while
        # checking for errors to make sure the credentials were correct.
        # This will only happen with the client secret because it's only
        # checked when requesting the user token.
        try:
            # A RefreshingToken is used instead of a regular Token so that
            # it's automatically refreshed before it expires. self.creds is
            # of type `RefreshingCredentials`, so it returns always a
            # RefreshingToken.
            token = self.creds.request_user_token(code)
        except OAuthError as e:
            self.browser.hide()
            self.web_form.show()
            self.web_form.show_error(str(e))
            return

        # Removing the GUI elements used to obtain the credentials
        self.layout.removeWidget(self.web_form)
        self.web_form.hide()
        self.layout.removeWidget(self.browser)
        self.browser.hide()

        # Finally starting the Web API
        self.done.emit(token)
コード例 #6
0
ファイル: auth.py プロジェクト: BenMcGrory/tekore
 def _initialise(self):
     return RefreshingCredentials(self.client_id, self.client_secret,
                                  self.redirect_uri)