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

feat: add third-party auth support #905

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 20 additions & 14 deletions supabase/_async/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,10 @@
from supafunc import AsyncFunctionsClient

from ..lib.client_options import ClientOptions
from ..utils import AuthProxy, SupabaseException
from .auth_client import AsyncSupabaseAuthClient


# Create an exception class when user does not provide a valid url or key.
class SupabaseException(Exception):
def __init__(self, message: str):
self.message = message
super().__init__(self.message)


class AsyncClient:
"""Supabase client class."""

Expand Down Expand Up @@ -77,10 +71,15 @@ def __init__(
self.functions_url = f"{supabase_url}/functions/v1"

# Instantiate clients.
self.auth = self._init_supabase_auth_client(
auth_url=self.auth_url,
client_options=options,
)
if not options.access_token:
self.auth = self._init_supabase_auth_client(
auth_url=self.auth_url,
client_options=options,
)
else:
self.access_token = options.access_token
self.auth = AuthProxy()

self.realtime = self._init_realtime_client(
realtime_url=self.realtime_url,
supabase_key=self.supabase_key,
Expand All @@ -89,7 +88,9 @@ def __init__(
self._postgrest = None
self._storage = None
self._functions = None
self.auth.on_auth_state_change(self._listen_to_auth_events)

if not options.access_token:
self.auth.on_auth_state_change(self._listen_to_auth_events)

@classmethod
async def create(
Expand All @@ -103,8 +104,13 @@ async def create(

if auth_header is None:
try:
session = await client.auth.get_session()
session_access_token = client._create_auth_header(session.access_token)
if not options.access_token:
session = await client.auth.get_session()
session_access_token = client._create_auth_header(
session.access_token
)
else:
session_access_token = options.access_token
except Exception as err:
session_access_token = None

Expand Down
34 changes: 20 additions & 14 deletions supabase/_sync/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,10 @@
from supafunc import SyncFunctionsClient

from ..lib.client_options import ClientOptions
from ..utils import AuthProxy, SupabaseException
from .auth_client import SyncSupabaseAuthClient


# Create an exception class when user does not provide a valid url or key.
class SupabaseException(Exception):
def __init__(self, message: str):
self.message = message
super().__init__(self.message)


class SyncClient:
"""Supabase client class."""

Expand Down Expand Up @@ -77,10 +71,15 @@ def __init__(
self.functions_url = f"{supabase_url}/functions/v1"

# Instantiate clients.
self.auth = self._init_supabase_auth_client(
auth_url=self.auth_url,
client_options=options,
)
if not options.access_token:
self.auth = self._init_supabase_auth_client(
auth_url=self.auth_url,
client_options=options,
)
else:
self.access_token = options.access_token
self.auth = AuthProxy()

self.realtime = self._init_realtime_client(
realtime_url=self.realtime_url,
supabase_key=self.supabase_key,
Expand All @@ -89,7 +88,9 @@ def __init__(
self._postgrest = None
self._storage = None
self._functions = None
self.auth.on_auth_state_change(self._listen_to_auth_events)

if not options.access_token:
self.auth.on_auth_state_change(self._listen_to_auth_events)

@classmethod
def create(
Expand All @@ -103,8 +104,13 @@ def create(

if auth_header is None:
try:
session = client.auth.get_session()
session_access_token = client._create_auth_header(session.access_token)
if not options.access_token:
session = client.auth.get_session()
session_access_token = client._create_auth_header(
session.access_token
)
else:
session_access_token = options.access_token
except Exception as err:
session_access_token = None

Expand Down
4 changes: 4 additions & 0 deletions supabase/lib/client_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ class ClientOptions:
flow_type: AuthFlowType = "implicit"
"""flow type to use for authentication"""

access_token: Union[str, None] = None

def replace(
self,
schema: Optional[str] = None,
Expand All @@ -66,6 +68,7 @@ def replace(
int, float, Timeout
] = DEFAULT_STORAGE_CLIENT_TIMEOUT,
flow_type: Optional[AuthFlowType] = None,
access_token: Union[str, None] = None,
) -> "ClientOptions":
"""Create a new SupabaseClientOptions with changes"""
client_options = ClientOptions()
Expand All @@ -84,4 +87,5 @@ def replace(
storage_client_timeout or self.storage_client_timeout
)
client_options.flow_type = flow_type or self.flow_type
client_options.access_token = access_token or self.access_token
return client_options
16 changes: 16 additions & 0 deletions supabase/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from gotrue.errors import AuthError


# Create an exception class when user does not provide a valid url or key.
class SupabaseException(Exception):
def __init__(self, message: str):
self.message = message
super().__init__(self.message)


class AuthProxy:
def __getattr__(self, attr):
raise AuthError(
f"Supabase Client is configured with the access_token option, accessing supabase.auth.{attr} is not possible.",
None,
)
Loading