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

Use utilities/whoami endpoint from FirecREST, when possible, to determine the username #60

Merged
merged 2 commits into from
Jul 17, 2023
Merged
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
15 changes: 11 additions & 4 deletions firecrest/BasicClient.py
Original file line number Diff line number Diff line change
Expand Up @@ -957,13 +957,20 @@ def view(self, machine: str, target_path: str) -> str:
)
return self._json_response([resp], 200)["output"]

def whoami(self) -> Optional[str]:
def whoami(self, machine=None) -> Optional[str]:
"""Returns the username that FirecREST will be using to perform the other calls.
Will return `None` if the token is not valid.
In the case the machine name is passed in the arguments, a call is made to the respective endpoint and the command whoami is run on the machine.
Otherwise, the library decodes the token and will return `None` if the token is not valid.

:calls: GET `/utilities/whoami`
"""
if machine:
resp = self._get_request(
endpoint="/utilities/whoami",
additional_headers={"X-Machine-Name": machine},
)
return self._json_response([resp], 200)["output"]

# FIXME This needs to be added as an endpoint in FirecREST,
# now it's making a guess and it could be wrong.
try:
decoded = jwt.decode(
self._authorization.get_access_token(),
Expand Down
14 changes: 10 additions & 4 deletions firecrest/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -577,11 +577,16 @@ def tail(


@app.command(rich_help_panel="Utilities commands")
def whoami():
"""Return the username that FirecREST will be using to perform the other calls
def whoami(
machine: Optional[str] = typer.Argument(
None, help="The machine name where the `whoami` command will run."
),
):
"""Return the username that FirecREST will be using to perform the other calls.
If no machine name is passed the username will be deduced from the token.
"""
try:
console.print(client.whoami())
console.print(client.whoami(machine))
except Exception as e:
examine_exeption(e)
raise typer.Exit(code=1)
Expand Down Expand Up @@ -1102,7 +1107,7 @@ def main(
api_version: str = typer.Option(
None,
help="Set the version of the api of firecrest. By default it will be assumed that you are using version 1.13.0 or "
"compatible. The version is parsed by the `packaging` library.",
"compatible. The version is parsed by the `packaging` library.",
envvar="FIRECREST_API_VERSION",
),
verbose: Optional[bool] = typer.Option(
Expand Down Expand Up @@ -1154,4 +1159,5 @@ def main(
handlers=[RichHandler(console=console)],
)


typer_click_object = typer.main.get_command(app)
37 changes: 37 additions & 0 deletions tests/test_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,25 @@ def head_tail_callback(request, uri, response_headers):
return [status_code, response_headers, json.dumps(ret)]


def whoami_callback(request, uri, response_headers):
if request.headers["Authorization"] != "Bearer VALID_TOKEN":
return [401, response_headers, '{"message": "Bad token; invalid JSON"}']

if request.headers["X-Machine-Name"] != "cluster1":
response_headers["X-Machine-Does-Not-Exist"] = "Machine does not exist"
return [
400,
response_headers,
'{"description": "Error on whoami operation", "error": "Machine does not exist"}',
]

return [
200,
response_headers,
'{"description": "Success on whoami operation.", "output": "username"}'
]


@pytest.fixture(autouse=True)
def setup_callbacks():
httpretty.enable(allow_net_connect=False, verbose=True)
Expand Down Expand Up @@ -612,6 +631,10 @@ def setup_callbacks():
httpretty.GET, "http://firecrest.cscs.ch/utilities/tail", body=head_tail_callback
)

httpretty.register_uri(
httpretty.GET, "http://firecrest.cscs.ch/utilities/whoami", body=whoami_callback
)

httpretty.register_uri(
httpretty.POST,
"https://myauth.com/auth/realms/cscs/protocol/openid-connect/token",
Expand Down Expand Up @@ -1299,3 +1322,17 @@ def test_view_invalid_machine(valid_client):
def test_view_invalid_client(invalid_client):
with pytest.raises(firecrest.UnauthorizedException):
invalid_client.view("cluster1", "/path/to/file")


def test_whoami(valid_client):
assert valid_client.whoami('cluster1') == "username"


def test_whoami_invalid_machine(valid_client):
with pytest.raises(firecrest.HeaderException):
valid_client.whoami('cluster2')


def test_whoami_invalid_client(invalid_client):
with pytest.raises(firecrest.UnauthorizedException):
invalid_client.whoami('cluster1')