Office365-REST-Python-Client 2.5.14__py3-none-any.whl → 2.6.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. {Office365_REST_Python_Client-2.5.14.dist-info → Office365_REST_Python_Client-2.6.1.dist-info}/METADATA +21 -30
  2. {Office365_REST_Python_Client-2.5.14.dist-info → Office365_REST_Python_Client-2.6.1.dist-info}/RECORD +210 -112
  3. office365/admin/__init__.py +0 -0
  4. office365/admin/admin.py +69 -0
  5. office365/admin/microsoft365_apps.py +5 -0
  6. office365/admin/people_settings.py +5 -0
  7. office365/admin/report_settings.py +5 -0
  8. office365/{onedrive → admin}/sharepoint.py +1 -1
  9. office365/azure_env.py +60 -0
  10. office365/directory/applications/app_ids.py +6 -0
  11. office365/directory/authentication/authentication.py +16 -0
  12. office365/directory/authentication/method_target.py +2 -1
  13. office365/directory/authentication/methods/microsoft_authenticator.py +6 -0
  14. office365/directory/authentication/methods/root.py +11 -0
  15. office365/directory/authentication/methods/sms.py +9 -0
  16. office365/directory/certificates/self_signed.py +31 -2
  17. office365/directory/identities/conditional_access_root.py +14 -0
  18. office365/directory/identitygovernance/privilegedaccess/approval.py +8 -0
  19. office365/directory/identitygovernance/privilegedaccess/group.py +30 -0
  20. office365/directory/identitygovernance/privilegedaccess/group_assignment_schedule_instance.py +7 -0
  21. office365/directory/identitygovernance/privilegedaccess/unified_role_assignment_schedule_request.py +7 -0
  22. office365/directory/identitygovernance/userconsent/request_collection.py +10 -0
  23. office365/directory/identitygovernance/workflow/__init__.py +0 -0
  24. office365/directory/identitygovernance/workflow/base.py +5 -0
  25. office365/directory/policies/cross_tenant_access.py +13 -0
  26. office365/directory/policies/feature_rollout.py +16 -0
  27. office365/directory/policies/root.py +39 -23
  28. office365/directory/policies/template.py +5 -0
  29. office365/directory/protection/threatassessment/email_file_request.py +20 -0
  30. office365/directory/protection/threatassessment/request.py +25 -0
  31. office365/directory/rolemanagement/application.py +15 -0
  32. office365/directory/rolemanagement/resource_action.py +8 -4
  33. office365/directory/rolemanagement/role_permission.py +3 -3
  34. office365/directory/security/alerts/collection.py +49 -0
  35. office365/directory/security/scorecontrol/__init__.py +0 -0
  36. office365/directory/security/scorecontrol/profile.py +6 -0
  37. office365/directory/security/security.py +17 -4
  38. office365/directory/serviceprincipals/service_principal.py +36 -28
  39. office365/directory/tenantinformation/__init__.py +0 -0
  40. office365/directory/tenantinformation/multi_organization.py +11 -0
  41. office365/directory/tenantinformation/relationship.py +61 -0
  42. office365/directory/users/insights_settings.py +5 -0
  43. office365/graph_client.py +52 -132
  44. office365/graph_request.py +78 -19
  45. office365/intune/servicecommunications/health/health.py +1 -1
  46. office365/intune/servicecommunications/issues/issue.py +2 -2
  47. office365/onedrive/columns/definition.py +1 -1
  48. office365/onedrive/contenttypes/content_type.py +1 -1
  49. office365/onedrive/driveitems/driveItem.py +13 -1
  50. office365/onedrive/drives/drive.py +1 -1
  51. office365/onedrive/filestorage/__init__.py +0 -0
  52. office365/onedrive/filestorage/container.py +7 -0
  53. office365/onedrive/filestorage/file_storage.py +20 -0
  54. office365/onedrive/listitems/field_value_set.py +1 -1
  55. office365/onedrive/listitems/list_item.py +1 -1
  56. office365/onedrive/lists/list.py +1 -1
  57. office365/onedrive/recyclebin/__init__.py +0 -0
  58. office365/onedrive/recyclebin/item.py +6 -0
  59. office365/onedrive/recyclebin/recyclebin.py +29 -0
  60. office365/onedrive/recyclebin/settings.py +13 -0
  61. office365/onedrive/shares/drive_item.py +1 -1
  62. office365/onedrive/sitepages/base.py +1 -1
  63. office365/onedrive/sitepages/canvas_layout.py +2 -2
  64. office365/onedrive/sitepages/sections/__init__.py +0 -0
  65. office365/onedrive/sitepages/{horizontal_section.py → sections/horizontal.py} +1 -1
  66. office365/onedrive/sitepages/webparts/data.py +5 -0
  67. office365/onedrive/sitepages/webparts/position.py +5 -0
  68. office365/onedrive/sitepages/webparts/standard.py +9 -0
  69. office365/onedrive/sitepages/webparts/web_part.py +12 -0
  70. office365/onedrive/sites/site.py +1 -1
  71. office365/onedrive/storage/storage.py +10 -0
  72. office365/onedrive/workbooks/charts/axes.py +41 -1
  73. office365/onedrive/workbooks/charts/axis.py +5 -0
  74. office365/onedrive/workbooks/charts/chart.py +64 -5
  75. office365/onedrive/workbooks/charts/fill.py +5 -0
  76. office365/onedrive/workbooks/charts/font.py +5 -0
  77. office365/onedrive/workbooks/charts/legend/__init__.py +0 -0
  78. office365/onedrive/workbooks/charts/legend/format.py +5 -0
  79. office365/onedrive/workbooks/charts/legend/legend.py +26 -0
  80. office365/onedrive/workbooks/charts/point.py +5 -0
  81. office365/onedrive/workbooks/charts/series/__init__.py +0 -0
  82. office365/onedrive/workbooks/charts/series/format.py +5 -0
  83. office365/onedrive/workbooks/charts/series/series.py +31 -0
  84. office365/onedrive/workbooks/charts/title.py +5 -0
  85. office365/onedrive/workbooks/filter.py +10 -0
  86. office365/onedrive/workbooks/filter_criteria.py +3 -3
  87. office365/onedrive/workbooks/ranges/fill.py +11 -1
  88. office365/onedrive/workbooks/ranges/range.py +26 -0
  89. office365/onedrive/workbooks/ranges/view.py +14 -0
  90. office365/onedrive/workbooks/sort_field.py +8 -3
  91. office365/onedrive/workbooks/tables/sort.py +20 -0
  92. office365/onedrive/workbooks/worksheets/worksheet.py +11 -0
  93. office365/partners/billing/azure_usage.py +17 -0
  94. office365/partners/billing/billed_usage.py +21 -0
  95. office365/partners/billing/billing.py +17 -0
  96. office365/partners/billing/operation.py +5 -0
  97. office365/partners/partners.py +17 -0
  98. office365/reports/root.py +9 -0
  99. office365/reports/userregistration/feature_summary.py +5 -0
  100. office365/runtime/auth/auth_cookies.py +48 -0
  101. office365/runtime/auth/authentication_context.py +36 -19
  102. office365/runtime/auth/entra/__init__.py +0 -0
  103. office365/runtime/auth/entra/authentication_context.py +165 -0
  104. office365/runtime/auth/providers/acs_token_provider.py +12 -27
  105. office365/runtime/auth/providers/saml_token_provider.py +46 -67
  106. office365/runtime/auth/sts_profile.py +37 -22
  107. office365/runtime/auth/token_response.py +4 -0
  108. office365/sharepoint/administration/custom_fonts_resource.py +5 -0
  109. office365/sharepoint/administration/sitemove/__init__.py +0 -0
  110. office365/sharepoint/administration/sitemove/service.py +68 -0
  111. office365/sharepoint/administration/sitemove/service_info.py +11 -0
  112. office365/sharepoint/changes/item.py +15 -0
  113. office365/sharepoint/client_context.py +61 -37
  114. office365/sharepoint/directory/group.py +2 -0
  115. office365/sharepoint/directory/helper.py +2 -0
  116. office365/sharepoint/directory/provider/provider.py +6 -0
  117. office365/sharepoint/directory/user.py +20 -0
  118. office365/sharepoint/files/publish/__init__.py +0 -0
  119. office365/sharepoint/files/publish/status.py +9 -0
  120. office365/sharepoint/flows/connector_result.py +17 -0
  121. office365/sharepoint/flows/permissions.py +11 -7
  122. office365/sharepoint/fontpackages/__init__.py +0 -0
  123. office365/sharepoint/fontpackages/collection.py +26 -0
  124. office365/sharepoint/fontpackages/creation_parameters.py +5 -0
  125. office365/sharepoint/fontpackages/font_package.py +5 -0
  126. office365/sharepoint/fontpackages/oob_settings.py +5 -0
  127. office365/sharepoint/forms/customization.py +26 -0
  128. office365/sharepoint/ir/__init__.py +0 -0
  129. office365/sharepoint/ir/migration.py +5 -0
  130. office365/sharepoint/lists/list.py +30 -0
  131. office365/sharepoint/marketplace/app_metadata.py +12 -1
  132. office365/sharepoint/marketplace/app_metadata_collection.py +8 -0
  133. office365/sharepoint/marketplace/corporatecuratedgallery/addins/instance_info.py +22 -0
  134. office365/sharepoint/marketplace/corporatecuratedgallery/addins/permission_failed_info.py +5 -0
  135. office365/sharepoint/marketplace/corporatecuratedgallery/addins/permission_info.py +12 -0
  136. office365/sharepoint/marketplace/corporatecuratedgallery/addins/permission_response.py +15 -0
  137. office365/sharepoint/marketplace/corporatecuratedgallery/addins/principals_response.py +5 -0
  138. office365/sharepoint/marketplace/corporatecuratedgallery/app_request_information.py +9 -0
  139. office365/sharepoint/marketplace/corporatecuratedgallery/app_response_information.py +9 -0
  140. office365/sharepoint/marketplace/corporatecuratedgallery/available_addins_response.py +4 -0
  141. office365/sharepoint/marketplace/corporatecuratedgallery/card_design.py +9 -0
  142. office365/sharepoint/marketplace/corporatecuratedgallery/card_designs.py +9 -0
  143. office365/sharepoint/marketplace/corporatecuratedgallery/teams_package_download.py +14 -0
  144. office365/sharepoint/marketplace/tenant/appcatalog/accessor.py +62 -3
  145. office365/sharepoint/multigeo/services.py +14 -0
  146. office365/sharepoint/multigeo/storage_quota.py +9 -0
  147. office365/sharepoint/policy/license_utilities.py +27 -0
  148. office365/sharepoint/principal/principal.py +6 -0
  149. office365/sharepoint/request.py +95 -10
  150. office365/sharepoint/search/administration/document_crawl_log.py +16 -2
  151. office365/sharepoint/search/administration/tenant_crawl_versions_info_provider.py +1 -1
  152. office365/sharepoint/search/reports/abandoned_queries.py +11 -1
  153. office365/sharepoint/search/reports/abandonedqueries/item.py +7 -1
  154. office365/sharepoint/sharing/domain_restriction_settings.py +5 -0
  155. office365/sharepoint/sharing/information.py +12 -0
  156. office365/sharepoint/sitehealth/result.py +4 -4
  157. office365/sharepoint/sitehealth/summary.py +5 -5
  158. office365/sharepoint/sites/copy_job_progress.py +5 -0
  159. office365/sharepoint/sites/copy_migration_iInfo.py +5 -0
  160. office365/sharepoint/sites/home/__init__.py +0 -0
  161. office365/sharepoint/sites/{sph_site.py → home/site.py} +1 -1
  162. office365/sharepoint/sites/site.py +26 -1
  163. office365/sharepoint/tenant/administration/app_service_principal_public.py +17 -0
  164. office365/sharepoint/tenant/administration/audit/data.py +12 -0
  165. office365/sharepoint/tenant/administration/audit/unified_record.py +18 -0
  166. office365/sharepoint/tenant/administration/coms/__init__.py +0 -0
  167. office365/sharepoint/tenant/administration/coms/messages_fields_data.py +5 -0
  168. office365/sharepoint/tenant/administration/coms/messages_service_proxy.py +16 -0
  169. office365/sharepoint/tenant/administration/copilot/__init__.py +0 -0
  170. office365/sharepoint/tenant/administration/copilot/adaptive_card_config.py +11 -0
  171. office365/sharepoint/tenant/administration/datagovernance/__init__.py +0 -0
  172. office365/sharepoint/tenant/administration/datagovernance/client_base.py +9 -0
  173. office365/sharepoint/tenant/administration/datagovernance/insight_client.py +82 -0
  174. office365/sharepoint/tenant/administration/datagovernance/insight_metadata.py +5 -0
  175. office365/sharepoint/tenant/administration/default_time_zone_id.py +11 -0
  176. office365/sharepoint/tenant/administration/endpoints.py +53 -2
  177. office365/sharepoint/tenant/administration/insights/onedrive_site_sharing.py +4 -0
  178. office365/sharepoint/tenant/administration/internal/appservice/permission_request.py +4 -0
  179. office365/sharepoint/tenant/administration/malware/__init__.py +0 -0
  180. office365/sharepoint/tenant/administration/malware/file.py +18 -0
  181. office365/sharepoint/tenant/administration/modified_property.py +5 -0
  182. office365/sharepoint/tenant/administration/policies/content_security_configuration.py +9 -0
  183. office365/sharepoint/tenant/administration/recent_action.py +9 -0
  184. office365/sharepoint/tenant/administration/reports/__init__.py +0 -0
  185. office365/sharepoint/tenant/administration/settings_service.py +38 -5
  186. office365/sharepoint/tenant/administration/sites/properties.py +78 -0
  187. office365/sharepoint/tenant/administration/sites/properties_collection.py +19 -0
  188. office365/sharepoint/tenant/administration/tenant.py +134 -7
  189. office365/sharepoint/tenant/administration/types.py +76 -1
  190. office365/sharepoint/tenant/insights/report_manager.py +29 -0
  191. office365/sharepoint/tenant/management/office365_tenant.py +7 -4
  192. office365/sharepoint/translation/job_status.py +22 -0
  193. office365/sharepoint/userprofiles/user_profile.py +6 -0
  194. office365/sharepoint/webparts/tile_data.py +21 -0
  195. office365/sharepoint/webs/dataleakage_prevention_status_info.py +5 -0
  196. office365/sharepoint/webs/web.py +80 -1
  197. office365/teams/chats/event_message_detail.py +8 -0
  198. office365/teams/deleted.py +24 -0
  199. office365/teams/work.py +35 -0
  200. office365/directory/tenant_relationship.py +0 -23
  201. office365/onedrive/admin.py +0 -32
  202. office365/onedrive/workbooks/charts/legend.py +0 -7
  203. office365/onedrive/workbooks/charts/series.py +0 -5
  204. {Office365_REST_Python_Client-2.5.14.dist-info → Office365_REST_Python_Client-2.6.1.dist-info}/LICENSE +0 -0
  205. {Office365_REST_Python_Client-2.5.14.dist-info → Office365_REST_Python_Client-2.6.1.dist-info}/WHEEL +0 -0
  206. {Office365_REST_Python_Client-2.5.14.dist-info → Office365_REST_Python_Client-2.6.1.dist-info}/top_level.txt +0 -0
  207. /office365/{onedrive → admin}/sharepoint_settings.py +0 -0
  208. /office365/directory/{tenant_information.py → tenantinformation/information.py} +0 -0
  209. /office365/{base_item.py → onedrive/base_item.py} +0 -0
  210. /office365/onedrive/sitepages/{horizontal_section_column.py → sections/horizontal_column.py} +0 -0
  211. /office365/onedrive/sitepages/{vertical_section.py → sections/vertical.py} +0 -0
  212. /office365/sharepoint/sites/{home_sites_details.py → home/details.py} +0 -0
  213. /office365/sharepoint/sites/{home_site_reference.py → home/reference.py} +0 -0
  214. /office365/sharepoint/tenant/administration/{app_billing_properties.py → policies/app_billing_properties.py} +0 -0
@@ -4,7 +4,7 @@ from office365.runtime.client_value_collection import ClientValueCollection
4
4
 
5
5
 
6
6
  class RolePermission(ClientValue):
7
- """ """
7
+ """Contains the set of ResourceActions determining the allowed and not allowed permissions for each role."""
8
8
 
9
- def __init__(self, resourceActions=None):
10
- self.resourceActions = ClientValueCollection(ResourceAction, resourceActions)
9
+ def __init__(self, resource_actions=None):
10
+ self.resourceActions = ClientValueCollection(ResourceAction, resource_actions)
@@ -0,0 +1,49 @@
1
+ from office365.directory.security.alerts.alert import Alert
2
+ from office365.entity_collection import EntityCollection
3
+ from office365.runtime.http.request_options import RequestOptions
4
+
5
+
6
+ class AlertCollection(EntityCollection[Alert]):
7
+ """Service Principal's collection"""
8
+
9
+ def __init__(self, context, resource_path=None):
10
+ super(AlertCollection, self).__init__(context, Alert, resource_path)
11
+
12
+ def add(
13
+ self,
14
+ title,
15
+ description=None,
16
+ severity=None,
17
+ category=None,
18
+ status=None,
19
+ source=None,
20
+ vendor_information=None,
21
+ ):
22
+ """
23
+ Creates an alert object.
24
+ :param str title:
25
+ :param str description:
26
+ :param str severity:
27
+ :param str category:
28
+ :param str status:
29
+ :param str source:
30
+ :param str vendor_information:
31
+ """
32
+
33
+ def _construct_request(request):
34
+ # type: (RequestOptions) -> None
35
+ request.set_header("Content-Type", "application/json")
36
+
37
+ return (
38
+ super(AlertCollection, self)
39
+ .add(
40
+ title=title,
41
+ description=description,
42
+ severity=severity,
43
+ category=category,
44
+ status=status,
45
+ source=source,
46
+ vendorInformation=vendor_information,
47
+ )
48
+ .before_execute(_construct_request)
49
+ )
File without changes
@@ -0,0 +1,6 @@
1
+ from office365.entity import Entity
2
+
3
+
4
+ class SecureScoreControlProfile(Entity):
5
+ """Represents a tenant's secure score per control data. By default, it returns all controls
6
+ for a tenant and can explicitly pull individual controls."""
@@ -1,8 +1,10 @@
1
1
  from office365.directory.security.alerts.alert import Alert
2
+ from office365.directory.security.alerts.collection import AlertCollection
2
3
  from office365.directory.security.attacksimulations.root import AttackSimulationRoot
3
4
  from office365.directory.security.cases.root import CasesRoot
4
5
  from office365.directory.security.hunting_query_results import HuntingQueryResults
5
6
  from office365.directory.security.incidents.incident import Incident
7
+ from office365.directory.security.scorecontrol.profile import SecureScoreControlProfile
6
8
  from office365.directory.security.threatintelligence.threat_intelligence import (
7
9
  ThreatIntelligence,
8
10
  )
@@ -35,12 +37,10 @@ class Security(Entity):
35
37
 
36
38
  @property
37
39
  def alerts(self):
38
- # type: () -> EntityCollection[Alert]
40
+ # type: () -> AlertCollection
39
41
  return self.properties.get(
40
42
  "alerts",
41
- EntityCollection(
42
- self.context, Alert, ResourcePath("alerts", self.resource_path)
43
- ),
43
+ AlertCollection(self.context, ResourcePath("alerts", self.resource_path)),
44
44
  )
45
45
 
46
46
  @property
@@ -83,6 +83,18 @@ class Security(Entity):
83
83
  ),
84
84
  )
85
85
 
86
+ @property
87
+ def secure_score_control_profiles(self):
88
+ """"""
89
+ return self.properties.get(
90
+ "secureScoreControlProfiles",
91
+ EntityCollection(
92
+ self.context,
93
+ SecureScoreControlProfile,
94
+ ResourcePath("secureScoreControlProfiles", self.resource_path),
95
+ ),
96
+ )
97
+
86
98
  @property
87
99
  def triggers(self):
88
100
  """"""
@@ -106,6 +118,7 @@ class Security(Entity):
106
118
  property_mapping = {
107
119
  "alerts_v2": self.alerts_v2,
108
120
  "attackSimulation": self.attack_simulation,
121
+ "secureScoreControlProfiles": self.secure_score_control_profiles,
109
122
  "threatIntelligence": self.threat_intelligence,
110
123
  }
111
124
  default_value = property_mapping.get(name, None)
@@ -1,4 +1,3 @@
1
- from collections.abc import Callable
2
1
  from typing import Optional
3
2
 
4
3
  from typing_extensions import Self
@@ -103,31 +102,20 @@ class ServicePrincipal(DirectoryObject):
103
102
  self.context.add_query(qry)
104
103
  return return_type
105
104
 
106
- def _get_service_principal_by_app(self, app, action):
107
- # type: (Application|str, Callable[[Application], None]) -> None
108
- if isinstance(app, Application):
109
-
110
- def _after():
111
- action(app)
112
-
113
- app.ensure_property("id", _after)
114
- else:
115
- self.context.service_principals.get_by_app(app).get().after_execute(action)
116
-
117
105
  def get_delegated_permissions(self, app, principal=None):
118
106
  # type: (Application|str, User|str) -> ClientResult[StringCollection]
119
107
  """Gets a delegated API permission"""
120
108
 
109
+ consent_type = "Principal" if principal else "AllPrincipals"
110
+
121
111
  return_type = ClientResult(self.context, StringCollection())
122
112
 
123
113
  def _get_delegated_permissions(client_id, principal_id=None):
124
114
  # type: (str, str) -> None
125
115
 
126
116
  if principal_id is None:
127
- query_text = (
128
- "clientId eq '{0}' and consentType eq 'AllPrincipals'".format(
129
- client_id
130
- )
117
+ query_text = "clientId eq '{0}' and consentType eq '{1}'".format(
118
+ client_id, consent_type
131
119
  )
132
120
  else:
133
121
  query_text = "principalId eq '{0}' and clientId eq '{1}'".format(
@@ -171,14 +159,16 @@ class ServicePrincipal(DirectoryObject):
171
159
  return return_type
172
160
 
173
161
  def grant_delegated_permissions(self, app, principal, scope):
174
- # type: (Application|str, User|str, AppRole|str) -> Self
162
+ # type: (Application|str, User|str|None, AppRole|str) -> Self
175
163
  """Grants a delegated permission to the client service principal on behalf of a user"""
176
164
 
165
+ consent_type = "Principal" if principal else "AllPrincipals"
166
+
177
167
  def _grant_delegated(principal_id, client_id):
178
168
  # type: (str, str) -> None
179
169
  self.context.oauth2_permission_grants.add(
180
170
  clientId=client_id,
181
- consentType="Principal",
171
+ consentType=consent_type,
182
172
  resourceId=self.id,
183
173
  principalId=principal_id,
184
174
  scope=scope,
@@ -206,34 +196,51 @@ class ServicePrincipal(DirectoryObject):
206
196
  self.ensure_property("id", _resource_resolved)
207
197
  return self
208
198
 
209
- def revoke_delegated_permissions(self, app, principal, scope):
199
+ def revoke_delegated_permissions(self, app, principal=None, scope=None):
210
200
  # type: (Application|str, User|str, AppRole|str) -> Self
211
201
  """"""
212
202
 
213
- def _revoke_delegated_permissions(app_id, principal_id):
203
+ def _revoke_delegated_permissions(principal_id, client_id):
214
204
  # type: (str, str) -> None
215
205
 
216
206
  def _after(return_type):
217
- pass
207
+ if len(return_type) > 0:
208
+ return_type[0].delete_object()
209
+
210
+ if principal:
211
+ query_text = "clientId eq '{0}' and principalId eq '{1}' and resourceId eq '{2}'".format(
212
+ client_id, principal_id, self.id
213
+ )
214
+ else:
215
+ query_text = "clientId eq '{0}' and consentType eq 'AllPrincipals' and resourceId eq '{1}'".format(
216
+ client_id, self.id
217
+ )
218
218
 
219
- query_text = "clientId eq '{0}' and principalId eq '{1}'".format(
220
- app_id, principal_id
221
- )
222
219
  self.context.oauth2_permission_grants.filter(
223
220
  query_text
224
221
  ).get().after_execute(_after)
225
222
 
226
- def _ensure_principal(return_type):
223
+ def _principal_resolved(principal_id):
224
+ # type: (str) -> None
225
+ def _client_loaded(return_type):
226
+ # type: (ServicePrincipal) -> None
227
+ _revoke_delegated_permissions(principal_id, return_type.id)
228
+
229
+ self.context.service_principals.get_by_app(app).get().after_execute(
230
+ _client_loaded
231
+ )
232
+
233
+ def _resource_resolved():
227
234
  if isinstance(principal, User):
228
235
 
229
236
  def _after():
230
- _revoke_delegated_permissions(principal.id, return_type.id)
237
+ _principal_resolved(principal.id)
231
238
 
232
239
  principal.ensure_property("id", _after)
233
240
  else:
234
- _revoke_delegated_permissions(principal, return_type.id)
241
+ _principal_resolved(principal)
235
242
 
236
- self._get_service_principal_by_app(app, _ensure_principal)
243
+ self.ensure_property("id", _resource_resolved)
237
244
  return self
238
245
 
239
246
  def get_application_permissions(self, app):
@@ -241,6 +248,7 @@ class ServicePrincipal(DirectoryObject):
241
248
  return_type = ClientResult(self.context, AppRoleCollection())
242
249
 
243
250
  def _get_application_permissions(app_id):
251
+ # type: (str) -> None
244
252
  app_role_ids = [
245
253
  app_role.app_role_id
246
254
  for app_role in self.app_role_assigned_to
File without changes
@@ -0,0 +1,11 @@
1
+ from office365.entity import Entity
2
+
3
+
4
+ class MultiTenantOrganization(Entity):
5
+ """
6
+ Defines an organization with more than one instance of Microsoft Entra ID. A multitenant organization enables
7
+ multiple tenants to collaborate like a single entity.
8
+
9
+ There can only be one multitenant organization per active tenant. It is not possible to be part of multiple
10
+ multitenant organizations.
11
+ """
@@ -0,0 +1,61 @@
1
+ from office365.directory.tenantinformation.information import TenantInformation
2
+ from office365.directory.tenantinformation.multi_organization import (
3
+ MultiTenantOrganization,
4
+ )
5
+ from office365.entity import Entity
6
+ from office365.runtime.client_result import ClientResult
7
+ from office365.runtime.paths.resource_path import ResourcePath
8
+ from office365.runtime.queries.function import FunctionQuery
9
+
10
+
11
+ class TenantRelationship(Entity):
12
+ """Represent the various type of tenant relationships."""
13
+
14
+ def find_tenant_information_by_domain_name(self, domain_name):
15
+ """Given a domain name, search for a tenant and read its tenantInformation. You can use this API to
16
+ validate tenant information and use their tenantId to configure cross-tenant access settings between you
17
+ and the tenant.
18
+
19
+ :param str domain_name: Primary domain name of an Azure AD tenant.
20
+ """
21
+ return_type = ClientResult(self.context, TenantInformation())
22
+ params = {"domainName": domain_name}
23
+ qry = FunctionQuery(
24
+ self, "findTenantInformationByDomainName", params, return_type
25
+ )
26
+ self.context.add_query(qry)
27
+ return return_type
28
+
29
+ def find_tenant_information_by_tenant_id(self, tenant_id):
30
+ """Given a tenant ID, search for a tenant and read its tenantInformation. You can use this API to validate
31
+ tenant information and use the tenantId to configure cross-tenant cross-tenant access settings between you
32
+ and the tenant.
33
+
34
+ :param str tenant_id: Unique tenant identifier of a Microsoft Entra tenant.
35
+ """
36
+ return_type = ClientResult(self.context, TenantInformation())
37
+ params = {"tenantId": tenant_id}
38
+ qry = FunctionQuery(
39
+ self, "findTenantInformationByTenantId", params, return_type
40
+ )
41
+ self.context.add_query(qry)
42
+ return return_type
43
+
44
+ @property
45
+ def multi_tenant_organization(self):
46
+ """Represents a setting to control people-related admin settings in the tenant."""
47
+ return self.properties.get(
48
+ "multiTenantOrganization",
49
+ MultiTenantOrganization(
50
+ self.context,
51
+ ResourcePath("multiTenantOrganization", self.resource_path),
52
+ ),
53
+ )
54
+
55
+ def get_property(self, name, default_value=None):
56
+ if default_value is None:
57
+ property_mapping = {
58
+ "multiTenantOrganization": self.multi_tenant_organization,
59
+ }
60
+ default_value = property_mapping.get(name, None)
61
+ return super(TenantRelationship, self).get_property(name, default_value)
@@ -0,0 +1,5 @@
1
+ from office365.entity import Entity
2
+
3
+
4
+ class UserInsightsSettings(Entity):
5
+ """"""
office365/graph_client.py CHANGED
@@ -1,5 +1,7 @@
1
1
  from typing import Any, Callable, List, Optional
2
2
 
3
+ from office365.admin.admin import Admin
4
+ from office365.azure_env import AzureEnvironment
3
5
  from office365.booking.solutions.root import SolutionsRoot
4
6
  from office365.communications.cloud_communications import CloudCommunications
5
7
  from office365.delta_collection import DeltaCollection
@@ -36,7 +38,7 @@ from office365.directory.rolemanagement.management import RoleManagement
36
38
  from office365.directory.rolemanagement.role import DirectoryRole
37
39
  from office365.directory.security.security import Security
38
40
  from office365.directory.serviceprincipals.collection import ServicePrincipalCollection
39
- from office365.directory.tenant_relationship import TenantRelationship
41
+ from office365.directory.tenantinformation.relationship import TenantRelationship
40
42
  from office365.directory.users.collection import UserCollection
41
43
  from office365.directory.users.user import User
42
44
  from office365.education.root import EducationRoot
@@ -47,15 +49,14 @@ from office365.intune.devices.collection import DeviceCollection
47
49
  from office365.intune.devices.management.management import DeviceManagement
48
50
  from office365.intune.organizations.contact import OrgContact
49
51
  from office365.intune.organizations.organization import Organization
50
- from office365.onedrive.admin import Admin
51
52
  from office365.onedrive.drives.drive import Drive
52
53
  from office365.onedrive.shares.collection import SharesCollection
53
54
  from office365.onedrive.sites.sites_with_root import SitesWithRoot
55
+ from office365.onedrive.storage.storage import Storage
54
56
  from office365.outlook.calendar.place import Place
55
57
  from office365.outlook.calendar.rooms.list import RoomList
56
58
  from office365.planner.planner import Planner
57
59
  from office365.reports.root import ReportRoot
58
- from office365.runtime.auth.token_response import TokenResponse
59
60
  from office365.runtime.client_runtime_context import ClientRuntimeContext
60
61
  from office365.runtime.http.http_method import HttpMethod
61
62
  from office365.runtime.http.request_options import RequestOptions
@@ -77,157 +78,73 @@ from office365.teams.viva.employee_experience import EmployeeExperience
77
78
  class GraphClient(ClientRuntimeContext):
78
79
  """Graph Service client"""
79
80
 
80
- def __init__(self, acquire_token_callback):
81
- # type: (Callable[[], dict]) -> None
81
+ def __init__(
82
+ self,
83
+ token_callback=None,
84
+ tenant=None,
85
+ scopes=None,
86
+ token_cache=None,
87
+ environment=AzureEnvironment.Global,
88
+ ):
89
+ # type: (Callable[[], dict], str, list[str], Any, str) -> None
90
+ """
91
+ :param list[str] or None scopes: Scopes requested to access an API
92
+ :param Any token_cache: Default cache is in memory only,
93
+ Refer https://msal-python.readthedocs.io/en/latest/#msal.SerializableTokenCache
94
+ """
82
95
  super(GraphClient, self).__init__()
83
96
  self._pending_request = None
84
- self._acquire_token_callback = acquire_token_callback
97
+ self._token_callback = token_callback
98
+ self._tenant = tenant
99
+ self._token_cache = token_cache
100
+ self._environment = environment
101
+ self._scopes = scopes
85
102
 
86
- @staticmethod
87
- def with_certificate(
88
- tenant, client_id, thumbprint, private_key, scopes=None, token_cache=None
89
- ):
103
+ def with_certificate(self, client_id, thumbprint, private_key):
90
104
  """
91
105
  Initializes the confidential client with client certificate
92
106
 
93
- :param str tenant: Tenant name, for example: contoso.onmicrosoft.com
94
107
  :param str client_id: The OAuth client id of the calling application.
95
108
  :param str thumbprint: Thumbprint
96
109
  :param str private_key: Private key
97
- :param list[str] or None scopes: Scopes requested to access an API
98
- :param Any token_cache: Default cache is in memory only,
99
- Refer https://msal-python.readthedocs.io/en/latest/#msal.SerializableTokenCache
100
110
  """
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)
111
+ self.pending_request().with_certificate(client_id, thumbprint, private_key)
112
+ return self
122
113
 
123
- @staticmethod
124
- def with_client_secret(
125
- tenant, client_id, client_secret, scopes=None, token_cache=None
126
- ):
127
- # type: (str, str, str, List[str], Any) -> "GraphClient"
114
+ def with_client_secret(self, client_id, client_secret):
115
+ # type: (str, str) -> "GraphClient"
128
116
  """
129
117
  Initializes the confidential client with client secret
130
118
 
131
- :param str tenant: Tenant name, for example: contoso.onmicrosoft.com
132
119
  :param str client_id: The OAuth client id of the calling application.
133
120
  :param str client_secret: Client secret
134
- :param list[str] or None scopes: Scopes requested to access an API
135
- :param Any token_cache: Default cache is in memory only,
136
- Refer https://msal-python.readthedocs.io/en/latest/#msal.SerializableTokenCache
137
121
  """
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
-
150
- def _acquire_token():
151
- return app.acquire_token_for_client(scopes=scopes)
152
-
153
- return GraphClient(_acquire_token)
122
+ self.pending_request().with_client_secret(client_id, client_secret)
123
+ return self
154
124
 
155
- @staticmethod
156
- def with_token_interactive(tenant, client_id, username=None, scopes=None):
157
- # type: (str, str, Optional[str], List[str]) -> "GraphClient"
125
+ def with_token_interactive(self, client_id, username=None):
126
+ # type: (str, Optional[str]) -> "GraphClient"
158
127
  """
159
128
  Initializes the client via user credentials
160
129
  Note: only works if your app is registered with redirect_uri as http://localhost
161
130
 
162
- :param str tenant: Tenant name, for example: contoso.onmicrosoft.com
163
131
  :param str client_id: The OAuth client id of the calling application.
164
132
  :param str username: Typically a UPN in the form of an email address.
165
- :param list[str] or None scopes: Scopes requested to access an API
166
133
  """
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)
193
-
194
- @staticmethod
195
- def with_username_and_password(tenant, client_id, username, password, scopes=None):
196
- # type: (str, str, str, str, List[str]) -> "GraphClient"
134
+ self.pending_request().with_token_interactive(client_id, username)
135
+ return self
136
+
137
+ def with_username_and_password(self, client_id, username, password):
138
+ # type: (str, str, str) -> "GraphClient"
197
139
  """
198
140
  Initializes the client via user credentials
199
141
 
200
- :param str tenant: Tenant name, for example: contoso.onmicrosoft.com
201
142
  :param str client_id: The OAuth client id of the calling application.
202
143
  :param str username: Typically a UPN in the form of an email address.
203
144
  :param str password: The password.
204
- :param list[str] or None scopes: Scopes requested to access an API
205
145
  """
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)
146
+ self.pending_request().with_username_and_password(client_id, username, password)
147
+ return self
231
148
 
232
149
  def execute_batch(self, items_per_batch=20, success_callback=None):
233
150
  """Constructs and submit a batch request
@@ -238,7 +155,7 @@ class GraphClient(ClientRuntimeContext):
238
155
  :param (List[ClientObject|ClientResult])-> None success_callback: A success callback
239
156
  """
240
157
  batch_request = ODataV4BatchRequest(V4JsonFormat())
241
- batch_request.beforeExecute += self._authenticate_request
158
+ batch_request.beforeExecute += self.pending_request().authenticate_request
242
159
  while self.has_pending_request:
243
160
  qry = self._get_next_query(items_per_batch)
244
161
  batch_request.execute_query(qry)
@@ -249,8 +166,11 @@ class GraphClient(ClientRuntimeContext):
249
166
  def pending_request(self):
250
167
  # type: () -> GraphRequest
251
168
  if self._pending_request is None:
252
- self._pending_request = GraphRequest()
253
- self._pending_request.beforeExecute += self._authenticate_request
169
+ self._pending_request = GraphRequest(
170
+ tenant=self._tenant, environment=self._environment
171
+ )
172
+ if callable(self._token_callback):
173
+ self._pending_request.with_access_token(self._token_callback)
254
174
  self._pending_request.beforeExecute += self._build_specific_query
255
175
  return self._pending_request
256
176
 
@@ -266,13 +186,6 @@ class GraphClient(ClientRuntimeContext):
266
186
  elif isinstance(self.current_query, DeleteEntityQuery):
267
187
  request.method = HttpMethod.Delete
268
188
 
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
189
  @property
277
190
  def admin(self):
278
191
  """A container for administrator functionality for SharePoint and OneDrive."""
@@ -475,6 +388,13 @@ class GraphClient(ClientRuntimeContext):
475
388
  """
476
389
  return InformationProtection(self, ResourcePath("informationProtection"))
477
390
 
391
+ @property
392
+ def storage(self):
393
+ """
394
+ Facilitates the structures of fileStorageContainers.
395
+ """
396
+ return Storage(self, ResourcePath("storage"))
397
+
478
398
  @property
479
399
  def subscriptions(self):
480
400
  """