Skip to content
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

Refreshing a session via Boto3SessionProvider::refresh_callback fails in botocore.credentials.py:582 with a TypeError exception, "argument of type 'RefreshableCredentials' is not iterable" #20

Open
rub73 opened this issue Mar 27, 2024 · 1 comment

Comments

@rub73
Copy link

rub73 commented Mar 27, 2024

This is caused by the implementation of streamlit_cognito_auth.session_provider.py::_get_credentials, where the refresh_using lambda executes a recursive call to _get_credentials and, thus, returns a (Refreshable)Credentials object, that is then iterated upon in botocore while performing the refresh logic.

Changing the code to return a dict instead works:

    def _get_credentials(self, id_token: str) -> botocore.credentials.Credentials:
        kwargs = self._get_credentials_metadata(id_token)
        credentials = botocore.credentials.RefreshableCredentials(
            **kwargs,
            refresh_using=lambda: self._get_credentials_metadata(self.refresh_callback(), refresh=True),
        ) if self.refresh_callback is not None else botocore.credentials.Credentials(**kwargs)
        return credentials

    def _get_credentials_metadata(self, id_token: str, refresh=False) -> dict:
        identity_id = self._get_identity_id(id_token)
        aws_credentials = self._get_aws_credentials(identity_id, id_token)
        data = {
            "access_key": aws_credentials["AccessKeyId"],
            "secret_key": aws_credentials["SecretKey"],
            "token": aws_credentials["SessionToken"],
            "method": "custom_cognito_auth",
        }

        if self.refresh_callback:
            expiration = aws_credentials["Expiration"]
            if refresh:
                expiration = str(expiration)
            
            data["expiry_time"] = expiration

        return data

Note that the expiry_time object is expected to be a str in botocore.credentials.py:594, hence the str() case.

Blocking issue, preventing sessions to be refreshed

@pop-srw
Copy link
Owner

pop-srw commented Apr 28, 2024

Thanks for your thoughtful suggestion and the effort you put into crafting a potential solution.
Your code looks promising, but I'd like to take some time to thoroughly review and test it to ensure it resolves the issue without any unintended side effects.
Once validated, I'll include it in the next release.

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

No branches or pull requests

2 participants