Skip to content

Add option to authenticate via refresh token #322

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

WebSpider
Copy link
Contributor

This implements the option to start an authenticated session via an OIDC/Oauth2 refresh token, in preparation for the homeassistant integration to start storing the refresh tokens, speeding up authentication since we no longer have to do the Oauth2 dance via webforms.

This PR changes the auth/authorize() and the connect() call in the following ways:

  • You need to specify either email+password or refresh_token
  • If you specify email+password, nothing changes
  • If you do not specify email+password, but specify refresh_token, the token will be used to retrieve a new acces token, granting access

Since the refresh_token argument is not the first argument, you can not call MySkoda.connect('tokencontent'), you now need to specify that you are sending a refresh_token as argument.

Options to authenticate are:

  1. Regular username/password authentication:

This can be

MySkoda.connect('username','verysecrethush`)

which is backwards compatible

OR

MySkoda.connect(email='username',password='verysecrethush`)
  1. Using a refresh token you need to specify you are using a refresh token. Otherwise we silently assume you send email/password.
MySkoda.connect(refresh_token='tokencontent')

The result will be the same: The library will connect and authenticate/authorize based on the credentials sent. With the authenticated MySkoda object you can perform all other calls next.

@WebSpider WebSpider added the enhancement New feature or request label Jan 9, 2025
@WebSpider
Copy link
Contributor Author

@dvx76 I'd like your opinion about this approach. Should we make changes to existing methods, or make new ones?

@dvx76 dvx76 self-requested a review February 17, 2025 14:14
@dvx76
Copy link
Member

dvx76 commented Feb 17, 2025

@dvx76 I'd like your opinion about this approach. Should we make changes to existing methods, or make new ones?

Why not keep the username and password as mandatory arguments? We need them anyway if using the refresh_token fails (existing logic in refresh_token(), which I would keep).

So something like

async def authorize(self, email: str, password: str, refresh_token: str | None = None):
    self.email = email
    self.password = password
    if refresh_token:
        self.idk_session = await self._get_idk_from_token(refresh_token)
    else:
        self.idk_session = await self._get_idk_session()

Out-of-scope side note: I can't remember why we're only passing in username and password (and now refresh_token) in MySkoda.connect()/Authorization.authorize(), instead of directly in the __init__() functions, which makes more sense to me.

@WebSpider
Copy link
Contributor Author

I guess this is so you can instantiate without authentication right away.

@dvx76
Copy link
Member

dvx76 commented Mar 25, 2025

pre-commit.ci run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants