Microsoft Graph - Can't read/write the calendar of other users - outlook

I have a web app registered on Azure with the goal of being able to read and write the calendars of other users. To do so, I set these permissions for this app on Azure.
However, when I try to, for example, create a new event for a given user, I get an error message. Here's what I'm using:
Endpoint
https://graph.microsoft.com/v1.0/users/${requester}/calendar/events
HTTP Header
Content-Type application/json
Request Body
{
"subject": "${subject}",
"body": {
"contentType": "HTML",
"content": "${remarks}"
},
"start": {
"dateTime": "${startTime}",
"timeZone": "${timezone}"
},
"end": {
"dateTime": "${endTime}",
"timeZone": "${timezone}"
},
"location": {
"displayName": "${spaceName}",
"locationEmailAddress": "${spaceEmail}"
},
"attendees": [
{
"emailAddress": {
"address": "${spaceEmail}",
"name": "${spaceName}"
},
"type": "resource"
}
]
}
Error message
{
"error": {
"code": "ErrorItemNotFound",
"message": "The specified object was not found in the store.",
"innerError": {
"request-id": "XXXXXXXXXXXXXXXX",
"date": "2018-07-11T09:16:19"
}
}
}
Is there something I'm missing? Thanks in advance for any help!
Solution update
I managed to solve the problem by following the steps described in this link:
https://developer.microsoft.com/en-us/graph/docs/concepts/auth_v2_service

From your screenshot it's visible that you used application permission (although it'd be nice to include this information in your question):
Depending on kind of the permission you have given, you need to use proper flow to obtain access token (on behalf of a user or as a service. For application permissions you have to use flow for service, not on behalf of a user.
You can also check your token using jwt.io and make sure it's payload contains appropriate role. If it doesn't, it's very likely you used incorrect flow.
Regarding the expiration time of it, you may have found the information about refresh token (for example here). Keep in mind that it applies only to rights granted on behalf of a user. For access without a user you should make sure that you know when your token is going to expire and request a new one accordingly.

Related

403 Forbidden on Microsoft Teams RSC graph api calls, except on own tenant

I'm working on a Microsoft Teams tab and am planning to use some of the new RSC endpoints to retrieve members of the Team/group the app has been added to.
I have followed all steps from the RSC docs looked at the RSC sample code but still have an issue making Graph API calls to the beta rsc endpoints.
I have listed the RSC permission in the Teams manifest:
"webApplicationInfo": {
"id": "{AD_APP_CLIENT_ID}",
"resource": "https://notapplicable"
},
"showLoadingIndicator": true,
"authorization": {
"permissions": {
"orgWide": [],
"resourceSpecific": [
{
"name": "Member.Read.Group",
"type": "Application"
},
{
"name": "TeamSettings.Read.Group",
"type": "Application"
},
{
"name": "ChatSettings.Read.Chat",
"type": "Application"
},
{
"name": "ChatMember.Read.Chat",
"type": "Application"
},
{
"name": "ChannelSettings.Read.Group",
"type": "Application"
},
{
"name": "TeamMember.Read.Group",
"type": "Application"
}
]
}
}
Query Graph API like so:
GET https://graph.microsoft.com/beta/teams/{{group_id}}/channels/{{channel_id}}
Authorization: Bearer {{access_token}}
content-type: application/json
Where access_token is retrieved like so:
POST https://login.microsoftonline.com/{{ad_tenant_id}}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id={{ad_app_client_id}}&client_secret={{ad_app_client_secret}}&scope=https://graph.microsoft.com/.default
When I make the GET request to a group+channel which is in the same AAD as where the AAD Application is registered it works fine and information is returned. However, when I run the exact same code on a group+channel which is in a different AD it returns 403 Forbidden.
{
"error": {
"code": "Forbidden",
"message": "Missing role permissions on the request. API requires one of 'TeamMember.Read.All, TeamMember.ReadWrite.All, Group.Read.All, Group.ReadWrite.All, TeamMember.Read.Group, Member.Read.Group'. Roles on the request 'Group.Selected'. Resource specific consent grants on the request ''.",
"innerError": {
"date": "2022-04-06T14:13:26",
"request-id": "ce212ed2-48dc-4a8e-a7ea-4172d0cfd4c4",
"client-request-id": "ce212ed2-48dc-4a8e-a7ea-4172d0cfd4c4"
}
}
}
The response mentions "Resource specific consent grants on the request ''." which seems to suggest it's either missing a header or another access token.
As mentioned before, this exact same code works perfectly fine when I use a group_id and channel_id from within the same AD tenant.
What other steps need to be done to get RSC calls working?

InvalidAudienceForResource exception with Exchange.Callback.V2 token in Outlook for iOS

I have an Outlook add-in with ReadWriteMailbox permissions that calls Office.context.mailbox.getCallbackTokenAsync({isRest: true}) to get what is generally a valid auth token:
{
"oid": "oid",
"puid": "puid",
"smtp": "xxx",
"upn": "xxx",
"clientappid": "3382ce5c-ed22-4195-aeca-c5b67384706f",
"ver": "Exchange.Callback.V2",
"appid": "00000002-0000-0ff1-ce00-000000000000",
"deploymentid": "https://outlook.office365.com/",
"tid": "tid",
"acr": "1",
"appidacr": "0",
"scp": "Mail.ReadWrite Mail.Send Calendars.ReadWrite Contacts.ReadWrite",
"nbf": 1588259750,
"exp": 1588260650,
"iss": "https://outlook.office365.com/",
"aud": "a_vanity_url",
"happ": "API"
}
In Outlook for iOS, I am now seeing this exception in a handful of environments:
{
"readyState": 4,
"responseText": "omitted_for_redundancy",
"responseJSON": {
"error": {
"code": "InvalidAudienceForResource",
"message": "The audience claim value is invalid for current resource.
Audience claim is 'a_vanity_url',
request url is 'https://outlook.office365.com/api/v2.0/me/messages/a_message_id'
and resource type is 'Exchange'.",
"innerError": {
"requestId": "requestId",
"date": "2020-04-30T15:15:51"
}
}
},
"status": 401,
"statusText": "Unauthorized"
}
The common theme seems to be whenever an MDM/MAM is configured (usually Intune), and it's happening across all managed devices on the tenant, and continues to fail until a device is unregistered and its Outlook accounts are removed and re-added.
Is there something I can do differently when I request an auth token to prevent this failure? Or is there a device management setting that Outlook for iOS requires to run add-ins?
Thank you for reporting and it seems like it is not an addin issue. Can you please raise a support case with Intune by going to Link, navigate to "Troubleshooting + Support". The corresponding team will address the issue.
The workaround here is just to use the vanity domain returned in the JWT's audience claim as the API URL base instead of the value returned by Office.context.mailbox.restUrl.

Problem with create team with Microsoft Graph Api

I have a problem with creating teams using the Microsoft Graph Api. I can get/create groups but when I try to get/create teams I get an error. I'm using postman and the group has owners and members, just as the documentation of MS, also has the permissitions it asks for groups. If somebody can help me, cause I look everywhere for a same error but no found it.
PUT https://graph.microsoft.com/v1.0/groups/{id}/team
Headers: Authorization: bearer token and content-type: json
Body is
{
"memberSettings": {
"allowCreateUpdateChannels": true
},
"messagingSettings": {
"allowUserEditMessages": true,
"allowUserDeleteMessages": true
},
"funSettings": {
"allowGiphy": true,
"giphyContentRating": "strict"
}
}
I always get the same error
{
"error": {
"code": "BadGateway",
"message": "Failed to execute backend request.",
"innerError": {
"request-id": "45eeba8a-9d35-45e8-b42e-c60da7a47dde",
"date": "2020-01-23T21:55:44"
}
}
}
According to the Graph API docs for this, you're not calling the correct endpoint to create a new Team. It should be
POST https://graph.microsoft.com/beta/teams
and a payload similar to
Content-Type: application/json
{
"template#odata.bind": "https://graph.microsoft.com/beta/teamsTemplates('standard')",
"displayName": "My Sample Team",
"description": "My Sample Team’s Description",
"owners#odata.bind": [
"https://graph.microsoft.com/beta/users('userId')"
]
}
Note that it's slightly different, as per the docs, whether you're using delegated versus application permissons.

Slack API: How to determine which human user owns a Legacy API token

When using a legacy token in slack I want to determine which user account owns this application. The information is not directly in the bot.info:
{
"ok": true,
"bot": {
"id": "foobar",
"deleted": false,
"name": "Slack API Tester",
"updated": 123456789,
"app_id": "A123"
}
}
Could I use the bot.id or bot.app_id objects to find who owns this application? If so which api call would I use.
To determine which user owns any token (incl. legacy token) just call the auth.test endpoint with that token. You will get the user ID and name of the token owner.
Example response from documentation:
{
"ok": true,
"url": "https://subarachnoid.slack.com/",
"team": "Subarachnoid Workspace",
"user": "grace",
"team_id": "T12345678",
"user_id": "W12345678"
}
If you need more info about the user you can call users.info for that user with his ID. Since you are using a legacy token you will have the necessary permissions.

Google Logging API - What service name to use when writing entries from non-Google application?

I am trying to use Google Cloud Logging API to write log entries from a web application I'm developing (happens to be .net).
To do this, I must use the logging.projects.logs.entries.write request. This request dictates that I provide a serviceName argument:
{
"entries": [
{
"textPayload": "test",
"metadata":
{
"serviceName": "compute.googleapis.com"
"projectId": "...",
"region": "us-central1",
"zone": "us-central1-a",
"severity": "DEFAULT",
"timestamp": "2015-01-13T19:17:01Z",
"userId": "",
}
}]
}
Unless I specify "compute.googleapis.com" as the serviceName I get an error 400 response:
{
"error":
{
"code": 400,
"message": "Unsupported service specified",
"status": "INVALID_ARGUMENT"
}
}
For now using "compute.googleapis.com" seems to work but I'm asking - what service name should I give, given that I'm not using Google Compute Engine or Google App Engine here?
The Cloud Logging API currently only officially supports Google resources, so the best course of action is to continue to use "compute.googleapis.com" as the service and supply the labels "compute.googleapis.com/resource_type" and "compute.googleapis.com/resource_id", which are used for indexing and visible in the UI drop-downs.
We also currently permit the service name "custom.googleapis.com" with index labels "custom.googleapis.com/primary_key" and "custom.googleapis.com/secondary_key" but that is not officially supported and subject to change in a future release.

Resources