sander1988 / Indego

Home Assistant Custom Component for Bosch Indego Lawn Mower
Apache License 2.0
96 stars 29 forks source link

Implement re-authentication of expired OAuth (Single ID) tokens #250

Open Vitani opened 2 months ago

Vitani commented 2 months ago

When I get the error (in the logs) Token request for indego failed (invalid_grant): ABC123: The provided grant has expired. Please re-authenticate and try again. I know I have to re-authenticate, but the only way I can seem to do that is to delete the integration and re-add it; is that the correct way, or am I missing an alternative?

Larnak23 commented 2 months ago

Same for me

kimzeuner commented 2 months ago

i think at the moment this is the only (and therefore correct) way to re-authenticate. I don't know if there will be another solution in the future.

github-actions[bot] commented 1 month ago

This issue is stale because it has been open for 14 days with no activity.

brononius commented 1 month ago

I'm also checking for an easier way to renew the token...

github-actions[bot] commented 1 month ago

This issue is stale because it has been open for 14 days with no activity.

sander1988 commented 3 weeks ago

Currently there is no way to renew an expired token. You have to remove and re-add the mower.

I will keep this issue open. As it might be a nice improvement for a future release.

dvdmaz commented 3 weeks ago

Thank you Sander, we really appreciate your efforts!

Rosi2143 commented 2 weeks ago

Thanks @sander1988.

I will keep looking at this issue - every once in a while.

sander1988 commented 1 week ago

This has been implemented and is available for testing on the dev branch. HA will now show a warning and a reconfigure button when the authentication fails. indego-reauth

@Vitani - I had to make the assumption that the Bosch API reports HTTP error code 401 in this case. As the error log/stacktrace is missing in the issue description. Maybe you still have the original error?

sander1988 commented 1 week ago

This change requires some new translations (see the EN file in commit 517f97ba6459c8cc50c99c6b9e037d0e849b2068). I have added them for EN and NL.

Can someone provide DE, FR, PL and/or SK?

kimzeuner commented 1 week ago

I will take care of the DE translations tomorrow.

Vitani commented 1 week ago

@sander1988 I don't have the original logs, sorry

pbwild commented 1 week ago

I deleted the integration, and followed the instructions here https://github.com/sander1988/Indego?tab=readme-ov-file#known-issues to re-enable, but am now getting the following error: Bosch Indego Mower The connection to the Bosch Indego API failed! Please use the known issues page (https://github.com/sander1988/Indego?tab=readme-ov-file#known-issues) for possible solutions. In the logs I see: Request to 'https://api.indego-cloud.iot.bosch-si.com/api/v1/alms' failed with HTTP status code: 403 and Error while retrieving mower serial in account! Reason: 403, message='Forbidden', url='https://api.indego-cloud.iot.bosch-si.com/api/v1/alms' I have edited the configuration.yaml file to turn on de-bugging, but do not see any additional logs. Any help greatly appreciated. Peter Wild

sander1988 commented 1 week ago

@pbwild - Please open a new issue for your error (and answer the questions in the template). The error doesn't seem to be related to this issue.

kimzeuner commented 1 week ago

Here is the updated de.json translation file.

de.json

urbatecte commented 1 week ago

Hi there ! Here is the updated french translation. fr.json

Cheers.

sander1988 commented 1 week ago

Thank you @kimzeuner and @urbatecte for the DE and FR translations. I just merged the files on the dev branch.

sander1988 commented 1 week ago

Was anyone able to test this new feature due to an expired token? I would like some feedback before merging and releasing it.

I faked expired tokens during testing, but I would like to know/see if it works for real.

mintar commented 1 week ago

I'd be willing to test this (I have a currently-broken install with expired tokens after the upgrade to 5.7.7), but I couldn't figure out how to switch to the develop branch.

kimzeuner commented 1 week ago

I think with the new HACS it is no longer possible to load develop branches or beta version through HACS. I think you will have to go to the indego integration on github. There you will find a button with "main" in the upper left corner (next to the box where the files and folders are listed). There you have to choose "develop". Download the files from "custom_components/indego" and copy them to your HA instance (again in the folder "custom_components/indego". After a HA restart it should have the new version. You can download the whole directory as a zip file.

mintar commented 1 week ago

Thanks @kimzeuner, that did the trick. I was looking for an official way to do it because replacing the files under the hood seemed a bit hacky, but I found none.

Anyways, @kimzeuner's method worked, and I'm now on the develop branch (commit 209e359e52ce5b731a7cf8c1ab569f8af3d469e0). However, I don't see the "Opnieuw configureren" button:

grafik

It should also be noted that I don't get a 401 error, but a 400 error. My logs look like this:


Logger: homeassistant.config_entries
Quelle: config_entries.py:635
Erstmals aufgetreten: 14. November 2024 um 08:20:22 (2 Vorkommnisse)
Zuletzt protokolliert: 16:58:51

Error setting up entry rasi (XXXXXXXXX) for indego
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/config_entries.py", line 635, in __async_setup_with_context
    result = await component.async_setup_entry(hass, self)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/indego/__init__.py", line 235, in async_setup_entry
    await indego_hub.update_generic_data_and_load_platforms(load_platforms)
  File "/config/custom_components/indego/__init__.py", line 472, in update_generic_data_and_load_platforms
    generic_data = await self._update_generic_data()
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/indego/__init__.py", line 730, in _update_generic_data
    await self._indego_client.update_generic_data()
  File "/usr/local/lib/python3.12/site-packages/pyIndego/indego_async_client.py", line 276, in update_generic_data
    self._update_generic_data(await self.get(f"alms/{self.serial}"))
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pyIndego/indego_async_client.py", line 583, in get
    return await self._request(method=Methods.GET, path=path, timeout=timeout)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pyIndego/indego_async_client.py", line 478, in _request
    await self.start()
  File "/usr/local/lib/python3.12/site-packages/pyIndego/indego_async_client.py", line 78, in start
    self._token = await self._token_refresh_method()
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/indego/__init__.py", line 405, in async_token_refresh
    await session.async_ensure_token_valid()
  File "/usr/src/homeassistant/homeassistant/helpers/config_entry_oauth2_flow.py", line 531, in async_ensure_token_valid
    new_token = await self.implementation.async_refresh_token(self.token)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/config_entry_oauth2_flow.py", line 103, in async_refresh_token
    new_token = await self._async_refresh_token(token)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/config_entry_oauth2_flow.py", line 193, in _async_refresh_token
    new_token = await self._token_request(
                ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/config_entry_oauth2_flow.py", line 226, in _token_request
    resp.raise_for_status()
  File "/usr/local/lib/python3.12/site-packages/aiohttp/client_reqrep.py", line 1157, in raise_for_status
    raise ClientResponseError(
aiohttp.client_exceptions.ClientResponseError: 400, message='Bad Request', url='https://prodindego.b2clogin.com/prodindego.onmicrosoft.com/b2c_1a_signup_signin/oauth2/v2.0/token'

----------------------------------------------------------------------

Logger: homeassistant.helpers.config_entry_oauth2_flow
Quelle: helpers/config_entry_oauth2_flow.py:220
Erstmals aufgetreten: 14. November 2024 um 08:20:22 (2 Vorkommnisse)
Zuletzt protokolliert: 16:58:51

Token request for indego failed (invalid_grant): AADB2C90080: The provided grant has expired. Please re-authenticate and try again. Current time: 1731568822, Grant issued time: 1730890132, Grant sliding window expiration time: 1730920481.
 Correlation ID: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 Timestamp: 2024-11-14 07:20:22Z
Token request for indego failed (invalid_grant): AADB2C90080: The provided grant has expired. Please re-authenticate and try again. Current time: 1731772731, Grant issued time: 1730890132, Grant sliding window expiration time: 1730920481.
 Correlation ID: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 Timestamp: 2024-11-16 15:58:51Z

Let me know if you need any additional information. And also thanks for looking into this issue!

mintar commented 1 week ago

Oh, by the way, the logs above were from 5.7.7. With develop, there's no stack trace any more, but still the same error 400:

Logger: custom_components.indego
Quelle: custom_components/indego/__init__.py:243
Integration: Bosch Indego Mower (Dokumentation)
Erstmals aufgetreten: 20:27:38 (1 Vorkommnisse)
Zuletzt protokolliert: 20:27:38

Login unsuccessful: 400, message='Bad Request', url='https://prodindego.b2clogin.com/prodindego.onmicrosoft.com/b2c_1a_signup_signin/oauth2/v2.0/token'

-------------------------------

Logger: homeassistant.helpers.config_entry_oauth2_flow
Quelle: helpers/config_entry_oauth2_flow.py:220
Erstmals aufgetreten: 20:27:38 (1 Vorkommnisse)
Zuletzt protokolliert: 20:27:38

Token request for indego failed (invalid_grant): AADB2C90080: The provided grant has expired. Please re-authenticate and try again. Current time: 1731785258, Grant issued time: 1730890132, Grant sliding window expiration time: 1730920481.
 Correlation ID: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx
 Timestamp: 2024-11-16 19:27:38Z
sander1988 commented 6 days ago

Are you sure the user-agent is set to a value that's known to have worked before? As normally 400 = Azure WAF blocking the request (which it does for unknown reasons for some user-agents), 401 = OAuth token issue.

mintar commented 6 days ago

I'm using "Rasi Indego (3.2.0)" as a user agent, and that has worked before. I've changed it to "Rasi2 Indego (3.2.0)", same error.

Did you look at the "Token request has failed" error message as well?

sander1988 commented 6 days ago

Can you perform a test by changing this line https://github.com/sander1988/Indego/blob/develop/custom_components/indego/__init__.py#L239 to:

if exc.status >= 400 and exc.status < 500:

Make sure you don't break the indention of the file.

This should show the reconfigure button ("opnieuw configureren") for all 4XX errors. I'm wondering if the reconfigure flow can get you out of your current OAuth state. Please share the results.

mintar commented 6 days ago

Yes, it's working beautifully! The reconfigure flow could fix my current OAuth state.

Here are some screenshots of the new "reconfigure" button:

grafik

grafik

grafik

And here are my very verbose notes of what I did:

sander1988 commented 6 days ago

@mintar - Thank you for testing and feedback!

I will do some more tests and make the change permanent when I'm sure it doesn't break anything.