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

Global state for sessions causes race conditions on async code #705

Closed
gpkc opened this issue Feb 16, 2024 · 2 comments
Closed

Global state for sessions causes race conditions on async code #705

gpkc opened this issue Feb 16, 2024 · 2 comments
Labels

Comments

@gpkc
Copy link

gpkc commented Feb 16, 2024

Issue summary

It seems that the package is only geared towards non-async apps.
This is because session management is done globally. Even the temp method for creating a temporary session will simply use the global state by calling shopify.ShopifyResource.activate_session, and all of the consumer sub-packages also just read the session from the global state.
I couldn't find any documentation if it's possible to create a truly local session.

Related issue: #191

Expected behavior

There should be a way to create a fully scoped, thread safe session. Or there should be clear documentation

Actual behavior

If you authenticate a new session while there's another thread with a session going, the new session will override the other one.
Or at least this behavior should be clearly documented. It is not safe when building applications that handle users' tokens, as this will absolutely cause information leakage.

Steps to reproduce the problem

Just run:


import asyncio
import shopify

shops = [
    {"url": "my_test_shop_1.myshopify.com", "token": "access_token1", "api_version": "2023-10"},
    {"url": "my_test_shop_2.myshopify.com", "token": "access_token2", "api_version": "2023-10"}
]


async def fetch_shop_details(shop):
    with shopify.Session.temp(shop["url"], shop["api_version"], shop["token"]):  # the same will happen with using activate_session
        await asyncio.sleep(0.1)
        try:
            shop_details = shopify.Shop.current()
            print(f"Fetched details for {shop['url']}: {shop_details}")
        except Exception as e:
            print(f"Failed to fetch details for {shop['url']}: {e}")
        await asyncio.sleep(0.1)


async def main():
    tasks = [fetch_shop_details(shop) for shop in shops]
    await asyncio.gather(*tasks)


asyncio.run(main())

This will print something like this, assuming you don't replace the tokens with valid ones, demonstrating that the session leaked into a separate task:

Failed to fetch details for my_test_shop_1.myshopify.com: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Hostname mismatch, certificate is not valid for 'my_test_shop_2.myshopify.com'. (_ssl.c:1006)>
Failed to fetch details for my_test_shop_2.myshopify.com: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Hostname mismatch, certificate is not valid for 'my_test_shop_2.myshopify.com'. (_ssl.c:1006)>
Copy link

This issue is stale because it has been open for 60 days with no activity. It will be closed if no further action occurs in 14 days.

@github-actions github-actions bot added the Stale label Apr 17, 2024
Copy link

github-actions bot commented May 1, 2024

We are closing this issue because it has been inactive for a few months.
This probably means that it is not reproducible or it has been fixed in a newer version.
If it’s an enhancement and hasn’t been taken on since it was submitted, then it seems other issues have taken priority.

If you still encounter this issue with the latest stable version, please reopen using the issue template. You can also contribute directly by submitting a pull request– see the CONTRIBUTING.md file for guidelines

Thank you!

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale May 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant