5555from office365 .outlook .calendar .rooms .list import RoomList
5656from office365 .planner .planner import Planner
5757from office365 .reports .root import ReportRoot
58- from office365 .runtime .auth .token_response import TokenResponse
58+ from office365 .runtime .auth .entra . authentication_context import AuthenticationContext
5959from office365 .runtime .client_runtime_context import ClientRuntimeContext
6060from office365 .runtime .http .http_method import HttpMethod
6161from office365 .runtime .http .request_options import RequestOptions
7777class GraphClient (ClientRuntimeContext ):
7878 """Graph Service client"""
7979
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
8282 super (GraphClient , self ).__init__ ()
8383 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
8590
8691 @staticmethod
8792 def with_certificate (
@@ -98,27 +103,10 @@ def with_certificate(
98103 :param Any token_cache: Default cache is in memory only,
99104 Refer https://msal-python.readthedocs.io/en/latest/#msal.SerializableTokenCache
100105 """
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 )
122110
123111 @staticmethod
124112 def with_client_secret (
@@ -135,22 +123,11 @@ def with_client_secret(
135123 :param Any token_cache: Default cache is in memory only,
136124 Refer https://msal-python.readthedocs.io/en/latest/#msal.SerializableTokenCache
137125 """
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- )
149126
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 )
154131
155132 @staticmethod
156133 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):
164141 :param str username: Typically a UPN in the form of an email address.
165142 :param list[str] or None scopes: Scopes requested to access an API
166143 """
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 )
193148
194149 @staticmethod
195150 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
203158 :param str password: The password.
204159 :param list[str] or None scopes: Scopes requested to access an API
205160 """
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 )
231165
232166 def execute_batch (self , items_per_batch = 20 , success_callback = None ):
233167 """Constructs and submit a batch request
@@ -238,7 +172,7 @@ def execute_batch(self, items_per_batch=20, success_callback=None):
238172 :param (List[ClientObject|ClientResult])-> None success_callback: A success callback
239173 """
240174 batch_request = ODataV4BatchRequest (V4JsonFormat ())
241- batch_request .beforeExecute += self ._authenticate_request
175+ batch_request .beforeExecute += self ._auth_context . authenticate_request
242176 while self .has_pending_request :
243177 qry = self ._get_next_query (items_per_batch )
244178 batch_request .execute_query (qry )
@@ -250,7 +184,9 @@ def pending_request(self):
250184 # type: () -> GraphRequest
251185 if self ._pending_request is None :
252186 self ._pending_request = GraphRequest ()
253- self ._pending_request .beforeExecute += self ._authenticate_request
187+ self ._pending_request .beforeExecute += (
188+ self ._auth_context .authenticate_request
189+ )
254190 self ._pending_request .beforeExecute += self ._build_specific_query
255191 return self ._pending_request
256192
@@ -266,13 +202,6 @@ def _build_specific_query(self, request):
266202 elif isinstance (self .current_query , DeleteEntityQuery ):
267203 request .method = HttpMethod .Delete
268204
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-
276205 @property
277206 def admin (self ):
278207 """A container for administrator functionality for SharePoint and OneDrive."""
0 commit comments