From b2d4802761b221b97ce1d82069049730a4f9dd50 Mon Sep 17 00:00:00 2001 From: vgrem Date: Sun, 9 Jun 2024 14:08:32 +0300 Subject: [PATCH] #612: introduced SharePointRequest --- examples/sharepoint/read_resource_no_model.py | 7 ++-- generator/builders/template_context.py | 4 +- generator/import_metadata.py | 4 +- generator/metadata/MicrosoftGraph.xml | 7 ++++ office365/directory/synchronization/status.py | 9 ++++- .../synchronization/task_execution.py | 5 +++ office365/onedrive/listitems/list_item.py | 1 + office365/runtime/http/request_options.py | 10 +++-- .../changes/app_consent_principal.py | 5 +++ office365/sharepoint/request.py | 37 ++++++++++++++++++- office365/sharepoint/sharing/information.py | 5 +++ .../sharing/permission_collection.py | 20 +++++----- .../sharepoint/sharing/recipient_limits.py | 9 +++++ .../sharing/site_sharing_report_helper.py | 5 +-- 14 files changed, 102 insertions(+), 26 deletions(-) create mode 100644 office365/directory/synchronization/task_execution.py create mode 100644 office365/sharepoint/changes/app_consent_principal.py create mode 100644 office365/sharepoint/sharing/recipient_limits.py diff --git a/examples/sharepoint/read_resource_no_model.py b/examples/sharepoint/read_resource_no_model.py index fb5f56542..8c458b898 100644 --- a/examples/sharepoint/read_resource_no_model.py +++ b/examples/sharepoint/read_resource_no_model.py @@ -4,13 +4,12 @@ import json -from office365.sharepoint.client_context import ClientContext +from office365.sharepoint.request import SharePointRequest from tests import test_site_url, test_user_credentials if __name__ == "__main__": - client = ClientContext(test_site_url).with_credentials(test_user_credentials) - response = client.execute_request_direct("web") - response.raise_for_status() + request = SharePointRequest(test_site_url).with_credentials(test_user_credentials) + response = request.execute_request("web") json = json.loads(response.content) web_title = json["d"]["Title"] print("Web title: {0}".format(web_title)) diff --git a/generator/builders/template_context.py b/generator/builders/template_context.py index ef0143559..7ab857855 100644 --- a/generator/builders/template_context.py +++ b/generator/builders/template_context.py @@ -1,8 +1,6 @@ class TemplateContext: def __init__(self, template_path): - """ - :type template_path: str - """ + # type: (str) -> None self._template_path = template_path def build(self, schema): diff --git a/generator/import_metadata.py b/generator/import_metadata.py index 0bb39167f..093a0ba27 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="sharepoint", + default="microsoftgraph", ) parser.add_argument( "-p", "--path", dest="path", - default="./metadata/SharePoint.xml", + default="./metadata/MicrosoftGraph.xml", help="Import metadata endpoint", ) diff --git a/generator/metadata/MicrosoftGraph.xml b/generator/metadata/MicrosoftGraph.xml index 89b83f279..28e0c2924 100644 --- a/generator/metadata/MicrosoftGraph.xml +++ b/generator/metadata/MicrosoftGraph.xml @@ -18337,6 +18337,12 @@ + + + + + + @@ -28889,6 +28895,7 @@ + diff --git a/office365/directory/synchronization/status.py b/office365/directory/synchronization/status.py index 44acffb04..13e9cfa62 100644 --- a/office365/directory/synchronization/status.py +++ b/office365/directory/synchronization/status.py @@ -1,5 +1,6 @@ from office365.directory.synchronization.progress import SynchronizationProgress from office365.directory.synchronization.quarantine import SynchronizationQuarantine +from office365.directory.synchronization.task_execution import SynchronizationTaskExecution from office365.runtime.client_value import ClientValue from office365.runtime.client_value_collection import ClientValueCollection @@ -7,10 +8,16 @@ class SynchronizationStatus(ClientValue): """Represents the current status of the synchronizationJob.""" - def __init__(self, progress=None, quarantine=SynchronizationQuarantine()): + def __init__(self, progress=None, quarantine=SynchronizationQuarantine(), + last_execution=SynchronizationTaskExecution(), + last_successful_execution=SynchronizationTaskExecution(), + last_successful_execution_with_exports=SynchronizationTaskExecution()): """ :param list[SynchronizationProgress] progress: Details of the progress of a job toward completion. :param SynchronizationQuarantine quarantine: """ self.progress = ClientValueCollection(SynchronizationProgress, progress) self.quarantine = quarantine + self.lastExecution = last_execution + self.lastSuccessfulExecution = last_successful_execution + self.lastSuccessfulExecutionWithExports = last_successful_execution_with_exports diff --git a/office365/directory/synchronization/task_execution.py b/office365/directory/synchronization/task_execution.py new file mode 100644 index 000000000..7bb629b23 --- /dev/null +++ b/office365/directory/synchronization/task_execution.py @@ -0,0 +1,5 @@ +from office365.runtime.client_value import ClientValue + + +class SynchronizationTaskExecution(ClientValue): + """Summarizes the results of the synchronization job run.""" diff --git a/office365/onedrive/listitems/list_item.py b/office365/onedrive/listitems/list_item.py index cac77ab54..15df796b8 100644 --- a/office365/onedrive/listitems/list_item.py +++ b/office365/onedrive/listitems/list_item.py @@ -38,6 +38,7 @@ def fields(self): @property def versions(self): + # type: () -> EntityCollection[ListItemVersion] """The list of previous versions of the list item.""" return self.properties.get( "versions", diff --git a/office365/runtime/http/request_options.py b/office365/runtime/http/request_options.py index a239aaedc..65caf3455 100644 --- a/office365/runtime/http/request_options.py +++ b/office365/runtime/http/request_options.py @@ -1,20 +1,22 @@ +from typing import Any + from office365.runtime.http.http_method import HttpMethod class RequestOptions(object): """Request options""" - def __init__(self, url): + def __init__(self, url, method=HttpMethod.Get, data=None): """ Request options :param str url: URL for the new :class:`requests.Request` object """ self.url = url - self.data = None + self.data = data self.headers = {} self.auth = None - self.method = HttpMethod.Get + self.method = method self.verify = True self.stream = False self.proxies = None @@ -28,8 +30,10 @@ def is_bytes(self): return hasattr(self.data, "decode") and callable(self.data.decode) def set_header(self, name, value): + # type: (str, Any) -> None self.headers[name] = value def ensure_header(self, name, value): + # type: (str, Any) -> None if name not in self.headers: self.headers[name] = value diff --git a/office365/sharepoint/changes/app_consent_principal.py b/office365/sharepoint/changes/app_consent_principal.py new file mode 100644 index 000000000..8e54c3ae8 --- /dev/null +++ b/office365/sharepoint/changes/app_consent_principal.py @@ -0,0 +1,5 @@ +from office365.sharepoint.changes.change import Change + + +class ChangeAppConsentPrincipal(Change): + """""" diff --git a/office365/sharepoint/request.py b/office365/sharepoint/request.py index 7f67fdc8e..e64ae73f8 100644 --- a/office365/sharepoint/request.py +++ b/office365/sharepoint/request.py @@ -1,7 +1,42 @@ +from typing import Optional + +from requests import Response +from typing_extensions import Self + +from office365.runtime.auth.authentication_context import AuthenticationContext +from office365.runtime.auth.client_credential import ClientCredential +from office365.runtime.auth.user_credential import UserCredential +from office365.runtime.http.request_options import RequestOptions from office365.runtime.odata.request import ODataRequest from office365.runtime.odata.v3.json_light_format import JsonLightFormat class SharePointRequest(ODataRequest): - def __init__(self): + def __init__(self, base_url): super().__init__(JsonLightFormat()) + self._auth_context = AuthenticationContext(url=base_url) + self.beforeExecute += self._authenticate_request + + def execute_request(self, path): + # type: (str) -> Response + request_url = "{0}/_api/{1}".format(self._auth_context.url, path) + return self.execute_request_direct(RequestOptions(request_url)) + + def with_credentials(self, credentials, environment="commercial"): + # type: (UserCredential|ClientCredential, Optional[str]) -> Self + """ + Initializes a client to acquire a token via user or client credentials + :type credentials: UserCredential or ClientCredential + :param str environment: The Office 365 Cloud Environment endpoint used for authentication + defaults to 'commercial'. + """ + self._auth_context.with_credentials( + credentials, environment=environment + ) + return self + + def _authenticate_request(self, request): + # type: (RequestOptions) -> None + """Authenticate request""" + self._auth_context.authenticate_request(request) + diff --git a/office365/sharepoint/sharing/information.py b/office365/sharepoint/sharing/information.py index b0bb9eaed..6bab378d0 100644 --- a/office365/sharepoint/sharing/information.py +++ b/office365/sharepoint/sharing/information.py @@ -22,6 +22,11 @@ def access_request_settings(self): """ return self.properties.get("accessRequestSettings", AccessRequestSettings()) + @property + def anonymous_link_expiration_restriction_days(self): + """Tenant's anonymous link expiration restriction in days.""" + return self.properties.get("anonymousLinkExpirationRestrictionDays", None) + @property def permissions_information(self): """ diff --git a/office365/sharepoint/sharing/permission_collection.py b/office365/sharepoint/sharing/permission_collection.py index af6290635..b570454aa 100644 --- a/office365/sharepoint/sharing/permission_collection.py +++ b/office365/sharepoint/sharing/permission_collection.py @@ -14,25 +14,27 @@ class PermissionCollection(ClientValue): def __init__( self, - hasInheritedLinks=None, + app_consent_principals=None, + has_inherited_links=None, links=None, principals=None, - siteAdmins=None, - totalNumberOfPrincipals=None, + site_admins=None, + total_number_of_principals=None, ): """ - :param bool hasInheritedLinks: + :param bool has_inherited_links: :param list[LinkInfo] links: The List of tokenized sharing links with their LinkInfo objects. :param list[PrincipalInfo] principals: The List of Principals with their roles on this list item. - :param list[PrincipalInfo] siteAdmins: The List of Principals who are Site Admins. This property is returned + :param list[PrincipalInfo] site_admins: The List of Principals who are Site Admins. This property is returned only if the caller is an Auditor. - :param int totalNumberOfPrincipals: + :param int total_number_of_principals: """ - self.hasInheritedLinks = hasInheritedLinks + self.appConsentPrincipals = ClientValueCollection(PrincipalInfo, app_consent_principals) + self.hasInheritedLinks = has_inherited_links self.links = ClientValueCollection(LinkInfo, links) self.principals = ClientValueCollection(PrincipalInfo, principals) - self.siteAdmins = ClientValueCollection(PrincipalInfo, siteAdmins) - self.totalNumberOfPrincipals = totalNumberOfPrincipals + self.siteAdmins = ClientValueCollection(PrincipalInfo, site_admins) + self.totalNumberOfPrincipals = total_number_of_principals @property def entity_type_name(self): diff --git a/office365/sharepoint/sharing/recipient_limits.py b/office365/sharepoint/sharing/recipient_limits.py new file mode 100644 index 000000000..d54ce1d02 --- /dev/null +++ b/office365/sharepoint/sharing/recipient_limits.py @@ -0,0 +1,9 @@ +from office365.runtime.client_value import ClientValue + + +class RecipientLimits(ClientValue): + """""" + + @property + def entity_type_name(self): + return "SP.Sharing.RecipientLimits" diff --git a/office365/sharepoint/sharing/site_sharing_report_helper.py b/office365/sharepoint/sharing/site_sharing_report_helper.py index d44e30990..99050c856 100644 --- a/office365/sharepoint/sharing/site_sharing_report_helper.py +++ b/office365/sharepoint/sharing/site_sharing_report_helper.py @@ -1,5 +1,6 @@ from office365.runtime.client_result import ClientResult from office365.runtime.queries.service_operation import ServiceOperationQuery +from office365.sharepoint.client_context import ClientContext from office365.sharepoint.entity import Entity from office365.sharepoint.sharing.reports.site_capabilities import ( SiteSharingReportCapabilities, @@ -12,9 +13,7 @@ class SiteSharingReportHelper(Entity): @staticmethod def cancel_sharing_report_job(context): - """ - :type context: office365.sharepoint.client_context.ClientContext - """ + # type: (ClientContext) -> ClientResult[SiteSharingReportStatus] return_type = ClientResult(context, SiteSharingReportStatus()) binding_type = SiteSharingReportHelper(context) qry = ServiceOperationQuery(