From a0abb4392684b22751cfa0ace429d0f07c8fc45e Mon Sep 17 00:00:00 2001 From: vgrem Date: Mon, 21 Oct 2024 22:27:05 +0300 Subject: [PATCH] bookingbusiness namespace updates, examples fixes for directory API --- .../applications/grant_application_perms.py | 12 ++++---- .../applications/has_application_perms.py | 29 +++++++++++++++++++ .../applications/has_delegated_perms.py | 23 +++++---------- .../applications/list_application_perms.py | 5 ---- .../applications/list_delegated_perms.py | 14 +++------ office365/booking/business/business.py | 13 +++++++++ office365/booking/business/collection.py | 12 +++++--- office365/sharepoint/lists/list.py | 11 +++++++ tests/booking/test_business.py | 10 ++++++- 9 files changed, 89 insertions(+), 40 deletions(-) create mode 100644 examples/directory/applications/has_application_perms.py diff --git a/examples/directory/applications/grant_application_perms.py b/examples/directory/applications/grant_application_perms.py index 27d93684b..af43233c0 100644 --- a/examples/directory/applications/grant_application_perms.py +++ b/examples/directory/applications/grant_application_perms.py @@ -18,22 +18,24 @@ from tests import ( test_admin_principal_name, test_client_id, + test_client_secret, test_tenant, ) -client = GraphClient.with_token_interactive( - test_tenant, test_client_id, test_admin_principal_name -) +# 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) # Step 1: Get the resource service principal resource = client.service_principals.get_by_name("Microsoft Graph") # Step 2: Grant an app role to a client app app = client.applications.get_by_app_id(test_client_id) -resource.grant_application_permissions(app, "MailboxSettings.Read").execute_query() +resource.grant_application_permissions(app, "Bookings.Read.All").execute_query() -# Step 3. Print app role assignments +# Step 3 (optional). Print app role assignments result = resource.app_role_assigned_to.get_all().execute_query() for app_role_assignment in result: print(app_role_assignment) diff --git a/examples/directory/applications/has_application_perms.py b/examples/directory/applications/has_application_perms.py new file mode 100644 index 000000000..be0b6e504 --- /dev/null +++ b/examples/directory/applications/has_application_perms.py @@ -0,0 +1,29 @@ +""" +How to grant and revoke delegated permissions for an app using Microsoft Graph. +Delegated permissions, also called scopes or OAuth2 permissions, allow an app to call an API +on behalf of a signed-in user. + + +https://learn.microsoft.com/en-us/graph/permissions-grant-via-msgraph?tabs=http&pivots=grant-delegated-permissions +""" + +from office365.graph_client import GraphClient +from tests import ( + test_client_id, + test_client_secret, + test_tenant, +) + +client = GraphClient.with_client_secret(test_tenant, test_client_id, test_client_secret) + + +resource = client.service_principals.get_by_name("Microsoft Graph") +app_role = "Bookings.Read.All" +result = resource.get_application_permissions(test_client_id).execute_query() +if ( + len([cur_app_role for cur_app_role in result.value if cur_app_role == app_role]) + == 0 +): + print("Application permission '{0}' is not granted".format(app_role)) +else: + print(result.value) diff --git a/examples/directory/applications/has_delegated_perms.py b/examples/directory/applications/has_delegated_perms.py index cd169c2a3..a6ebf6456 100644 --- a/examples/directory/applications/has_delegated_perms.py +++ b/examples/directory/applications/has_delegated_perms.py @@ -1,5 +1,5 @@ """ -Determines whether the delegated permissions is defined by the Microsoft Graph service principal in the tenant. +Determines whether the delegated permissions is granted by the Microsoft Graph service principal in the tenant. https://learn.microsoft.com/en-us/graph/permissions-grant-via-msgraph?tabs=http&pivots=grant-delegated-permissions """ @@ -8,26 +8,19 @@ from tests import ( test_admin_principal_name, test_client_id, + test_client_secret, test_tenant, ) -# client = GraphClient.with_username_and_password( -# test_tenant, test_client_id, test_username, test_password -# ) -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") -# app_role = "User.Read.All" -app_role = "DeviceLocalCredential.Read.All" +scope = "DeviceLocalCredential.Read.All" 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() -if len(result) == 0: - print("Delegated permission '{0}' is not set".format(app_role)) +# result = resource.get_delegated_permissions(test_client_id, user).execute_query() +result = resource.get_delegated_permissions(test_client_id).execute_query() +if len([cur_scope for cur_scope in result.value if cur_scope == scope]) == 0: + print("Delegated permission '{0}' is not granted".format(scope)) else: print(result.value) diff --git a/examples/directory/applications/list_application_perms.py b/examples/directory/applications/list_application_perms.py index 79728f679..d52e9a3c8 100644 --- a/examples/directory/applications/list_application_perms.py +++ b/examples/directory/applications/list_application_perms.py @@ -14,15 +14,10 @@ test_tenant, ) -# 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") - 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 2581d0640..9c5cb07c2 100644 --- a/examples/directory/applications/list_delegated_perms.py +++ b/examples/directory/applications/list_delegated_perms.py @@ -1,5 +1,5 @@ """ -How to grant and revoke delegated permissions for an app using Microsoft Graph. +How to list delegated permissions for an app using Microsoft Graph. Delegated permissions, also called scopes or OAuth2 permissions, allow an app to call an API on behalf of a signed-in user. @@ -14,17 +14,11 @@ test_tenant, ) -# 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() -) +resource = client.service_principals.get_by_name("Microsoft Graph") result = resource.get_delegated_permissions(test_client_id).execute_query() -for grant in result: - print(grant.scope + ";") +for scope in result.value: + print(scope) diff --git a/office365/booking/business/business.py b/office365/booking/business/business.py index c0f2f2e04..24d336ddd 100644 --- a/office365/booking/business/business.py +++ b/office365/booking/business/business.py @@ -46,6 +46,19 @@ def get_staff_availability( self.context.add_query(qry) return return_type + def publish(self): + """ + Make the scheduling page of a business available to external customers. + + Set the isPublished property to true, and the publicUrl property to the URL of the scheduling page. + """ + qry = ServiceOperationQuery( + self, + "publish", + ) + self.context.add_query(qry) + return self + @property def address(self): """ diff --git a/office365/booking/business/collection.py b/office365/booking/business/collection.py index fad8ed977..64c2eb39a 100644 --- a/office365/booking/business/collection.py +++ b/office365/booking/business/collection.py @@ -1,5 +1,8 @@ +from typing import Optional + from office365.booking.business.business import BookingBusiness from office365.entity_collection import EntityCollection +from office365.outlook.mail.physical_address import PhysicalAddress class BookingBusinessCollection(EntityCollection[BookingBusiness]): @@ -10,12 +13,13 @@ def __init__(self, context, resource_path=None): context, BookingBusiness, resource_path ) - def add(self, display_name): + def add(self, display_name, address=None, email=None): + # type: (str, Optional[PhysicalAddress], Optional[str]) -> BookingBusiness """ Create a new Microsoft Bookings business in a tenant. :param str display_name: The business display name. + :param PhysicalAddress address: The business display name. + :param str email: The email address for the business. """ - props = { - "displayName": display_name, - } + props = {"displayName": display_name, "address": address, "email": email} return super(BookingBusinessCollection, self).add(**props) diff --git a/office365/sharepoint/lists/list.py b/office365/sharepoint/lists/list.py index c090b3cbc..62c5959dd 100644 --- a/office365/sharepoint/lists/list.py +++ b/office365/sharepoint/lists/list.py @@ -21,6 +21,7 @@ EventReceiverDefinitionCollection, ) from office365.sharepoint.fields.collection import FieldCollection +from office365.sharepoint.fields.field import Field from office365.sharepoint.fields.related_field_collection import RelatedFieldCollection from office365.sharepoint.files.checked_out_file_collection import ( CheckedOutFileCollection, @@ -212,6 +213,16 @@ def _list_loaded(): self.ensure_property("RootFolder", _list_loaded) return return_type + def ensure_signoff_status_field(self): + """""" + return_type = Field(self.context) + self.fields.add_child(return_type) + qry = ServiceOperationQuery( + self, "EnsureSignoffStatusField", None, None, None, return_type + ) + self.context.add_query(qry) + return return_type + def get_all_rules(self): """Retrieves rules of a List""" return_type = ClientResult(self.context, ClientValueCollection(SPListRule)) diff --git a/tests/booking/test_business.py b/tests/booking/test_business.py index 27007d381..9a36ac553 100644 --- a/tests/booking/test_business.py +++ b/tests/booking/test_business.py @@ -20,5 +20,13 @@ def test2_create_booking_business(self): # result = self.__class__.business.get_staff_availability().execute_query() # self.assertIsNotNone(result.resource_path) - def test4_delete_booking_business(self): + def test3_get(self): + result = self.__class__.business.get().execute_query() + self.assertIsNotNone(result.resource_path) + + def test4_publish(self): + result = self.__class__.business.publish().execute_query() + self.assertIsNotNone(result.resource_path) + + def test5_delete_booking_business(self): self.__class__.business.delete_object().execute_query()