From 3600a76f352d2c6733b55fed37db39250a7f23a9 Mon Sep 17 00:00:00 2001 From: vgrem Date: Sat, 28 Sep 2024 22:07:25 +0300 Subject: [PATCH] SharePoint API (web, list & portal namespaces) updated --- .../applications/has_delegated_perms.py | 4 +- .../applications/list_application_perms.py | 10 +- .../applications/list_delegated_perms.py | 14 +- .../applications/revoke_application_perms.py | 4 +- .../applications/revoke_delegated_perms.py | 4 +- examples/sharepoint/__init__.py | 2 - .../sharepoint/lists/get_data_as_stream.py | 28 ++++ .../tenant/export_tenant_settings.py | 3 +- generator/import_metadata.py | 4 +- generator/metadata/MicrosoftGraph.xml | 136 ++++++++++++++++ generator/metadata/SharePoint.xml | 150 +++++++++++++++++- .../communications/callrecords/collection.py | 5 +- .../applications/required_resource_access.py | 1 - .../directory/applications/resource_access.py | 4 +- .../authentication/methods/details.py | 29 ++++ .../directory/authentication/methods/root.py | 8 + office365/directory/permissions/scope.py | 2 +- .../security/attacksimulations/user.py | 2 +- .../attacksimulations/users/details.py | 4 +- office365/runtime/client_result.py | 2 + .../sharepoint/listhome/favorite_item.py | 9 ++ office365/sharepoint/lists/data_parameters.py | 5 + office365/sharepoint/lists/list.py | 34 +++- .../lists/render_data_parameters.py | 9 ++ .../sharepoint/portal/groups/site_manager.py | 14 ++ .../sharepoint/portal/project/__init__.py | 9 ++ .../userprofiles/documentsshared}/__init__.py | 0 .../with_group.py} | 4 +- .../with_me.py} | 0 .../documentsshared/with_person.py | 9 ++ .../userprofiles/sharedwithme/__init__.py | 0 .../userprofiles/sharedwithme/document.py | 2 +- .../sharedwithme/document_user.py | 0 .../sharedwithme/item_collection.py | 0 .../userprofiles/sharedwithme/items.py | 4 +- .../sharedwithme/view_item_removal_result.py | 0 .../sharepoint/sharing/document_manager.py | 6 +- office365/sharepoint/sitescripts/metadata.py | 31 +++- office365/sharepoint/smartcache/__init__.py | 0 office365/sharepoint/smartcache/item.py | 9 ++ .../administration/app_billing_properties.py | 11 ++ .../administration/sites/creation_source.py | 16 +- .../tenant/administration/tenant.py | 47 +++++- .../sharepoint/webs/templates/__init__.py | 0 office365/sharepoint/webs/time_zone.py | 2 +- office365/sharepoint/webs/web.py | 21 +++ tests/communications/test_callrecords.py | 2 +- tests/directory/test_identity.py | 2 +- 48 files changed, 597 insertions(+), 65 deletions(-) create mode 100644 examples/sharepoint/lists/get_data_as_stream.py create mode 100644 office365/sharepoint/listhome/favorite_item.py create mode 100644 office365/sharepoint/lists/data_parameters.py create mode 100644 office365/sharepoint/portal/project/__init__.py rename office365/sharepoint/{userprofiles/sharedwithme => portal/userprofiles/documentsshared}/__init__.py (100%) rename office365/sharepoint/portal/userprofiles/{documents_shared_with_group.py => documentsshared/with_group.py} (91%) rename office365/sharepoint/portal/userprofiles/{documents_shared_with_me.py => documentsshared/with_me.py} (100%) create mode 100644 office365/sharepoint/portal/userprofiles/documentsshared/with_person.py create mode 100644 office365/sharepoint/portal/userprofiles/sharedwithme/__init__.py rename office365/sharepoint/{ => portal}/userprofiles/sharedwithme/document.py (95%) rename office365/sharepoint/{ => portal}/userprofiles/sharedwithme/document_user.py (100%) rename office365/sharepoint/{ => portal}/userprofiles/sharedwithme/item_collection.py (100%) rename office365/sharepoint/{ => portal}/userprofiles/sharedwithme/items.py (88%) rename office365/sharepoint/{ => portal}/userprofiles/sharedwithme/view_item_removal_result.py (100%) create mode 100644 office365/sharepoint/smartcache/__init__.py create mode 100644 office365/sharepoint/smartcache/item.py create mode 100644 office365/sharepoint/tenant/administration/app_billing_properties.py create mode 100644 office365/sharepoint/webs/templates/__init__.py diff --git a/examples/directory/applications/has_delegated_perms.py b/examples/directory/applications/has_delegated_perms.py index 52414d54d..cd169c2a3 100644 --- a/examples/directory/applications/has_delegated_perms.py +++ b/examples/directory/applications/has_delegated_perms.py @@ -24,7 +24,9 @@ user = client.users.get_by_principal_name(test_admin_principal_name) client_app = client.applications.get_by_app_id(test_client_id) # result = resource.get_delegated(client_app, user, app_role).execute_query() -result = resource.get_delegated_permissions(test_client_id, user, app_role).execute_query() +result = resource.get_delegated_permissions( + test_client_id, user, app_role +).execute_query() if len(result) == 0: print("Delegated permission '{0}' is not set".format(app_role)) else: diff --git a/examples/directory/applications/list_application_perms.py b/examples/directory/applications/list_application_perms.py index 391f74529..79728f679 100644 --- a/examples/directory/applications/list_application_perms.py +++ b/examples/directory/applications/list_application_perms.py @@ -10,8 +10,8 @@ from office365.graph_client import GraphClient from tests import ( test_client_id, - test_tenant, test_client_secret, + test_tenant, ) # client = GraphClient.with_token_interactive( @@ -21,14 +21,8 @@ client = GraphClient.with_client_secret(test_tenant, test_client_id, test_client_secret) -resource = ( - client.service_principals.get_by_name("Microsoft Graph") -) +resource = client.service_principals.get_by_name("Microsoft Graph") result = resource.get_application_permissions(test_client_id).execute_query() for app_role in result.value: print(app_role) - - - - diff --git a/examples/directory/applications/list_delegated_perms.py b/examples/directory/applications/list_delegated_perms.py index 39689ae65..b4d3c1872 100644 --- a/examples/directory/applications/list_delegated_perms.py +++ b/examples/directory/applications/list_delegated_perms.py @@ -10,19 +10,23 @@ from office365.graph_client import GraphClient from tests import ( test_client_id, - test_tenant, test_client_secret, + test_tenant, ) -#client = GraphClient.with_token_interactive( +# client = GraphClient.with_token_interactive( # test_tenant, test_client_id, test_admin_principal_name -#) +# ) client = GraphClient.with_client_secret(test_tenant, test_client_id, test_client_secret) -resource = client.service_principals.get_by_name("Microsoft Graph").get().execute_query() -result = resource.get_delegated_permissions(test_client_id, only_admin_consent=True).execute_query() +resource = ( + client.service_principals.get_by_name("Microsoft Graph").get().execute_query() +) +result = resource.get_delegated_permissions( + test_client_id, only_admin_consent=True +).execute_query() for grant in result: print(grant.scope) diff --git a/examples/directory/applications/revoke_application_perms.py b/examples/directory/applications/revoke_application_perms.py index e4da2c0f5..02da38b77 100644 --- a/examples/directory/applications/revoke_application_perms.py +++ b/examples/directory/applications/revoke_application_perms.py @@ -24,4 +24,6 @@ # Get resource resource = client.service_principals.get_by_name("Microsoft Graph") -resource.revoke_application_permissions(test_client_id, "MailboxSettings.Read").execute_query() +resource.revoke_application_permissions( + test_client_id, "MailboxSettings.Read" +).execute_query() diff --git a/examples/directory/applications/revoke_delegated_perms.py b/examples/directory/applications/revoke_delegated_perms.py index 669f4e7b4..f7add907e 100644 --- a/examples/directory/applications/revoke_delegated_perms.py +++ b/examples/directory/applications/revoke_delegated_perms.py @@ -19,4 +19,6 @@ # Step 1: Get resource service principal resource = client.service_principals.get_by_name("Microsoft Graph") user = client.users.get_by_principal_name(test_user_principal_name) -resource.revoke_delegated_permissions(test_client_id, user, "User.Read.All").execute_query() +resource.revoke_delegated_permissions( + test_client_id, user, "User.Read.All" +).execute_query() diff --git a/examples/sharepoint/__init__.py b/examples/sharepoint/__init__.py index b28b04f64..8b1378917 100644 --- a/examples/sharepoint/__init__.py +++ b/examples/sharepoint/__init__.py @@ -1,3 +1 @@ - - diff --git a/examples/sharepoint/lists/get_data_as_stream.py b/examples/sharepoint/lists/get_data_as_stream.py new file mode 100644 index 000000000..2187593ea --- /dev/null +++ b/examples/sharepoint/lists/get_data_as_stream.py @@ -0,0 +1,28 @@ +""" +Returns a SharePoint List data +""" +from office365.sharepoint.client_context import ClientContext +from tests import test_client_credentials, test_team_site_url + +ctx = ClientContext(test_team_site_url).with_credentials(test_client_credentials) + +view_xml = """ + + + + + + + + + + + 100 + +""" + + +result = ( + ctx.web.get_list_data_as_stream("/Shared Documents", view_xml=view_xml).execute_query() +) +print(result.value) diff --git a/examples/sharepoint/tenant/export_tenant_settings.py b/examples/sharepoint/tenant/export_tenant_settings.py index fffcb9d44..536039ef4 100644 --- a/examples/sharepoint/tenant/export_tenant_settings.py +++ b/examples/sharepoint/tenant/export_tenant_settings.py @@ -1,10 +1,11 @@ +""" """ from office365.sharepoint.client_context import ClientContext from tests import test_admin_credentials, test_admin_site_url admin_client = ClientContext(test_admin_site_url).with_credentials( test_admin_credentials ) -result = admin_client.tenant.export_to_csv().execute_query() +result = admin_client.tenant.export_to_csv(view_xml="", list_name="Style Library").execute_query() print( "Sites details have been exported into {0}{1}".format( test_admin_site_url, result.value diff --git a/generator/import_metadata.py b/generator/import_metadata.py index 310481611..324762b51 100644 --- a/generator/import_metadata.py +++ b/generator/import_metadata.py @@ -26,13 +26,13 @@ def export_to_file(path, content): "--endpoint", dest="endpoint", help="Import metadata endpoint", - default="graph", + default="sharepoint", ) parser.add_argument( "-p", "--path", dest="path", - default="./metadata/MicrosoftGraph.xml", + default="./metadata/SharePoint.xml", help="Import metadata endpoint", ) diff --git a/generator/metadata/MicrosoftGraph.xml b/generator/metadata/MicrosoftGraph.xml index 1f5c810e7..d7365ef90 100644 --- a/generator/metadata/MicrosoftGraph.xml +++ b/generator/metadata/MicrosoftGraph.xml @@ -3773,6 +3773,27 @@ + + + + + + + + + + + + + + + + + + + + + @@ -3909,6 +3930,7 @@ + @@ -4163,6 +4185,7 @@ + @@ -6158,6 +6181,9 @@ + + + @@ -16768,6 +16794,57 @@ + + + + + + + + + + + + + Org.OData.Core.V1.Permission/Read + + + + + + + + + + + + + + + + + + + + + + + + + + + Org.OData.Core.V1.Permission/Read + + + + + + Org.OData.Core.V1.Permission/Read + + @@ -40522,6 +40599,15 @@ + + + + + + + + + @@ -40532,6 +40618,8 @@ + + @@ -40577,12 +40665,28 @@ + + + + + + + + + + + + + + + + @@ -41218,6 +41322,17 @@ + + + + + + + + + + + @@ -41361,13 +41476,16 @@ + + + @@ -42107,6 +42225,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/generator/metadata/SharePoint.xml b/generator/metadata/SharePoint.xml index 0187d5c5e..4294e20bb 100644 --- a/generator/metadata/SharePoint.xml +++ b/generator/metadata/SharePoint.xml @@ -4769,12 +4769,14 @@ + + @@ -5992,6 +5994,10 @@ + + + + @@ -10336,6 +10342,7 @@ + @@ -10538,19 +10545,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -10558,6 +10595,9 @@ + + + @@ -13096,6 +13136,7 @@ + @@ -16755,6 +16796,14 @@ + + + + + + + + @@ -16843,6 +16892,10 @@ + + + + @@ -17010,6 +17063,7 @@ + @@ -22337,6 +22391,9 @@ + + + @@ -22718,6 +22775,12 @@ + + + + + + @@ -22739,6 +22802,9 @@ + + + @@ -24291,6 +24357,9 @@ + + + @@ -25227,6 +25296,9 @@ + + + @@ -25350,6 +25422,12 @@ + + + + + + @@ -25593,6 +25671,9 @@ + + + @@ -26715,7 +26796,7 @@ - + @@ -27633,7 +27714,7 @@ - + @@ -28506,6 +28587,12 @@ + + + + + + @@ -33409,6 +33496,7 @@ + @@ -35574,11 +35662,11 @@ - + - + - + @@ -36766,6 +36854,8 @@ + + @@ -37411,6 +37501,12 @@ + + + + + + @@ -38288,6 +38384,9 @@ + + + @@ -38349,6 +38448,14 @@ + + + + + + + + @@ -38368,6 +38475,18 @@ + + + + + + + + + + + + @@ -38618,6 +38737,13 @@ + + + + + + + @@ -38661,12 +38787,18 @@ + + + + + + - + - - + + @@ -38765,6 +38897,8 @@ + + diff --git a/office365/communications/callrecords/collection.py b/office365/communications/callrecords/collection.py index c705a40e3..bb9a62819 100644 --- a/office365/communications/callrecords/collection.py +++ b/office365/communications/callrecords/collection.py @@ -29,7 +29,10 @@ def get_direct_routing_calls(self, from_datetime=None, to_datetime=None): return_type = ClientResult( self.context, ClientValueCollection(DirectRoutingLogRow) ) - payload = {"fromDateTime": from_datetime.strftime('%Y-%m-%d'), "toDateTime": to_datetime.strftime('%Y-%m-%d')} + payload = { + "fromDateTime": from_datetime.strftime("%Y-%m-%d"), + "toDateTime": to_datetime.strftime("%Y-%m-%d"), + } qry = FunctionQuery(self, "getDirectRoutingCalls", payload, return_type) def _patch_request(request): diff --git a/office365/directory/applications/required_resource_access.py b/office365/directory/applications/required_resource_access.py index f6d7c85e5..0531132c9 100644 --- a/office365/directory/applications/required_resource_access.py +++ b/office365/directory/applications/required_resource_access.py @@ -19,6 +19,5 @@ def __init__(self, resource_access=None, resource_app_id=None): self.resourceAccess = ClientValueCollection(ResourceAccess, resource_access) self.resourceAppId = resource_app_id - def __repr__(self): return self.resourceAppId or self.entity_type_name diff --git a/office365/directory/applications/resource_access.py b/office365/directory/applications/resource_access.py index df26f60ec..27ca51e97 100644 --- a/office365/directory/applications/resource_access.py +++ b/office365/directory/applications/resource_access.py @@ -2,8 +2,8 @@ class ResourceAccess(ClientValue): - """ Object used to specify an OAuth 2.0 permission scope or an app role that an application requires, - through the resourceAccess property of the requiredResourceAccess resource type. """ + """Object used to specify an OAuth 2.0 permission scope or an app role that an application requires, + through the resourceAccess property of the requiredResourceAccess resource type.""" def __init__(self, id_=None, type_=None): """ diff --git a/office365/directory/authentication/methods/details.py b/office365/directory/authentication/methods/details.py index b019a482b..10caa41fa 100644 --- a/office365/directory/authentication/methods/details.py +++ b/office365/directory/authentication/methods/details.py @@ -54,6 +54,32 @@ def is_sspr_enabled(self): """ return self.properties.get("isSsprEnabled", None) + @property + def user_display_name(self): + # type: () -> Optional[str] + """ + The user display name, such as Adele Vance. Supports $filter (eq, startsWith) and $orderby. + """ + return self.properties.get("userDisplayName", None) + + @property + def user_preferred_method_for_secondary_authentication(self): + # type: () -> Optional[str] + """ + The method the user selected as the default second-factor for performing multifactor authentication. + """ + return self.properties.get( + "userPreferredMethodForSecondaryAuthentication", None + ) + + @property + def user_principal_name(self): + # type: () -> Optional[str] + """ + The user principal name, such as AdeleV@contoso.com. Supports $filter (eq, startsWith) and $orderby. + """ + return self.properties.get("userPrincipalName", None) + @property def user_type(self): # type: () -> Optional[str] @@ -62,3 +88,6 @@ def user_type(self): The possible values are: member, guest, unknownFutureValue. """ return self.properties.get("userType", None) + + def __repr__(self): + return self.user_principal_name or self.id or self.entity_type_name diff --git a/office365/directory/authentication/methods/root.py b/office365/directory/authentication/methods/root.py index d6dc5bf1e..904538737 100644 --- a/office365/directory/authentication/methods/root.py +++ b/office365/directory/authentication/methods/root.py @@ -32,3 +32,11 @@ def user_registration_details(self): ResourcePath("userRegistrationDetails", self.resource_path), ), ) + + def get_property(self, name, default_value=None): + if default_value is None: + property_mapping = { + "userRegistrationDetails": self.user_registration_details + } + default_value = property_mapping.get(name, None) + return super(AuthenticationMethodsRoot, self).get_property(name, default_value) diff --git a/office365/directory/permissions/scope.py b/office365/directory/permissions/scope.py index 8adf7b051..6d58bd8a9 100644 --- a/office365/directory/permissions/scope.py +++ b/office365/directory/permissions/scope.py @@ -21,7 +21,7 @@ def __init__( type_=None, user_consent_description=None, user_consent_display_name=None, - value=None + value=None, ): """ :param str admin_consent_display_name: The permission's title, intended to be read by an administrator granting diff --git a/office365/directory/security/attacksimulations/user.py b/office365/directory/security/attacksimulations/user.py index 3fcc0b4af..bbc3552d6 100644 --- a/office365/directory/security/attacksimulations/user.py +++ b/office365/directory/security/attacksimulations/user.py @@ -2,4 +2,4 @@ class AttackSimulationUser(ClientValue): - """ Represents a user in an attack simulation and training campaign. """ + """Represents a user in an attack simulation and training campaign.""" diff --git a/office365/directory/security/attacksimulations/users/details.py b/office365/directory/security/attacksimulations/users/details.py index c391b8070..e6f08f7b8 100644 --- a/office365/directory/security/attacksimulations/users/details.py +++ b/office365/directory/security/attacksimulations/users/details.py @@ -5,7 +5,9 @@ class UserSimulationDetails(ClientValue): """Represents a user of a tenant and their online actions in an attack simulation and training campaign.""" - def __init__(self, assigned_trainings_count=None, simulation_user=AttackSimulationUser()): + def __init__( + self, assigned_trainings_count=None, simulation_user=AttackSimulationUser() + ): """ :param int assigned_trainings_count: Number of trainings assigned to a user in an attack simulation and training campaign. diff --git a/office365/runtime/client_result.py b/office365/runtime/client_result.py index 5103fbf9f..b212adc34 100644 --- a/office365/runtime/client_result.py +++ b/office365/runtime/client_result.py @@ -40,6 +40,8 @@ def set_property(self, key, value, persist_changes=False): if isinstance(self._value, ClientValue): self._value.set_property(key, value, persist_changes) + elif isinstance(self._value, dict): + self._value[key] = value else: self._value = value return self diff --git a/office365/sharepoint/listhome/favorite_item.py b/office365/sharepoint/listhome/favorite_item.py new file mode 100644 index 000000000..76bc0cc73 --- /dev/null +++ b/office365/sharepoint/listhome/favorite_item.py @@ -0,0 +1,9 @@ +from office365.sharepoint.listhome.item import ListHomeItem + + +class FavoriteListHomeItem(ListHomeItem): + """ """ + + @property + def entity_type_name(self): + return "Microsoft.SharePoint.ListHome.FavoriteListHomeItem" diff --git a/office365/sharepoint/lists/data_parameters.py b/office365/sharepoint/lists/data_parameters.py new file mode 100644 index 000000000..aafffdac4 --- /dev/null +++ b/office365/sharepoint/lists/data_parameters.py @@ -0,0 +1,5 @@ +from office365.runtime.client_value import ClientValue + + +class RenderListFilterDataParameters(ClientValue): + """Specifies the parameters that are used to retrieve filter data.""" diff --git a/office365/sharepoint/lists/list.py b/office365/sharepoint/lists/list.py index afc506e40..eefa2d2b3 100644 --- a/office365/sharepoint/lists/list.py +++ b/office365/sharepoint/lists/list.py @@ -393,25 +393,46 @@ def render_list_data(self, view_xml): return return_type @staticmethod - def get_list_data_as_stream(context, list_full_url, parameters=None): + def get_list_data_as_stream( + context, + list_full_url, + parameters=None, + casc_del_warn_message=None, + custom_action=None, + drill_down=None, + field=None, + field_internal_name=None, + return_type=None, + ): """ Returns list data from the specified list url and for the specified query parameters. :param office365.sharepoint.client_context.ClientContext context: Client context :param str list_full_url: The absolute URL of the list. :param RenderListDataParameters parameters: The parameters to be used. - """ - result = ClientResult(context) + :param str casc_del_warn_message: + :param str custom_action: + :param str drill_down: + :param str field: + :param str field_internal_name: + :param ClientResult[dict] return_type: The return type. + """ + if return_type is None: + return_type = ClientResult(context, dict()) payload = { "listFullUrl": list_full_url, "parameters": parameters, + "CascDelWarnMessage": casc_del_warn_message, + "CustomAction": custom_action, + "DrillDown": drill_down, + "Field": field, + "FieldInternalName": field_internal_name, } - target_list = context.web.get_list(list_full_url) qry = ServiceOperationQuery( - target_list, "GetListDataAsStream", None, payload, None, result + List(context), "GetListDataAsStream", None, payload, None, return_type, True ) context.add_query(qry) - return result + return return_type def bulk_validate_update_list_items( self, @@ -451,6 +472,7 @@ def bulk_validate_update_list_items( def get_lookup_field_choices(self, target_field_name, paging_info=None): """ + Retrieves the possible choices or values for a lookup field in a SharePoint list :param str target_field_name: :param str paging_info: """ diff --git a/office365/sharepoint/lists/render_data_parameters.py b/office365/sharepoint/lists/render_data_parameters.py index 7be71e0e1..dae3363ff 100644 --- a/office365/sharepoint/lists/render_data_parameters.py +++ b/office365/sharepoint/lists/render_data_parameters.py @@ -16,6 +16,9 @@ def __init__( expand_groups=None, expand_user_field=None, filter_out_channel_folders_in_default_doc_lib=None, + require_folder_coloring_fields=None, + show_stub_file=None, + view_xml=None, ): """ :param bool add_all_fields: @@ -29,6 +32,9 @@ def __init__( :param bool expand_groups: Specifies whether to expand the grouping or not. :param bool expand_user_field: :param bool filter_out_channel_folders_in_default_doc_lib: + :param bool require_folder_coloring_fields: + :param bool show_stub_file: + :param str view_xml: """ self.AddAllFields = add_all_fields self.AddAllViewFields = add_all_view_fields @@ -44,6 +50,9 @@ def __init__( self.FilterOutChannelFoldersInDefaultDocLib = ( filter_out_channel_folders_in_default_doc_lib ) + self.RequireFolderColoringFields = require_folder_coloring_fields + self.ShowStubFile = show_stub_file + self.ViewXml = view_xml @property def entity_type_name(self): diff --git a/office365/sharepoint/portal/groups/site_manager.py b/office365/sharepoint/portal/groups/site_manager.py index 238e4d5a3..f9c10e048 100644 --- a/office365/sharepoint/portal/groups/site_manager.py +++ b/office365/sharepoint/portal/groups/site_manager.py @@ -15,12 +15,17 @@ class GroupSiteManager(ClientObject): + """Management of Group Sites in SharePoint. Group Sites, also known as Microsoft 365 Groups, + provide collaboration spaces that integrate with various Microsoft 365 services like Teams, Outlook, and Planner. + """ + def __init__(self, context, resource_path=None): if resource_path is None: resource_path = ResourcePath("GroupSiteManager") super(GroupSiteManager, self).__init__(context, resource_path) def can_user_create_group(self): + """Determines if the current user can create group site""" return_type = ClientResult(self.context, bool()) qry = ServiceOperationQuery( self, "CanUserCreateGroup", None, None, None, return_type @@ -131,6 +136,7 @@ def get_current_user_joined_teams( return result def get_current_user_shared_channel_member_groups(self): + """ """ return_type = ClientResult(self.context) qry = ServiceOperationQuery( self, @@ -145,6 +151,8 @@ def get_current_user_shared_channel_member_groups(self): def get_team_channels(self, team_id, use_staging_endpoint=False): """ + Retrieves the channels associated with a specific Microsoft 365 Group (or Team) + :param str team_id: :param bool use_staging_endpoint: """ @@ -188,6 +196,8 @@ def recent_and_joined_teams( existing_joined_teams_data=None, ): """ + Retrieves a list of teams that a user has recently accessed or joined + :param bool include_recent: :param bool include_teams: :param bool include_pinned: @@ -205,3 +215,7 @@ def recent_and_joined_teams( ) self.context.add_query(qry) return return_type + + @property + def entity_type_name(self): + return "Microsoft.SharePoint.Portal.GroupSiteManager" diff --git a/office365/sharepoint/portal/project/__init__.py b/office365/sharepoint/portal/project/__init__.py new file mode 100644 index 000000000..c7f38c6ce --- /dev/null +++ b/office365/sharepoint/portal/project/__init__.py @@ -0,0 +1,9 @@ +from office365.runtime.client_value import ClientValue + + +class MyRecsCacheBlob(ClientValue): + """""" + + @property + def entity_type_name(self): + return "Microsoft.SharePoint.Portal.Project.MyRecsCacheBlob" diff --git a/office365/sharepoint/userprofiles/sharedwithme/__init__.py b/office365/sharepoint/portal/userprofiles/documentsshared/__init__.py similarity index 100% rename from office365/sharepoint/userprofiles/sharedwithme/__init__.py rename to office365/sharepoint/portal/userprofiles/documentsshared/__init__.py diff --git a/office365/sharepoint/portal/userprofiles/documents_shared_with_group.py b/office365/sharepoint/portal/userprofiles/documentsshared/with_group.py similarity index 91% rename from office365/sharepoint/portal/userprofiles/documents_shared_with_group.py rename to office365/sharepoint/portal/userprofiles/documentsshared/with_group.py index e00bf0408..a2edd2ae9 100644 --- a/office365/sharepoint/portal/userprofiles/documents_shared_with_group.py +++ b/office365/sharepoint/portal/userprofiles/documentsshared/with_group.py @@ -1,7 +1,9 @@ from office365.runtime.queries.service_operation import ServiceOperationQuery from office365.sharepoint.entity import Entity from office365.sharepoint.entity_collection import EntityCollection -from office365.sharepoint.userprofiles.sharedwithme.document import SharedWithMeDocument +from office365.sharepoint.portal.userprofiles.sharedwithme.document import ( + SharedWithMeDocument, +) class DocumentsSharedWithGroup(Entity): diff --git a/office365/sharepoint/portal/userprofiles/documents_shared_with_me.py b/office365/sharepoint/portal/userprofiles/documentsshared/with_me.py similarity index 100% rename from office365/sharepoint/portal/userprofiles/documents_shared_with_me.py rename to office365/sharepoint/portal/userprofiles/documentsshared/with_me.py diff --git a/office365/sharepoint/portal/userprofiles/documentsshared/with_person.py b/office365/sharepoint/portal/userprofiles/documentsshared/with_person.py new file mode 100644 index 000000000..3a8eae8e1 --- /dev/null +++ b/office365/sharepoint/portal/userprofiles/documentsshared/with_person.py @@ -0,0 +1,9 @@ +from office365.sharepoint.entity import Entity + + +class DocumentsSharedWithPerson(Entity): + """ """ + + @property + def entity_type_name(self): + return "Microsoft.SharePoint.Portal.UserProfiles.DocumentsSharedWithPerson" diff --git a/office365/sharepoint/portal/userprofiles/sharedwithme/__init__.py b/office365/sharepoint/portal/userprofiles/sharedwithme/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/office365/sharepoint/userprofiles/sharedwithme/document.py b/office365/sharepoint/portal/userprofiles/sharedwithme/document.py similarity index 95% rename from office365/sharepoint/userprofiles/sharedwithme/document.py rename to office365/sharepoint/portal/userprofiles/sharedwithme/document.py index f87791282..13a9a3816 100644 --- a/office365/sharepoint/userprofiles/sharedwithme/document.py +++ b/office365/sharepoint/portal/userprofiles/sharedwithme/document.py @@ -3,7 +3,7 @@ from office365.runtime.client_value_collection import ClientValueCollection from office365.sharepoint.entity import Entity -from office365.sharepoint.userprofiles.sharedwithme.document_user import ( +from office365.sharepoint.portal.userprofiles.sharedwithme.document_user import ( SharedWithMeDocumentUser, ) diff --git a/office365/sharepoint/userprofiles/sharedwithme/document_user.py b/office365/sharepoint/portal/userprofiles/sharedwithme/document_user.py similarity index 100% rename from office365/sharepoint/userprofiles/sharedwithme/document_user.py rename to office365/sharepoint/portal/userprofiles/sharedwithme/document_user.py diff --git a/office365/sharepoint/userprofiles/sharedwithme/item_collection.py b/office365/sharepoint/portal/userprofiles/sharedwithme/item_collection.py similarity index 100% rename from office365/sharepoint/userprofiles/sharedwithme/item_collection.py rename to office365/sharepoint/portal/userprofiles/sharedwithme/item_collection.py diff --git a/office365/sharepoint/userprofiles/sharedwithme/items.py b/office365/sharepoint/portal/userprofiles/sharedwithme/items.py similarity index 88% rename from office365/sharepoint/userprofiles/sharedwithme/items.py rename to office365/sharepoint/portal/userprofiles/sharedwithme/items.py index ad61115fd..2a1a6f3a5 100644 --- a/office365/sharepoint/userprofiles/sharedwithme/items.py +++ b/office365/sharepoint/portal/userprofiles/sharedwithme/items.py @@ -1,7 +1,9 @@ from office365.runtime.queries.service_operation import ServiceOperationQuery from office365.sharepoint.entity import Entity from office365.sharepoint.entity_collection import EntityCollection -from office365.sharepoint.userprofiles.sharedwithme.document import SharedWithMeDocument +from office365.sharepoint.portal.userprofiles.sharedwithme.document import ( + SharedWithMeDocument, +) class SharedWithMeItems(Entity): diff --git a/office365/sharepoint/userprofiles/sharedwithme/view_item_removal_result.py b/office365/sharepoint/portal/userprofiles/sharedwithme/view_item_removal_result.py similarity index 100% rename from office365/sharepoint/userprofiles/sharedwithme/view_item_removal_result.py rename to office365/sharepoint/portal/userprofiles/sharedwithme/view_item_removal_result.py diff --git a/office365/sharepoint/sharing/document_manager.py b/office365/sharepoint/sharing/document_manager.py index c00e0ee07..2b257a893 100644 --- a/office365/sharepoint/sharing/document_manager.py +++ b/office365/sharepoint/sharing/document_manager.py @@ -3,11 +3,11 @@ from office365.runtime.queries.service_operation import ServiceOperationQuery from office365.sharepoint.entity import Entity from office365.sharepoint.permissions.roles.definitions.definition import RoleDefinition -from office365.sharepoint.sharing.user_role_assignment import UserRoleAssignment -from office365.sharepoint.sharing.user_sharing_result import UserSharingResult -from office365.sharepoint.userprofiles.sharedwithme.view_item_removal_result import ( +from office365.sharepoint.portal.userprofiles.sharedwithme.view_item_removal_result import ( SharedWithMeViewItemRemovalResult, ) +from office365.sharepoint.sharing.user_role_assignment import UserRoleAssignment +from office365.sharepoint.sharing.user_sharing_result import UserSharingResult class DocumentSharingManager(Entity): diff --git a/office365/sharepoint/sitescripts/metadata.py b/office365/sharepoint/sitescripts/metadata.py index 664ad7f77..cc6384ed5 100644 --- a/office365/sharepoint/sitescripts/metadata.py +++ b/office365/sharepoint/sitescripts/metadata.py @@ -2,11 +2,36 @@ class SiteScriptMetadata(ClientValue): - def __init__(self, _id=None, content=None, description=None): + """Represents metadata about a SharePoint site script in the SharePoint framework. + Site scripts are used to automate the provisioning of SharePoint sites by defining actions like + applying a theme, adding lists, and configuring site settings.""" + + def __init__( + self, + id_=None, + content=None, + description=None, + is_site_script_package=None, + title=None, + version=None, + ): """ - :param str content: + :param str id_: unique identifier (GUID) for the site script. This is used to uniquely identify the script + within SharePoint. + :param str content: The actual JSON content of the site script. This contains the actions that the script + will execute when applied to a SharePoint site. :param str description: + :param bool is_site_script_package: + :param str title: + :param int version: """ - self.Id = _id + self.Id = id_ self.Content = content self.Description = description + self.IsSiteScriptPackage = is_site_script_package + self.Title = title + self.Version = version + + @property + def entity_type_name(self): + return "Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteScriptMetadata" diff --git a/office365/sharepoint/smartcache/__init__.py b/office365/sharepoint/smartcache/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/office365/sharepoint/smartcache/item.py b/office365/sharepoint/smartcache/item.py new file mode 100644 index 000000000..eeca84ac1 --- /dev/null +++ b/office365/sharepoint/smartcache/item.py @@ -0,0 +1,9 @@ +from office365.sharepoint.entity import Entity + + +class SmartCacheItem(Entity): + """ """ + + @property + def entity_type_name(self): + return "Microsoft.SharePoint.SmartCache.SmartCacheItem" diff --git a/office365/sharepoint/tenant/administration/app_billing_properties.py b/office365/sharepoint/tenant/administration/app_billing_properties.py new file mode 100644 index 000000000..57190100e --- /dev/null +++ b/office365/sharepoint/tenant/administration/app_billing_properties.py @@ -0,0 +1,11 @@ +from office365.runtime.client_value import ClientValue + + +class SPOAppBillingProperties(ClientValue): + """ """ + + @property + def entity_type_name(self): + return ( + "Microsoft.Online.SharePoint.TenantAdministration.SPOAppBillingProperties" + ) diff --git a/office365/sharepoint/tenant/administration/sites/creation_source.py b/office365/sharepoint/tenant/administration/sites/creation_source.py index 9f578ade8..56f51e12b 100644 --- a/office365/sharepoint/tenant/administration/sites/creation_source.py +++ b/office365/sharepoint/tenant/administration/sites/creation_source.py @@ -11,20 +11,20 @@ class SiteCreationSource(ClientValue): def __init__( self, - IsSyncThresholdLimitReached=None, - LastRefreshTimeStamp=None, + is_sync_threshold_limit_reached=None, + last_refresh_time_stamp=None, site_creation_data=None, - SyncThresholdLimit=None, - TotalSitesCount=None, + sync_threshold_limit=None, + total_sites_count=None, ): # type: (bool, datetime, List[SiteCreationData], int, int) -> None - self.IsSyncThresholdLimitReached = IsSyncThresholdLimitReached - self.LastRefreshTimeStamp = LastRefreshTimeStamp + self.IsSyncThresholdLimitReached = is_sync_threshold_limit_reached + self.LastRefreshTimeStamp = last_refresh_time_stamp self.SiteCreationData = ClientValueCollection( SiteCreationData, site_creation_data ) - self.SyncThresholdLimit = SyncThresholdLimit - self.TotalSitesCount = TotalSitesCount + self.SyncThresholdLimit = sync_threshold_limit + self.TotalSitesCount = total_sites_count @property def entity_type_name(self): diff --git a/office365/sharepoint/tenant/administration/tenant.py b/office365/sharepoint/tenant/administration/tenant.py index c584ea9f3..8cfd6718c 100644 --- a/office365/sharepoint/tenant/administration/tenant.py +++ b/office365/sharepoint/tenant/administration/tenant.py @@ -19,6 +19,9 @@ from office365.sharepoint.publishing.portal_health_status import PortalHealthStatus from office365.sharepoint.sites.home_sites_details import HomeSitesDetails from office365.sharepoint.sites.site import Site +from office365.sharepoint.tenant.administration.app_billing_properties import ( + SPOAppBillingProperties, +) from office365.sharepoint.tenant.administration.collaboration.insights_data import ( CollaborationInsightsData, ) @@ -88,8 +91,28 @@ def __init__(self, context): ) super(Tenant, self).__init__(context, static_path) + def accept_syntex_repository_terms_of_service(self): + """ + Used to accept the Microsoft Syntex repository terms of service for your organization. + This acceptance is often necessary for enabling features related to document processing or repositories + in Microsoft Syntex. + """ + qry = ServiceOperationQuery(self, "AcceptSyntexRepositoryTermsOfService") + self.context.add_query(qry) + return self + + def activate_application_billing_policy(self, billing_policy_id): + """ """ + payload = {"billingPolicyId": billing_policy_id} + return_type = ClientResult(self.context, SPOAppBillingProperties()) + qry = ServiceOperationQuery( + self, "ActivateApplicationBillingPolicy", None, payload, None, return_type + ) + self.context.add_query(qry) + return return_type + def add_recent_admin_action_report(self): - """""" + """Logs recent administrative actions within a SharePoint Online tenant""" return_type = ClientResult(self.context, RecentAdminActionReport()) payload = {"payload": RecentAdminActionReportPayload()} qry = ServiceOperationQuery( @@ -121,6 +144,9 @@ def get_chat_gpt_response(self): def delete_policy_definition(self, item_id): """ + Deletes a policy definition from a Microsoft 365 tenant. + Policy definitions may refer to specific settings related to compliance, security, + or site governance (such as site or group creation policies). :param int item_id: """ qry = ServiceOperationQuery( @@ -140,6 +166,7 @@ def delete_recent_admin_action_report(self, report_id): return self def get_spo_tenant_all_web_templates(self): + """ """ return_type = SPOTenantWebTemplateCollection(self.context) qry = ServiceOperationQuery( self, "GetSPOTenantAllWebTemplates", None, None, None, return_type @@ -148,6 +175,7 @@ def get_spo_tenant_all_web_templates(self): return return_type def get_onedrive_site_sharing_insights(self, query_mode): + """Retrieves insights or reports related to OneDrive for Business site sharing activities""" return_type = ClientResult(self.context, OneDriveSiteSharingInsights()) payload = {"queryMode": query_mode} qry = ServiceOperationQuery( @@ -229,6 +257,7 @@ def get_home_site_url(self): def get_home_sites(self): # type: () -> ClientResult[ClientValueCollection[HomeSitesDetails]] + """Retrieves the Home Site that has been designated for your Microsoft 365 tenant.""" return_type = ClientResult( self.context, ClientValueCollection(HomeSitesDetails), # pylint: disable=E1120 @@ -238,6 +267,7 @@ def get_home_sites(self): return return_type def get_home_sites_details(self): + """Retrieves detailed information about the Home Sites configured in a SharePoint Online tenant.""" return_type = ClientResult( self.context, ClientValueCollection(HomeSitesDetails) ) @@ -267,12 +297,23 @@ def has_valid_education_license(self): self.context.add_query(qry) return return_type - def export_to_csv(self, view_xml=None): + def export_to_csv( + self, view_xml=None, time_zone_id=None, columns_info=None, list_name=None + ): """ + Exports tenant-level data to a CSV file. :param str view_xml: + :param int time_zone_id: + :param list columns_info: + :param str list_name: """ return_type = ClientResult(self.context) - payload = {"viewXml": view_xml} + payload = { + "viewXml": view_xml, + "timeZoneId": time_zone_id, + "columnsInfo": columns_info, + "listName": list_name, + } qry = ServiceOperationQuery( self, "ExportToCSV", None, payload, None, return_type ) diff --git a/office365/sharepoint/webs/templates/__init__.py b/office365/sharepoint/webs/templates/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/office365/sharepoint/webs/time_zone.py b/office365/sharepoint/webs/time_zone.py index 85b1852f3..572793a99 100644 --- a/office365/sharepoint/webs/time_zone.py +++ b/office365/sharepoint/webs/time_zone.py @@ -44,7 +44,7 @@ def information(self): return self.properties.get("Information", TimeZoneInformation()) -class TimeZoneCollection(EntityCollection): +class TimeZoneCollection(EntityCollection[TimeZone]): """TimeZone collection""" def __init__(self, context, resource_path=None): diff --git a/office365/sharepoint/webs/web.py b/office365/sharepoint/webs/web.py index 256f66917..be58ed946 100644 --- a/office365/sharepoint/webs/web.py +++ b/office365/sharepoint/webs/web.py @@ -51,6 +51,7 @@ ) from office365.sharepoint.lists.get_parameters import GetListsParameters from office365.sharepoint.lists.list import List +from office365.sharepoint.lists.render_data_parameters import RenderListDataParameters from office365.sharepoint.lists.template_collection import ListTemplateCollection from office365.sharepoint.lists.template_type import ListTemplateType from office365.sharepoint.marketplace.corporatecuratedgallery.available_addins_response import ( @@ -222,6 +223,26 @@ def consent_to_power_platform(self): self.context.add_query(qry) return return_type + def get_list_data_as_stream(self, path, view_xml=None): + """Returns list data from the specified list url and for the specified query parameters. + + :param str path: A string that contains the site-relative URL for a list, for example, /Lists/Announcements. + :param str view_xml: + """ + if view_xml is None: + view_xml = "" + return_type = ClientResult(self.context, dict()) + + def _get_list_data_as_stream(): + list_abs_url = self.url + path + parameters = RenderListDataParameters(view_xml=view_xml) + List.get_list_data_as_stream( + self.context, list_abs_url, parameters, return_type=return_type + ) + + self.ensure_property("Url", _get_list_data_as_stream) + return return_type + def get_list_operation(self, list_id, operation_id): # type: (str, str) -> SPLargeOperation """ """ diff --git a/tests/communications/test_callrecords.py b/tests/communications/test_callrecords.py index 3237e421f..6d189198e 100644 --- a/tests/communications/test_callrecords.py +++ b/tests/communications/test_callrecords.py @@ -1,5 +1,5 @@ from office365.graph_client import GraphClient -from tests import test_tenant, test_client_id, test_client_secret +from tests import test_client_id, test_client_secret, test_tenant from tests.graph_case import GraphTestCase diff --git a/tests/directory/test_identity.py b/tests/directory/test_identity.py index 633c2c55c..4be4518b8 100644 --- a/tests/directory/test_identity.py +++ b/tests/directory/test_identity.py @@ -25,6 +25,6 @@ def test3_available_provider_types(self): ) self.assertIsNotNone(result.value) - #def test4_list_risky_users(self): + # def test4_list_risky_users(self): # result = self.client.identity_protection.risky_users.get().execute_query() # self.assertIsNotNone(result.resource_path)