Microsoft.Fast.Profile.Core.Exception.ImageNotFoundException - Cannot PUT a profile picture via MS Graph - microsoft-graph-api

I am trying to update a profile picture on behalf of the current logged in user (by Open ID Connect) by using the following MS Graph interfaces:
PUT /me/photo/$value
PUT /users/{id | userPrincipalName}/photo/$value
Regardless of the endpoint I use (/me/ or /users/principalname) or whether I use PUT or PATCH methods, I constantly receive the following error:
{"error":{"code":"InvalidImage",
"message":"Exception of type 'Microsoft.Fast.Profile.Core.Exception.ImageNotFoundException' was thrown.",
"innerError":....}
I have made sure to have delegated User.ReadWrite permissions and in each test case I have succcesfully obtained a token through OIDC. The image I try to upload is a .JPEG image and I Base 64 encoded it's binary content.
PUT https://graph.microsoft.com/v1.0/me/photo/$value
Content-Type: image/jpeg
Authentication: Bearer {token}
[Base 64 encoded binary content of JPEG image]
The error does not make sense to me for a PUT or PATCH method as you would expect no existing image to be required (although I made sure that my user account has a profile picture available). Does anyone have an idea of a possible root cause of this error?
Any help/direction is much appreciated! :)

Related

Microsoft Graph API - get drive "Url specified is invalid."

I am facing a weird issue with microsoft's graph api.
I am trying to retrieve files stored on Sharepoint. I don't know what the issue is and I have tried a lot of different things:
Call to get all drives for the site works and returns a list of all available drives:
GET https://graph.microsoft.com/v1.0/sites/site.sharepoint.com,<id>,<id>:/teams/myTeam:/drives
Via the previous endpoint I can extract the id for that drive with which I would then like to retrieve drive details (and in consequence all children of that drive):
GET https://graph.microsoft.com/v1.0/sites/site.sharepoint.com,<id>,<id>:/teams/myTeam:/drives/<driveId>
GET https://graph.microsoft.com/v1.0/sites/site.sharepoint.com,<id>,<id>:/teams/myTeam:/drives/<driveId>/root
GET https://graph.microsoft.com/v1.0/sites/site.sharepoint.com,<id>,<id>:/teams/myTeam:/drives/<driveId>/root/children
But all 3 above endpoints throw a 400 Bad Request Error with message: Url specified is invalid.
Additional information:
My access token has the following scopes: Sites.FullControl.All User.Read profile openid email
I am able to retrieve an individual drive item through the list endpoints (but the folder structure is quite complex and I need to list several layers of folders/files - this is why I believe the syntax with drive would be a lot more convenient):
GET https://graph.microsoft.com/v1.0/sites/site.sharepoint.com,<id>,<id>:/teams/myTeam:/lists/<list-id>/items/<item-id>/driveItem
via the field parentReference I am also able to fetch the driveId and even the relative path (/drives/<drive-id>/root:) but I also have no idea how I would get the content from that.
Help is greatly appreciated as I have been stuck for a long time now - thank you!
Try with the below HTTP call.
https://graph.microsoft.com/v1.0/sites/site.sharepoint.com,<id>,<id>/drives/driveid/root/children
It worked for me.

Does Microsoft Graph API /search() work when using app-only token

I am trying to use the graph API (v1.0) to search for files and folders within our team's sharepoint/onedrive folders but when using an app-only token I consistently get no results for any /search(...) request I try.
I have an registered and application with https://apps.dev.microsoft.com and have requested and granted consent for the permissions stated in the API Documentation;
User.ReadWrite.All, Group.Read.All, Sites.Read.All, Sites.ReadWrite.All, Group.ReadWrite.All, Sites.Manage.All, Files.ReadWrite.All, User.Read.All, Files.Read.All, Sites.FullControl.All
When I request a token from https://login.microsoftonline.com/ I can see the granted permissions in the payload.
Using this token I can successfully access the drive and retrieve information about its contents using drive/root
I have a small test folder structure that contains a few simple text files.
I can confirm that this token gives me access to my files and folders by calling drives/{driveid}/items/{folderid}/children recursively to build a complete tree structure.
However, when I try to search the drive for filenames or text phrases that I know exist I get no results at all, no matter what combination of paths or search terms I use. I've never seen a search result from an app-only token.
Examples that I've tried;
sites/root/drive/search(q='test')
drive/root/search(q='test')
drives/{driveid}/search(q='test')
drives/{driveid}/root/search(q='test')
The phrase "test" exists both as a filename and also within the text content of some of the files.
I get an HTTP:200 response but the value collection https://graph.microsoft.com/v1.0/$metadata#Collection(driveItem) is always empty.
I'm building http requests in my application (Coldfusion), not using a SDK.
I wondered if I was having encoding problems so have tried various approaches of url-encoding the search part of the url (q='test') etc.
I've also tried running the same requests with Postman and cUrl but the results are the same. Empty.
The only thing that works is when I try the same searches using the Graph Explorer I get the results I would expect to see.
I know that Explorer uses a different type of token so I'm wondering if this is and issues related to my token being app-only.
Does anyone know if .../search() actually work for app-only tokens?
Does anyone know if .../search() actually work for app-only tokens?
The answer is yes, ../search() actually work for app-only tokens
Based on my test, the following search API works well for app-only token
https://graph.microsoft.com/v1.0/drive/root/microsoft.graph.search(q='test')
https://graph.microsoft.com/v1.0/drives/{driveid}/root/microsoft.graph.search(q='test')
https://graph.microsoft.com/v1.0/drives/{driveid}/microsoft.graph.search(q='test')
https://graph.microsoft.com/v1.0/sites/root/drive/search(q='test')
For permission config, just put "Files.Read.All, Files.ReadWrite.All, Sites.Read.All, Sites.ReadWrite.All" into the GraphScopes in the project config file as docs states.
Above answer is based on your description:****register app in http://apps.dev.microsoft.com/. You can ignore the SDK although it is the best choice. If you don't have a project config with GraphScopes, you need to pass the scope to auth request, it is difficult for operation.
If your app-only mean register app in SharePoint online, then the Graph Search API won't work. SharePoint doesn't share AccessToken with Graph directly.
Here is the same question again. The answer has been commented by a microsoft developer. He confirmed, it was a bug.

How can I download a OneDrive file with Office365 REST API into a Ruby variable?

I'm building a Ruby on Rails app, and I'd like to integrate some Office365 features.
For instance : I would like to download a file from OneDrive and then attach it to an Email in order to send it via Outlook rest API.
I found this get Item content OneDrive REST API but I dont understand how to use it.
I understand that I have to send a GET request (formated as explained in msdn.microsoft.com) with Rails, which will then provide me a "a pre-authenticated download URL" to download the file.
Then I will have to send a second GET request with this a pre-authenticated download URL to start the download, but I don't understand how to deal with the Response in order to save the file into a variable.
How can I retrieve the file into a variable of my Ruby on Rails App, so that I can attach it to an Email with an Outlook REST API to send it from my own Rail controller ?
Also this workflow is really not optimized in term of Bandwidth and Processing (3 REST API request + 1 download + 1 upload), it will work.
However if it exist a single REST API that direclty attach a OneDrive file to an email to send it, that would ease a lot my life, save energy, save money from Microsoft datacenter, and spare the planet ecology.
Any tutorial, examples, or more explanatory doc would be much appreciated.
--- EDIT ---
Adding link to the email is not wished as the email may have to be send to someone outside of Office365 users, and public link are a security issue for confidential documents.
Any help is welcome.
There isn't a single REST API call you can make currently to do what you want, although being able to easily attach a file from OneDrive to a new email message is a great scenario for Microsoft Graph API, it just isn't supported right now.
If you want to attach the file, you need to do as you mentioned, download the contents of the file, and then upload it again as an attachment to the message.
However, I'd recommend sending a link to the file instead, even though you mentioned you don't want to do that. OneDrive for Business now supports "company shareable links" which are scoped to just the user's organization instead of being available totally anonymously.
Something else to consider: The security concerns of sending an anonymous link aren't that different than sending an attached file. In fact, the anonymous link can be more secure, because access to the file can be monitored and revoked in the future (unlike the attachment, which will always be out there).

Mendeley API File retrieval by id fails with response code 0

I'm experimenting with the Mendeley API to upload and retrieve documents and files and have a problem with the files/{file_id} endpoint.
I have a personal Mendeley account I'm using for testing, populated with some PDF documents.
For example, on the API documentation page if I call
GET /files
I see all the files I've added, but if I take an id value, then call
GET /files/{file_id}
using the ID, e.g.
https://api.mendeley.com:443/files/7b188de2-32a7-f067-51bd-520179e866b8
I get a strange response code of 0, response headers is {}, response body is 'no content'. This happens with all the ids from the file listing - is this a bug or am I doing something wrong?
If I alter the id string, I get a 404 Not found error, which is to be expected, so it's not an authorisation or other general issue.
It's a limitation of Swagger, the software that's used to run the API documentation web page.
That endpoint returns a redirect to an S3 download URL, to allow you to grab the file. Unfortunately Swagger doesn't handle the redirect properly, and it shows it as a response code of 0.
The endpoint is working correctly; it's just not displaying properly on the documentation page.

Amazon S3 : access without Secret Key

I am developing an iOS app which saves picture in an Amazon S3 server. Unfortunately, the owner of the server prefers not to give me his secret key. Instead, he generates and provides me with a signature he says I can use to upload a file.
The problem is that I cannot find a way to perform that. Especially with the Amazon S3 sample "S3Uploader".
Do you have any idea about that ?
Thanks in advance
The secret key is only needed to calculate the signature, so if you already have a signature you don't need it. You do however need the access key id (so that amazon knows which secret key to use to validate the signature).
I had a quick look at the iOS sdk docs and it doesn't look like they provide a way to short-circuit the signature calculation process. Uploading a file is easy though, you just make a PUT request:
PUT /ObjectName HTTP/1.1
Host: BucketName.s3.amazonaws.com
Date: date
Authorization: signatureValue
Content-Length: 1234
There are details of extra headers you can use in the documentation.
Another workflow is that instead of providing you with signature values, the remote service could use the amazon STS api to return temporary credentials authorised only to upload files to the specified bucket. If you go this route then you would be able to just use the SDK provided by amazon.

Resources