def test_init_persona__success(make_token, tmp_path, dummy_context, mocker): """ Validate that the ``init_persona()`` function will load tokens from the cache, validate them, extract identity data, and return a new ``Persona`` instance with the tokens and identity data contained within it. """ access_token = make_token( identity_data=dict( user_email="*****@*****.**", org_name="good_org", ), expires="2022-02-16 22:30:00", ) access_token_path = tmp_path / "access.jwt" access_token_path.write_text(access_token) refresh_token = "dummy-refresh-token" refresh_token_path = tmp_path / "refresh.jwt" refresh_token_path.write_text(refresh_token) mocker.patch.object(settings, "JOBBERGATE_API_ACCESS_TOKEN_PATH", new=access_token_path) mocker.patch.object(settings, "JOBBERGATE_API_REFRESH_TOKEN_PATH", new=refresh_token_path) with plummet.frozen_time("2022-02-16 21:30:00"): persona = init_persona(dummy_context) assert persona.token_set.access_token == access_token assert persona.token_set.refresh_token == refresh_token assert persona.identity_data.user_email == "*****@*****.**" assert persona.identity_data.org_name == "good_org"
def login(ctx: typer.Context): """ Log in to the jobbergate-cli by storing the supplied token argument in the cache. """ token_set: TokenSet = fetch_auth_tokens(ctx.obj) persona: Persona = init_persona(ctx.obj, token_set) terminal_message( f"User was logged in with email '{persona.identity_data.user_email}'", subject="Logged in!", )
def main( ctx: typer.Context, verbose: bool = typer.Option( False, help="Enable verbose logging to the terminal"), full: bool = typer.Option(False, help="Print all fields from CRUD commands"), raw: bool = typer.Option( False, help="Print output from CRUD commands as raw json"), version: bool = typer.Option( False, help="Print the version of jobbergate-cli and exit"), ): """ Welcome to the Jobbergate CLI! More information can be shown for each command listed below by running it with the --help option. """ if version: typer.echo(importlib_metadata.version("jobbergate-cli")) raise typer.Exit() if ctx.invoked_subcommand is None: terminal_message( conjoin( "No command provided. Please check the [bold magenta]usage[/bold magenta] and add a command", "", f"[yellow]{ctx.get_help()}[/yellow]", ), subject="Need a jobbergate command", ) raise typer.Exit() init_logs(verbose=verbose) init_sentry() persona = None client = httpx.Client( base_url=f"https://{settings.AUTH0_LOGIN_DOMAIN}", headers={"content-type": "application/x-www-form-urlencoded"}, ) context = JobbergateContext(persona=None, client=client) if ctx.invoked_subcommand not in ("login", "logout"): persona = init_persona(context) context.client = httpx.Client( base_url=settings.JOBBERGATE_API_ENDPOINT, headers=dict( Authorization=f"Bearer {persona.token_set.access_token}"), ) context.persona = persona context.full_output = full context.raw_output = raw ctx.obj = context
def test_init_persona__refreshes_access_token_if_it_is_expired( make_token, tmp_path, respx_mock, dummy_context, mocker): """ Validate that the ``init_persona()`` function will refresh the access token if it is expired and, after validating it, save it to the cache. """ access_token = make_token( identity_data=dict( user_email="*****@*****.**", org_name="good_org", ), expires="2022-02-16 22:30:00", ) access_token_path = tmp_path / "access.jwt" access_token_path.write_text(access_token) refresh_token = "dummy-refresh-token" refresh_token_path = tmp_path / "refresh.jwt" refresh_token_path.write_text(refresh_token) refreshed_access_token = make_token( identity_data=dict( user_email="*****@*****.**", org_name="good_org", ), expires="2022-02-17 22:30:00", ) respx_mock.post(f"{LOGIN_DOMAIN}/oauth/token").mock( return_value=httpx.Response( httpx.codes.OK, json=dict(access_token=refreshed_access_token), ), ) mocker.patch.object(settings, "JOBBERGATE_API_ACCESS_TOKEN_PATH", new=access_token_path) mocker.patch.object(settings, "JOBBERGATE_API_REFRESH_TOKEN_PATH", new=refresh_token_path) with plummet.frozen_time("2022-02-16 23:30:00"): persona = init_persona(dummy_context) assert persona.token_set.access_token == refreshed_access_token assert persona.token_set.refresh_token == refresh_token assert persona.identity_data.user_email == "*****@*****.**" assert persona.identity_data.org_name == "good_org" assert access_token_path.exists() assert access_token_path.read_text() == refreshed_access_token assert refresh_token_path.exists() assert refresh_token_path.read_text() == refresh_token
def test_init_persona__uses_passed_token_set(make_token, tmp_path, dummy_context, mocker): """ Validate that the ``init_persona()`` function will used the passed ``TokenSet`` instance instead of loading it from the cache and will write the tokens to the cache after validating them. """ access_token = make_token( identity_data=dict( user_email="*****@*****.**", org_name="good_org", ), expires="2022-02-16 22:30:00", ) access_token_path = tmp_path / "access.jwt" refresh_token = "dummy-refresh-token" refresh_token_path = tmp_path / "refresh.jwt" token_set = TokenSet( access_token=access_token, refresh_token=refresh_token, ) assert not access_token_path.exists() assert not refresh_token_path.exists() mocker.patch.object(settings, "JOBBERGATE_API_ACCESS_TOKEN_PATH", new=access_token_path) mocker.patch.object(settings, "JOBBERGATE_API_REFRESH_TOKEN_PATH", new=refresh_token_path) with plummet.frozen_time("2022-02-16 21:30:00"): persona = init_persona(dummy_context, token_set) assert persona.token_set.access_token == access_token assert persona.token_set.refresh_token == refresh_token assert persona.identity_data.user_email == "*****@*****.**" assert persona.identity_data.org_name == "good_org" assert access_token_path.exists() assert access_token_path.read_text() == access_token assert refresh_token_path.exists()