Skip to content

Commit d85a11b

Browse files
authored
Merge pull request #217 from AzureAD/release-1.4.1
MSAL Python 1.4.1
2 parents 814d710 + 1879347 commit d85a11b

File tree

5 files changed

+17
-44
lines changed

5 files changed

+17
-44
lines changed

msal/application.py

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222

2323
# The __init__.py will import this. Not the other way around.
24-
__version__ = "1.4.0"
24+
__version__ = "1.4.1"
2525

2626
logger = logging.getLogger(__name__)
2727

@@ -198,9 +198,8 @@ def __init__(
198198
authority or "https://login.microsoftonline.com/common/",
199199
self.http_client, validate_authority=validate_authority)
200200
# Here the self.authority is not the same type as authority in input
201-
self.client = None
202201
self.token_cache = token_cache or TokenCache()
203-
self._client_credential = client_credential
202+
self.client = self._build_client(client_credential, self.authority)
204203
self.authority_groups = None
205204

206205
def _build_client(self, client_credential, authority):
@@ -249,12 +248,6 @@ def _build_client(self, client_credential, authority):
249248
on_removing_rt=self.token_cache.remove_rt,
250249
on_updating_rt=self.token_cache.update_rt)
251250

252-
def _get_client(self):
253-
if not self.client:
254-
self.authority.initialize()
255-
self.client = self._build_client(self._client_credential, self.authority)
256-
return self.client
257-
258251
def get_authorization_request_url(
259252
self,
260253
scopes, # type: list[str]
@@ -314,7 +307,6 @@ def get_authorization_request_url(
314307
authority,
315308
self.http_client
316309
) if authority else self.authority
317-
the_authority.initialize()
318310

319311
client = Client(
320312
{"authorization_endpoint": the_authority.authorization_endpoint},
@@ -375,7 +367,7 @@ def acquire_token_by_authorization_code(
375367
# really empty.
376368
assert isinstance(scopes, list), "Invalid parameter type"
377369
self._validate_ssh_cert_input_data(kwargs.get("data", {}))
378-
return self._get_client().obtain_token_by_authorization_code(
370+
return self.client.obtain_token_by_authorization_code(
379371
code, redirect_uri=redirect_uri,
380372
scope=decorate_scope(scopes, self.client_id),
381373
headers={
@@ -399,7 +391,6 @@ def get_accounts(self, username=None):
399391
Your app can choose to display those information to end user,
400392
and allow user to choose one of his/her accounts to proceed.
401393
"""
402-
self.authority.initialize()
403394
accounts = self._find_msal_accounts(environment=self.authority.instance)
404395
if not accounts: # Now try other aliases of this authority instance
405396
for alias in self._get_authority_aliases(self.authority.instance):
@@ -552,7 +543,6 @@ def acquire_token_silent_with_error(
552543
# authority,
553544
# self.http_client,
554545
# ) if authority else self.authority
555-
self.authority.initialize()
556546
result = self._acquire_token_silent_from_cache_and_possibly_refresh_it(
557547
scopes, account, self.authority, force_refresh=force_refresh,
558548
correlation_id=correlation_id,
@@ -565,7 +555,6 @@ def acquire_token_silent_with_error(
565555
"https://" + alias + "/" + self.authority.tenant,
566556
self.http_client,
567557
validate_authority=False)
568-
the_authority.initialize()
569558
result = self._acquire_token_silent_from_cache_and_possibly_refresh_it(
570559
scopes, account, the_authority, force_refresh=force_refresh,
571560
correlation_id=correlation_id,
@@ -735,7 +724,7 @@ def acquire_token_by_refresh_token(self, refresh_token, scopes):
735724
* A dict contains "error" and some other keys, when error happened.
736725
* A dict contains no "error" key means migration was successful.
737726
"""
738-
return self._get_client().obtain_token_by_refresh_token(
727+
return self.client.obtain_token_by_refresh_token(
739728
refresh_token,
740729
scope=decorate_scope(scopes, self.client_id),
741730
rt_getter=lambda rt: rt,
@@ -766,7 +755,7 @@ def initiate_device_flow(self, scopes=None, **kwargs):
766755
- an error response would contain some other readable key/value pairs.
767756
"""
768757
correlation_id = _get_new_correlation_id()
769-
flow = self._get_client().initiate_device_flow(
758+
flow = self.client.initiate_device_flow(
770759
scope=decorate_scope(scopes or [], self.client_id),
771760
headers={
772761
CLIENT_REQUEST_ID: correlation_id,
@@ -790,7 +779,7 @@ def acquire_token_by_device_flow(self, flow, **kwargs):
790779
- A successful response would contain "access_token" key,
791780
- an error response would contain "error" and usually "error_description".
792781
"""
793-
return self._get_client().obtain_token_by_device_flow(
782+
return self.client.obtain_token_by_device_flow(
794783
flow,
795784
data=dict(kwargs.pop("data", {}), code=flow["device_code"]),
796785
# 2018-10-4 Hack:
@@ -827,15 +816,14 @@ def acquire_token_by_username_password(
827816
CLIENT_CURRENT_TELEMETRY: _build_current_telemetry_request_header(
828817
self.ACQUIRE_TOKEN_BY_USERNAME_PASSWORD_ID),
829818
}
830-
self.authority.initialize()
831819
if not self.authority.is_adfs:
832820
user_realm_result = self.authority.user_realm_discovery(
833821
username, correlation_id=headers[CLIENT_REQUEST_ID])
834822
if user_realm_result.get("account_type") == "Federated":
835823
return self._acquire_token_by_username_password_federated(
836824
user_realm_result, username, password, scopes=scopes,
837825
headers=headers, **kwargs)
838-
return self._get_client().obtain_token_by_username_password(
826+
return self.client.obtain_token_by_username_password(
839827
username, password, scope=scopes,
840828
headers=headers,
841829
**kwargs)
@@ -864,16 +852,16 @@ def _acquire_token_by_username_password_federated(
864852
GRANT_TYPE_SAML1_1 = 'urn:ietf:params:oauth:grant-type:saml1_1-bearer'
865853
grant_type = {
866854
SAML_TOKEN_TYPE_V1: GRANT_TYPE_SAML1_1,
867-
SAML_TOKEN_TYPE_V2: Client.GRANT_TYPE_SAML2,
855+
SAML_TOKEN_TYPE_V2: self.client.GRANT_TYPE_SAML2,
868856
WSS_SAML_TOKEN_PROFILE_V1_1: GRANT_TYPE_SAML1_1,
869-
WSS_SAML_TOKEN_PROFILE_V2: Client.GRANT_TYPE_SAML2
857+
WSS_SAML_TOKEN_PROFILE_V2: self.client.GRANT_TYPE_SAML2
870858
}.get(wstrust_result.get("type"))
871859
if not grant_type:
872860
raise RuntimeError(
873861
"RSTR returned unknown token type: %s", wstrust_result.get("type"))
874-
Client.grant_assertion_encoders.setdefault( # Register a non-standard type
875-
grant_type, Client.encode_saml_assertion)
876-
return self._get_client().obtain_token_by_assertion(
862+
self.client.grant_assertion_encoders.setdefault( # Register a non-standard type
863+
grant_type, self.client.encode_saml_assertion)
864+
return self.client.obtain_token_by_assertion(
877865
wstrust_result["token"], grant_type, scope=scopes, **kwargs)
878866

879867

@@ -891,7 +879,7 @@ def acquire_token_for_client(self, scopes, **kwargs):
891879
- an error response would contain "error" and usually "error_description".
892880
"""
893881
# TBD: force_refresh behavior
894-
return self._get_client().obtain_token_for_client(
882+
return self.client.obtain_token_for_client(
895883
scope=scopes, # This grant flow requires no scope decoration
896884
headers={
897885
CLIENT_REQUEST_ID: _get_new_correlation_id(),
@@ -923,9 +911,9 @@ def acquire_token_on_behalf_of(self, user_assertion, scopes, **kwargs):
923911
"""
924912
# The implementation is NOT based on Token Exchange
925913
# https://tools.ietf.org/html/draft-ietf-oauth-token-exchange-16
926-
return self._get_client().obtain_token_by_assertion( # bases on assertion RFC 7521
914+
return self.client.obtain_token_by_assertion( # bases on assertion RFC 7521
927915
user_assertion,
928-
Client.GRANT_TYPE_JWT, # IDTs and AAD ATs are all JWTs
916+
self.client.GRANT_TYPE_JWT, # IDTs and AAD ATs are all JWTs
929917
scope=decorate_scope(scopes, self.client_id), # Decoration is used for:
930918
# 1. Explicitly requesting an RT, without relying on AAD default
931919
# behavior, even though it currently still issues an RT.

msal/authority.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,6 @@ def __init__(self, authority_url, http_client, validate_authority=True):
5252
This parameter only controls whether an instance discovery will be
5353
performed.
5454
"""
55-
self._http_client = http_client
56-
self._authority_url = authority_url
57-
self._validate_authority = validate_authority
58-
self._is_initialized = False
59-
60-
def initialize(self):
61-
if not self._is_initialized:
62-
self.__initialize(self._authority_url, self._http_client, self._validate_authority)
63-
self._is_initialized = True
64-
65-
def __initialize(self, authority_url, http_client, validate_authority):
6655
self._http_client = http_client
6756
authority, self.instance, tenant = canonicalize(authority_url)
6857
parts = authority.path.split('/')

tests/test_application.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ def setUp(self):
104104
self.authority_url = "https://login.microsoftonline.com/common"
105105
self.authority = msal.authority.Authority(
106106
self.authority_url, MinimalHttpClient())
107-
self.authority.initialize()
108107
self.scopes = ["s1", "s2"]
109108
self.uid = "my_uid"
110109
self.utid = "my_utid"

tests/test_authority.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ def test_wellknown_host_and_tenant(self):
1313
for host in WELL_KNOWN_AUTHORITY_HOSTS:
1414
a = Authority(
1515
'https://{}/common'.format(host), MinimalHttpClient())
16-
a.initialize()
1716
self.assertEqual(
1817
a.authorization_endpoint,
1918
'https://%s/common/oauth2/v2.0/authorize' % host)
@@ -35,7 +34,7 @@ def test_unknown_host_wont_pass_instance_discovery(self):
3534
_assert = getattr(self, "assertRaisesRegex", self.assertRaisesRegexp) # Hack
3635
with _assert(ValueError, "invalid_instance"):
3736
Authority('https://example.com/tenant_doesnt_matter_in_this_case',
38-
MinimalHttpClient()).initialize()
37+
MinimalHttpClient())
3938

4039
def test_invalid_host_skipping_validation_can_be_turned_off(self):
4140
try:
@@ -86,7 +85,7 @@ def test_memorize(self):
8685
authority = "https://login.microsoftonline.com/common"
8786
self.assertNotIn(authority, Authority._domains_without_user_realm_discovery)
8887
a = Authority(authority, MinimalHttpClient(), validate_authority=False)
89-
a.initialize()
88+
9089
# We now pretend this authority supports no User Realm Discovery
9190
class MockResponse(object):
9291
status_code = 404

tests/test_authority_patch.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ def test_authority_honors_a_patched_requests(self):
1515
# First, we test that the original, unmodified authority is working
1616
a = msal.authority.Authority(
1717
"https://login.microsoftonline.com/common", MinimalHttpClient())
18-
a.initialize()
1918
self.assertEqual(
2019
a.authorization_endpoint,
2120
'https://login.microsoftonline.com/common/oauth2/v2.0/authorize')
@@ -28,7 +27,6 @@ def test_authority_honors_a_patched_requests(self):
2827
with self.assertRaises(RuntimeError):
2928
a = msal.authority.Authority(
3029
"https://login.microsoftonline.com/common", MinimalHttpClient())
31-
a.initialize()
3230
finally: # Tricky:
3331
# Unpatch is necessary otherwise other test cases would be affected
3432
msal.authority.requests = original

0 commit comments

Comments
 (0)