Skip to content

Commit

Permalink
SharePoint API Attachments namespace enhancements
Browse files Browse the repository at this point in the history
  • Loading branch information
vgrem committed Apr 11, 2024
1 parent 86b2dd8 commit 1b5982f
Show file tree
Hide file tree
Showing 25 changed files with 717 additions and 122 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,36 +15,22 @@
"""

from office365.graph_client import GraphClient
from tests import test_admin_principal_name, test_client_id, test_tenant
from tests import (
test_admin_principal_name,
test_client_id,
test_tenant,
)

client = GraphClient.with_token_interactive(
test_tenant, test_client_id, test_admin_principal_name
)

# Step 1: Get the appRoles of the resource service principal
resource = (
client.service_principals.get_by_name("Microsoft Graph")
.get()
.select(["id", "displayName", "appId", "appRoles"])
.execute_query()
)


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

for role in resource.app_roles:
print(role)
# 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(app, app_role).execute_query()
resource.grant_application(app, "MailboxSettings.Read").execute_query()


# Step 3. Print app role assignments
Expand Down
44 changes: 44 additions & 0 deletions examples/directory/applications/grant_delegated_perms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""
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_admin_principal_name,
test_client_id,
test_tenant,
test_user_principal_name,
)

client = GraphClient.with_token_interactive(
test_tenant, test_client_id, test_admin_principal_name
)

# Step 1: Get the delegated permissions of the resource service principal
resource = (
client.service_principals.get_by_name("Microsoft Graph")
.get()
.select(["id", "displayName", "appId", "oauth2PermissionScopes"])
.execute_query()
)


# Step 2: Grant a delegated permission to the client service principal on behalf of a user
app_role = "User.Read.All"
user = client.users.get_by_principal_name(test_user_principal_name)
resource.grant_delegated(test_client_id, user, app_role).execute_query()


# Step 3. Confirm and print permission grants
result = (
client.oauth2_permission_grants.filter("clientId eq '{0}'".format(test_client_id))
.get()
.execute_query()
)
for grant in result:
print(grant)
22 changes: 22 additions & 0 deletions examples/directory/applications/revoke_delegated_perms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"""
Revoke delegated permissions granted to a service principal on behalf of a user
https://learn.microsoft.com/en-us/graph/permissions-grant-via-msgraph?tabs=http&pivots=grant-delegated-permissions#step-3-revoke-delegated-permissions-granted-to-a-service-principal-on-behalf-of-a-user-optional
"""

from office365.graph_client import GraphClient
from tests import (
test_admin_principal_name,
test_client_id,
test_tenant,
test_user_principal_name,
)

client = GraphClient.with_token_interactive(
test_tenant, test_client_id, test_admin_principal_name
)

# 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(test_client_id, user, "User.Read.All").execute_query()
5 changes: 0 additions & 5 deletions examples/directory/applications/update_props.py

This file was deleted.

15 changes: 15 additions & 0 deletions examples/onedrive/drives/get_by_path.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""
Demonstrates how to get a drive by path.
"""
from office365.graph_client import GraphClient
from tests import (
test_client_id,
test_client_secret,
test_site_url,
test_tenant,
)

client = GraphClient.with_client_secret(test_tenant, test_client_id, test_client_secret)
drive_abs_url = "{0}/Documents".format(test_site_url)
result = client.shares.by_url(drive_abs_url).site.drive.get().execute_query()
print("Drive url: {0}".format(result))
File renamed without changes.
6 changes: 2 additions & 4 deletions examples/sharepoint/listitems/attachments/download.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import os
import tempfile

from office365.sharepoint.attachments.attachment import Attachment
from office365.sharepoint.client_context import ClientContext
from office365.sharepoint.listitems.listitem import ListItem
from tests import test_client_credentials, test_team_site_url

ctx = ClientContext(test_team_site_url).with_credentials(test_client_credentials)
Expand All @@ -15,14 +13,14 @@
items = source_list.items
ctx.load(items, ["ID", "UniqueId", "FileRef", "LinkFilename", "Title", "Attachments"])
ctx.execute_query()
for item in items: # type: ListItem
for item in items:
if item.properties[
"Attachments"
]: # 1. determine whether ListItem contains attachments
# 2. Explicitly load attachments for ListItem
attachment_files = item.attachment_files.get().execute_query()
# 3. Enumerate and save attachments
for attachment_file in attachment_files: # type: Attachment
for attachment_file in attachment_files:
download_file_name = os.path.join(
download_path, os.path.basename(attachment_file.file_name)
)
Expand Down
2 changes: 1 addition & 1 deletion examples/sharepoint/listitems/attachments/enumerate.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
)
for item in items:
for attachment_file in item.attachment_files:
print(attachment_file.server_relative_url)
print(attachment_file)
17 changes: 5 additions & 12 deletions examples/sharepoint/listitems/attachments/upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@
Creates a list item and uploads an attachment
"""

import os

from office365.sharepoint.attachments.creation_information import (
AttachmentCreationInformation,
)
from office365.sharepoint.client_context import ClientContext
from tests import test_client_credentials, test_team_site_url

Expand All @@ -17,12 +12,10 @@
# 1. create a new list item
task_item = tasks_list.add_item({"Title": "New Task"}).execute_query()

task_item.attachment_files.delete_all().execute_query()

# 2. read & upload attachment for a list item
path = "../../../data/Financial Sample.xlsx"
with open(path, "rb") as fh:
file_content = fh.read()
attachment_file_info = AttachmentCreationInformation(
os.path.basename(path), file_content
)
attachment = task_item.attachment_files.add(attachment_file_info).execute_query()
print(attachment.server_relative_url)
with open(path, "rb") as f:
attachment = task_item.attachment_files.upload(f).execute_query()
print(attachment)
23 changes: 15 additions & 8 deletions examples/sharepoint/listitems/system_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@

from office365.sharepoint.client_context import ClientContext
from office365.sharepoint.fields.user_value import FieldUserValue
from tests import test_client_credentials, test_site_url, test_user_principal_name
from tests import (
test_client_credentials,
test_site_url,
test_user_principal_name,
)

ctx = ClientContext(test_site_url).with_credentials(test_client_credentials)

Expand All @@ -16,20 +20,23 @@
if len(items) == 0:
sys.exit("No items were found")

item_to_update = items[0]
# item_to_update = items[0]
item_to_update = items.get_by_id(items[0].id)


author = ctx.web.site_users.get_by_email(test_user_principal_name)

created_date = datetime.utcnow() - timedelta(days=14)
modified_date = datetime.utcnow() - timedelta(days=7)

created_date = datetime.utcnow() - timedelta(days=21)
modified_date = datetime.utcnow() - timedelta(days=14)
result = item_to_update.validate_update_list_item(
{
"Title": "Task (updated)",
"Editor": FieldUserValue.from_user(author),
"Modified": modified_date,
"Created": created_date,
# "Modified": modified_date,
# "Created": created_date,
"Author": FieldUserValue.from_user(author),
},
dates_in_utc=True,
# dates_in_utc=True,
new_document_update=True,
).execute_query()

Expand Down
6 changes: 5 additions & 1 deletion examples/sharepoint/users/search_tenant_users.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
"""
Search tenant users.
"""

import json

from office365.sharepoint.client_context import ClientContext
Expand All @@ -8,7 +12,7 @@

ctx = ClientContext(test_team_site_url).with_credentials(test_client_credentials)
result = ClientPeoplePickerWebServiceInterface.client_people_picker_search_user(
ctx, "Doe"
ctx, "Joe"
).execute_query()
entries = json.loads(result.value)
for entry in entries:
Expand Down
4 changes: 2 additions & 2 deletions generator/import_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,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

0 comments on commit 1b5982f

Please sign in to comment.