Source code for globus_sdk.services.auth.client.native_client

from __future__ import annotations

import logging
import typing as t

from globus_sdk._types import ScopeCollectionType, UUIDLike
from globus_sdk.authorizers import NullAuthorizer
from globus_sdk.response import GlobusHTTPResponse

from ..flow_managers import GlobusNativeAppFlowManager
from ..response import OAuthTokenResponse
from .base_login_client import AuthLoginClient

log = logging.getLogger(__name__)


[docs] class NativeAppAuthClient(AuthLoginClient): """ This type of ``AuthLoginClient`` is used to represent a Native App's communications with Globus Auth. It requires a Client ID, and cannot take an ``authorizer``. Native Apps are applications, like the Globus CLI, which are run client-side and therefore cannot keep secrets. Unable to possess client credentials, several Globus Auth interactions have to be specialized to accommodate the absence of a secret. Any keyword arguments given are passed through to the ``AuthClient`` constructor. .. automethodlist:: globus_sdk.NativeAppAuthClient """ def __init__( self, client_id: UUIDLike, environment: str | None = None, base_url: str | None = None, app_name: str | None = None, transport_params: dict[str, t.Any] | None = None, ) -> None: super().__init__( client_id=client_id, authorizer=NullAuthorizer(), environment=environment, base_url=base_url, app_name=app_name, transport_params=transport_params, )
[docs] def oauth2_start_flow( self, requested_scopes: ScopeCollectionType | None = None, *, redirect_uri: str | None = None, state: str = "_default", verifier: str | None = None, refresh_tokens: bool = False, prefill_named_grant: str | None = None, ) -> GlobusNativeAppFlowManager: """ Starts a Native App OAuth2 flow. This is done internally by instantiating a :class:`GlobusNativeAppFlowManager <.GlobusNativeAppFlowManager>` While the flow is in progress, the ``NativeAppAuthClient`` becomes non thread-safe as temporary state is stored during the flow. :param requested_scopes: The scopes on the token(s) being requested. Defaults to ``openid profile email urn:globus:auth:scope:transfer.api.globus.org:all`` :param redirect_uri: The page that users should be directed to after authenticating at the authorize URL. Defaults to 'https://auth.globus.org/v2/web/auth-code', which displays the resulting ``auth_code`` for users to copy-paste back into your application (and thereby be passed back to the ``GlobusNativeAppFlowManager``) :param state: The ``redirect_uri`` page will have this included in a query parameter, so you can use it to pass information to that page if you use a custom page. It defaults to the string '_default' :param verifier: A secret used for the Native App flow. It will by default be a freshly generated random string, known only to this ``GlobusNativeAppFlowManager`` instance :param refresh_tokens: When True, request refresh tokens in addition to access tokens. [Default: ``False``] :param prefill_named_grant: Prefill the named grant label on the consent page .. tab-set:: .. tab-item:: Example Usage You can see an example of this flow :ref:`in the usage examples <examples_native_app_login>`. .. tab-item:: API Info The Globus Auth specification for Native App grants details modifications to the Authorization Code grant flow as `The PKCE Security Protocol <https://docs.globus.org/api/auth/developer-guide/#pkce>`_. """ log.info("Starting Native App Grant Flow") self.current_oauth2_flow_manager = GlobusNativeAppFlowManager( self, requested_scopes=requested_scopes, redirect_uri=redirect_uri, state=state, verifier=verifier, refresh_tokens=refresh_tokens, prefill_named_grant=prefill_named_grant, ) return self.current_oauth2_flow_manager
[docs] def oauth2_refresh_token( self, refresh_token: str, *, body_params: dict[str, t.Any] | None = None, ) -> OAuthTokenResponse: """ ``NativeAppAuthClient`` specializes the refresh token grant to include its client ID as a parameter in the POST body. It needs this specialization because it cannot authenticate the refresh grant call with client credentials, as is normal. :param refresh_token: The refresh token to use to get a new access token :param body_params: Extra parameters to include in the POST body """ log.info("Executing token refresh without client credentials") form_data = { "refresh_token": refresh_token, "grant_type": "refresh_token", "client_id": self.client_id, } return self.oauth2_token(form_data, body_params=body_params)
[docs] def create_native_app_instance( self, template_id: UUIDLike, name: str, ) -> GlobusHTTPResponse: """ Create a new native app instance. The new instance is a confidential client. :param template_id: The client ID of the calling native app :param name: The name given to the new app instance .. tab-set:: .. tab-item:: Example Usage .. code-block:: pycon >>> ac = globus_sdk.NativeAppAuthClient(...) >>> template_id = ... >>> r = ac.create_native_app_instance( ... template_id, ... "My new native app instance", ... ) >>> client_id = r["client"]["id"] .. tab-item:: Example Response Data .. expandtestfixture:: auth.create_native_app_instance .. tab-item:: API Info ``POST /v2/api/clients`` .. extdoclink:: Create Client :ref: auth/reference/#create_client """ body: dict[str, t.Any] = { "name": name, "template_id": template_id, } return self.post("/v2/api/clients", data={"client": body})