Office365-REST-Python-Client 2.4.3__py3-none-any.whl → 2.4.4__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.
- {Office365_REST_Python_Client-2.4.3.dist-info → Office365_REST_Python_Client-2.4.4.dist-info}/METADATA +8 -7
- {Office365_REST_Python_Client-2.4.3.dist-info → Office365_REST_Python_Client-2.4.4.dist-info}/RECORD +254 -162
- office365/base_item.py +26 -4
- office365/communications/calls/invitation_participant_info.py +17 -1
- office365/communications/calls/options.py +9 -0
- office365/communications/onlinemeetings/provider_type.py +3 -0
- office365/communications/presences/presence.py +14 -0
- office365/communications/presences/status_message.py +12 -0
- office365/directory/audit/signins/activity.py +31 -0
- office365/directory/audit/signins/location.py +17 -0
- office365/directory/audit/signins/signin.py +25 -0
- office365/directory/authentication/authentication.py +9 -0
- office365/directory/authentication/methods/details.py +18 -0
- office365/directory/authentication/methods/email.py +16 -0
- office365/directory/authentication/methods/root.py +10 -0
- office365/directory/certificates/authority.py +6 -1
- office365/directory/extensions/extended_property.py +8 -1
- office365/directory/extensions/extension_property.py +0 -3
- office365/directory/extensions/open_type.py +8 -0
- office365/directory/groups/group.py +2 -1
- office365/directory/identities/governance.py +2 -0
- office365/directory/insights/shared.py +15 -1
- office365/directory/insights/usage_details.py +16 -0
- office365/directory/insights/used.py +7 -0
- office365/directory/licenses/assigned_plan.py +14 -2
- office365/directory/licenses/service_plan_info.py +4 -0
- office365/directory/licenses/subscribed_sku.py +26 -0
- office365/directory/licenses/units_detail.py +11 -0
- office365/directory/permissions/email_identity.py +5 -0
- office365/directory/permissions/grants/condition_set.py +26 -0
- office365/directory/permissions/grants/resource_specific.py +21 -0
- office365/directory/policies/authentication_flows.py +9 -0
- office365/directory/policies/authentication_strength.py +10 -0
- office365/directory/policies/authorization.py +8 -0
- office365/directory/policies/cross_tenant_access.py +5 -0
- office365/directory/policies/root.py +35 -2
- office365/directory/rolemanagement/template.py +8 -0
- office365/directory/rolemanagement/unified_role_assignment.py +37 -0
- office365/directory/security/alerts/alert.py +21 -0
- office365/directory/security/alerts/history_state.py +5 -0
- office365/directory/security/attacksimulations/automation.py +21 -0
- office365/directory/security/attacksimulations/automation_run.py +5 -0
- office365/directory/security/attacksimulations/repeat_offender.py +6 -0
- office365/directory/security/attacksimulations/root.py +26 -0
- office365/directory/security/attacksimulations/simulation.py +17 -0
- office365/directory/security/cases/ediscovery.py +6 -0
- office365/directory/security/cases/root.py +22 -0
- office365/directory/security/incidents/incident.py +67 -0
- office365/directory/security/security.py +10 -1
- office365/directory/serviceprincipals/service_principal.py +88 -3
- office365/directory/synchronization/job.py +16 -0
- office365/directory/synchronization/progress.py +5 -0
- office365/directory/synchronization/status.py +13 -0
- office365/directory/synchronization/synchronization.py +24 -0
- office365/directory/tenant_information.py +12 -0
- office365/directory/users/password_profile.py +15 -3
- office365/directory/users/user.py +136 -8
- office365/graph_client.py +28 -1
- office365/intune/audit/actor.py +5 -0
- office365/intune/audit/event.py +21 -25
- office365/intune/audit/event_collection.py +26 -0
- office365/intune/audit/property.py +5 -0
- office365/intune/audit/resource.py +11 -0
- office365/intune/brand.py +6 -0
- office365/intune/devices/compliance/__init__.py +0 -0
- office365/intune/devices/compliance/policy.py +6 -0
- office365/intune/devices/compliance/policy_state.py +5 -0
- office365/intune/devices/enrollment/__init__.py +0 -0
- office365/intune/devices/enrollment/configuration.py +25 -0
- office365/intune/devices/enrollment/configuration_assignment.py +5 -0
- office365/intune/devices/enrollment/limit_configuration.py +5 -0
- office365/intune/devices/managed.py +28 -3
- office365/intune/devices/management/__init__.py +0 -0
- office365/intune/devices/management/management.py +69 -0
- office365/intune/devices/management/reports/__init__.py +0 -0
- office365/intune/devices/management/reports/reports.py +5 -0
- office365/intune/devices/management/settings.py +18 -0
- office365/intune/organizations/branding.py +15 -0
- office365/intune/organizations/organization.py +14 -0
- office365/intune/printing/base.py +11 -0
- office365/intune/printing/capabilities.py +5 -0
- office365/intune/printing/connectors/__init__.py +0 -0
- office365/intune/printing/connectors/connector.py +6 -0
- office365/intune/printing/operations/__init__.py +0 -0
- office365/intune/printing/print.py +24 -0
- office365/intune/printing/printer.py +6 -0
- office365/intune/printing/services/__init__.py +0 -0
- office365/intune/printing/services/endpoint.py +5 -0
- office365/intune/printing/services/service.py +17 -0
- office365/intune/printing/share.py +5 -0
- office365/intune/printing/shares/__init__.py +0 -0
- office365/intune/printing/taskdefinitions/__init__.py +0 -0
- office365/intune/provisioned_plan.py +5 -1
- office365/intune/servicecommunications/issues/issue.py +15 -0
- office365/intune/vpp_token.py +10 -0
- office365/onedrive/columns/content_approval_status.py +5 -0
- office365/onedrive/columns/datetime.py +15 -0
- office365/onedrive/columns/definition.py +49 -3
- office365/onedrive/columns/definition_collection.py +17 -6
- office365/onedrive/columns/types.py +13 -0
- office365/onedrive/driveitems/audio.py +12 -1
- office365/onedrive/driveitems/driveItem.py +66 -15
- office365/onedrive/driveitems/image.py +8 -1
- office365/onedrive/driveitems/remote_item.py +19 -4
- office365/onedrive/drives/recipient.py +4 -0
- office365/onedrive/files/system_info.py +8 -6
- office365/onedrive/lists/collection.py +11 -5
- office365/onedrive/lists/list.py +13 -5
- office365/onedrive/operations/pending.py +13 -0
- office365/onedrive/operations/pending_content_update.py +5 -0
- office365/onedrive/permissions/collection.py +1 -1
- office365/onedrive/sensitivitylabels/__init__.py +0 -0
- office365/onedrive/sensitivitylabels/assignment.py +17 -0
- office365/onedrive/sensitivitylabels/assignment_method.py +4 -0
- office365/onedrive/sensitivitylabels/extract_result.py +13 -0
- office365/onedrive/sharepoint_settings.py +25 -0
- office365/outlook/calendar/calendar.py +116 -5
- office365/outlook/calendar/dateTimeTimeZone.py +3 -0
- office365/outlook/calendar/email_address.py +7 -0
- office365/outlook/calendar/events/event.py +0 -4
- office365/outlook/calendar/events/reminder.py +22 -3
- office365/outlook/calendar/group.py +0 -2
- office365/outlook/calendar/location_constraint.py +16 -1
- office365/outlook/calendar/permissions/__init__.py +0 -0
- office365/outlook/calendar/permissions/collection.py +24 -0
- office365/outlook/calendar/{permission.py → permissions/permission.py} +35 -2
- office365/outlook/calendar/role_type.py +17 -0
- office365/outlook/calendar/sharing_message.py +2 -2
- office365/outlook/calendar/time_zone_base.py +3 -0
- office365/outlook/calendar/working_hours.py +17 -1
- office365/outlook/contacts/collection.py +39 -0
- office365/outlook/contacts/contact.py +21 -11
- office365/outlook/geo_coordinates.py +20 -0
- office365/outlook/item.py +5 -2
- office365/outlook/locale_info.py +3 -0
- office365/outlook/mail/folders/folder.py +51 -2
- office365/outlook/mail/folders/search.py +11 -0
- office365/outlook/mail/importance.py +1 -0
- office365/outlook/mail/item_body.py +3 -0
- office365/outlook/mail/location.py +27 -2
- office365/outlook/mail/location_constraint_item.py +5 -0
- office365/outlook/mail/messages/collection.py +7 -0
- office365/outlook/mail/messages/followup_flag.py +21 -0
- office365/outlook/mail/messages/internet_header.py +16 -0
- office365/outlook/mail/messages/message.py +183 -4
- office365/outlook/mail/messages/rules/actions.py +33 -0
- office365/outlook/mail/patterned_recurrence.py +14 -1
- office365/outlook/mail/physical_address.py +5 -1
- office365/outlook/mail/recipient.py +3 -0
- office365/outlook/mail/recurrence_pattern.py +18 -1
- office365/outlook/mail/recurrence_range.py +16 -2
- office365/reports/root.py +19 -1
- office365/reports/security/__init__.py +0 -0
- office365/reports/security/root.py +21 -0
- office365/reports/userregistration/__init__.py +0 -0
- office365/reports/userregistration/method_count.py +17 -0
- office365/reports/userregistration/method_summary.py +21 -0
- office365/sharepoint/activities/logger.py +25 -0
- office365/sharepoint/addtoonedrive/mount_point.py +25 -0
- office365/sharepoint/addtoonedrive/mounted_folder_info.py +5 -0
- office365/sharepoint/alerts/alert.py +31 -0
- office365/sharepoint/changes/item.py +14 -0
- office365/sharepoint/client_context.py +6 -0
- office365/sharepoint/clientsidecomponent/component_context_info.py +7 -0
- office365/sharepoint/clientsidecomponent/identifier.py +3 -0
- office365/sharepoint/compliance/tag_info.py +17 -0
- office365/sharepoint/contenttypes/content_type.py +42 -0
- office365/sharepoint/contenttypes/fieldlinks/collection.py +5 -6
- office365/sharepoint/features/known_list.py +2 -0
- office365/sharepoint/fields/collection.py +60 -41
- office365/sharepoint/fields/creation_information.py +5 -4
- office365/sharepoint/fields/field.py +73 -15
- office365/sharepoint/fields/user.py +3 -3
- office365/sharepoint/files/file.py +9 -4
- office365/sharepoint/folders/coloring.py +39 -0
- office365/sharepoint/folders/coloring_information.py +15 -0
- office365/sharepoint/folders/folder.py +21 -10
- office365/sharepoint/forms/customization.py +8 -0
- office365/sharepoint/listitems/listitem.py +10 -3
- office365/sharepoint/lists/bloom_filter.py +0 -1
- office365/sharepoint/lists/creation_information.py +18 -4
- office365/sharepoint/lists/list.py +199 -24
- office365/sharepoint/lists/render_data_parameters.py +21 -1
- office365/sharepoint/navigation/configured_metadata_items.py +25 -1
- office365/sharepoint/navigation/metadata_settings.py +6 -4
- office365/sharepoint/permissions/irm/file_settings.py +43 -0
- office365/sharepoint/portal/userprofiles/documents_shared_with_group.py +3 -0
- office365/sharepoint/publishing/base_custom_property.py +8 -0
- office365/sharepoint/publishing/navigation/structural_navigation_cache_wrapper.py +8 -0
- office365/sharepoint/publishing/pagecopywithassets/__init__.py +0 -0
- office365/sharepoint/publishing/pagecopywithassets/response.py +8 -0
- office365/sharepoint/publishing/pages/campaign_publication.py +7 -0
- office365/sharepoint/publishing/pages/page.py +4 -1
- office365/sharepoint/publishing/pages/reposts/metadata.py +8 -0
- office365/sharepoint/publishing/personmagazine/person_magazine.py +4 -1
- office365/sharepoint/search/administration/tenant_crawl_versions_info_provider.py +8 -1
- office365/sharepoint/search/query/auto_completion_match.py +3 -0
- office365/sharepoint/search/query/property_value.py +18 -0
- office365/sharepoint/search/request.py +16 -2
- office365/sharepoint/sharing/abilities.py +22 -0
- office365/sharepoint/sharing/direct_abilities.py +27 -0
- office365/sharepoint/sharing/link_abilities.py +9 -1
- office365/sharepoint/sharing/links/data.py +26 -1
- office365/sharepoint/sharing/links/info.py +1 -1
- office365/sharepoint/sharing/links/partial_success_response.py +5 -0
- office365/sharepoint/sharing/links/share_settings.py +24 -1
- office365/sharepoint/sharing/object_sharing_information.py +65 -2
- office365/sharepoint/sharing/object_sharing_information_user.py +9 -0
- office365/sharepoint/sharing/object_sharing_settings.py +17 -4
- office365/sharepoint/sharing/principal.py +10 -0
- office365/sharepoint/sharing/securable_object_extensions.py +1 -17
- office365/sharepoint/sharing/site_sharing_report_helper.py +2 -1
- office365/sharepoint/sharing/user_sharing_result.py +18 -8
- office365/sharepoint/sitehealth/result.py +10 -0
- office365/sharepoint/sites/language.py +11 -1
- office365/sharepoint/sites/language_collection.py +1 -0
- office365/sharepoint/sites/site.py +34 -6
- office365/sharepoint/tenant/administration/audit/search_request_status.py +8 -0
- office365/sharepoint/tenant/administration/hubsites/permission.py +10 -0
- office365/sharepoint/tenant/administration/tenant.py +1 -0
- office365/sharepoint/tenant/apps/information.py +3 -1
- office365/sharepoint/tenant/management/office365_tenant.py +0 -1
- office365/sharepoint/types/resource_path.py +3 -1
- office365/sharepoint/userprofiles/people_manager.py +0 -2
- office365/sharepoint/userprofiles/sharedwithme/document.py +16 -0
- office365/sharepoint/userprofiles/sharedwithme/document_user.py +12 -0
- office365/sharepoint/userprofiles/sharedwithme/item_collection.py +41 -0
- office365/sharepoint/userprofiles/sharedwithme/items.py +18 -1
- office365/sharepoint/webs/web.py +2 -3
- office365/subscriptions/collection.py +12 -6
- office365/subscriptions/subscription.py +119 -1
- office365/teams/channels/iIdentity.py +5 -0
- office365/teams/chats/collection.py +1 -2
- office365/teams/chats/messages/info.py +9 -0
- office365/teams/chats/messages/message.py +17 -2
- office365/teams/members/aad_user_conversation.py +2 -2
- office365/teams/members/conversation_collection.py +3 -3
- office365/teams/schedule/change_tracked_entity.py +11 -2
- office365/teams/tabs/configuration.py +12 -1
- office365/teams/tabs/tab.py +0 -1
- office365/teams/team.py +23 -1
- office365/teams/teamwork/__init__.py +0 -0
- office365/teams/teamwork/activity_topic.py +5 -0
- office365/teams/teamwork/tags/__init__.py +0 -0
- office365/teams/teamwork/tags/member.py +5 -0
- office365/{directory/security/cases_root.py → teams/viva/employee_experience_user.py} +1 -1
- office365/intune/devices/management.py +0 -35
- {Office365_REST_Python_Client-2.4.3.dist-info → Office365_REST_Python_Client-2.4.4.dist-info}/LICENSE +0 -0
- {Office365_REST_Python_Client-2.4.3.dist-info → Office365_REST_Python_Client-2.4.4.dist-info}/WHEEL +0 -0
- {Office365_REST_Python_Client-2.4.3.dist-info → Office365_REST_Python_Client-2.4.4.dist-info}/top_level.txt +0 -0
- /office365/{teams/messages → directory/security/cases}/__init__.py +0 -0
- /office365/{teams/tags → directory/synchronization}/__init__.py +0 -0
- /office365/teams/{tags → teamwork/tags}/identity.py +0 -0
- /office365/teams/{tags → teamwork/tags}/tag.py +0 -0
- /office365/teams/{user_teamwork.py → teamwork/user.py} +0 -0
|
@@ -19,6 +19,23 @@ class PermissionGrantConditionSet(Entity):
|
|
|
19
19
|
"""
|
|
20
20
|
return self.properties.get("clientApplicationIds", StringCollection())
|
|
21
21
|
|
|
22
|
+
@property
|
|
23
|
+
def client_application_publisher_ids(self):
|
|
24
|
+
"""
|
|
25
|
+
A list of Microsoft Partner Network (MPN) IDs for verified publishers of the client application, or a list
|
|
26
|
+
with the single value all to match with client apps from any publisher. Default is the single value all.
|
|
27
|
+
"""
|
|
28
|
+
return self.properties.get("clientApplicationPublisherIds", StringCollection())
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def client_applications_from_verified_publisher_only(self):
|
|
32
|
+
"""
|
|
33
|
+
Set to true to only match on client applications with a verified publisher. Set to false to match on any client
|
|
34
|
+
app, even if it does not have a verified publisher. Default is false.
|
|
35
|
+
:rtype: bool
|
|
36
|
+
"""
|
|
37
|
+
return self.properties.get("clientApplicationsFromVerifiedPublisherOnly", None)
|
|
38
|
+
|
|
22
39
|
@property
|
|
23
40
|
def permissions(self):
|
|
24
41
|
"""
|
|
@@ -30,3 +47,12 @@ class PermissionGrantConditionSet(Entity):
|
|
|
30
47
|
Default is the single value all.
|
|
31
48
|
"""
|
|
32
49
|
return self.properties.get("permissions", StringCollection())
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def resource_application(self):
|
|
53
|
+
"""
|
|
54
|
+
The appId of the resource application (e.g. the API) for which a permission is being granted, or any to match
|
|
55
|
+
with any resource application or API. Default is any.
|
|
56
|
+
:rtype: str
|
|
57
|
+
"""
|
|
58
|
+
return self.properties.get("resourceApplication", None)
|
|
@@ -17,3 +17,24 @@ class ResourceSpecificPermissionGrant(DirectoryObject):
|
|
|
17
17
|
"""ID of the service principal of the Azure AD app that has been granted access."""
|
|
18
18
|
return self.properties.get("clientAppId", None)
|
|
19
19
|
|
|
20
|
+
@property
|
|
21
|
+
def permission(self):
|
|
22
|
+
"""The name of the resource-specific permission.
|
|
23
|
+
:rtype: str
|
|
24
|
+
"""
|
|
25
|
+
return self.properties.get("permission", None)
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
def permission_type(self):
|
|
29
|
+
"""The type of permission. Possible values are: Application, Delegated. Read-only.
|
|
30
|
+
:rtype: str
|
|
31
|
+
"""
|
|
32
|
+
return self.properties.get("permissionType", None)
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def resource_app_id(self):
|
|
36
|
+
"""ID of the Azure AD app that is hosting the resource. Read-only.
|
|
37
|
+
:rtype: str
|
|
38
|
+
"""
|
|
39
|
+
return self.properties.get("resourceAppId", None)
|
|
40
|
+
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
from office365.entity import Entity
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class AuthenticationFlowsPolicy(Entity):
|
|
5
|
+
"""
|
|
6
|
+
Represents the policy configuration of self-service sign-up experience at a tenant level that lets external
|
|
7
|
+
users request to sign up for approval. It contains information, such as the identifier, display name, and
|
|
8
|
+
description, and indicates whether self-service sign-up is enabled for the policy.
|
|
9
|
+
"""
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
from office365.entity import Entity
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class AuthenticationStrengthPolicy(Entity):
|
|
5
|
+
"""
|
|
6
|
+
A collection of settings that define specific combinations of authentication methods and metadata.
|
|
7
|
+
The authentication strength policy, when applied to a given scenario using Azure AD Conditional Access,
|
|
8
|
+
defines which authentication methods must be used to authenticate in that scenario. An authentication strength
|
|
9
|
+
may be built-in or custom (defined by the tenant) and may or may not fulfill the requirements to grant an MFA claim.
|
|
10
|
+
"""
|
|
@@ -4,3 +4,11 @@ from office365.directory.policies.base import PolicyBase
|
|
|
4
4
|
class AuthorizationPolicy(PolicyBase):
|
|
5
5
|
"""Represents a policy that can control Azure Active Directory authorization settings.
|
|
6
6
|
It's a singleton that inherits from base policy type, and always exists for the tenant."""
|
|
7
|
+
|
|
8
|
+
@property
|
|
9
|
+
def allowed_to_sign_up_email_based_subscriptions(self):
|
|
10
|
+
"""
|
|
11
|
+
Indicates whether a user can join the tenant by email validation.
|
|
12
|
+
:rtype: bool
|
|
13
|
+
"""
|
|
14
|
+
return self.properties.get("allowedToSignUpEmailBasedSubscriptions", None)
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
from office365.directory.policies.app_management import AppManagementPolicy
|
|
2
|
+
from office365.directory.policies.authentication_flows import AuthenticationFlowsPolicy
|
|
1
3
|
from office365.directory.policies.authentication_methods import AuthenticationMethodsPolicy
|
|
4
|
+
from office365.directory.policies.authentication_strength import AuthenticationStrengthPolicy
|
|
5
|
+
from office365.directory.policies.cross_tenant_access import CrossTenantAccessPolicy
|
|
2
6
|
from office365.directory.policies.permission_grant import PermissionGrantPolicy
|
|
3
7
|
from office365.directory.policies.authorization import AuthorizationPolicy
|
|
4
8
|
from office365.directory.policies.conditional_access import ConditionalAccessPolicy
|
|
@@ -21,6 +25,22 @@ class PolicyRoot(Entity):
|
|
|
21
25
|
ResourcePath("authenticationMethodsPolicy",
|
|
22
26
|
self.resource_path)))
|
|
23
27
|
|
|
28
|
+
def authentication_strength_policies(self):
|
|
29
|
+
"""
|
|
30
|
+
The authentication method combinations that are to be used in scenarios defined by Azure AD Conditional Access.
|
|
31
|
+
"""
|
|
32
|
+
return self.properties.get('authenticationStrengthPolicies',
|
|
33
|
+
EntityCollection(self.context, AuthenticationStrengthPolicy,
|
|
34
|
+
ResourcePath("authenticationStrengthPolicies", self.resource_path)))
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
def authentication_flows_policy(self):
|
|
38
|
+
""" The policy configuration of the self-service sign-up experience of external users."""
|
|
39
|
+
return self.properties.get('authenticationFlowsPolicy',
|
|
40
|
+
AuthenticationFlowsPolicy(self.context,
|
|
41
|
+
ResourcePath("authenticationFlowsPolicy",
|
|
42
|
+
self.resource_path)))
|
|
43
|
+
|
|
24
44
|
@property
|
|
25
45
|
def authorization_policy(self):
|
|
26
46
|
"""The policy that controls Azure AD authorization settings."""
|
|
@@ -33,8 +53,18 @@ class PolicyRoot(Entity):
|
|
|
33
53
|
"""The policies that enforce app management restrictions for specific applications and service principals,
|
|
34
54
|
overriding the defaultAppManagementPolicy."""
|
|
35
55
|
return self.properties.get('appManagementPolicies',
|
|
36
|
-
|
|
37
|
-
|
|
56
|
+
EntityCollection(self.context, AppManagementPolicy,
|
|
57
|
+
ResourcePath("appManagementPolicies", self.resource_path)))
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def cross_tenant_access_policy(self):
|
|
61
|
+
"""
|
|
62
|
+
The custom rules that define an access scenario when interacting with external Azure AD tenants.
|
|
63
|
+
"""
|
|
64
|
+
return self.properties.get('crossTenantAccessPolicy',
|
|
65
|
+
CrossTenantAccessPolicy(self.context,
|
|
66
|
+
ResourcePath("crossTenantAccessPolicy",
|
|
67
|
+
self.resource_path)))
|
|
38
68
|
|
|
39
69
|
@property
|
|
40
70
|
def permission_grant_policies(self):
|
|
@@ -57,10 +87,13 @@ class PolicyRoot(Entity):
|
|
|
57
87
|
def get_property(self, name, default_value=None):
|
|
58
88
|
if default_value is None:
|
|
59
89
|
property_mapping = {
|
|
90
|
+
"authenticationStrengthPolicies": self.authentication_strength_policies,
|
|
91
|
+
"authenticationFlowsPolicy": self.authentication_flows_policy,
|
|
60
92
|
"appManagementPolicies": self.app_management_policies,
|
|
61
93
|
"authenticationMethodsPolicy": self.authentication_methods_policy,
|
|
62
94
|
"authorizationPolicy": self.authorization_policy,
|
|
63
95
|
"conditional_access_policies": self.conditional_access_policies,
|
|
96
|
+
"crossTenantAccessPolicy": self.cross_tenant_access_policy,
|
|
64
97
|
"permissionGrantPolicies": self.permission_grant_policies,
|
|
65
98
|
}
|
|
66
99
|
default_value = property_mapping.get(name, None)
|
|
@@ -4,3 +4,11 @@ from office365.directory.object import DirectoryObject
|
|
|
4
4
|
class DirectoryRoleTemplate(DirectoryObject):
|
|
5
5
|
"""Represents a directory role template. A directory role template specifies the property values of a directory
|
|
6
6
|
role (directoryRole). """
|
|
7
|
+
|
|
8
|
+
@property
|
|
9
|
+
def display_name(self):
|
|
10
|
+
"""
|
|
11
|
+
The display name to set for the directory role
|
|
12
|
+
:rtype: str
|
|
13
|
+
"""
|
|
14
|
+
return self.properties.get("displayName", None)
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
from office365.directory.rolemanagement.unified_role_definition import UnifiedRoleDefinition
|
|
1
2
|
from office365.entity import Entity
|
|
3
|
+
from office365.runtime.paths.resource_path import ResourcePath
|
|
2
4
|
|
|
3
5
|
|
|
4
6
|
class UnifiedRoleAssignment(Entity):
|
|
@@ -6,3 +8,38 @@ class UnifiedRoleAssignment(Entity):
|
|
|
6
8
|
A role assignment is used to grant access to resources. It represents a role definition assigned to a principal
|
|
7
9
|
(for example, a user or a role-assignable group) at a particular scope.
|
|
8
10
|
"""
|
|
11
|
+
|
|
12
|
+
@property
|
|
13
|
+
def app_scope_id(self):
|
|
14
|
+
"""
|
|
15
|
+
Identifier of the app-specific scope when the assignment scope is app-specific. Either this property or
|
|
16
|
+
directoryScopeId is required. App scopes are scopes that are defined and understood by this application only.
|
|
17
|
+
Use / for tenant-wide app scopes. Use directoryScopeId to limit the scope to particular directory objects,
|
|
18
|
+
for example, administrative units. Supports $filter (eq, in).
|
|
19
|
+
:rtype: str
|
|
20
|
+
"""
|
|
21
|
+
return self.properties.get("appScopeId", None)
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
def condition(self):
|
|
25
|
+
"""
|
|
26
|
+
:rtype: str
|
|
27
|
+
"""
|
|
28
|
+
return self.properties.get("condition", None)
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def role_definition(self):
|
|
32
|
+
"""
|
|
33
|
+
The roleDefinition the assignment is for. Supports $expand. roleDefinition.Id will be auto expanded.
|
|
34
|
+
"""
|
|
35
|
+
return self.properties.get('roleDefinition',
|
|
36
|
+
UnifiedRoleDefinition(self.context,
|
|
37
|
+
ResourcePath("roleDefinition", self.resource_path)))
|
|
38
|
+
|
|
39
|
+
def get_property(self, name, default_value=None):
|
|
40
|
+
if default_value is None:
|
|
41
|
+
property_mapping = {
|
|
42
|
+
"roleDefinition": self.role_definition,
|
|
43
|
+
}
|
|
44
|
+
default_value = property_mapping.get(name, None)
|
|
45
|
+
return super(UnifiedRoleAssignment, self).get_property(name, default_value)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from office365.directory.security.alerts.evidence import AlertEvidence
|
|
2
|
+
from office365.directory.security.alerts.history_state import AlertHistoryState
|
|
2
3
|
from office365.entity import Entity
|
|
3
4
|
from office365.runtime.client_value_collection import ClientValueCollection
|
|
4
5
|
|
|
@@ -8,7 +9,27 @@ class Alert(Entity):
|
|
|
8
9
|
representing potential security issues within a customer's tenant that Microsoft 365 Defender,
|
|
9
10
|
or a security provider integrated with Microsoft 365 Defender, has identified."""
|
|
10
11
|
|
|
12
|
+
@property
|
|
13
|
+
def actor_display_name(self):
|
|
14
|
+
"""
|
|
15
|
+
The adversary or activity group that is associated with this alert.
|
|
16
|
+
:rtype: str
|
|
17
|
+
"""
|
|
18
|
+
return self.properties.get("actorDisplayName", None)
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def alert_policy_id(self):
|
|
22
|
+
"""
|
|
23
|
+
:rtype: str
|
|
24
|
+
"""
|
|
25
|
+
return self.properties.get("alertPolicyId", None)
|
|
26
|
+
|
|
11
27
|
@property
|
|
12
28
|
def evidence(self):
|
|
13
29
|
"""Collection of evidence related to the alert."""
|
|
14
30
|
return self.properties.get("evidence", ClientValueCollection(AlertEvidence))
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def history_states(self):
|
|
34
|
+
"""Collection of changes for the alert."""
|
|
35
|
+
return self.properties.get("historyStates", ClientValueCollection(AlertHistoryState))
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from office365.directory.permissions.email_identity import EmailIdentity
|
|
2
|
+
from office365.directory.security.attacksimulations.automation_run import SimulationAutomationRun
|
|
3
|
+
from office365.entity import Entity
|
|
4
|
+
from office365.entity_collection import EntityCollection
|
|
5
|
+
from office365.runtime.paths.resource_path import ResourcePath
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SimulationAutomation(Entity):
|
|
9
|
+
"""Represents simulation automation created to run on a tenant."""
|
|
10
|
+
|
|
11
|
+
@property
|
|
12
|
+
def created_by(self):
|
|
13
|
+
"""Identity of the user who created the attack simulation automation."""
|
|
14
|
+
return self.properties.get('createdBy', EmailIdentity())
|
|
15
|
+
|
|
16
|
+
@property
|
|
17
|
+
def runs(self):
|
|
18
|
+
"""A collection of simulation automation runs."""
|
|
19
|
+
return self.properties.get('runs',
|
|
20
|
+
EntityCollection(self.context, SimulationAutomationRun,
|
|
21
|
+
ResourcePath("runs", self.resource_path)))
|
|
@@ -1,6 +1,32 @@
|
|
|
1
|
+
from office365.directory.security.attacksimulations.automation import SimulationAutomation
|
|
2
|
+
from office365.directory.security.attacksimulations.simulation import Simulation
|
|
1
3
|
from office365.entity import Entity
|
|
4
|
+
from office365.entity_collection import EntityCollection
|
|
5
|
+
from office365.runtime.paths.resource_path import ResourcePath
|
|
2
6
|
|
|
3
7
|
|
|
4
8
|
class AttackSimulationRoot(Entity):
|
|
5
9
|
"""Represents an abstract type that provides the ability to launch a realistic phishing attack that organizations
|
|
6
10
|
can learn from."""
|
|
11
|
+
|
|
12
|
+
@property
|
|
13
|
+
def simulations(self):
|
|
14
|
+
"""Represents an attack simulation training campaign in a tenant."""
|
|
15
|
+
return self.properties.get('simulations',
|
|
16
|
+
EntityCollection(self.context, Simulation,
|
|
17
|
+
ResourcePath("simulations", self.resource_path)))
|
|
18
|
+
|
|
19
|
+
@property
|
|
20
|
+
def simulation_automations(self):
|
|
21
|
+
"""Represents simulation automation created to run on a tenant."""
|
|
22
|
+
return self.properties.get('simulationAutomations',
|
|
23
|
+
EntityCollection(self.context, SimulationAutomation,
|
|
24
|
+
ResourcePath("simulationAutomations", self.resource_path)))
|
|
25
|
+
|
|
26
|
+
def get_property(self, name, default_value=None):
|
|
27
|
+
if default_value is None:
|
|
28
|
+
property_mapping = {
|
|
29
|
+
"simulationAutomations": self.simulation_automations,
|
|
30
|
+
}
|
|
31
|
+
default_value = property_mapping.get(name, None)
|
|
32
|
+
return super(AttackSimulationRoot, self).get_property(name, default_value)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from office365.entity import Entity
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Simulation(Entity):
|
|
5
|
+
"""
|
|
6
|
+
Represents an attack simulation training campaign in a tenant.
|
|
7
|
+
|
|
8
|
+
Attack simulation and training is a service available as part of Microsoft Defender for Office 365.
|
|
9
|
+
This service lets tenant users experience a realistic benign phishing attack and learn from it.
|
|
10
|
+
The service enables tenant administrators to simulate, assign trainings, and read derived insights into online
|
|
11
|
+
behaviors of users in the phishing simulations. The service provides attack simulation reports that help tenants
|
|
12
|
+
identify security knowledge gaps, so that they can further train their users to decrease their susceptibility
|
|
13
|
+
to attacks.
|
|
14
|
+
|
|
15
|
+
The attack simulation and training API enables tenant administrators to list launched simulation exercises
|
|
16
|
+
and trainings, and get reports on derived insights into online behaviors of users in the phishing simulations.
|
|
17
|
+
"""
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from office365.directory.security.cases.ediscovery import EdiscoveryCase
|
|
2
|
+
from office365.entity import Entity
|
|
3
|
+
from office365.entity_collection import EntityCollection
|
|
4
|
+
from office365.runtime.paths.resource_path import ResourcePath
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class CasesRoot(Entity):
|
|
8
|
+
""""""
|
|
9
|
+
|
|
10
|
+
@property
|
|
11
|
+
def ediscovery_cases(self):
|
|
12
|
+
return self.properties.get('ediscoveryCases',
|
|
13
|
+
EntityCollection(self.context, EdiscoveryCase,
|
|
14
|
+
ResourcePath("ediscoveryCases", self.resource_path)))
|
|
15
|
+
|
|
16
|
+
def get_property(self, name, default_value=None):
|
|
17
|
+
if default_value is None:
|
|
18
|
+
property_mapping = {
|
|
19
|
+
"ediscoveryCases": self.ediscovery_cases
|
|
20
|
+
}
|
|
21
|
+
default_value = property_mapping.get(name, None)
|
|
22
|
+
return super(CasesRoot, self).get_property(name, default_value)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
|
|
3
|
+
from office365.directory.security.alerts.alert import Alert
|
|
4
|
+
from office365.directory.security.alerts.comment import AlertComment
|
|
5
|
+
from office365.entity import Entity
|
|
6
|
+
from office365.entity_collection import EntityCollection
|
|
7
|
+
from office365.runtime.client_value_collection import ClientValueCollection
|
|
8
|
+
from office365.runtime.paths.resource_path import ResourcePath
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Incident(Entity):
|
|
12
|
+
"""
|
|
13
|
+
An incident in Microsoft 365 Defender is a collection of correlated alert instances and associated metadata
|
|
14
|
+
that reflects the story of an attack in a tenant.
|
|
15
|
+
|
|
16
|
+
Microsoft 365 services and apps create alerts when they detect a suspicious or malicious event or activity.
|
|
17
|
+
Individual alerts provide valuable clues about a completed or ongoing attack. However, attacks typically employ
|
|
18
|
+
various techniques against different types of entities, such as devices, users, and mailboxes. The result is
|
|
19
|
+
multiple alerts for multiple entities in your tenant. Because piecing the individual alerts together to gain
|
|
20
|
+
insight into an attack can be challenging and time-consuming, Microsoft 365 Defender automatically aggregates the
|
|
21
|
+
alerts and their associated information into an incident.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def assigned_to(self):
|
|
26
|
+
"""
|
|
27
|
+
Owner of the incident, or null if no owner is assigned. Free editable text.
|
|
28
|
+
:rtype: str or None
|
|
29
|
+
"""
|
|
30
|
+
return self.properties.get("assignedTo", None)
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def classification(self):
|
|
34
|
+
"""
|
|
35
|
+
The specification for the incident.
|
|
36
|
+
Possible values are: unknown, falsePositive, truePositive, informationalExpectedActivity, unknownFutureValue.
|
|
37
|
+
:rtype: str or None
|
|
38
|
+
"""
|
|
39
|
+
return self.properties.get("classification", None)
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def comments(self):
|
|
43
|
+
"""
|
|
44
|
+
Array of comments created by the Security Operations (SecOps) team when the incident is managed.
|
|
45
|
+
"""
|
|
46
|
+
return self.properties.get("comments", ClientValueCollection(AlertComment))
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def created_datetime(self):
|
|
50
|
+
"""
|
|
51
|
+
Time when the incident was first created.
|
|
52
|
+
"""
|
|
53
|
+
return self.properties("createdDateTime", datetime.min)
|
|
54
|
+
|
|
55
|
+
@property
|
|
56
|
+
def alerts(self):
|
|
57
|
+
"""The list of related alerts. Supports $expand."""
|
|
58
|
+
return self.properties.get('alerts',
|
|
59
|
+
EntityCollection(self.context, Alert, ResourcePath("alerts", self.resource_path)))
|
|
60
|
+
|
|
61
|
+
def get_property(self, name, default_value=None):
|
|
62
|
+
if default_value is None:
|
|
63
|
+
property_mapping = {
|
|
64
|
+
"createdDateTime": self.created_datetime
|
|
65
|
+
}
|
|
66
|
+
default_value = property_mapping.get(name, None)
|
|
67
|
+
return super(Incident, self).get_property(name, default_value)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from office365.directory.security.alerts.alert import Alert
|
|
2
2
|
from office365.directory.security.attacksimulations.root import AttackSimulationRoot
|
|
3
|
-
from office365.directory.security.
|
|
3
|
+
from office365.directory.security.cases.root import CasesRoot
|
|
4
|
+
from office365.directory.security.incidents.incident import Incident
|
|
4
5
|
from office365.directory.security.triggers.root import TriggersRoot
|
|
5
6
|
from office365.entity import Entity
|
|
6
7
|
from office365.entity_collection import EntityCollection
|
|
@@ -37,6 +38,14 @@ class Security(Entity):
|
|
|
37
38
|
AttackSimulationRoot(self.context,
|
|
38
39
|
ResourcePath("attackSimulation", self.resource_path)))
|
|
39
40
|
|
|
41
|
+
@property
|
|
42
|
+
def incidents(self):
|
|
43
|
+
"""A collection of correlated alert instances and associated metadata that reflects the story of
|
|
44
|
+
an attack in a tenant"""
|
|
45
|
+
return self.properties.get('incidents',
|
|
46
|
+
EntityCollection(self.context, Incident,
|
|
47
|
+
ResourcePath("incidents", self.resource_path)))
|
|
48
|
+
|
|
40
49
|
@property
|
|
41
50
|
def triggers(self):
|
|
42
51
|
return self.properties.get('triggers',
|
|
@@ -7,10 +7,12 @@ from office365.directory.object import DirectoryObject
|
|
|
7
7
|
from office365.directory.password_credential import PasswordCredential
|
|
8
8
|
from office365.directory.permissions.grants.oauth2 import OAuth2PermissionGrant
|
|
9
9
|
from office365.directory.permissions.scope import PermissionScope
|
|
10
|
+
from office365.directory.synchronization.synchronization import Synchronization
|
|
10
11
|
from office365.runtime.client_result import ClientResult
|
|
11
12
|
from office365.runtime.client_value_collection import ClientValueCollection
|
|
12
13
|
from office365.runtime.paths.resource_path import ResourcePath
|
|
13
14
|
from office365.runtime.queries.service_operation import ServiceOperationQuery
|
|
15
|
+
from office365.runtime.types.collections import StringCollection
|
|
14
16
|
|
|
15
17
|
|
|
16
18
|
class ServicePrincipal(DirectoryObject):
|
|
@@ -85,17 +87,44 @@ class ServicePrincipal(DirectoryObject):
|
|
|
85
87
|
return return_type
|
|
86
88
|
|
|
87
89
|
def remove_password(self, key_id):
|
|
88
|
-
"""
|
|
89
|
-
|
|
90
|
+
"""
|
|
91
|
+
Remove a password from a servicePrincipal object.
|
|
90
92
|
:param str key_id: The unique identifier for the password.
|
|
91
93
|
"""
|
|
92
94
|
qry = ServiceOperationQuery(self, "removePassword", None, {"keyId": key_id})
|
|
93
95
|
self.context.add_query(qry)
|
|
94
96
|
return self
|
|
95
97
|
|
|
98
|
+
@property
|
|
99
|
+
def account_enabled(self):
|
|
100
|
+
"""
|
|
101
|
+
true if the service principal account is enabled; otherwise, false. If set to false, then no users will be
|
|
102
|
+
able to sign in to this app, even if they are assigned to it. Supports $filter (eq, ne, not, in).
|
|
103
|
+
:rtype: bool
|
|
104
|
+
"""
|
|
105
|
+
return self.properties.get('accountEnabled', None)
|
|
106
|
+
|
|
107
|
+
@property
|
|
108
|
+
def alternative_names(self):
|
|
109
|
+
"""
|
|
110
|
+
Used to retrieve service principals by subscription, identify resource group and full resource ids for
|
|
111
|
+
managed identities. Supports $filter (eq, not, ge, le, startsWith).
|
|
112
|
+
"""
|
|
113
|
+
return self.properties.get('alternativeNames', StringCollection())
|
|
114
|
+
|
|
115
|
+
@property
|
|
116
|
+
def app_description(self):
|
|
117
|
+
"""
|
|
118
|
+
The description exposed by the associated application.
|
|
119
|
+
:rtype: str
|
|
120
|
+
"""
|
|
121
|
+
return self.properties.get('appDescription', None)
|
|
122
|
+
|
|
96
123
|
@property
|
|
97
124
|
def app_display_name(self):
|
|
98
|
-
"""
|
|
125
|
+
"""
|
|
126
|
+
The display name exposed by the associated application.
|
|
127
|
+
:rtype: str
|
|
99
128
|
"""
|
|
100
129
|
return self.properties.get('appDisplayName', None)
|
|
101
130
|
|
|
@@ -108,6 +137,51 @@ class ServicePrincipal(DirectoryObject):
|
|
|
108
137
|
AppRoleAssignmentCollection(self.context,
|
|
109
138
|
ResourcePath("appRoleAssignedTo", self.resource_path)))
|
|
110
139
|
|
|
140
|
+
@property
|
|
141
|
+
def homepage(self):
|
|
142
|
+
"""
|
|
143
|
+
Home page or landing page of the application.
|
|
144
|
+
:rtype: str
|
|
145
|
+
"""
|
|
146
|
+
return self.properties.get('homepage', None)
|
|
147
|
+
|
|
148
|
+
@property
|
|
149
|
+
def key_credentials(self):
|
|
150
|
+
"""
|
|
151
|
+
The collection of key credentials associated with the service principal. Not nullable.
|
|
152
|
+
Supports $filter (eq, not, ge, le).
|
|
153
|
+
"""
|
|
154
|
+
return self.properties.setdefault('keyCredentials', ClientValueCollection(KeyCredential))
|
|
155
|
+
|
|
156
|
+
@property
|
|
157
|
+
def login_url(self):
|
|
158
|
+
"""
|
|
159
|
+
Specifies the URL where the service provider redirects the user to Azure AD to authenticate.
|
|
160
|
+
Azure AD uses the URL to launch the application from Microsoft 365 or the Azure AD My Apps. When blank,
|
|
161
|
+
Azure AD performs IdP-initiated sign-on for applications configured with SAML-based single sign-on.
|
|
162
|
+
The user launches the application from Microsoft 365, the Azure AD My Apps, or the Azure AD SSO URL.
|
|
163
|
+
:rtype: str
|
|
164
|
+
"""
|
|
165
|
+
return self.properties.get('loginUrl', None)
|
|
166
|
+
|
|
167
|
+
@property
|
|
168
|
+
def logout_url(self):
|
|
169
|
+
"""
|
|
170
|
+
Specifies the URL that will be used by Microsoft's authorization service to logout an user using
|
|
171
|
+
OpenId Connect front-channel, back-channel or SAML logout protocols.
|
|
172
|
+
:rtype: str
|
|
173
|
+
"""
|
|
174
|
+
return self.properties.get('logoutUrl', None)
|
|
175
|
+
|
|
176
|
+
@property
|
|
177
|
+
def notification_email_addresses(self):
|
|
178
|
+
"""
|
|
179
|
+
Specifies the list of email addresses where Azure AD sends a notification when the active certificate is near
|
|
180
|
+
the expiration date. This is only for the certificates used to sign the SAML token issued for Azure
|
|
181
|
+
AD Gallery applications.
|
|
182
|
+
"""
|
|
183
|
+
return self.properties.get('notificationEmailAddresses', StringCollection())
|
|
184
|
+
|
|
111
185
|
@property
|
|
112
186
|
def service_principal_type(self):
|
|
113
187
|
"""
|
|
@@ -170,6 +244,16 @@ class ServicePrincipal(DirectoryObject):
|
|
|
170
244
|
DirectoryObjectCollection(self.context,
|
|
171
245
|
ResourcePath("ownedObjects", self.resource_path)))
|
|
172
246
|
|
|
247
|
+
@property
|
|
248
|
+
def synchronization(self):
|
|
249
|
+
"""
|
|
250
|
+
Represents the capability for Azure Active Directory (Azure AD) identity synchronization through
|
|
251
|
+
the Microsoft Graph API.
|
|
252
|
+
"""
|
|
253
|
+
return self.properties.get('synchronization',
|
|
254
|
+
Synchronization(self.context,
|
|
255
|
+
ResourcePath("synchronization", self.resource_path)))
|
|
256
|
+
|
|
173
257
|
@property
|
|
174
258
|
def token_encryption_key_id(self):
|
|
175
259
|
"""
|
|
@@ -185,6 +269,7 @@ class ServicePrincipal(DirectoryObject):
|
|
|
185
269
|
property_mapping = {
|
|
186
270
|
"appRoleAssignedTo": self.app_role_assigned_to,
|
|
187
271
|
"created_objects": self.created_objects,
|
|
272
|
+
"keyCredentials": self.key_credentials,
|
|
188
273
|
"oauth2PermissionScopes": self.oauth2_permission_scopes,
|
|
189
274
|
"ownedObjects": self.owned_objects,
|
|
190
275
|
"oauth2PermissionGrants": self.oauth2_permission_grants
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from office365.directory.synchronization.status import SynchronizationStatus
|
|
2
|
+
from office365.entity import Entity
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class SynchronizationJob(Entity):
|
|
6
|
+
"""
|
|
7
|
+
Performs synchronization by periodically running in the background, polling for changes in one directory,
|
|
8
|
+
and pushing them to another directory. The synchronization job is always specific to a particular instance
|
|
9
|
+
of an application in your tenant. As part of the synchronization job setup, you need to give authorization
|
|
10
|
+
to read and write objects in your target directory, and customize the job's synchronization schema.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
@property
|
|
14
|
+
def status(self):
|
|
15
|
+
"""Status of the job, which includes when the job was last run, current job state, and errors."""
|
|
16
|
+
return self.properties.get("status", SynchronizationStatus())
|