Skip to content

Commit

Permalink
booking namespace new types & methods
Browse files Browse the repository at this point in the history
  • Loading branch information
vgrem committed Sep 20, 2023
1 parent 3cc489b commit 221c5e4
Show file tree
Hide file tree
Showing 63 changed files with 1,177 additions and 442 deletions.
2 changes: 1 addition & 1 deletion examples/directory/users/get_my_activities.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
from tests.graph_case import acquire_token_by_username_password

client = GraphClient(acquire_token_by_username_password)
activities = client.me.activities.get().execute_query()
activities = client.me.activities.get().top(5).execute_query()
for activity in activities: # type: UserActivity
print(activity)
17 changes: 17 additions & 0 deletions examples/sharepoint/pushnotifications/configure.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"""
Configure and use push notifications in SharePoint apps
"""

from office365.sharepoint.client_context import ClientContext
from office365.sharepoint.features.definitions.scope import FeatureDefinitionScope
from office365.sharepoint.features.known_list import KnownFeaturesList
from tests import test_client_credentials, test_site_url


def subscribe_to_service():
""""""


ctx = ClientContext(test_site_url).with_credentials(test_client_credentials)
f = ctx.web.features.add(KnownFeaturesList.PushNotifications, False, FeatureDefinitionScope.Farm, True).execute_query()
print("Feature has been activated.")
4 changes: 2 additions & 2 deletions generator/import_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ def export_to_file(path, content):

parser = ArgumentParser()
parser.add_argument("-e", "--endpoint", dest="endpoint",
help="Import metadata endpoint", default="sharepoint")
help="Import metadata endpoint", default="microsoftgraph")
parser.add_argument("-p", "--path",
dest="path", default="./metadata/SharePoint.xml",
dest="path", default="./metadata/MicrosoftGraph.xml",
help="Import metadata endpoint")

args = parser.parse_args()
Expand Down
833 changes: 477 additions & 356 deletions generator/metadata/MicrosoftGraph.xml

Large diffs are not rendered by default.

173 changes: 165 additions & 8 deletions generator/metadata/SharePoint.xml

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions office365/booking/appointment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from office365.entity import Entity


class BookingAppointment(Entity):
"""
Represents a business in Microsoft Bookings. This is the top level object in the Microsoft Bookings API.
It contains business information and related business objects such as appointments, customers, services,
and staff members.
"""
26 changes: 0 additions & 26 deletions office365/booking/business.py

This file was deleted.

File renamed without changes.
114 changes: 114 additions & 0 deletions office365/booking/business/business.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
from office365.booking.appointment import BookingAppointment
from office365.booking.custom_question import BookingCustomQuestion
from office365.booking.customers.base import BookingCustomerBase
from office365.booking.service import BookingService
from office365.booking.staff.availability_item import StaffAvailabilityItem
from office365.booking.staff.member_base import BookingStaffMemberBase
from office365.booking.work_hours import BookingWorkHours
from office365.entity import Entity
from office365.entity_collection import EntityCollection
from office365.outlook.mail.physical_address import PhysicalAddress
from office365.runtime.client_result import ClientResult
from office365.runtime.client_value_collection import ClientValueCollection
from office365.runtime.paths.resource_path import ResourcePath
from office365.runtime.queries.service_operation import ServiceOperationQuery


class BookingBusiness(Entity):
"""Represents a business in Microsoft Bookings. This is the top level object in the Microsoft Bookings API.
It contains business information and related business objects such as appointments, customers, services,
and staff members."""

def get_staff_availability(self, staff_ids=None, start_datetime=None, end_datetime=None):
"""
Get the availability information of staff members of a Microsoft Bookings calendar.
:param list[str] staff_ids: The list of staff IDs
:param datetime.datetime start_datetime:
:param datetime.datetime end_datetime:
"""
return_type = ClientResult(self.context, ClientValueCollection(StaffAvailabilityItem))
payload = {
"staffIds": staff_ids,
"startDateTime": start_datetime,
"endDateTime": end_datetime
}
qry = ServiceOperationQuery(self, "getStaffAvailability", None, payload, None, return_type)
self.context.add_query(qry)
return return_type

@property
def address(self):
"""
The street address of the business. The address property, together with phone and webSiteUrl, appear in the
footer of a business scheduling page. The attribute type of physicalAddress is not supported in v1.0.
Internally we map the addresses to the type others.
"""
return self.properties.get("address", PhysicalAddress())

@property
def business_hours(self):
"""
The hours of operation for the business.
"""
return self.properties.get("businessHours", ClientValueCollection(BookingWorkHours))

def display_name(self):
"""
The name of the business, which interfaces with customers. This name appears at the top of the business
scheduling page.
:rtype: str or None
"""
return self.properties.get('displayName', None)

@property
def appointments(self):
"""All the appointments of this business. Read-only. Nullable."""
return self.properties.get('appointments',
EntityCollection(self.context, BookingAppointment,
ResourcePath("appointments", self.resource_path)))

@property
def calendar_view(self):
"""The set of appointments of this business in a specified date range. Read-only. Nullable."""
return self.properties.get('calendarView',
EntityCollection(self.context, BookingAppointment,
ResourcePath("calendarView", self.resource_path)))

@property
def customers(self):
"""All the customers of this business. Read-only. Nullable."""
return self.properties.get('customers',
EntityCollection(self.context, BookingCustomerBase,
ResourcePath("customers", self.resource_path)))

@property
def custom_questions(self):
"""All the services offered by this business. Read-only. Nullable."""
return self.properties.get('customQuestions',
EntityCollection(self.context, BookingCustomQuestion,
ResourcePath("customQuestions", self.resource_path)))

@property
def services(self):
"""All the services offered by this business. Read-only. Nullable."""
return self.properties.get('services',
EntityCollection(self.context, BookingService,
ResourcePath("services", self.resource_path)))

@property
def staff_members(self):
"""The collection of open extensions defined for the message. Nullable."""
return self.properties.get('staffMembers',
EntityCollection(self.context, BookingStaffMemberBase,
ResourcePath("staffMembers", self.resource_path)))

def get_property(self, name, default_value=None):
if default_value is None:
property_mapping = {
"businessHours": self.business_hours,
"calendarView": self.calendar_view,
"customQuestions": self.custom_questions,
"staffMembers": self.staff_members
}
default_value = property_mapping.get(name, None)
return super(BookingBusiness, self).get_property(name, default_value)
19 changes: 19 additions & 0 deletions office365/booking/business/collection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from office365.booking.business.business import BookingBusiness
from office365.entity_collection import EntityCollection


class BookingBusinessCollection(EntityCollection):
""""""

def __init__(self, context, resource_path=None):
super(BookingBusinessCollection, self).__init__(context, BookingBusiness, resource_path)

def add(self, display_name):
"""
Create a new Microsoft Bookings business in a tenant.
:param str display_name: The business display name.
"""
props = {
"displayName": display_name,
}
return super(BookingBusinessCollection, self).add(**props)
5 changes: 5 additions & 0 deletions office365/booking/custom_question.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from office365.entity import Entity


class BookingCustomQuestion(Entity):
"""Represents a custom question for a bookingBusiness."""
File renamed without changes.
5 changes: 5 additions & 0 deletions office365/booking/customers/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from office365.entity import Entity


class BookingCustomerBase(Entity):
""""""
8 changes: 8 additions & 0 deletions office365/booking/service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from office365.entity import Entity


class BookingService(Entity):
"""
Represents information about a particular service provided by a bookingBusiness, such as the service name,
price, and the staff that usually provides such service.
"""
Empty file.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from office365.booking.business import BookingBusiness
from office365.booking.business.collection import BookingBusinessCollection
from office365.booking.currency import BookingCurrency
from office365.entity import Entity
from office365.entity_collection import EntityCollection
Expand All @@ -12,8 +12,8 @@ class SolutionsRoot(Entity):
def booking_businesses(self):
""" Get a collection of bookingBusiness objects that has been created for the tenant."""
return self.properties.get('bookingBusinesses',
EntityCollection(self.context, BookingBusiness,
ResourcePath("bookingBusinesses", self.resource_path)))
BookingBusinessCollection(self.context,
ResourcePath("bookingBusinesses", self.resource_path)))

@property
def booking_currencies(self):
Expand Down
Empty file.
5 changes: 5 additions & 0 deletions office365/booking/staff/availability_item.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from office365.runtime.client_value import ClientValue


class StaffAvailabilityItem(ClientValue):
"""Represents the available and busy time slots of a Microsoft Bookings staff member."""
File renamed without changes.
56 changes: 56 additions & 0 deletions office365/directory/audit/signins/signin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import datetime

from office365.directory.audit.signins.location import SignInLocation
from office365.directory.audit.signins.status import SignInStatus
from office365.entity import Entity
Expand Down Expand Up @@ -34,12 +36,41 @@ def client_app_used(self):
"""
return self.properties.get("clientAppUsed", None)

@property
def correlation_id(self):
"""
The request ID sent from the client when the sign-in is initiated; used to troubleshoot sign-in activity.
:rtype: str
"""
return self.properties.get("correlationId", None)

@property
def created_datetime(self):
""" Date and time (UTC) the sign-in was initiated. """
return self.properties.get('createdDateTime', datetime.datetime.min)

@property
def device_detail(self):
"""Device information from where the sign-in occurred; includes device ID, operating system, and browser.
Supports $filter (eq and startsWith operators only) on browser and operatingSytem properties."""
return self.properties.get("deviceDetail", DeviceDetail())

@property
def ip_address(self):
"""
IP address of the client used to sign in.
:rtype: str
"""
return self.properties.get("ipAddress", None)

@property
def is_interactive(self):
"""
Indicates if a sign-in is interactive or not.
:rtype: bool or None
"""
return self.properties.get("isInteractive", None)

@property
def location(self):
"""
Expand All @@ -48,6 +79,30 @@ def location(self):
"""
return self.properties.get("status", SignInLocation())

@property
def resource_display_name(self):
"""
Name of the resource the user signed into.
:rtype: str or None
"""
return self.properties.get("resourceDisplayName", None)

@property
def resource_id(self):
"""
ID of the resource that the user signed into.
:rtype: str or None
"""
return self.properties.get("resourceId", None)

@property
def risk_detail(self):
"""
Provides the 'reason' behind a specific state of a risky user, sign-in or a risk event.
:rtype: str or None
"""
return self.properties.get("riskDetail", None)

@property
def user_id(self):
"""
Expand Down Expand Up @@ -76,6 +131,7 @@ def status(self):
def get_property(self, name, default_value=None):
if default_value is None:
property_mapping = {
"createdDateTime": self.created_datetime,
"deviceDetail": self.device_detail
}
default_value = property_mapping.get(name, None)
Expand Down
21 changes: 21 additions & 0 deletions office365/directory/authentication/strength_usage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from office365.directory.policies.conditional_access import ConditionalAccessPolicy
from office365.runtime.client_value import ClientValue
from office365.runtime.client_value_collection import ClientValueCollection


class AuthenticationStrengthUsage(ClientValue):
"""
An object containing two collections of Conditional Access policies that reference the specified authentication
strength. One collection references Conditional Access policies that require an MFA claim; the other collection
references Conditional Access policies that don't require such a claim.
"""

def __init__(self, mfa=None, none=None):
"""
:param list[ConditionalAccessPolicy] mfa: A collection of Conditional Access policies that reference the
specified authentication strength policy and that require an MFA claim.
:param list[ConditionalAccessPolicy] none: A collection of Conditional Access policies that reference the
specified authentication strength policy and that do not require an MFA claim.
"""
self.mfa = ClientValueCollection(ConditionalAccessPolicy, mfa)
self.none = ClientValueCollection(ConditionalAccessPolicy, none)
16 changes: 16 additions & 0 deletions office365/directory/policies/authentication_strength.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from office365.directory.authentication.strength_usage import AuthenticationStrengthUsage
from office365.entity import Entity
from office365.runtime.client_result import ClientResult
from office365.runtime.queries.function import FunctionQuery


class AuthenticationStrengthPolicy(Entity):
Expand All @@ -8,3 +11,16 @@ class AuthenticationStrengthPolicy(Entity):
defines which authentication methods must be used to authenticate in that scenario. An authentication strength
may be built-in or custom (defined by the tenant) and may or may not fulfill the requirements to grant an MFA claim.
"""

def usage(self):
"""
Allows the caller to see which Conditional Access policies reference a specified authentication strength policy.
The policies are returned in two collections, one containing Conditional Access policies that require an
MFA claim and the other containing Conditional Access policies that do not require such a claim.
Policies in the former category are restricted in what kinds of changes may be made to them to prevent
undermining the MFA requirement of those policies.
"""
return_type = ClientResult(self.context, AuthenticationStrengthUsage())
qry = FunctionQuery(self, "usage", None, return_type)
self.context.add_query(qry)
return return_type
9 changes: 9 additions & 0 deletions office365/directory/security/artifact.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from office365.entity import Entity


class Artifact(Entity):
"""Represents an abstract entity found online by Microsoft security services."""

@property
def entity_type_name(self):
return "microsoft.graph.security.artifact"
Loading

0 comments on commit 221c5e4

Please sign in to comment.