Skip to content

Commit

Permalink
feat: add third-party auth support
Browse files Browse the repository at this point in the history
  • Loading branch information
silentworks committed Aug 20, 2024
1 parent 37f9962 commit add4edd
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 28 deletions.
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,
)

0 comments on commit add4edd

Please sign in to comment.