Skip to content

Commit 98a5312

Browse files
committed
TPT-4175: cli: Update interactive config token access check
1 parent 13ddc88 commit 98a5312

2 files changed

Lines changed: 47 additions & 1 deletion

File tree

linodecli/configuration/auth.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,14 @@ def _check_full_access(base_url: str, token: str) -> bool:
176176
verify=API_CA_PATH,
177177
)
178178

179-
_handle_response_status(result, exit_on_error=True)
179+
# IAM-enrolled users receive a 403 from /profile/grants since that
180+
# endpoint is not accessible to them. Treat 403 as a valid response
181+
# (i.e. not full access) rather than a fatal error.
182+
_handle_response_status(
183+
result,
184+
exit_on_error=True,
185+
status_validator=lambda status: status == 403,
186+
)
180187

181188
return result.status_code == 204
182189

tests/unit/test_configuration.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
_default_text_input,
2020
_default_thing_input,
2121
)
22+
from linodecli.configuration.auth import _check_full_access
2223

2324

2425
class TestConfiguration:
@@ -676,3 +677,41 @@ def test_custom_config_path(self, monkeypatch, tmp_path):
676677

677678
for i, _ in enumerate(expected_configs):
678679
assert expected_configs[i] == configs[i]
680+
681+
682+
class TestCheckFullAccess:
683+
"""
684+
Unit tests for _check_full_access
685+
"""
686+
687+
base_url = "https://linode-test.com"
688+
test_token = "cli-dev-token"
689+
690+
def test_full_access_returns_true(self):
691+
"""
692+
204 No Content means the token has full (unrestricted) access.
693+
"""
694+
with requests_mock.Mocker() as m:
695+
m.get(f"{self.base_url}/profile/grants", status_code=204)
696+
assert _check_full_access(self.base_url, self.test_token) is True
697+
698+
def test_restricted_access_returns_false(self):
699+
"""
700+
200 with a grants body means the token has restricted access.
701+
"""
702+
with requests_mock.Mocker() as m:
703+
m.get(
704+
f"{self.base_url}/profile/grants",
705+
status_code=200,
706+
json={"linode": []},
707+
)
708+
assert _check_full_access(self.base_url, self.test_token) is False
709+
710+
def test_iam_user_403_returns_false(self):
711+
"""
712+
IAM-enrolled users receive a 403 from /profile/grants.
713+
This should be treated as "not full access" rather than a fatal error.
714+
"""
715+
with requests_mock.Mocker() as m:
716+
m.get(f"{self.base_url}/profile/grants", status_code=403)
717+
assert _check_full_access(self.base_url, self.test_token) is False

0 commit comments

Comments
 (0)