OneDrive user A shares a folder with OneDrive user B, and B can access that folder by using the share id.
For example using the graph explorer
GET https://graph.microsoft.com/v1.0/shares/{shareId}
yields
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#shares/$entity",
"id": "{shareId}",
"name": "ASharedFolder",
"owner": { ... }
}
Now, B wants to upload a new file to ASharedFolder.
Reading the OneDrive docs for upload I have tried
PUT https://graph.microsoft.com/v1.0/shares/{shareId}/driveItem/children:/SomeFile.txt:/content
Content-Type text/plain
some text goes here
as well as
PUT https://graph.microsoft.com/v1.0/shares/{shareId}/items/{sharedItemId}:/SomeFile.txt:/content
Content-Type text/plain
some text goes here
but both yield "BadRequest", "Unsupported segment type..."
Edit: I have now played out this scenario in the OneDrive Web UI using two different browsers for OneDrive users A and B, so I know that it is possible (without first adding the shared folder to B's own root), but I need some help figuring out the right request for the OneDrive REST API.
Does anyone know?
I checked the possibility of uploading files to a shared folder on OneDrive belonging to another user. I did not have any problems to achieve it using GraphExplorer.
Here is what I did:
I got a list of shared files and folders:
GET /me/drive/sharedWithMe
Returned (some of the data has been omitted):
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#Collection(driveItem)",
"value": [
{
"#odata.type": "#microsoft.graph.driveItem",
"id": "<itemId>",
"name": "Folder name",
"parentReference": {
"driveId": "<myUserId>",
"driveType": "personal"
},
"remoteItem": {
"id": "<remoteItemId>",
"name": "Folder name",
"createdBy":
"user": {
"displayName": "Other user name",
"id": "<otherUserId>"
}
},
"folder": {
"childCount": 0
},
"parentReference": {
"driveId": "<otherUserId>",
"driveType": "personal"
},
"shared": {
"owner": {
"user": {
"displayName": "Other user name",
"id": "<otherUserId>"
}
}
}
}
}
]
}
Then I preformed PUT request with the following data:
PUT /drives/{otherUserId}/items/{remoteItemId}:/test.txt:/content
Content-Type: text/plain
The contents of the file goes here.
Response: Success - Status Code 201
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#drives('<otherUserId>')/items/$entity",
"id": "<itemId>",
"name": "test.txt",
"size": 35,
"createdBy": {
"application": {
"displayName": "Graph explorer"
},
"user": {
"displayName": "My user name",
"id": "<myUserId>"
}
},
"parentReference": {
"driveId": "<otherUserId>",
"driveType": "personal",
"id": "<parentReferenceId>",
"name": "Folder name",
"path": "/drives/<otherUserId>/items/<parentReferenceId>"
},
"file": {
"mimeType": "text/plain"
}
}
Then, on the subsequent GET /me/drive/sharedWithMe request, the value of the childCount of the folder has been increased to 1.
NOTE:
The \shares endpoint only allows GET requests to access a shared DriveItem or a collection of shared items. It does not allow to create new items.
Related
I have a SharePoint URL of the form https://organizationname.sharepoint.com/sites/....
I want to use the Graph API to get a list of all resources in this drive. Reading the API documentation it appears that I require the drive-id of this drive in order to perform this request.
/drives/{drive-id}/root/children
Also, according to the answer to a similar stackoverflow question it appears there are no APIs to convert SharePoint URL to OneDrive driveId. Is there a possible workaround? Is there any way to programmatically get a list of resources from a SharePoint URL?
If your SharePoint URL is https://organizationname.sharepoint.com/sites/yourSiteName, then you can issue a request like this via the Graph API (scope Sites.Read.All might be required):
client.api("/sites/organizationname.sharepoint.com:/sites/yourSiteName:/drives").get();
That request will return something like this:
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#drives",
"value": [
{
"createdDateTime": "2021-07-24T23:35:00Z",
"description": "",
"id": "b!A1234567-ZYXWVUTSRQPONMLKJIHGFEDCBA9876543210",
"lastModifiedDateTime": "2021-08-12T16:39:23Z",
"name": "Dokumente",
"webUrl": "https://organizationname.sharepoint.com/sites/yourSIteName/folderName",
"driveType": "documentLibrary",
"createdBy": {
"user": {
"displayName": "abc"
}
},
"lastModifiedBy": {
"user": {
"email": "bla#organizationame.onmicrosoft.com",
"id": "12345678-4321-4321-4321-012345678901",
"displayName": "zz"
}
},
"owner": {
"group": {
"email": "x#y.onmicrosoft.com",
"id": "09876543-1234-1234-1234-012345678901",
"displayName": "Owner of something"
}
},
"quota": {
"deleted": 345678,
"remaining": 27487788453406,
"state": "normal",
"total": 27487790694400,
"used": 96120
}
}
]
}
The id under description is the drive-id. With that you can get /root/children like so:
client.api("/sites/yourorganizationname.sharepoint.com/drives/b!A1234567-ZYXWVUTSRQPONMLKJIHGFEDCBA9876543210/root/children").get();
While there is no single API or algorithm that allows you to programmatically get a list of resources from a SharePoint URL, you can achieve the same with two Graph API requests.
I'm trying to upload the content bytes of an inline picture from a Teams chat message as a new bitmap file. I'm getting the content bytes of the inline picture with this method GET https://graph.microsoft.com/beta/teams/{teamId}/channels/{channelId}/messages/{messageId}/hostedContents/{hostedContentId}/$value.
The response gives me content bytes which I try sending directly as the request body in this call PUT https://graph.microsoft.com/beta/drives/{channelDriveId}/items/{currentPhaseInBilderFolderId}:/picture_123.jpg:/content. To this request I have included "image/jpeg" as Content-Type in the header. The file gets created alright, but it's not created as an image. When trying to view the picture from the newly created file I'm prompted with this error: "This is not a valid bitmap file, or its format is not currently supported".
How can I grab an inline picture in a chat message and create a bitmap file out of it using Microsoft graph?
Can you share the complete PUT request along with the file which got created in the drive folder?
Without much information on the file I will not be able to help further
Edit-1:
Try specifying the image name with file format (xyz.bmp or xyz.jpg) when uploading the contents through PUT request.
Could you also post the PUT reponse here
like the example in graph api docs
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": "0123456789abc",
"name": "FileB.txt",
"size": 35,
"file": { }
}
The code is created with UiPath Studio (RPA tool). The request to get the content bytes looks like this:
The result of this GET is replace in the "getContentBytesResponse" variable as a string value. This is then used in the PUT method as such:
The reponse code from this call is 201 which indicates that the file was successfully created. And from the folder I see the file created, but not as an image. This picture is too large to be uploaded here. The limit is 2 MB and the file 2.4 MB.
I need to understand what is the proper approach to upload content bytes to be created as an image. Or does this upload method support text files solely?
EDITED:
Here is the response from the PUT method
{
"#odata.context": "https://graph.microsoft.com/beta/$metadata#drives('{id}')/items/$entity",
"#microsoft.graph.downloadUrl": "
"createdDateTime": "2020-06-04T06:50:31Z",
"eTag": "\"{AC1ABBB1-CE9A-4A02-93BE-6B27395A8FB7},1\"",
"id": "01PJW2BXNRXMNKZGWOAJFJHPTLE44VVD5X",
"lastModifiedDateTime": "2020-06-04T06:50:31Z",
"name": "picture_04-06-2020-08-06-30-50.png",
"webUrl": "https://{tenant}.sharepoint.com/sites/{sitepath}/picture_04-06-2020-08-06-30-50.png",
"cTag": "\"c:{AC1ABBB1-CE9A-4A02-93BE-6B27395A8FB7},1\"",
"size": 942463,
"createdBy": {
"application": {
"id": "{id}",
"displayName": "Dank Bot"
},
"user": {
"email": "dankbot-cb7313ce1c#{tenant}.onmicrosoft.com",
"id": "{id}",
"displayName": "Dank Bot"
}
},
"lastModifiedBy": {
"application": {
"id": "{id]",
"displayName": "Dank Bot"
},
"user": {
"email": "dankbot-cb7313ce1c#{tenant}.onmicrosoft.com",
"id": "{id}",
"displayName": "Dank Bot"
}
},
"parentReference": {
"driveId": "{id}",
"driveType": "documentLibrary",
"id": "{id}",
"path": "/drives/{drivepath}"
},
"file": {
"mimeType": "image/png",
"hashes": {
"quickXorHash": "zeZrJjSTjzjHtAn3QgXa5vgaxxA="
}
},
"fileSystemInfo": {
"createdDateTime": "2020-06-04T06:50:31Z",
"lastModifiedDateTime": "2020-06-04T06:50:31Z"
},
"image": {}
}
What is the correct way to upload image files?
When reviewing some example OneDrive Items using Graph Explorer, it appears that the user.id and the parentReference.driveId are identical. Is MSFT re-using one Id to identify both the user and drive object?
I have been testing my app against a number of OneDrive Business accounts and I do not believe I have seen this scenario. I would like to understand if this is something specific to OneDrive Personal and/or what implications it might have...
I am not sure this will cause any issues, but my understanding was that all "IDs" were generally unique.
Here's a redacted snippet of JSON returned from Graph Explorer to illustrate what I am seeing:
{
"#microsoft.graph.downloadUrl": "https://xxx.yyy",
"createdDateTime": "2018-12-04T19:02:41.173Z",
"cTag": "aYzpDQjBCMTc0REJFRUY2RTU4ITMxNzEuMjI1",
"eTag": "aQ0IwQjE3NERCRUVGNkU1OCEzMTcxLjk",
"id": "<MY_USER_ID>!3171",
"lastModifiedDateTime": "2018-12-04T19:10:36.83Z",
"name": "blah-2018.docx",
"size": 250538,
"webUrl": "https://1drv.ms/...",
"createdBy": {
"application": {
"displayName": "MSOffice15",
"id": "480728c5"
},
"device": {
"id": "188000899fbcaf"
},
"user": {
"displayName": "My Name",
"id": "<MY_USER_ID>"
}
},
"lastModifiedBy": {
"application": {
"displayName": "MSOffice15",
"id": "480728c5"
},
"device": {
"id": "188000899fbcaf"
},
"user": {
"displayName": "My Name",
"id": "<MY_USER_ID>"
}
},
"parentReference": {
"driveId": "<MY_USER_ID>",
"driveType": "personal",
"id": "<MY_USER_ID>!109",
"path": "/drive/root:"
},
"file": {
"mimeType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"hashes": {
"sha1Hash": "F0370F54348ED81F421EB036868AEBE5253AF58A"
}
},
"fileSystemInfo": {
"createdDateTime": "2018-12-04T19:02:41.173Z",
"lastModifiedDateTime": "2018-12-04T19:02:38.633Z"
}
},
Note that MY_USER_ID is all uppercase in the prefix of the driveItem.Id. It is all lowercase as my driveId and my userId.
OneDrive Personal isn't reusing the same id, it's using the User's Id as a prefix for Drive and DriveItem ids:
{User Id}!{OneDrive ID}
Since there is a 1:1 relationship between an MSA and it's Drive, there isn't much call for a more complex mechanism. OneDrive for Business, on the other hand, is hosted in SharePoint and, as such, use's SharePoint's identifiers.
`
Using the MS Graph REST API, I can retrieve driveItems that are shared with me. The Permissions of those "remote" driveItems include one identifying me as a user. However, that Permission object has no "Roles" in it (specifically, the Roles list has zero entries).
I tried looking at the RemoteItem properties, but these do not contain any security info.
What is the correct method to determine what my user's permissions are on that specific DriveItem?
Thus far, I have tested using the C# MSGraph SDK and found all the items shared with me to have an empty Roles list.
I have also used the online Graph Explorer and determined the same to be true.
When I retrieved the actual item using Graph Explorer, note the following in this example snippet from MSFT:
{
"id": "aTowIy5mfG1lbWJlcnNoaXB8YWxleHdAbTM2NXgyMTQzNTUub25taWNyb3NvZnQuY29t",
"roles": [],
"grantedTo": {
"user": {
"email": "AlexW#M365x214355.onmicrosoft.com",
"id": "4782e723-f4f4-4af3-a76e-25e3bab0d896",
"displayName": "Alex Wilber"
}
}
},
(No roles are listed for the user?)
I would have expected, since my User was explicitly listed in one of the Permits of the actual DriveItem retrieved, that the Role would also have specified my access/actual permission.
The following endpoint:
GET /drives/{remoteItem-driveId}/items/{remoteItem-id}/permissions
returns sharing permissions on a DriveItem resource
Result
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#drives('b%21IZJbPb0BjUKDAjMnMOSRf44bwdRO75NGunQibG16o65AcVUi0kiOSZ9k4-NxVd6C')/items('01H24BBVK3QUEPTCR2MNB3HMLTNUZINN54')/permissions",
"value": [
{
"id": "c0594808-fbbb-4c56-9b62-bc37307a2424",
"roles": [
"write"
],
"link": {
"scope": "anonymous",
"type": "edit",
"webUrl": "https://contoso-my.sharepoint.com/:w:/g/personal/jdoe_contoso_onmicrosoft_com/EVuFCPmKOmNDs7FzbTKGt7wBxdHHpbjDMOzy3_ng2KHCAQ"
}
},
{
"id": "8a03ff0b-5196-4585-b8a9-4d95115e10c2",
"roles": [
"read"
],
"link": {
"scope": "anonymous",
"type": "view",
"webUrl": "https://contoso-my.sharepoint.com/:w:/g/personal/jdoe_contoso_onmicrosoft_com/EVuFCPmKOmNDs7FzbTKGt7wB8wPZsfAqSd-IQYE337GDjg"
}
},
{
"id": "aTowIy5mfG1lbWJlcnNoaXB8dmdyZW1AbWVkaWFkZXY4OC5vbm1pY3Jvc29mdC5jb20",
"roles": [
"owner"
],
"grantedTo": {
"user": {
"email": "jdoe#contoso.onmicrosoft.com",
"id": "1ee49b6f-4632-4806-a4dd-e065844f9cd1",
"displayName": "Jon Doe"
}
}
}
]
}
The following example demonstrates how to print Permissions resource Roles property via msgraph-sdk-dotnet:
var item = await graphClient.Drives[driveId].Items[itemId].Request().Expand("Permissions").GetAsync();
foreach (var permission in item.Permissions)
{
var roleNames = String.Join(", ", permission.Roles.ToArray());
Console.WriteLine(roleNames);
}
I have been trying to grant a single user (possibly outside of the organization) access to a folder used by a shared group in Share Point The Microsoft Graph Docs state that the response should have an Id in it.
If I use a personal oneDrive account, and make the following request:
POST v1.0
https://graph.microsoft.com/v1.0/groups/{groupId}/drive/items/{folderId}/invite
body: {
"requireSignIn": true,
"sendInvitation": true,
"roles": [ "read"],
"recipients": [
{ "email": "{myPersonalEmail}" },
],
"message": "testing giving permission to self"
}
I get the following response:
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#Collection(permission)",
"value": [
{
"#odata.type": "#microsoft.graph.permission",
"id": "{permissionID}",
"roles": [
"read"
],
"grantedTo": {
"user": {
"email": "{myPersonalEmail}",
"id": "{responseID}",
"displayName": "Sarah"
}
}
}
]
}
However, we setup a different SharePoint account that when I make the same request https://graph.microsoft.com/v1.0/groups/{groupId}/drive/items/{folderId}/invite
I get a completely different response:
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#Collection(permission)",
"value": [
{
"#odata.type": "#microsoft.graph.permission",
"roles": [
"read"
],
"invitation": {
"signInRequired": true
},
"link": {
"type": "view",
"webUrl": "{shareURL}"
}
}
]
}
This is so bizarre to me, because we are hitting the same endpoint. It makes me think that maybe there are some site configurations that are making these two responses differ.
Does anyone know why we would be getting a different results from the same endpoint?