Office365-REST-Python-Client 2.5.1__py3-none-any.whl → 2.5.3__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 (271) hide show
  1. {Office365_REST_Python_Client-2.5.1.dist-info → Office365_REST_Python_Client-2.5.3.dist-info}/METADATA +6 -6
  2. {Office365_REST_Python_Client-2.5.1.dist-info → Office365_REST_Python_Client-2.5.3.dist-info}/RECORD +265 -259
  3. office365/base_item.py +12 -20
  4. office365/communications/onlinemeetings/collection.py +1 -1
  5. office365/communications/onlinemeetings/online_meeting.py +20 -35
  6. office365/communications/presences/presence.py +18 -7
  7. office365/delta_collection.py +10 -1
  8. office365/delta_path.py +1 -1
  9. office365/directory/administrative_unit.py +6 -7
  10. office365/directory/applications/application.py +24 -18
  11. office365/directory/applications/roles/assignment.py +13 -1
  12. office365/directory/applications/roles/collection.py +13 -0
  13. office365/directory/applications/roles/role.py +6 -1
  14. office365/directory/audit/directory.py +8 -7
  15. office365/directory/audit/log_root.py +3 -0
  16. office365/directory/audit/signins/signin.py +19 -29
  17. office365/directory/authentication/authentication.py +1 -0
  18. office365/directory/authentication/methods/details.py +8 -6
  19. office365/directory/authentication/methods/phone.py +3 -1
  20. office365/directory/extensions/extension_property.py +7 -9
  21. office365/directory/groups/collection.py +10 -3
  22. office365/directory/groups/group.py +19 -19
  23. office365/directory/groups/lifecycle_policy.py +8 -7
  24. office365/directory/identities/provider.py +5 -6
  25. office365/directory/insights/usage_details.py +8 -3
  26. office365/directory/internal/paths/me.py +1 -1
  27. office365/directory/invitations/collection.py +1 -1
  28. office365/directory/invitations/invitation.py +6 -6
  29. office365/directory/object_collection.py +2 -3
  30. office365/directory/permissions/email_identity.py +7 -0
  31. office365/directory/permissions/grants/resource_specific.py +10 -9
  32. office365/directory/permissions/identity.py +3 -0
  33. office365/directory/permissions/identity_set.py +3 -0
  34. office365/directory/policies/base.py +4 -4
  35. office365/directory/policies/root.py +6 -4
  36. office365/directory/protection/information.py +3 -3
  37. office365/directory/rolemanagement/application.py +2 -0
  38. office365/directory/rolemanagement/role.py +11 -10
  39. office365/directory/rolemanagement/template.py +9 -8
  40. office365/directory/rolemanagement/unified_role_assignment.py +5 -4
  41. office365/directory/rolemanagement/unified_role_definition.py +6 -4
  42. office365/directory/security/security.py +3 -0
  43. office365/directory/serviceprincipals/collection.py +20 -4
  44. office365/directory/serviceprincipals/service_principal.py +79 -12
  45. office365/directory/users/activities/activity.py +5 -4
  46. office365/directory/users/user.py +29 -34
  47. office365/entity.py +2 -2
  48. office365/entity_collection.py +12 -5
  49. office365/graph_client.py +90 -8
  50. office365/intune/audit/event.py +4 -3
  51. office365/intune/devices/enrollment/configuration.py +6 -4
  52. office365/intune/devices/managed.py +9 -12
  53. office365/onedrive/analytics/item_activity_stat.py +4 -3
  54. office365/onedrive/columns/column_link.py +4 -4
  55. office365/onedrive/columns/definition.py +29 -32
  56. office365/onedrive/columns/definition_collection.py +1 -1
  57. office365/onedrive/contenttypes/content_type.py +16 -18
  58. office365/onedrive/documentsets/version.py +7 -3
  59. office365/onedrive/driveitems/driveItem.py +48 -49
  60. office365/onedrive/drives/drive.py +7 -2
  61. office365/onedrive/internal/paths/children.py +2 -2
  62. office365/onedrive/internal/paths/root.py +1 -1
  63. office365/onedrive/internal/paths/shared.py +1 -1
  64. office365/onedrive/internal/paths/site.py +3 -3
  65. office365/onedrive/internal/paths/url.py +2 -2
  66. office365/onedrive/listitems/list_item.py +2 -0
  67. office365/onedrive/lists/list.py +7 -4
  68. office365/onedrive/permissions/collection.py +28 -7
  69. office365/onedrive/permissions/permission.py +5 -7
  70. office365/onedrive/permissions/sharing_link.py +1 -1
  71. office365/onedrive/sharepoint.py +1 -0
  72. office365/onedrive/shares/collection.py +2 -5
  73. office365/onedrive/shares/drive_item.py +4 -0
  74. office365/onedrive/sites/site.py +6 -0
  75. office365/onedrive/termstore/groups/collection.py +3 -8
  76. office365/onedrive/termstore/groups/group.py +8 -0
  77. office365/onedrive/termstore/sets/collection.py +2 -6
  78. office365/onedrive/termstore/sets/name.py +5 -0
  79. office365/onedrive/termstore/sets/set.py +7 -0
  80. office365/onedrive/termstore/store.py +10 -13
  81. office365/onedrive/versions/drive_item.py +3 -1
  82. office365/onedrive/workbooks/ranges/range.py +9 -13
  83. office365/onedrive/workbooks/ranges/view.py +1 -0
  84. office365/onedrive/workbooks/tables/rows/row.py +3 -0
  85. office365/onedrive/workbooks/tables/table.py +7 -4
  86. office365/onedrive/workbooks/worksheets/worksheet.py +12 -4
  87. office365/onenote/entity_hierarchy_model.py +4 -0
  88. office365/onenote/internal/multipart_page_query.py +4 -5
  89. office365/onenote/notebooks/notebook.py +4 -0
  90. office365/onenote/pages/collection.py +3 -2
  91. office365/onenote/resources/resource.py +5 -4
  92. office365/onenote/sectiongroups/section_group.py +10 -7
  93. office365/onenote/sections/section.py +1 -1
  94. office365/outlook/calendar/attendees/base.py +2 -1
  95. office365/outlook/calendar/calendar.py +18 -10
  96. office365/outlook/calendar/events/collection.py +0 -2
  97. office365/outlook/calendar/group.py +7 -8
  98. office365/outlook/calendar/meetingtimes/suggestion.py +8 -4
  99. office365/outlook/calendar/meetingtimes/time_slot.py +3 -0
  100. office365/outlook/calendar/permissions/collection.py +1 -1
  101. office365/outlook/calendar/rooms/__init__.py +0 -0
  102. office365/outlook/calendar/rooms/list.py +27 -0
  103. office365/outlook/calendar/rooms/room.py +8 -0
  104. office365/outlook/calendar/schedule/information.py +0 -1
  105. office365/outlook/contacts/collection.py +0 -8
  106. office365/outlook/contacts/contact.py +14 -14
  107. office365/outlook/contacts/folder.py +3 -0
  108. office365/outlook/mail/attachments/attachment.py +31 -31
  109. office365/outlook/mail/attachments/collection.py +34 -6
  110. office365/outlook/mail/conversation.py +6 -4
  111. office365/outlook/mail/folders/collection.py +0 -7
  112. office365/outlook/mail/folders/folder.py +50 -18
  113. office365/outlook/mail/messages/collection.py +0 -1
  114. office365/outlook/mail/messages/message.py +58 -68
  115. office365/outlook/mail/physical_address.py +11 -5
  116. office365/outlook/mail/recipient.py +3 -1
  117. office365/outlook/mail/recurrence_range.py +14 -6
  118. office365/outlook/user.py +1 -0
  119. office365/planner/planner.py +9 -12
  120. office365/planner/plans/collection.py +17 -18
  121. office365/planner/plans/container.py +11 -0
  122. office365/planner/plans/plan.py +21 -10
  123. office365/runtime/auth/authentication_context.py +3 -3
  124. office365/runtime/auth/providers/acs_token_provider.py +7 -9
  125. office365/runtime/auth/providers/saml_token_provider.py +5 -2
  126. office365/runtime/client_object.py +6 -15
  127. office365/runtime/client_object_collection.py +36 -35
  128. office365/runtime/client_result.py +6 -7
  129. office365/runtime/client_runtime_context.py +10 -16
  130. office365/runtime/client_value_collection.py +3 -10
  131. office365/runtime/compat.py +2 -0
  132. office365/runtime/odata/query_options.py +1 -3
  133. office365/runtime/odata/reader.py +1 -1
  134. office365/runtime/odata/request.py +2 -4
  135. office365/runtime/odata/type.py +17 -0
  136. office365/runtime/odata/v4/upload_session_request.py +27 -30
  137. office365/runtime/paths/appid.py +1 -1
  138. office365/runtime/{odata/url_builder.py → paths/builder.py} +24 -9
  139. office365/runtime/paths/item.py +3 -1
  140. office365/runtime/paths/resource_path.py +12 -16
  141. office365/runtime/paths/service_operation.py +8 -7
  142. office365/runtime/paths/v3/__init__.py +0 -0
  143. office365/runtime/paths/{key.py → v3/entity.py} +5 -5
  144. office365/runtime/paths/v4/__init__.py +0 -0
  145. office365/runtime/paths/{entity.py → v4/entity.py} +13 -11
  146. office365/runtime/queries/function.py +1 -1
  147. office365/runtime/types/event_handler.py +1 -3
  148. office365/search/entity.py +15 -8
  149. office365/search/external/external.py +1 -0
  150. office365/search/sort_property.py +3 -0
  151. office365/sharepoint/attachments/attachment.py +3 -1
  152. office365/sharepoint/attachments/collection.py +3 -0
  153. office365/sharepoint/changes/change.py +12 -1
  154. office365/sharepoint/changes/collection.py +1 -1
  155. office365/sharepoint/changes/list.py +3 -0
  156. office365/sharepoint/changes/token.py +4 -0
  157. office365/sharepoint/changes/type.py +23 -23
  158. office365/sharepoint/changes/web.py +7 -3
  159. office365/sharepoint/client_context.py +21 -18
  160. office365/sharepoint/clientsidecomponent/hostedapps/manager.py +3 -3
  161. office365/sharepoint/contenttypes/content_type.py +47 -56
  162. office365/sharepoint/contenttypes/content_type_id.py +1 -1
  163. office365/sharepoint/documentmanagement/document_id.py +2 -2
  164. office365/sharepoint/documentmanagement/document_set.py +6 -7
  165. office365/sharepoint/entity_collection.py +9 -0
  166. office365/sharepoint/features/feature.py +6 -8
  167. office365/sharepoint/fields/collection.py +6 -5
  168. office365/sharepoint/fields/field.py +28 -46
  169. office365/sharepoint/fields/related_field_collection.py +1 -1
  170. office365/sharepoint/fields/user_value.py +3 -3
  171. office365/sharepoint/files/checked_out_file.py +4 -2
  172. office365/sharepoint/files/checked_out_file_collection.py +1 -1
  173. office365/sharepoint/files/collection.py +84 -14
  174. office365/sharepoint/files/file.py +118 -110
  175. office365/sharepoint/files/versions/collection.py +5 -3
  176. office365/sharepoint/files/versions/event.py +6 -3
  177. office365/sharepoint/files/versions/version.py +31 -18
  178. office365/sharepoint/folders/collection.py +5 -10
  179. office365/sharepoint/folders/folder.py +41 -24
  180. office365/sharepoint/forms/collection.py +1 -1
  181. office365/sharepoint/forms/form.py +4 -4
  182. office365/sharepoint/internal/paths/static_operation.py +9 -0
  183. office365/sharepoint/internal/paths/web.py +20 -0
  184. office365/sharepoint/listitems/collection.py +4 -0
  185. office365/sharepoint/listitems/listitem.py +37 -38
  186. office365/sharepoint/listitems/versions/collection.py +1 -1
  187. office365/sharepoint/listitems/versions/version.py +18 -11
  188. office365/sharepoint/lists/collection.py +1 -2
  189. office365/sharepoint/lists/list.py +106 -153
  190. office365/sharepoint/marketplace/app_metadata_collection.py +3 -1
  191. office365/sharepoint/navigation/node.py +16 -15
  192. office365/sharepoint/navigation/node_collection.py +9 -3
  193. office365/sharepoint/permissions/base_permissions.py +11 -6
  194. office365/sharepoint/permissions/roles/assignments/collection.py +8 -12
  195. office365/sharepoint/permissions/roles/definitions/definition.py +3 -1
  196. office365/sharepoint/permissions/securable_object.py +38 -31
  197. office365/sharepoint/portal/groups/service.py +12 -16
  198. office365/sharepoint/portal/groups/site_manager.py +0 -1
  199. office365/sharepoint/principal/groups/group.py +24 -30
  200. office365/sharepoint/principal/principal.py +21 -19
  201. office365/sharepoint/principal/users/collection.py +5 -0
  202. office365/sharepoint/principal/users/user.py +20 -26
  203. office365/sharepoint/publishing/pages/collection.py +1 -4
  204. office365/sharepoint/publishing/pages/metadata.py +38 -51
  205. office365/sharepoint/publishing/pages/metadata_collection.py +5 -2
  206. office365/sharepoint/publishing/pages/page.py +12 -21
  207. office365/sharepoint/publishing/pages/reposts/repost.py +5 -9
  208. office365/sharepoint/publishing/pages/service.py +36 -49
  209. office365/sharepoint/pushnotifications/collection.py +3 -1
  210. office365/sharepoint/recyclebin/item.py +11 -9
  211. office365/sharepoint/recyclebin/item_collection.py +1 -1
  212. office365/sharepoint/search/service.py +8 -6
  213. office365/sharepoint/sharing/links/info.py +5 -2
  214. office365/sharepoint/sharing/links/share_response.py +3 -0
  215. office365/sharepoint/sharing/links/share_settings.py +3 -0
  216. office365/sharepoint/sharing/object_sharing_information.py +25 -19
  217. office365/sharepoint/sharing/object_sharing_information_user.py +10 -19
  218. office365/sharepoint/sharing/result.py +18 -41
  219. office365/sharepoint/sharing/role.py +20 -0
  220. office365/sharepoint/sharing/role_type.py +1 -0
  221. office365/sharepoint/sharing/user_sharing_result.py +12 -0
  222. office365/sharepoint/sites/language.py +6 -0
  223. office365/sharepoint/sites/language_collection.py +3 -0
  224. office365/sharepoint/sites/site.py +65 -86
  225. office365/sharepoint/storagemetrics/storage_metrics.py +5 -6
  226. office365/sharepoint/taxonomy/item.py +11 -10
  227. office365/sharepoint/taxonomy/stores/store.py +8 -8
  228. office365/sharepoint/taxonomy/terms/label.py +3 -0
  229. office365/sharepoint/taxonomy/terms/term.py +31 -0
  230. office365/sharepoint/tenant/administration/collaboration/insights_overview.py +10 -0
  231. office365/sharepoint/tenant/administration/hubsites/collection.py +1 -2
  232. office365/sharepoint/tenant/administration/hubsites/hub_site.py +20 -24
  233. office365/sharepoint/tenant/administration/internal/permission_grant.py +7 -0
  234. office365/sharepoint/tenant/administration/sites/properties.py +55 -44
  235. office365/sharepoint/tenant/administration/tenant.py +69 -69
  236. office365/sharepoint/types/resource_path.py +2 -2
  237. office365/sharepoint/ui/applicationpages/peoplepicker/query_parameters.py +1 -1
  238. office365/sharepoint/usercustomactions/collection.py +1 -2
  239. office365/sharepoint/userprofiles/my_site_links.py +4 -4
  240. office365/sharepoint/userprofiles/people_manager.py +1 -3
  241. office365/sharepoint/userprofiles/user_profile.py +9 -11
  242. office365/sharepoint/utilities/principal_info.py +12 -0
  243. office365/sharepoint/viva/employee_engagement.py +1 -1
  244. office365/sharepoint/webparts/definition_collection.py +1 -1
  245. office365/sharepoint/webs/collection.py +8 -0
  246. office365/sharepoint/webs/template_collection.py +3 -5
  247. office365/sharepoint/webs/web.py +75 -95
  248. office365/subscriptions/collection.py +1 -1
  249. office365/subscriptions/subscription.py +13 -11
  250. office365/teams/apps/app.py +1 -0
  251. office365/teams/channels/channel.py +1 -3
  252. office365/teams/collection.py +12 -16
  253. office365/teams/info.py +7 -4
  254. office365/teams/members/conversation_collection.py +1 -3
  255. office365/teams/operations/async_operation.py +3 -5
  256. office365/teams/schedule/groups/group.py +3 -0
  257. office365/teams/team.py +18 -20
  258. office365/todo/attachments/base.py +7 -9
  259. office365/todo/linked_resource.py +6 -6
  260. office365/todo/tasks/list.py +1 -0
  261. office365/todo/tasks/task.py +3 -0
  262. office365/onedrive/internal/queries/resumable_file_upload.py +0 -36
  263. office365/outlook/internal/queries/attachment_upload.py +0 -53
  264. office365/runtime/odata/path_builder.py +0 -23
  265. office365/sharepoint/internal/key_value.py +0 -28
  266. office365/sharepoint/internal/queries/create_file.py +0 -20
  267. office365/sharepoint/internal/queries/upload_session.py +0 -103
  268. {Office365_REST_Python_Client-2.5.1.dist-info → Office365_REST_Python_Client-2.5.3.dist-info}/LICENSE +0 -0
  269. {Office365_REST_Python_Client-2.5.1.dist-info → Office365_REST_Python_Client-2.5.3.dist-info}/WHEEL +0 -0
  270. {Office365_REST_Python_Client-2.5.1.dist-info → Office365_REST_Python_Client-2.5.3.dist-info}/top_level.txt +0 -0
  271. /office365/planner/plans/{plan_details.py → details.py} +0 -0
@@ -1,3 +1,5 @@
1
+ from typing import Optional
2
+
1
3
  from office365.directory.object import DirectoryObject
2
4
 
3
5
 
@@ -9,31 +11,30 @@ class ResourceSpecificPermissionGrant(DirectoryObject):
9
11
 
10
12
  @property
11
13
  def client_id(self):
14
+ # type: () -> Optional[str]
12
15
  """ID of the Azure AD app that has been granted access."""
13
16
  return self.properties.get("clientId", None)
14
17
 
15
18
  @property
16
19
  def client_app_id(self):
20
+ # type: () -> Optional[str]
17
21
  """ID of the service principal of the Azure AD app that has been granted access."""
18
22
  return self.properties.get("clientAppId", None)
19
23
 
20
24
  @property
21
25
  def permission(self):
22
- """The name of the resource-specific permission.
23
- :rtype: str
24
- """
26
+ # type: () -> Optional[str]
27
+ """The name of the resource-specific permission."""
25
28
  return self.properties.get("permission", None)
26
29
 
27
30
  @property
28
31
  def permission_type(self):
29
- """The type of permission. Possible values are: Application, Delegated. Read-only.
30
- :rtype: str
31
- """
32
+ # type: () -> Optional[str]
33
+ """The type of permission. Possible values are: Application, Delegated. Read-only."""
32
34
  return self.properties.get("permissionType", None)
33
35
 
34
36
  @property
35
37
  def resource_app_id(self):
36
- """ID of the Azure AD app that is hosting the resource. Read-only.
37
- :rtype: str
38
- """
38
+ # type: () -> Optional[str]
39
+ """ID of the Azure AD app that is hosting the resource. Read-only."""
39
40
  return self.properties.get("resourceAppId", None)
@@ -16,3 +16,6 @@ class Identity(ClientValue):
16
16
  super(Identity, self).__init__()
17
17
  self.displayName = display_name
18
18
  self.id = _id
19
+
20
+ def __repr__(self):
21
+ return repr(self.to_json())
@@ -17,3 +17,6 @@ class IdentitySet(ClientValue):
17
17
  self.application = application
18
18
  self.device = device
19
19
  self.user = user
20
+
21
+ def __repr__(self):
22
+ return repr({n: v.to_json() for n, v in self if v.to_json()})
@@ -1,3 +1,5 @@
1
+ from typing import Optional
2
+
1
3
  from office365.directory.object import DirectoryObject
2
4
 
3
5
 
@@ -6,8 +8,6 @@ class PolicyBase(DirectoryObject):
6
8
 
7
9
  @property
8
10
  def display_name(self):
9
- """
10
- Display name for this policy
11
- :rtype: str or None
12
- """
11
+ # type: () -> Optional[str]
12
+ """Display name for this policy"""
13
13
  return self.properties.get("displayName", None)
@@ -34,6 +34,7 @@ class PolicyRoot(Entity):
34
34
  )
35
35
 
36
36
  def authentication_strength_policies(self):
37
+ # type: () -> EntityCollection[AuthenticationStrengthPolicy]
37
38
  """
38
39
  The authentication method combinations that are to be used in scenarios defined by Azure AD Conditional Access.
39
40
  """
@@ -69,6 +70,7 @@ class PolicyRoot(Entity):
69
70
 
70
71
  @property
71
72
  def app_management_policies(self):
73
+ # type: () -> EntityCollection[AppManagementPolicy]
72
74
  """The policies that enforce app management restrictions for specific applications and service principals,
73
75
  overriding the defaultAppManagementPolicy."""
74
76
  return self.properties.get(
@@ -108,7 +110,8 @@ class PolicyRoot(Entity):
108
110
 
109
111
  @property
110
112
  def permission_grant_policies(self):
111
- """ "
113
+ # type: () -> EntityCollection[PermissionGrantPolicy]
114
+ """
112
115
  The policy that specifies the conditions under which consent can be granted.
113
116
  """
114
117
  return self.properties.get(
@@ -122,9 +125,8 @@ class PolicyRoot(Entity):
122
125
 
123
126
  @property
124
127
  def conditional_access_policies(self):
125
- """ "
126
- The custom rules that define an access scenario.
127
- """
128
+ # type: () -> EntityCollection[ConditionalAccessPolicy]
129
+ """The custom rules that define an access scenario"""
128
130
  return self.properties.get(
129
131
  "conditionalAccessPolicies",
130
132
  EntityCollection(
@@ -3,6 +3,7 @@ from office365.directory.protection.threatassessment.request import (
3
3
  )
4
4
  from office365.entity import Entity
5
5
  from office365.entity_collection import EntityCollection
6
+ from office365.runtime.http.request_options import RequestOptions
6
7
  from office365.runtime.paths.resource_path import ResourcePath
7
8
  from office365.runtime.queries.create_entity import CreateEntityQuery
8
9
 
@@ -29,9 +30,7 @@ class InformationProtection(Entity):
29
30
  self.threat_assessment_requests.add_child(return_type)
30
31
 
31
32
  def _construct_request(request):
32
- """
33
- :type request: office365.runtime.http.request_options.RequestOptions
34
- """
33
+ # type: (RequestOptions) -> None
35
34
  request.set_header("Content-Type", "application/json")
36
35
 
37
36
  def _create_and_add_query():
@@ -51,6 +50,7 @@ class InformationProtection(Entity):
51
50
 
52
51
  @property
53
52
  def threat_assessment_requests(self):
53
+ # type: () -> EntityCollection[ThreatAssessmentRequest]
54
54
  """"""
55
55
  return self.properties.get(
56
56
  "threatAssessmentRequests",
@@ -17,6 +17,7 @@ class RbacApplication(Entity):
17
17
 
18
18
  @property
19
19
  def role_assignments(self):
20
+ # type: () -> EntityCollection[UnifiedRoleAssignment]
20
21
  """Resource to grant access to users or groups."""
21
22
  return self.properties.get(
22
23
  "roleAssignments",
@@ -28,6 +29,7 @@ class RbacApplication(Entity):
28
29
  )
29
30
 
30
31
  def role_definitions(self):
32
+ # type: () -> EntityCollection[UnifiedRoleDefinition]
31
33
  """Resource representing the roles allowed by RBAC providers and the permissions assigned to the roles."""
32
34
  return self.properties.get(
33
35
  "roleDefinitions",
@@ -1,3 +1,5 @@
1
+ from typing import Optional
2
+
1
3
  from office365.directory.object import DirectoryObject
2
4
  from office365.runtime.paths.resource_path import ResourcePath
3
5
 
@@ -6,27 +8,26 @@ class DirectoryRole(DirectoryObject):
6
8
  """Represents an Azure AD directory role. Azure AD directory roles are also known as administrator roles"""
7
9
 
8
10
  def __repr__(self):
9
- return self.display_name
11
+ return self.id or self.entity_type_name
12
+
13
+ def __str__(self):
14
+ return "Name: {0}".format(self.display_name)
10
15
 
11
16
  @property
12
17
  def description(self):
13
- """The description for the directory role.
14
- :rtype: str or None
15
- """
18
+ # type: () -> Optional[str]
19
+ """The description for the directory role."""
16
20
  return self.properties.get("Description", None)
17
21
 
18
22
  @property
19
23
  def display_name(self):
20
- """The display name for the directory role.
21
- :rtype: str or None
22
- """
24
+ # type: () -> Optional[str]
25
+ """The display name for the directory role."""
23
26
  return self.properties.get("displayName", None)
24
27
 
25
28
  @property
26
29
  def members(self):
27
- """
28
- Users that are members of this directory role.
29
- """
30
+ """Users that are members of this directory role."""
30
31
  from office365.directory.object_collection import DirectoryObjectCollection
31
32
 
32
33
  return self.properties.get(
@@ -1,3 +1,5 @@
1
+ from typing import Optional
2
+
1
3
  from office365.directory.object import DirectoryObject
2
4
 
3
5
 
@@ -5,18 +7,17 @@ class DirectoryRoleTemplate(DirectoryObject):
5
7
  """Represents a directory role template. A directory role template specifies the property values of a directory
6
8
  role (directoryRole)."""
7
9
 
10
+ def __repr__(self):
11
+ return self.display_name
12
+
8
13
  @property
9
14
  def display_name(self):
10
- """
11
- The display name to set for the directory role
12
- :rtype: str
13
- """
15
+ # type: () -> Optional[str]
16
+ """The display name to set for the directory role"""
14
17
  return self.properties.get("displayName", None)
15
18
 
16
19
  @property
17
20
  def description(self):
18
- """
19
- The display name to set for the directory role
20
- :rtype: str
21
- """
21
+ # type: () -> Optional[str]
22
+ """The display name to set for the directory role"""
22
23
  return self.properties.get("description", None)
@@ -1,3 +1,5 @@
1
+ from typing import Optional
2
+
1
3
  from office365.directory.rolemanagement.unified_role_definition import (
2
4
  UnifiedRoleDefinition,
3
5
  )
@@ -13,20 +15,19 @@ class UnifiedRoleAssignment(Entity):
13
15
 
14
16
  @property
15
17
  def app_scope_id(self):
18
+ # type: () -> Optional[str]
16
19
  """
17
20
  Identifier of the app-specific scope when the assignment scope is app-specific. Either this property or
18
21
  directoryScopeId is required. App scopes are scopes that are defined and understood by this application only.
19
22
  Use / for tenant-wide app scopes. Use directoryScopeId to limit the scope to particular directory objects,
20
23
  for example, administrative units. Supports $filter (eq, in).
21
- :rtype: str
22
24
  """
23
25
  return self.properties.get("appScopeId", None)
24
26
 
25
27
  @property
26
28
  def condition(self):
27
- """
28
- :rtype: str
29
- """
29
+ # type: () -> Optional[str]
30
+ """ """
30
31
  return self.properties.get("condition", None)
31
32
 
32
33
  @property
@@ -1,3 +1,5 @@
1
+ from typing import Optional
2
+
1
3
  from office365.directory.rolemanagement.unified_role_permission import (
2
4
  UnifiedRolePermission,
3
5
  )
@@ -13,16 +15,15 @@ class UnifiedRoleDefinition(Entity):
13
15
 
14
16
  @property
15
17
  def display_name(self):
16
- """The display name for the unifiedRoleDefinition.
17
- :rtype: str
18
- """
18
+ # type: () -> Optional[str]
19
+ """The display name for the unifiedRoleDefinition."""
19
20
  return self.properties.get("displayName", None)
20
21
 
21
22
  @property
22
23
  def is_built_in(self):
24
+ # type: () -> Optional[bool]
23
25
  """Flag indicating whether the role definition is part of the default set included in
24
26
  Azure Active Directory (Azure AD) or a custom definition.
25
- :rtype: bool
26
27
  """
27
28
  return self.properties.get("isBuiltIn", None)
28
29
 
@@ -37,6 +38,7 @@ class UnifiedRoleDefinition(Entity):
37
38
 
38
39
  @property
39
40
  def inherits_permissions_from(self):
41
+ # type: () -> EntityCollection[UnifiedRoleDefinition]
40
42
  """
41
43
  Read-only collection of role definitions that the given role definition inherits from. Only Azure AD built-in
42
44
  roles (isBuiltIn is true) support this attribute. Supports $expand.
@@ -17,6 +17,7 @@ class Security(Entity):
17
17
 
18
18
  @property
19
19
  def alerts(self):
20
+ # type: () -> EntityCollection[Alert]
20
21
  return self.properties.get(
21
22
  "alerts",
22
23
  EntityCollection(
@@ -26,6 +27,7 @@ class Security(Entity):
26
27
 
27
28
  @property
28
29
  def alerts_v2(self):
30
+ # type: () -> EntityCollection[Alert]
29
31
  """
30
32
  A collection of alerts in Microsoft 365 Defender.
31
33
  """
@@ -55,6 +57,7 @@ class Security(Entity):
55
57
 
56
58
  @property
57
59
  def incidents(self):
60
+ # type: () -> EntityCollection[Incident]
58
61
  """A collection of correlated alert instances and associated metadata that reflects the story of
59
62
  an attack in a tenant"""
60
63
  return self.properties.get(
@@ -1,9 +1,10 @@
1
1
  from office365.delta_collection import DeltaCollection
2
+ from office365.directory.applications.application import Application
2
3
  from office365.directory.serviceprincipals.service_principal import ServicePrincipal
3
4
  from office365.runtime.paths.appid import AppIdPath
4
5
 
5
6
 
6
- class ServicePrincipalCollection(DeltaCollection):
7
+ class ServicePrincipalCollection(DeltaCollection[ServicePrincipal]):
7
8
  """Service Principal's collection"""
8
9
 
9
10
  def __init__(self, context, resource_path=None):
@@ -14,15 +15,30 @@ class ServicePrincipalCollection(DeltaCollection):
14
15
  def add(self, app_id):
15
16
  """
16
17
  Create a new servicePrincipal object.
17
-
18
18
  :param str app_id: The unique identifier for the associated application
19
- :rtype: ServicePrincipal
20
19
  """
21
20
  return super(ServicePrincipalCollection, self).add(appId=app_id)
22
21
 
23
22
  def get_by_app_id(self, app_id):
24
23
  """Retrieves the service principal using appId.
25
-
26
24
  :param str app_id: appId is referred to as Application (Client) ID, respectively, in the Azure portal
27
25
  """
28
26
  return ServicePrincipal(self.context, AppIdPath(app_id, self.resource_path))
27
+
28
+ def get_by_app(self, app):
29
+ # type: (str|Application) -> ServicePrincipal
30
+ if isinstance(app, Application):
31
+ return_type = ServicePrincipal(self.context, parent_collection=self)
32
+
33
+ def _app_resolved():
34
+ return_type.set_property("appId", app.app_id)
35
+
36
+ app.ensure_properties(["appId"], _app_resolved)
37
+ return return_type
38
+ else:
39
+ return self.get_by_app_id(app)
40
+
41
+ def get_by_name(self, name):
42
+ # type: (str) -> ServicePrincipal
43
+ """Retrieves the service principal using displayName."""
44
+ return self.single("displayName eq '{0}'".format(name))
@@ -1,9 +1,13 @@
1
1
  from typing import Optional
2
2
 
3
+ from typing_extensions import Self
4
+
3
5
  from office365.delta_collection import DeltaCollection
6
+ from office365.directory.applications.application import Application
4
7
  from office365.directory.applications.roles.assignment_collection import (
5
8
  AppRoleAssignmentCollection,
6
9
  )
10
+ from office365.directory.applications.roles.collection import AppRoleCollection
7
11
  from office365.directory.applications.roles.role import AppRole
8
12
  from office365.directory.certificates.self_signed import SelfSignedCertificate
9
13
  from office365.directory.key_credential import KeyCredential
@@ -15,6 +19,7 @@ from office365.directory.permissions.scope import PermissionScope
15
19
  from office365.directory.synchronization.synchronization import Synchronization
16
20
  from office365.runtime.client_result import ClientResult
17
21
  from office365.runtime.client_value_collection import ClientValueCollection
22
+ from office365.runtime.paths.appid import AppIdPath
18
23
  from office365.runtime.paths.resource_path import ResourcePath
19
24
  from office365.runtime.queries.service_operation import ServiceOperationQuery
20
25
  from office365.runtime.types.collections import StringCollection
@@ -23,6 +28,9 @@ from office365.runtime.types.collections import StringCollection
23
28
  class ServicePrincipal(DirectoryObject):
24
29
  """Represents an instance of an application in a directory."""
25
30
 
31
+ def __str__(self):
32
+ return self.display_name
33
+
26
34
  def add_key(self, key_credential, password_credential, proof):
27
35
  """
28
36
  Adds a key credential to a servicePrincipal. This method along with removeKey can be used by a servicePrincipal
@@ -32,8 +40,9 @@ class ServicePrincipal(DirectoryObject):
32
40
  The type, usage and key are required properties for this usage. Supported key types are:
33
41
  AsymmetricX509Cert: The usage must be Verify.
34
42
  X509CertAndPassword: The usage must be Sign
35
- :param PasswordCredential password_credential: Only secretText is required to be set which should contain the password
36
- for the key. This property is required only for keys of type X509CertAndPassword. Set it to null otherwise.
43
+ :param PasswordCredential password_credential: Only secretText is required to be set which should contain
44
+ the password for the key. This property is required only for keys of type X509CertAndPassword.
45
+ Set it to null otherwise.
37
46
  :param str proof: A self-signed JWT token used as a proof of possession of the existing keys
38
47
  """
39
48
  payload = {
@@ -92,6 +101,56 @@ class ServicePrincipal(DirectoryObject):
92
101
  self.context.add_query(qry)
93
102
  return return_type
94
103
 
104
+ def grant(self, app, app_role):
105
+ # type: (Application|str, AppRole|str) -> Self
106
+ """
107
+ Revokes an app role assignment to a client service principal
108
+ :param Application or str app: Application object or app identifier
109
+ :param AppRole or str app_role: AppRole object or name
110
+ """
111
+
112
+ def _grant(principal):
113
+ # type: ("ServicePrincipal") -> None
114
+ app_role_id = repr(app_role)
115
+ principal_id = principal.id
116
+ self.app_role_assigned_to.add(
117
+ principalId=principal_id, resourceId=self.id, appRoleId=app_role_id
118
+ )
119
+
120
+ def _ensure_principal():
121
+ self.context.service_principals.get_by_app(app).get().after_execute(_grant)
122
+
123
+ self.ensure_property("id", _ensure_principal)
124
+ return self
125
+
126
+ def revoke(self, app, app_role):
127
+ # type: (Application|str, AppRole|str) -> Self
128
+ """Revokes an app role assignment from a client service principal"""
129
+
130
+ def _revoke(principal):
131
+ # type ("ServicePrincipal") -> None
132
+ principal_id = principal.id
133
+ app_role_id = repr(app_role)
134
+ app_role_assigned_to_ids = [
135
+ item.id
136
+ for item in self.app_role_assigned_to
137
+ if item.principal_id == principal_id and item.app_role_id == app_role_id
138
+ ]
139
+ if len(app_role_assigned_to_ids) > 0:
140
+ self.app_role_assigned_to[app_role_assigned_to_ids[0]].delete_object()
141
+
142
+ def _ensure_resource(principal):
143
+ self.ensure_properties(["id", "appRoleAssignedTo"], _revoke, principal)
144
+ # self.app_role_assigned_to.get_all(page_loaded=_revoke)
145
+
146
+ def _ensure_principal():
147
+ self.context.service_principals.get_by_app(app).get().after_execute(
148
+ _ensure_resource
149
+ )
150
+
151
+ self.ensure_property("id", _ensure_principal)
152
+ return self
153
+
95
154
  def remove_password(self, key_id):
96
155
  """
97
156
  Remove a password from a servicePrincipal object.
@@ -129,9 +188,7 @@ class ServicePrincipal(DirectoryObject):
129
188
  @property
130
189
  def app_display_name(self):
131
190
  # type: () -> Optional[str]
132
- """
133
- The display name exposed by the associated application.
134
- """
191
+ """The display name exposed by the associated application."""
135
192
  return self.properties.get("appDisplayName", None)
136
193
 
137
194
  @property
@@ -151,14 +208,18 @@ class ServicePrincipal(DirectoryObject):
151
208
  """
152
209
  The roles exposed by the application which this service principal represents.
153
210
  """
154
- return self.properties.get("appRoles", ClientValueCollection(AppRole))
211
+ return self.properties.get("appRoles", AppRoleCollection())
212
+
213
+ @property
214
+ def display_name(self):
215
+ # type: () -> Optional[str]
216
+ """The display name."""
217
+ return self.properties.get("displayName", None)
155
218
 
156
219
  @property
157
220
  def homepage(self):
158
221
  # type: () -> Optional[str]
159
- """
160
- Home page or landing page of the application.
161
- """
222
+ """Home page or landing page of the application"""
162
223
  return self.properties.get("homepage", None)
163
224
 
164
225
  @property
@@ -184,10 +245,10 @@ class ServicePrincipal(DirectoryObject):
184
245
 
185
246
  @property
186
247
  def logout_url(self):
248
+ # type: () -> Optional[str]
187
249
  """
188
250
  Specifies the URL that will be used by Microsoft's authorization service to logout an user using
189
251
  OpenId Connect front-channel, back-channel or SAML logout protocols.
190
- :rtype: str
191
252
  """
192
253
  return self.properties.get("logoutUrl", None)
193
254
 
@@ -202,6 +263,7 @@ class ServicePrincipal(DirectoryObject):
202
263
 
203
264
  @property
204
265
  def service_principal_type(self):
266
+ # type: () -> Optional[str]
205
267
  """
206
268
  Identifies whether the service principal represents an application, a managed identity, or a legacy application.
207
269
  This is set by Azure AD internally. The servicePrincipalType property can be set to three different values:
@@ -220,8 +282,6 @@ class ServicePrincipal(DirectoryObject):
220
282
  but does not have an associated app registration. The appId value does not associate
221
283
  the service principal with an app registration.
222
284
  The service principal can only be used in the tenant where it was created.
223
-
224
- :rtype: str or None
225
285
  """
226
286
  return self.properties.get("servicePrincipalType", None)
227
287
 
@@ -249,6 +309,7 @@ class ServicePrincipal(DirectoryObject):
249
309
 
250
310
  @property
251
311
  def oauth2_permission_grants(self):
312
+ # type: () -> DeltaCollection[OAuth2PermissionGrant]
252
313
  """"""
253
314
  return self.properties.get(
254
315
  "oauth2PermissionGrants",
@@ -294,6 +355,7 @@ class ServicePrincipal(DirectoryObject):
294
355
 
295
356
  @property
296
357
  def token_encryption_key_id(self):
358
+ # type: () -> Optional[str]
297
359
  """
298
360
  Specifies the keyId of a public key from the keyCredentials collection. When configured, Azure AD issues tokens
299
361
  for this application encrypted using the key specified by this property. The application code that receives
@@ -315,3 +377,8 @@ class ServicePrincipal(DirectoryObject):
315
377
  }
316
378
  default_value = property_mapping.get(name, None)
317
379
  return super(ServicePrincipal, self).get_property(name, default_value)
380
+
381
+ def set_property(self, name, value, persist_changes=True):
382
+ if self._resource_path is None and name == "appId":
383
+ self._resource_path = AppIdPath(value, self.parent_collection.resource_path)
384
+ return super(ServicePrincipal, self).set_property(name, value, persist_changes)
@@ -1,4 +1,5 @@
1
1
  from datetime import datetime
2
+ from typing import Optional
2
3
 
3
4
  from office365.entity import Entity
4
5
  from office365.entity_collection import EntityCollection
@@ -15,14 +16,15 @@ class UserActivity(Entity):
15
16
 
16
17
  @property
17
18
  def activation_url(self):
19
+ # type: () -> Optional[str]
18
20
  """URL used to launch the activity in the best native experience represented by the appId.
19
21
  Might launch a web-based app if no native app exists
20
- :rtype: str or None
21
22
  """
22
23
  return self.properties.get("activationUrl", None)
23
24
 
24
25
  @property
25
26
  def activity_source_host(self):
27
+ # type: () -> Optional[str]
26
28
  """Required. URL for the domain representing the cross-platform identity mapping for the app.
27
29
  Mapping is stored either as a JSON file hosted on the domain or configurable via Windows Dev Center.
28
30
  The JSON file is named cross-platform-app-identifiers and is hosted at root of your HTTPS domain,
@@ -30,24 +32,23 @@ class UserActivity(Entity):
30
32
  For example: https://contoso.com or https://myapp.contoso.com but NOT https://myapp.contoso.com/somepath.
31
33
  You must have a unique file and domain (or sub domain) per cross-platform app identity.
32
34
  For example, a separate file and domain is needed for Word vs. PowerPoint.
33
- :rtype: str or None
34
35
  """
35
36
  return self.properties.get("activitySourceHost", None)
36
37
 
37
38
  @property
38
39
  def app_activity_id(self):
40
+ # type: () -> Optional[str]
39
41
  """
40
42
  The unique activity ID in the context of the app - supplied by caller and immutable thereafter.
41
- :rtype: str
42
43
  """
43
44
  return self.properties.get("appActivityId", None)
44
45
 
45
46
  @property
46
47
  def app_display_name(self):
48
+ # type: () -> Optional[str]
47
49
  """
48
50
  Short text description of the app used to generate the activity for use in cases when the app is
49
51
  not installed on the user’s local device.
50
- :rtype: str
51
52
  """
52
53
  return self.properties.get("appDisplayName", None)
53
54