Skip to content

Commit

Permalink
Intune API support & typings updates
Browse files Browse the repository at this point in the history
  • Loading branch information
vgrem committed Jan 27, 2024
1 parent 536356f commit c075dc5
Show file tree
Hide file tree
Showing 26 changed files with 293 additions and 200 deletions.
3 changes: 2 additions & 1 deletion examples/directory/applications/grant_perms.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@


# select specific appRole
app_role = resource.app_roles["ThreatHunting.Read.All"]
names = ["Directory.AccessAsUser.All", "ThreatHunting.Read.All"]
app_role = resource.app_roles["Directory.AccessAsUser.All"]

# Step 2: Grant an app role to a client app
app = client.applications.get_by_app_id(test_client_id)
Expand Down
4 changes: 2 additions & 2 deletions generator/import_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ def export_to_file(path, content):
"--endpoint",
dest="endpoint",
help="Import metadata endpoint",
default="microsoftgraph",
default="sharepoint",
)
parser.add_argument(
"-p",
"--path",
dest="path",
default="./metadata/MicrosoftGraph.xml",
default="./metadata/SharePoint.xml",
help="Import metadata endpoint",
)

Expand Down
134 changes: 88 additions & 46 deletions generator/metadata/SharePoint.xml

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions office365/directory/identities/providers/builtin_identity.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import Optional

from office365.directory.identities.providers.base import IdentityProviderBase


Expand All @@ -8,9 +10,8 @@ class BuiltInIdentityProvider(IdentityProviderBase):

@property
def identity_provider_type(self):
# type: () -> Optional[str]
"""
The identity provider type. For a B2B scenario, possible values: AADSignup, MicrosoftAccount, EmailOTP.
:rtype: str
"""
return self.properties.get("identityProviderType", None)
18 changes: 8 additions & 10 deletions office365/directory/licenses/subscribed_sku.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import Optional

from office365.directory.licenses.service_plan_info import ServicePlanInfo
from office365.directory.licenses.units_detail import LicenseUnitsDetail
from office365.entity import Entity
Expand All @@ -9,35 +11,31 @@ class SubscribedSku(Entity):

@property
def account_id(self):
"""
The unique ID of the account this SKU belongs to.
:rtype: str
"""
# type: () -> Optional[str]
"""The unique ID of the account this SKU belongs to."""
return self.properties.get("accountId", None)

@property
def applies_to(self):
# type: () -> Optional[str]
"""
The target class for this SKU. Only SKUs with target class User are assignable.
Possible values are: "User", "Company".
:rtype: str
"""
return self.properties.get("appliesTo", None)

@property
def sku_id(self):
"""
The unique identifier (GUID) for the service SKU.
:rtype: str
"""
# type: () -> Optional[str]
"""The unique identifier (GUID) for the service SKU."""
return self.properties.get("skuId", None)

@property
def sku_part_number(self):
# type: () -> Optional[str]
"""
The SKU part number; for example: "AAD_PREMIUM" or "RMSBASIC".
To get a list of commercial subscriptions that an organization has acquired, see List subscribedSkus.
:rtype: str
"""
return self.properties.get("skuPartNumber", None)

Expand Down
17 changes: 7 additions & 10 deletions office365/directory/permissions/grants/oauth2.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import Optional

from office365.entity import Entity


Expand All @@ -13,56 +15,51 @@ class OAuth2PermissionGrant(Entity):

@property
def client_id(self):
# type: () -> Optional[str]
"""
The id of the client service principal for the application which is authorized to act on behalf of a signed-in
user when accessing an API. Required. Supports $filter (eq only).
:rtype: str
"""
return self.properties.get("clientId", None)

@property
def consent_type(self):
# type: () -> Optional[str]
"""
Indicates if authorization is granted for the client application to impersonate all users or only a
specific user. AllPrincipals indicates authorization to impersonate all users.
Principal indicates authorization to impersonate a specific user. Consent on behalf of all users can be granted
by an administrator. Non-admin users may be authorized to consent on behalf of themselves in some cases,
for some delegated permissions. Required. Supports $filter (eq only).
:rtype: str
"""
return self.properties.get("consentType", None)

@property
def principal_id(self):
# type: () -> Optional[str]
"""
The id of the user on behalf of whom the client is authorized to access the resource, when consentType is
Principal. If consentType is AllPrincipals this value is null. Required when consentType is Principal.
Supports $filter (eq only).
:rtype: str
"""
return self.properties.get("principalId", None)

@property
def resource_id(self):
# type: () -> Optional[str]
"""
The id of the resource service principal to which access is authorized. This identifies the API which the
client is authorized to attempt to call on behalf of a signed-in user. Supports $filter (eq only).
:rtype: str
"""
return self.properties.get("resourceId", None)

@property
def scope(self):
# type: () -> Optional[str]
"""
A space-separated list of the claim values for delegated permissions which should be included in access tokens
for the resource application (the API). For example, openid User.Read GroupMember.Read.All. Each claim value
should match the value field of one of the delegated permissions defined by the API, listed in the
oauth2PermissionScopes property of the resource service principal. Must not exceed 3850 characters in length.
:rtype: str
"""
return self.properties.get("scope", None)
8 changes: 4 additions & 4 deletions office365/directory/policies/authorization.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import Optional

from office365.directory.policies.base import PolicyBase


Expand All @@ -8,8 +10,6 @@ class AuthorizationPolicy(PolicyBase):

@property
def allowed_to_sign_up_email_based_subscriptions(self):
"""
Indicates whether a user can join the tenant by email validation.
:rtype: bool
"""
# type: () -> Optional[bool]
"""Indicates whether a user can join the tenant by email validation."""
return self.properties.get("allowedToSignUpEmailBasedSubscriptions", None)
5 changes: 5 additions & 0 deletions office365/directory/security/hunting_query_results.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from office365.runtime.client_value import ClientValue


class HuntingQueryResults(ClientValue):
"""The results of running a query for advanced hunting."""
6 changes: 6 additions & 0 deletions office365/graph_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
from office365.education.root import EducationRoot
from office365.entity_collection import EntityCollection
from office365.intune.devices.app_management import DeviceAppManagement
from office365.intune.devices.collection import DeviceCollection
from office365.intune.devices.management.management import DeviceManagement
from office365.intune.organizations.contact import OrgContact
from office365.intune.organizations.organization import Organization
Expand Down Expand Up @@ -334,6 +335,11 @@ def directory_objects(self):
"""Directory Objects container"""
return DirectoryObjectCollection(self, ResourcePath("directoryObjects"))

@property
def devices(self):
"""Devices container"""
return DeviceCollection(self, ResourcePath("devices"))

@property
def teams(self):
"""Teams container"""
Expand Down
4 changes: 1 addition & 3 deletions office365/intune/audit/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ def activity(self):

@property
def actor(self):
"""
AAD user and application that are associated with the audit event.
"""
"""AAD user and application that are associated with the audit event."""
return self.properties.get("actor", AuditActor())

@property
Expand Down
4 changes: 4 additions & 0 deletions office365/intune/devices/alternative_security_id.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@

class AlternativeSecurityId(ClientValue):
""""""

def __init__(self, type_=None, key=None):
self.type = type_
self.key = key
48 changes: 38 additions & 10 deletions office365/intune/devices/device.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
from typing import Optional

from office365.directory.object import DirectoryObject
from office365.directory.object_collection import DirectoryObjectCollection
from office365.intune.devices.alternative_security_id import AlternativeSecurityId
from office365.runtime.client_value_collection import ClientValueCollection
from office365.runtime.paths.resource_path import ResourcePath


Expand All @@ -10,16 +14,28 @@ class Device(DirectoryObject):
authentication. These devices can range from desktop and laptop machines to phones and tablets.
"""

def get_property(self, name, default_value=None):
if default_value is None:
property_mapping = {
"memberOf": self.member_of,
"registeredOwners": self.registered_owners,
"registeredUsers": self.registered_users,
"transitiveMemberOf": self.transitive_member_of,
}
default_value = property_mapping.get(name, None)
return super(Device, self).get_property(name, default_value)
def __repr__(self):
return self.device_id or self.entity_type_name

@property
def alternative_security_ids(self):
"""For internal use only."""
return self.properties.get(
"alternativeSecurityIds", ClientValueCollection(AlternativeSecurityId)
)

@property
def device_id(self):
# type: () -> Optional[str]
"""Unique identifier set by Azure Device Registration Service at the time of registration.
This is an alternate key that can be used to reference the device object."""
return self.properties.get("deviceId", None)

@property
def device_ownership(self):
# type: () -> Optional[str]
"""Ownership of the device. This property is set by Intune. Possible values are: unknown, company, personal."""
return self.properties.get("deviceOwnership", None)

@property
def member_of(self):
Expand Down Expand Up @@ -65,3 +81,15 @@ def transitive_member_of(self):
self.context, ResourcePath("transitiveMemberOf", self.resource_path)
),
)

def get_property(self, name, default_value=None):
if default_value is None:
property_mapping = {
"alternativeSecurityIds": self.alternative_security_ids,
"memberOf": self.member_of,
"registeredOwners": self.registered_owners,
"registeredUsers": self.registered_users,
"transitiveMemberOf": self.transitive_member_of,
}
default_value = property_mapping.get(name, None)
return super(Device, self).get_property(name, default_value)
12 changes: 6 additions & 6 deletions office365/onedrive/operations/long_running.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import Optional

from office365.entity import Entity


Expand All @@ -6,14 +8,12 @@ class LongRunningOperation(Entity):

@property
def resource_location(self):
"""URI of the resource that the operation is performed on.
:rtype: str or None
"""
# type: () -> Optional[str]
"""URI of the resource that the operation is performed on."""
return self.properties.get("resourceLocation", None)

@property
def status_detail(self):
"""Details about the status of the operation.
:rtype: str or None
"""
# type: () -> Optional[str]
"""Details about the status of the operation."""
return self.properties.get("statusDetail", None)
4 changes: 1 addition & 3 deletions office365/runtime/client_request_exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@ def message_lang(self):

@property
def message(self):
"""
:rtype: str
"""
# type: () -> str
if self.payload:
error = self.payload.get("error")
if error:
Expand Down
11 changes: 4 additions & 7 deletions office365/runtime/odata/json_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,12 @@ def collection_next(self):

@property
def media_type(self):
"""
Gets media type
:rtype: str
"""
# type: () -> str
"""Gets media type"""
raise NotImplementedError

@property
def include_control_information(self):
"""Determines whether control information that is represented as annotations should be included in payload
:rtype: bool
"""
# type: () -> bool
"""Determines whether control information that is represented as annotations should be included in payload"""
raise NotImplementedError
22 changes: 8 additions & 14 deletions office365/sharepoint/fields/calculated.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import Optional

from office365.sharepoint.fields.field import Field


Expand All @@ -11,26 +13,18 @@ class FieldCalculated(Field):

@property
def currency_locale_id(self):
"""
Gets the locale ID that is used for currency on the Web site.
:rtype: int or None
"""
# type: () -> Optional[int]
"""Gets the locale ID that is used for currency on the Web site."""
return self.properties.get("CurrencyLocaleId", None)

@property
def formula(self):
"""
Specifies the formula for the field
:rtype: str or None
"""
# type: () -> Optional[str]
"""Specifies the formula for the field"""
return self.properties.get("Formula", None)

@formula.setter
def formula(self, val):
"""Sets a value that specifies the Formula.
:type val: str
"""
# type: (str) -> None
"""Sets a value that specifies the Formula."""
self.set_property("Formula", val)

0 comments on commit c075dc5

Please sign in to comment.