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

fix(user auth context): do not overwrite provided client options Authorization header #766

Merged
merged 1 commit into from
Apr 17, 2024

Conversation

Garee
Copy link
Contributor

@Garee Garee commented Apr 13, 2024

What kind of change does this PR introduce?

Bug fix for #420

Supports setting the client auth context for a particular user and therefore RLS.

  • Updated both sync and async clients.
  • Added unit tests.

What is the current behavior?

If a client is created with an Authorization header provided in ClientOptions, it is overwritten with the supabase key.

For example:

url = "https://example.supabase.com"
key = "apikey"
options = ClientOptions(headers={"Authorization": "Bearer userjwt"})
supabase = create_client(url, key, options)

# Subsequent requests will include the headers:
# apiKey: "apiKey"
# Authorization: "Bearer apiKey" <- Expected "Bearer userjwt"

What is the new behavior?

The Authorization header provided via client options is used for requests.

# apiKey: "apikey"
# Authorization: "Bearer userjwt"

If no header is provided the supabase key is used.

Additional context

This allows us to set the auth context in the same manner described in the official Edge Function documentation.

@Garee Garee requested a review from a team as a code owner April 13, 2024 11:01
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @Garee - I've reviewed your changes and they look great!

Here's what I looked at during the review
  • 🟢 General issues: all looks good
  • 🟢 Security: all looks good
  • 🟡 Testing: 3 issues found
  • 🟢 Complexity: all looks good
  • 🟢 Docstrings: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment to tell me if it was helpful.

_: Client = create_client(url, key)


def test_uses_key_as_authorization_header_by_default() -> None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Consider adding a test case for when the Authorization header is explicitly set to None.

This would help ensure that the default behavior is correctly handled even when the header is explicitly set to None, rather than just not provided.

Suggested change
def test_uses_key_as_authorization_header_by_default() -> None:
def test_uses_key_as_authorization_header_when_explicitly_set_to_none() -> None:
url = os.environ.get("SUPABASE_TEST_URL")
key = os.environ.get("SUPABASE_TEST_KEY")
options = ClientOptions(headers={"Authorization": None})
client = create_client(url, key, options)
assert client.options.headers.get("apiKey") == key
assert client.options.headers.get("Authorization") is None

assert client.storage.session.headers.get("Authorization") == f"Bearer {key}"


def test_supports_setting_a_global_authorization_header() -> None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Please add a test case to verify the behavior when an invalid JWT is provided in the Authorization header.

This test would help ensure that the system behaves as expected when an invalid JWT is used, potentially rejecting the request or handling it gracefully.

Suggested change
def test_supports_setting_a_global_authorization_header() -> None:
def test_rejects_invalid_jwt() -> None:
url = os.environ.get("SUPABASE_TEST_URL")
key = os.environ.get("SUPABASE_TEST_KEY")
invalid_jwt = "invalid_jwt"
client = create_client(url, key, ClientOptions(headers={"Authorization": f"Bearer {invalid_jwt}"}))
response = client.postgrest.get("some_endpoint")
assert response.status_code == 401

assert client.storage.session.headers.get("Authorization") == authorization


def test_updates_the_authorization_header_on_auth_events() -> None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Add a test to verify header updates when the auth event is 'SIGNED_OUT'.

This would ensure that headers are correctly reset or handled when a user signs out.

Suggested change
def test_updates_the_authorization_header_on_auth_events() -> None:
def test_authorization_header_reset_on_sign_out() -> None:
client._listen_to_auth_events("SIGNED_OUT", MagicMock(access_token=None))
assert client.options.headers.get("Authorization") is None
assert client.postgrest.session.headers.get("Authorization") is None
assert client.auth._headers.get("Authorization") is None
assert client.storage.session.headers.get("Authorization") is None

Copy link

codecov bot commented Apr 14, 2024

Codecov Report

Attention: Patch coverage is 40.00000% with 6 lines in your changes are missing coverage. Please review.

Project coverage is 52.98%. Comparing base (819ba63) to head (8176640).
Report is 30 commits behind head on main.

Files Patch % Lines
supabase/_async/client.py 0.00% 5 Missing ⚠️
supabase/_sync/client.py 80.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #766      +/-   ##
==========================================
+ Coverage   43.97%   52.98%   +9.00%     
==========================================
  Files          13       13              
  Lines         332      302      -30     
==========================================
+ Hits          146      160      +14     
+ Misses        186      142      -44     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@silentworks
Copy link
Contributor

I'm currently reviewing this PR. I will need to test it out for a bit as some code has been removed which were to fix a previous issue.

@silentworks silentworks self-assigned this Apr 17, 2024
@silentworks silentworks linked an issue Apr 17, 2024 that may be closed by this pull request
Copy link
Contributor

@silentworks silentworks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this PR.

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

Successfully merging this pull request may close these issues.

Create a client with Auth context of a user
2 participants