Skip to content

Commit c972dc7

Browse files
committed
Use new SF CLI command to obtain token for --sf-cli-org usage
1 parent be941aa commit c972dc7

2 files changed

Lines changed: 79 additions & 39 deletions

File tree

src/datacustomcode/token_provider.py

Lines changed: 58 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -101,48 +101,70 @@ def get_token(self) -> "AccessTokenResponse":
101101

102102
from datacustomcode.deploy import AccessTokenResponse
103103

104-
try:
105-
result = subprocess.run(
106-
["sf", "org", "display", "--target-org", self.sf_cli_org, "--json"],
107-
capture_output=True,
108-
text=True,
109-
check=True,
110-
timeout=30,
111-
)
112-
except FileNotFoundError as exc:
113-
raise RuntimeError(
114-
"The 'sf' command was not found. "
115-
"Install Salesforce CLI: https://developer.salesforce.com/tools/salesforcecli"
116-
) from exc
117-
except subprocess.TimeoutExpired as exc:
118-
raise RuntimeError(
119-
f"'sf org display' timed out for org '{self.sf_cli_org}'"
120-
) from exc
121-
except subprocess.CalledProcessError as exc:
122-
raise RuntimeError(
123-
f"'sf org display' failed for org '{self.sf_cli_org}': {exc.stderr}"
124-
) from exc
104+
def _run_sf_command(args: list[str], description: str) -> dict:
105+
try:
106+
result = subprocess.run(
107+
args,
108+
capture_output=True,
109+
text=True,
110+
check=True,
111+
timeout=30,
112+
)
113+
except FileNotFoundError as exc:
114+
raise RuntimeError(
115+
"The 'sf' command was not found. "
116+
"Install Salesforce CLI: "
117+
"https://developer.salesforce.com/tools/salesforcecli"
118+
) from exc
119+
except subprocess.TimeoutExpired as exc:
120+
raise RuntimeError(
121+
f"'{description}' timed out for org '{self.sf_cli_org}'"
122+
) from exc
123+
except subprocess.CalledProcessError as exc:
124+
raise RuntimeError(
125+
f"'{description}' failed for org '{self.sf_cli_org}': "
126+
f"{exc.stderr}"
127+
) from exc
125128

126-
try:
127-
data = json.loads(result.stdout)
128-
except json.JSONDecodeError as exc:
129-
raise RuntimeError(
130-
f"Failed to parse JSON from 'sf org display': {result.stdout}"
131-
) from exc
129+
try:
130+
data = json.loads(result.stdout)
131+
except json.JSONDecodeError as exc:
132+
raise RuntimeError(
133+
f"Failed to parse JSON from '{description}': {result.stdout}"
134+
) from exc
132135

133-
if data.get("status") != 0:
136+
if data.get("status") != 0:
137+
raise RuntimeError(
138+
f"SF CLI error for org '{self.sf_cli_org}': "
139+
f"{data.get('message', 'unknown error')}"
140+
)
141+
return data
142+
143+
# Get instanceUrl from sf org display
144+
display_data = _run_sf_command(
145+
["sf", "org", "display", "--target-org", self.sf_cli_org, "--json"],
146+
"sf org display",
147+
)
148+
instance_url = display_data.get("result", {}).get("instanceUrl")
149+
if not instance_url:
134150
raise RuntimeError(
135-
f"SF CLI error for org '{self.sf_cli_org}': "
136-
f"{data.get('message', 'unknown error')}"
151+
f"'sf org display' did not return an instance URL "
152+
f"for org '{self.sf_cli_org}'"
137153
)
138154

139-
result_data = data.get("result", {})
140-
access_token = result_data.get("accessToken")
141-
instance_url = result_data.get("instanceUrl")
142-
143-
if not access_token or not instance_url:
155+
# Get access token via show-access-token (newer SF CLI versions
156+
# redact the token in sf org display)
157+
token_data = _run_sf_command(
158+
[
159+
"sf", "org", "auth", "show-access-token",
160+
"--target-org", self.sf_cli_org, "--json",
161+
],
162+
"sf org auth show-access-token",
163+
)
164+
access_token = token_data.get("result", {}).get("accessToken")
165+
if not access_token:
144166
raise RuntimeError(
145-
f"'sf org display' did not return an access token or instance URL "
167+
f"'sf org auth show-access-token' did not return an access token "
146168
f"for org '{self.sf_cli_org}'"
147169
)
148170

tests/test_token_provider.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,25 +160,43 @@ def test_successful_token_retrieval(self):
160160

161161
provider = SFCLITokenProvider("test_org")
162162

163-
cli_output = json.dumps(
163+
display_output = json.dumps(
164164
{
165165
"status": 0,
166166
"result": {
167-
"accessToken": "cli_access_token",
167+
"accessToken": "[REDACTED]",
168168
"instanceUrl": "https://cli.salesforce.com",
169169
},
170170
}
171171
)
172+
token_output = json.dumps(
173+
{
174+
"status": 0,
175+
"result": {
176+
"accessToken": "cli_access_token",
177+
},
178+
}
179+
)
172180

173181
with patch("subprocess.run") as mock_run:
174-
mock_run.return_value = MagicMock(stdout=cli_output)
182+
mock_run.side_effect = [
183+
MagicMock(stdout=display_output),
184+
MagicMock(stdout=token_output),
185+
]
175186

176187
result = provider.get_token()
177188

178189
assert isinstance(result, AccessTokenResponse)
179190
assert result.access_token == "cli_access_token"
180191
assert result.instance_url == "https://cli.salesforce.com"
181192

193+
# Verify both commands were called
194+
assert mock_run.call_count == 2
195+
display_call = mock_run.call_args_list[0]
196+
token_call = mock_run.call_args_list[1]
197+
assert "org" in display_call[0][0] and "display" in display_call[0][0]
198+
assert "show-access-token" in token_call[0][0]
199+
182200
def test_sf_command_not_found(self):
183201
"""Test that FileNotFoundError is wrapped in RuntimeError."""
184202
provider = SFCLITokenProvider("test_org")

0 commit comments

Comments
 (0)