Skip to content

Commit

Permalink
Merge branch 'main' into j0/add_linking_methods
Browse files Browse the repository at this point in the history
  • Loading branch information
J0 committed Jan 28, 2024
2 parents 1308119 + c250f93 commit ed9edab
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 9 deletions.
58 changes: 58 additions & 0 deletions gotrue/_async/gotrue_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
model_dump_json,
model_validate,
parse_auth_response,
parse_sso_response,
parse_user_response,
)
from ..http_clients import AsyncClient
Expand Down Expand Up @@ -254,6 +255,63 @@ async def sign_in_with_password(
self._notify_all_subscribers("SIGNED_IN", response.session)
return response

async def sign_in_with_sso(self, credentials: SignInWithSSOCredentials):
"""
Attempts a single-sign on using an enterprise Identity Provider. A
successful SSO attempt will redirect the current page to the identity
provider authorization page. The redirect URL is implementation and SSO
protocol specific.
You can use it by providing a SSO domain. Typically you can extract this
domain by asking users for their email address. If this domain is
registered on the Auth instance the redirect will use that organization's
currently active SSO Identity Provider for the login.
If you have built an organization-specific login page, you can use the
organization's SSO Identity Provider UUID directly instead.
"""
self._remove_session()
provider_id = credentials.get("provider_id")
domain = credentials.get("domain")
options = credentials.get("options", {})
redirect_to = options.get("redirect_to")
captcha_token = options.get("captcha_token")
# HTTPX currently does not follow redirects: https://www.python-httpx.org/compatibility/
# Additionally, unlike the JS client, Python is a server side language and it's not possible
# to automatically redirect in browser for hte user
skip_http_redirect = options.get("skip_http_redirect", True)

if domain:
return self._request(
"POST",
"sso",
body={
"domain": domain,
"skip_http_redirect": skip_http_redirect,
"gotrue_meta_security": {
"captcha_token": captcha_token,
},
},
redirect_to=redirect_to,
xform=parse_sso_response,
)
if provider_id:
return self._request(
"POST",
"sso",
body={
"provider_id": provider_id,
"skip_http_redirect": skip_http_redirect,
"gotrue_meta_security": {
"captcha_token": captcha_token,
},
},
redirect_to=redirect_to,
xform=parse_sso_response,
)
raise AuthInvalidCredentialsError(
"You must provide either a domain or provider_id"
)

async def sign_in_with_oauth(
self,
credentials: SignInWithOAuthCredentials,
Expand Down
58 changes: 58 additions & 0 deletions gotrue/_sync/gotrue_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
model_dump_json,
model_validate,
parse_auth_response,
parse_sso_response,
parse_user_response,
)
from ..http_clients import SyncClient
Expand Down Expand Up @@ -254,6 +255,63 @@ def sign_in_with_password(
self._notify_all_subscribers("SIGNED_IN", response.session)
return response

def sign_in_with_sso(self, credentials: SignInWithSSOCredentials):
"""
Attempts a single-sign on using an enterprise Identity Provider. A
successful SSO attempt will redirect the current page to the identity
provider authorization page. The redirect URL is implementation and SSO
protocol specific.
You can use it by providing a SSO domain. Typically you can extract this
domain by asking users for their email address. If this domain is
registered on the Auth instance the redirect will use that organization's
currently active SSO Identity Provider for the login.
If you have built an organization-specific login page, you can use the
organization's SSO Identity Provider UUID directly instead.
"""
self._remove_session()
provider_id = credentials.get("provider_id")
domain = credentials.get("domain")
options = credentials.get("options", {})
redirect_to = options.get("redirect_to")
captcha_token = options.get("captcha_token")
# HTTPX currently does not follow redirects: https://www.python-httpx.org/compatibility/
# Additionally, unlike the JS client, Python is a server side language and it's not possible
# to automatically redirect in browser for hte user
skip_http_redirect = options.get("skip_http_redirect", True)

if domain:
return self._request(
"POST",
"sso",
body={
"domain": domain,
"skip_http_redirect": skip_http_redirect,
"gotrue_meta_security": {
"captcha_token": captcha_token,
},
},
redirect_to=redirect_to,
xform=parse_sso_response,
)
if provider_id:
return self._request(
"POST",
"sso",
body={
"provider_id": provider_id,
"skip_http_redirect": skip_http_redirect,
"gotrue_meta_security": {
"captcha_token": captcha_token,
},
},
redirect_to=redirect_to,
xform=parse_sso_response,
)
raise AuthInvalidCredentialsError(
"You must provide either a domain or provider_id"
)

def sign_in_with_oauth(
self,
credentials: SignInWithOAuthCredentials,
Expand Down
5 changes: 5 additions & 0 deletions gotrue/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
GenerateLinkProperties,
GenerateLinkResponse,
Session,
SSOResponse,
User,
UserResponse,
)
Expand Down Expand Up @@ -91,6 +92,10 @@ def parse_user_response(data: Any) -> UserResponse:
return model_validate(UserResponse, data)


def parse_sso_response(data: Any) -> SSOResponse:
return model_validate(SSOResponse, data)


def get_error_message(error: Any) -> str:
props = ["msg", "message", "error_description", "error"]
filter = (
Expand Down
2 changes: 0 additions & 2 deletions gotrue/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,9 @@ class OAuthResponse(BaseModel):
class SSOResponse(BaseModel):
url: str


class IdentitiesResponse(BaseModel):
identities: List[UserIdentity]


class UserResponse(BaseModel):
user: User

Expand Down
14 changes: 7 additions & 7 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit ed9edab

Please sign in to comment.