55
55
from office365 .outlook .calendar .rooms .list import RoomList
56
56
from office365 .planner .planner import Planner
57
57
from office365 .reports .root import ReportRoot
58
- from office365 .runtime .auth .token_response import TokenResponse
58
+ from office365 .runtime .auth .entra . authentication_context import AuthenticationContext
59
59
from office365 .runtime .client_runtime_context import ClientRuntimeContext
60
60
from office365 .runtime .http .http_method import HttpMethod
61
61
from office365 .runtime .http .request_options import RequestOptions
77
77
class GraphClient (ClientRuntimeContext ):
78
78
"""Graph Service client"""
79
79
80
- def __init__ (self , acquire_token_callback ):
81
- # type: (Callable[[], dict]) -> None
80
+ def __init__ (self , acquire_token_callback = None , auth_context = None ):
81
+ # type: (Callable[[], dict], AuthenticationContext ) -> None
82
82
super (GraphClient , self ).__init__ ()
83
83
self ._pending_request = None
84
- self ._acquire_token_callback = acquire_token_callback
84
+ if acquire_token_callback is not None :
85
+ self ._auth_context = AuthenticationContext ().with_access_token (
86
+ acquire_token_callback
87
+ )
88
+ else :
89
+ self ._auth_context = auth_context
85
90
86
91
@staticmethod
87
92
def with_certificate (
@@ -98,27 +103,10 @@ def with_certificate(
98
103
:param Any token_cache: Default cache is in memory only,
99
104
Refer https://msal-python.readthedocs.io/en/latest/#msal.SerializableTokenCache
100
105
"""
101
- if scopes is None :
102
- scopes = ["https://graph.microsoft.com/.default" ]
103
- authority_url = "https://login.microsoftonline.com/{0}" .format (tenant )
104
- import msal
105
-
106
- app = msal .ConfidentialClientApplication (
107
- client_id ,
108
- authority = authority_url ,
109
- client_credential = {
110
- "thumbprint" : thumbprint ,
111
- "private_key" : private_key ,
112
- },
113
- token_cache = token_cache , # Default cache is in memory only.
114
- # You can learn how to use SerializableTokenCache from
115
- # https://msal-python.readthedocs.io/en/latest/#msal.SerializableTokenCache
116
- )
117
-
118
- def _acquire_token ():
119
- return app .acquire_token_for_client (scopes = scopes )
120
-
121
- return GraphClient (_acquire_token )
106
+ auth_ctx = AuthenticationContext (
107
+ tenant = tenant , scopes = scopes , token_cache = token_cache
108
+ ).with_certificate (client_id , thumbprint , private_key )
109
+ return GraphClient (auth_context = auth_ctx )
122
110
123
111
@staticmethod
124
112
def with_client_secret (
@@ -135,22 +123,11 @@ def with_client_secret(
135
123
:param Any token_cache: Default cache is in memory only,
136
124
Refer https://msal-python.readthedocs.io/en/latest/#msal.SerializableTokenCache
137
125
"""
138
- if scopes is None :
139
- scopes = ["https://graph.microsoft.com/.default" ]
140
- authority_url = "https://login.microsoftonline.com/{0}" .format (tenant )
141
- import msal
142
-
143
- app = msal .ConfidentialClientApplication (
144
- client_id ,
145
- authority = authority_url ,
146
- client_credential = client_secret ,
147
- token_cache = token_cache ,
148
- )
149
126
150
- def _acquire_token ():
151
- return app . acquire_token_for_client ( scopes = scopes )
152
-
153
- return GraphClient (_acquire_token )
127
+ auth_ctx = AuthenticationContext (
128
+ tenant = tenant , scopes = scopes , token_cache = token_cache
129
+ ). with_client_secret ( client_id , client_secret )
130
+ return GraphClient (auth_context = auth_ctx )
154
131
155
132
@staticmethod
156
133
def with_token_interactive (tenant , client_id , username = None , scopes = None ):
@@ -164,32 +141,10 @@ def with_token_interactive(tenant, client_id, username=None, scopes=None):
164
141
:param str username: Typically a UPN in the form of an email address.
165
142
:param list[str] or None scopes: Scopes requested to access an API
166
143
"""
167
- if scopes is None :
168
- scopes = ["https://graph.microsoft.com/.default" ]
169
- authority_url = "https://login.microsoftonline.com/{0}" .format (tenant )
170
- import msal
171
-
172
- app = msal .PublicClientApplication (client_id , authority = authority_url )
173
-
174
- def _acquire_token ():
175
- # The pattern to acquire a token looks like this.
176
- result = None
177
-
178
- # Firstly, check the cache to see if this end user has signed in before
179
- accounts = app .get_accounts (username = username )
180
- if accounts :
181
- chosen = accounts [0 ] # Assuming the end user chose this one to proceed
182
- # Now let's try to find a token in cache for this account
183
- result = app .acquire_token_silent (scopes , account = chosen )
184
-
185
- if not result :
186
- result = app .acquire_token_interactive (
187
- scopes ,
188
- login_hint = username ,
189
- )
190
- return result
191
-
192
- return GraphClient (_acquire_token )
144
+ auth_ctx = AuthenticationContext (
145
+ tenant = tenant , scopes = scopes
146
+ ).with_token_interactive (client_id , username )
147
+ return GraphClient (auth_context = auth_ctx )
193
148
194
149
@staticmethod
195
150
def with_username_and_password (tenant , client_id , username , password , scopes = None ):
@@ -203,31 +158,10 @@ def with_username_and_password(tenant, client_id, username, password, scopes=Non
203
158
:param str password: The password.
204
159
:param list[str] or None scopes: Scopes requested to access an API
205
160
"""
206
- if scopes is None :
207
- scopes = ["https://graph.microsoft.com/.default" ]
208
- authority_url = "https://login.microsoftonline.com/{0}" .format (tenant )
209
- import msal
210
-
211
- app = msal .PublicClientApplication (
212
- authority = authority_url ,
213
- client_id = client_id ,
214
- )
215
-
216
- def _acquire_token ():
217
- result = None
218
- accounts = app .get_accounts (username = username )
219
- if accounts :
220
- result = app .acquire_token_silent (scopes , account = accounts [0 ])
221
-
222
- if not result :
223
- result = app .acquire_token_by_username_password (
224
- username = username ,
225
- password = password ,
226
- scopes = scopes ,
227
- )
228
- return result
229
-
230
- return GraphClient (_acquire_token )
161
+ auth_ctx = AuthenticationContext (
162
+ tenant = tenant , scopes = scopes
163
+ ).with_username_and_password (client_id , username , password )
164
+ return GraphClient (auth_context = auth_ctx )
231
165
232
166
def execute_batch (self , items_per_batch = 20 , success_callback = None ):
233
167
"""Constructs and submit a batch request
@@ -238,7 +172,7 @@ def execute_batch(self, items_per_batch=20, success_callback=None):
238
172
:param (List[ClientObject|ClientResult])-> None success_callback: A success callback
239
173
"""
240
174
batch_request = ODataV4BatchRequest (V4JsonFormat ())
241
- batch_request .beforeExecute += self ._authenticate_request
175
+ batch_request .beforeExecute += self ._auth_context . authenticate_request
242
176
while self .has_pending_request :
243
177
qry = self ._get_next_query (items_per_batch )
244
178
batch_request .execute_query (qry )
@@ -250,7 +184,9 @@ def pending_request(self):
250
184
# type: () -> GraphRequest
251
185
if self ._pending_request is None :
252
186
self ._pending_request = GraphRequest ()
253
- self ._pending_request .beforeExecute += self ._authenticate_request
187
+ self ._pending_request .beforeExecute += (
188
+ self ._auth_context .authenticate_request
189
+ )
254
190
self ._pending_request .beforeExecute += self ._build_specific_query
255
191
return self ._pending_request
256
192
@@ -266,13 +202,6 @@ def _build_specific_query(self, request):
266
202
elif isinstance (self .current_query , DeleteEntityQuery ):
267
203
request .method = HttpMethod .Delete
268
204
269
- def _authenticate_request (self , request ):
270
- # type: (RequestOptions) -> None
271
- """Authenticate request."""
272
- token_json = self ._acquire_token_callback ()
273
- token = TokenResponse .from_json (token_json )
274
- request .ensure_header ("Authorization" , "Bearer {0}" .format (token .accessToken ))
275
-
276
205
@property
277
206
def admin (self ):
278
207
"""A container for administrator functionality for SharePoint and OneDrive."""
0 commit comments