Skip to content

Commit 98bb6e9

Browse files
authored
EnvironmentCredential correctly initializes UsernamePasswordCredential (#11127)
1 parent c1a245d commit 98bb6e9

File tree

4 files changed

+141
-51
lines changed

4 files changed

+141
-51
lines changed

sdk/identity/azure-identity/azure/identity/_credentials/environment.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ def __init__(self, **kwargs):
7171
client_id=os.environ[EnvironmentVariables.AZURE_CLIENT_ID],
7272
username=os.environ[EnvironmentVariables.AZURE_USERNAME],
7373
password=os.environ[EnvironmentVariables.AZURE_PASSWORD],
74-
tenant=os.environ.get(EnvironmentVariables.AZURE_TENANT_ID), # optional for username/password auth
74+
tenant_id=os.environ.get(EnvironmentVariables.AZURE_TENANT_ID), # optional for username/password auth
7575
**kwargs
7676
)
7777

sdk/identity/azure-identity/tests/test_environment_credential.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,93 @@ def test_passes_authority_argument(credential_name, environment_variables):
5353
assert mock_credential.call_count == 1
5454
_, kwargs = mock_credential.call_args
5555
assert kwargs["authority"] == authority
56+
57+
58+
def test_client_secret_configuration():
59+
"""the credential should pass expected values and any keyword arguments to its inner credential"""
60+
61+
client_id = "client-id"
62+
client_secret = "..."
63+
tenant_id = "tenant_id"
64+
bar = "bar"
65+
66+
environment = {
67+
EnvironmentVariables.AZURE_CLIENT_ID: client_id,
68+
EnvironmentVariables.AZURE_CLIENT_SECRET: client_secret,
69+
EnvironmentVariables.AZURE_TENANT_ID: tenant_id,
70+
}
71+
with mock.patch(EnvironmentCredential.__module__ + ".ClientSecretCredential") as mock_credential:
72+
with mock.patch.dict("os.environ", environment, clear=True):
73+
EnvironmentCredential(foo=bar)
74+
75+
assert mock_credential.call_count == 1
76+
_, kwargs = mock_credential.call_args
77+
assert kwargs["client_id"] == client_id
78+
assert kwargs["client_secret"] == client_secret
79+
assert kwargs["tenant_id"] == tenant_id
80+
assert kwargs["foo"] == bar
81+
82+
83+
def test_certificate_configuration():
84+
"""the credential should pass expected values and any keyword arguments to its inner credential"""
85+
86+
client_id = "client-id"
87+
certificate_path = "..."
88+
tenant_id = "tenant_id"
89+
bar = "bar"
90+
91+
environment = {
92+
EnvironmentVariables.AZURE_CLIENT_ID: client_id,
93+
EnvironmentVariables.AZURE_CLIENT_CERTIFICATE_PATH: certificate_path,
94+
EnvironmentVariables.AZURE_TENANT_ID: tenant_id,
95+
}
96+
with mock.patch(EnvironmentCredential.__module__ + ".CertificateCredential") as mock_credential:
97+
with mock.patch.dict("os.environ", environment, clear=True):
98+
EnvironmentCredential(foo=bar)
99+
100+
assert mock_credential.call_count == 1
101+
_, kwargs = mock_credential.call_args
102+
assert kwargs["client_id"] == client_id
103+
assert kwargs["certificate_path"] == certificate_path
104+
assert kwargs["tenant_id"] == tenant_id
105+
assert kwargs["foo"] == bar
106+
107+
108+
def test_username_password_configuration():
109+
"""the credential should pass expected values and any keyword arguments to its inner credential"""
110+
111+
client_id = "client-id"
112+
username = "[email protected]"
113+
password = "password"
114+
bar = "bar"
115+
116+
environment = {
117+
EnvironmentVariables.AZURE_CLIENT_ID: client_id,
118+
EnvironmentVariables.AZURE_USERNAME: username,
119+
EnvironmentVariables.AZURE_PASSWORD: password,
120+
}
121+
with mock.patch(EnvironmentCredential.__module__ + ".UsernamePasswordCredential") as mock_credential:
122+
with mock.patch.dict("os.environ", environment, clear=True):
123+
EnvironmentCredential(foo=bar)
124+
125+
assert mock_credential.call_count == 1
126+
_, kwargs = mock_credential.call_args
127+
assert kwargs["client_id"] == client_id
128+
assert kwargs["username"] == username
129+
assert kwargs["password"] == password
130+
assert kwargs["foo"] == bar
131+
132+
# optional tenant id should be used when set
133+
tenant_id = "tenant-id"
134+
environment = dict(environment, **{EnvironmentVariables.AZURE_TENANT_ID: tenant_id})
135+
with mock.patch(EnvironmentCredential.__module__ + ".UsernamePasswordCredential") as mock_credential:
136+
with mock.patch.dict("os.environ", environment, clear=True):
137+
EnvironmentCredential(foo=bar)
138+
139+
assert mock_credential.call_count == 1
140+
_, kwargs = mock_credential.call_args
141+
assert kwargs["client_id"] == client_id
142+
assert kwargs["username"] == username
143+
assert kwargs["password"] == password
144+
assert kwargs["tenant_id"] == tenant_id
145+
assert kwargs["foo"] == bar

sdk/identity/azure-identity/tests/test_environment_credential_async.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,53 @@ def test_passes_authority_argument(credential_name, environment_variables):
4747
assert mock_credential.call_count == 1
4848
_, kwargs = mock_credential.call_args
4949
assert kwargs["authority"] == authority
50+
51+
52+
def test_client_secret_configuration():
53+
"""the credential should pass expected values and any keyword arguments to its inner credential"""
54+
55+
client_id = "client-id"
56+
client_secret = "..."
57+
tenant_id = "tenant_id"
58+
bar = "bar"
59+
60+
environment = {
61+
EnvironmentVariables.AZURE_CLIENT_ID: client_id,
62+
EnvironmentVariables.AZURE_CLIENT_SECRET: client_secret,
63+
EnvironmentVariables.AZURE_TENANT_ID: tenant_id,
64+
}
65+
with mock.patch(EnvironmentCredential.__module__ + ".ClientSecretCredential") as mock_credential:
66+
with mock.patch.dict("os.environ", environment, clear=True):
67+
EnvironmentCredential(foo=bar)
68+
69+
assert mock_credential.call_count == 1
70+
_, kwargs = mock_credential.call_args
71+
assert kwargs["client_id"] == client_id
72+
assert kwargs["client_secret"] == client_secret
73+
assert kwargs["tenant_id"] == tenant_id
74+
assert kwargs["foo"] == bar
75+
76+
77+
def test_certificate_configuration():
78+
"""the credential should pass expected values and any keyword arguments to its inner credential"""
79+
80+
client_id = "client-id"
81+
certificate_path = "..."
82+
tenant_id = "tenant_id"
83+
bar = "bar"
84+
85+
environment = {
86+
EnvironmentVariables.AZURE_CLIENT_ID: client_id,
87+
EnvironmentVariables.AZURE_CLIENT_CERTIFICATE_PATH: certificate_path,
88+
EnvironmentVariables.AZURE_TENANT_ID: tenant_id,
89+
}
90+
with mock.patch(EnvironmentCredential.__module__ + ".CertificateCredential") as mock_credential:
91+
with mock.patch.dict("os.environ", environment, clear=True):
92+
EnvironmentCredential(foo=bar)
93+
94+
assert mock_credential.call_count == 1
95+
_, kwargs = mock_credential.call_args
96+
assert kwargs["client_id"] == client_id
97+
assert kwargs["certificate_path"] == certificate_path
98+
assert kwargs["tenant_id"] == tenant_id
99+
assert kwargs["foo"] == bar

sdk/identity/azure-identity/tests/test_identity.py

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -244,53 +244,3 @@ def test_default_credential_shared_cache_use(mock_credential):
244244
assert mock_credential.call_count == 1
245245
assert mock_credential.supported.call_count == 1
246246
mock_credential.supported.reset_mock()
247-
248-
249-
def test_username_password_environment_credential():
250-
client_id = "fake-client-id"
251-
username = "[email protected]"
252-
password = "password"
253-
expected_token = "***"
254-
255-
create_transport = functools.partial(
256-
validating_transport,
257-
requests=[Request()] * 3, # not validating requests because they're formed by MSAL
258-
responses=[
259-
# tenant discovery
260-
mock_response(json_payload={"authorization_endpoint": "https://a/b", "token_endpoint": "https://a/b"}),
261-
# user realm discovery, interests MSAL only when the response body contains account_type == "Federated"
262-
mock_response(json_payload={}),
263-
# token request
264-
mock_response(
265-
json_payload={
266-
"access_token": expected_token,
267-
"expires_in": 42,
268-
"token_type": "Bearer",
269-
"ext_expires_in": 42,
270-
}
271-
),
272-
],
273-
)
274-
275-
environment = {
276-
EnvironmentVariables.AZURE_CLIENT_ID: client_id,
277-
EnvironmentVariables.AZURE_USERNAME: username,
278-
EnvironmentVariables.AZURE_PASSWORD: password,
279-
}
280-
with patch("os.environ", environment):
281-
token = EnvironmentCredential(transport=create_transport()).get_token("scope")
282-
283-
# not validating expires_on because doing so requires monkeypatching time, and this is tested elsewhere
284-
assert token.token == expected_token
285-
286-
# now with a tenant id
287-
environment = {
288-
EnvironmentVariables.AZURE_CLIENT_ID: client_id,
289-
EnvironmentVariables.AZURE_USERNAME: username,
290-
EnvironmentVariables.AZURE_PASSWORD: password,
291-
EnvironmentVariables.AZURE_TENANT_ID: "tenant_id",
292-
}
293-
with patch("os.environ", environment):
294-
token = EnvironmentCredential(transport=create_transport()).get_token("scope")
295-
296-
assert token.token == expected_token

0 commit comments

Comments
 (0)