Inviting a guest User to a SharePoint Site using PowerAutomate - sharepoint-online

We are developing a PowerAutomate Flow to automate the process of inviting external users to a SharePoint Site.
Below are the steps being followed so far
Created an MS Form for an external user to register
Passing the response**(Email)** from the form to the flow
Adding the user to a SharePoint Group using email parameter and sending an email invite to the External User(Requirement)
I have been able to get to point no 2 , However I have been experiencing challenges achieving point no 3
Came across different articles online for adding a guest users , However most of them talk about adding the guest to Azure AD as shown below
https://medium.com/southworks/adding-a-guest-to-an-office-365-sharepoint-site-with-javascript-fa7604ad8678
https://laurakokkarinen.com/how-to-build-a-guest-user-self-service-registration-for-office-365-with-azure/
https://www.timlinenterprises.com/how-to-invite-external-users-using-microsoft-flow-and-microsoft-graph-api/
Also checked a few articles for running PowerShell commands from Flow , However this approach doesn't look straightforward either
The below article works only for internal users
https://www.c-sharpcorner.com/article/add-the-users-to-the-sharepoint-groups-using-microsoft-flow/
The end goal here is to invite external user to a SharePoint Site once the user registers himself through a registration form (MS Form)
Would appreciate if anyone could help me out in achieving this.
Thanks in advance

Before inviting the user to SharePoint you must add him to Azure AD. So you will need to configure an HTTP action to invite the user first.
If you are using SharePoint Modern Sites (those who have Microsoft 365 groups associated), you need to create a HTTP action to add the guest to the group:
HTTP Action Configuration Here
NOTE: HTTP will not accept "#" sign directly, so you need to put it into a "Compose" or "Variable" and add it as per my screenshot.
In the URI you have the Group ID from Azure AD.
In the Body it's the guest user ID
You will need to register and Azure AD App to use for the HTTP action and give it the following permissions:
Graph -> Application -> GroupMember.ReadWrite.All, Group.ReadWrite.All and Directory.ReadWrite.All
https://learn.microsoft.com/en-us/graph/api/group-post-members?view=graph-rest-1.0&tabs=http#permissions
Use the App ID and Secret to connect the HTTP action.

This is my solution to add Guest Users to Private Channels in MS Teams with PowerAutomate.
Step0 - Register the domain of the Guest Users in your AD account as a valida Guest Domain
Step1 - User a registration form (MS Forms)
Step2 - Create a Trigger Process in MS PowerAutomate to receive the Form Data. I like to create small/short flows to only capture and validate form data, and then call a separate Flow / RestService. This makes your solution a little bit more decoupled and reusable. (Imagine replacing the Form with a web app form or mobile app form in the future).
Create a second HTTP request trigger flow receiving the Form data (optional way to setup multi-flow solution)
Step3 - Create a Private Channel in teams via GrapAPI
GraphAPI - POST https://graph.microsoft.com/v1.0/teams/<teams_id>/channels
POST BODY:
{
"membershipType": "private",
"displayName": "<e.g. channel name from form data>",
"description": "<e.g. description from form data>",
"members": [
{
"#odata.type": "#microsoft.graph.aadUserConversationMember",
"user#odata.bind": "https://graph.microsoft.com/v1.0/users('owner.user#mydomain.com')",
"roles": [
"owner"
]
}
],
"#odata.type": "#Microsoft.Graph.channel"
}
Step4 - Call GraphAPI to retrieve the Guest User Details
GraphAPI: GET https://graph.microsoft.com/v1.0/users?$filter=mail eq 'guest.user#email.com'
I have added this in a loop - since I had many members who had to be added - and I also included a condition check to check if the domain is indeed valid
Now you can assign the output (or portions of the output) to some variables
Step5 - Retrieve the ID value from the step above (Step4). This is the value that must be used to add the new guest member.
Retrieve the ID from the Step4 output
Also set a variable to the account type - which should (MUST BE) be "guest"
Now - Add guest users to the private teams channel
Step6 - Call GraphAPI to add guest members
GraphAPI: POST https://graph.microsoft.com/v1.0/teams/<team_id>/channels/<channel_id>/members
Post Body:
The role must be "guest" for guest account
But valid options for other types of access can be
owner
member
guest
Microsoft documentation (HERE) states roles must be owner or empty
This did not work so well for me.
Use guest
{
"#odata.type": "#microsoft.graph.aadUserConversationMember",
"roles": [
"#{variables('membership_type')}"
],
"user#odata.bind": "https://graph.microsoft.com/v1.0/users('#{variables('principal_user')}')"
}
Bonus Step
Now you can catch all responses from the previous steps and respond back with an HTTP Request/Response connector.
A 200 response on successful executions
A non-200 response on failed executions (or how ever you desire)
To configure exception handling or failure handling responses do this below

Related

"User not found" for Graph API request in the Azure enterprise app security group with client credentials auth flow

Design
Goal
Get calendar events for a given user.
Requirements
Application should have access to the MS Graph API.
Application should act like a daemon/background process and not depend on user's login.
Application should have access to the minimal number of users' data in the Azure Active Directory (AAD).
Application should be able to fetch user's calendar events and create them.
Implementation / Setup
to fulfill (1) Azure (Enterprise) App was created as described here.
to enable (2) client credentials flow was used with the setup of application permissions
to meet (3) a security group - as described here - was created with a limited number of users with the related policy that included related permissions (see here). The group was later connected to the app following this instruction.
to implement (4) the Calendar.Read and Calendar.ReadWrite as required by the actions here and here were added to the policy mentioned in the previous setup step.
Testing
Two HTTP requests were used: one to get the token and another to read events.
token request from the Identity Platform
curl --location --request POST 'https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/token' \
--data-raw 'client_id=<APPLICATION_TOKEN>&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret=<APPLICATION_SECRET>&grant_type=client_credentials'
Upon inspection of the token here I see that it contains required permissions:
"roles": [
"Calendars.Read",
"Calendars.ReadWrite"
]
fetch request of the calendar events from Graph API
curl --location --request GET 'https://graph.microsoft.com/v1.0/users/<USER_ID>/calendar/events' \
--header 'Authorization: Bearer <TOKEN>'
results in the following error:
{
"error": {
"code": "ResourceNotFound",
"message": "User not found",
"innerError": {
"date": "2022-02-08T08:25:39",
"request-id": "bfaca1f9-e79b-491c-8d75-5a62317e299b",
"client-request-id": "bfaca1f9-e79b-491c-8d75-5a62317e299b"
}
}
}
The user id is from my account that I found in the Azure Active Directory details of the Azure Tenant. I double-checked that after adding other users.
Before-asking investigation
This issue looks closest to my case as it uses the client credentials auth flow. But it uses global permissions for all users in the AAD, while we use more fine-grained approach with a security group. It also shows a different error "Resource could not be discovered." versus "User not found" in my case.
In order to call /{user-id}/calendar/events to work the user must have mailbox on Exchange Online if you are using client credentials for Daemon applications.
Also, It seems assigning license to a guest account (Personal account in this case) is not possible and hence the user account never gets access to the calendar service (part of o365 exchange online) due to which it cannot retrieve the calendar information of personal account.
Please refer my answer similar to this in Q&A for detailed description.
Short Version
I was missing the application permissions and assumed that they are assigned on the level of security group. Only restriction happen on that level.
Long Version
The updated mental model looks like this:
It means that the application permissions for MS Graph API are required.
The security group is only restricting / limiting the access to the users mentioned in the policy.

MS Teams - Rich notification are not supported for this resource in 'app + user' context (Graph API)

I'm trying to set up rich notifications for a channel subscription like in the docs below.
New or changed messages in a specific Teams channel: /teams/{id}/channels/{id}/messages
I'm supplying the details to the subscription url like below with ROPC auth flow.
{
"changeType": "created,updated",
"notificationUrl": "https://f554-118-110-222-226.ngrok.io/api/teams/events",
"resource": "teams/TEAM_ID/channels/CHANNEL_ID/messages",
"expirationDateTime": "2021-10-20T02:55:53Z",
"encryptionCertificate": "encryptionCertificate",
"encryptionCertificateId": "encryptionCertificateId",
"includeResourceData": true,
}
I should have all permissions necessary to access this resource since I can create a subscription when includeResourceData is false. However, I'm getting the following error when includeResourceData is true and I supply an encryption cert.
Operation: Create; Exception: [Status Code: BadRequest; Reason: Rich notification are not supported for this resource in 'app + user' context. Please set includeResourceData field to false.]
I think it might be with how my auth and permissions are set up but I'm not entirely sure what this means. Any help is appreciated
Would Suggest you to please try to revalidate and setup all the below prerequisite if might you have missed while setup change notification for team’s channel.
you need to include "includeResourceData" set to "true" and provide certificate information as described here
you need to get your application approved
Other way to subscribe notifications for channel messages dynamically(e.g. powerapp - current user can subscribe to all of his joinedTeams or selected teams and receives push notifications) Because Ms Flows and Logic apps only lets you setup one at a time.
Please follow this MS Document for Set up change notifications that include resource data while creating subscription.
Reference: is team channel messages allowed for change notifications beta? · Issue #3977 · microsoftgraph/microsoft-graph-docs · GitHub
Found the answer to my question in this block of the docs. Thanks to RahulKumarShaw-MT for linking the right version.
https://learn.microsoft.com/en-us/graph/api/subscription-post-subscriptions?view=graph-rest-beta&tabs=http#chatmessage
The error below means that since the app was using ROPC auth flow it falls under delegated permissions and is not supported by the API to send encrypted data.
Operation: Create; Exception: [Status Code: BadRequest; Reason: Rich
notification are not supported for this resource in 'app + user'
context. Please set includeResourceData field to false.]
I got around this by having to set up an additional auth token with app permissions set up specifically for this purpose.

Check if users deleted in clients Azure AD

I am integrating Login with Azure AD for one of my clients on my website. I am only targeting one specific group in their organisation, and not everybody in the entire organisation.
This new feature has 2 requirements:
We need to create an account for people logging in via their email using our clients Azure AD.
We need to run a CRON job daily to check if anybody has been removed in their AD (due to them leaving the company), so we also need to remove their profile in our application.
For number 1, I think it's sufficient to call the /authorization, /token and /userinfo endpoints. Is this correct?
But for number 2, I am having issues to see how this is possible.
When browsing the graph explorer (https://developer.microsoft.com/en-us/graph/graph-explorer) I can find the following 2 API methods:
GET all users in the organization /users ---> But i am unsure whether this returns all the users in their AD, or only the ones applicable for my application?
GET direct members of a group with count /groups/<id</members ---> Is this the one I am looking for when they are assigned into a specific group?
I've also found this SO link : https://stackoverflow.com/a/64553305 which talks about saving the access token and refresh token. Is it possible if I save these two to fetch the userinfo at any point in time? This way I could possibly query all the created accounts each day and if one of them returns a status deleted, or empty I know the account no longer exists? Or is this not an option?
Thanks in advance!
UPDATE:
I noticed that my client granted me the User.Read and User.Read.All graph permissions.
But i'm not certain how to call this API? When calling this API in Postman :
https://graph.microsoft.com/v1.0/users/123-this-is-the-id
I am getting the following response:
{
"error": {
"code": "InvalidAuthenticationToken",
"message": "Access token is empty.",
"innerError": {
"date": "2021-10-07T12:59:05",
"request-id": "...",
"client-request-id": "..."
}
}
}

Microsoft Graph to send mail with Client Credential Flow (application permission) and personal account

I am learning Microsoft Graph and for this I use Graph Explorer and Postman.
With Graph Explorer : I am Signed In with my personal user account (hotmail). As soon as I am connected, I can see the token. Strangely when I copy/paste this token in jwt.io it cannot be decoded. Yet I can perform query like https://graph.microsoft.com/v1.0/me which returns me some infos of myself as a user (with http 200). Or this query https://graph.microsoft.com/v1.0/me/sendMail which allow me to send a test and receive a test mail (with http 202). All of these requests was "delegated permission". So I don't have any problem using Graph Explorer with my personnal account (hotmail).
With Postman : this time I will perform some tests with "application permission". I followed the steps below:
On the Azure Portal
Step 1: App registrations / New registration / I give a name / Choose the 3rd account type (Accounts in any organizational directory and personal Microsoft accounts) / Click on Register button
Step 2: Api permissions / Add permission / Microsoft Graph / Application permissions / Mail.Send (send mail as any user)
Step 3: Grand admin consent for... button to activate the permission
Step 4: Certificate & Secrets / New client secret / Enter a description / Click Add button
Step 5: Obtain a token in Postman
POST
https://login.microsoftonline.com/{my-tenant-id-here}/oauth2/v2.0/token
HEADERS
Content-Type: application/x-www-form-urlencoded
BODY
client_id: {my-client-id-here}
client_secret: {my-client-secret-here}
grant_type: client_credentials
scope: https://graph.microsoft.com/.default
OK I got a token
When copy/paste this token in jwt.io I see this:
Step 6: Query for listing all users
GET
https://graph.microsoft.com/v1.0/users
AUTHORIZATION
Bearer token: {bearer-token-received-previously}
HEADERS
Content-Type: application/json
OK I got infos for all users (as json)
Step 7: Query for sending a mail
POST
https://graph.microsoft.com/v1.0/users/{user-principal-name}/sendMail
AUTHORIZATION
Bearer token: {bearer-token-received-previously}
HEADERS
Content-Type: application/json
BODY (JSON)
{
"message": {
"subject": "This is my subject",
"body": {
"contentType": "Text",
"content": "This is my content"
},
"toRecipients": [
{
"emailAddress": {
"address": "thierry.langie#skynet.be"
}
}
],
"ccRecipients": [
]
},
"saveToSentItems": "false"
}
NOT OK Error: MailboxNotEnabledForRESTAPI - REST API is not yet supported for this mailbox
I would like to know why I got this error ? I can send email with Graph Explorer (when using delegated permission) and not with Postman (when using application permission).
As you can see below, I grant admin consent in Enterprise applications on the Azure Portal.
I read somewhere that the error means the user doesn't have the mailbox in EXO cloud. EXO is O365 Exchange Online Cloud. So if you don't have mailbox in the cloud O365 Exchange REST APIs will not work for these users. If that is the case, what would you do ?
I have a Web application which should send mails from a shared mailbox. No matter which user is connected, this is always the same mailbox which is used to send mails. That's why I go with "application permission" and "Client credential flow".
As explained above, I use my personal account (hotmail) for testing purpose but in production I'll use a work account (not accessible from my dev environment).
As a side note, I know there are libraries to facilitate the process and avoid using REST API calls (urls) but I don't think that can explain the problem I am facing.
"MailboxNotEnabledForRESTAPI - REST API is not yet supported for this mailbox" This error message means that the email account you are using to send email doesn't have an Exchange Online license.
For a personal account, you should use Delegated permission, which you have tried in Microsoft Graph Explorer. See Permissions here.
.
If we add the personal account to your tenant as a guest user, although we can Assign a license to a guest user (I assume we can assign EXO license to the guest user), the mailbox hosted in EXO is different from the mailbox of the personal account. They are totally 2 separated mailboxes. And in fact I failed to assign EXO license to the guest.
So in this case Client Credential Flow applies to the AAD users, not the personal account.
UPDATE:
For personal account which uses Delegated permission (you have tried in Microsoft Graph Explorer), the authority endpoint is https://login.microsoftonline.com/commonm/oauth2/v2.0/authorize or https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize.
But when you use client credential flow with Application permission, you have to specify the tenant id in the request https://login.microsoftonline.com/{tenant id}/oauth2/v2.0/authorize.
Although your personal account is added into the tenant as a guest user, it doesn't have EXO license (based on test we are unable to assign EXO license to it), so it won't be hosted in O365.
That is why we can't use client credential flow with personal account.

How to obtain tfid(team foundation id) for azure devops AD group

Could someone provide with the rest api url for finding the tfid for an Azure Devops ad group ?
I am trying to restrict branch permissions for certain AD groups,
"https://dev.azure.com/{organization}/{}/_api/_security/DisplayPermissions?__v=5&tfid={}&permissionSetId={}&permissionSetToken=repoV2%2F{}%2F{}%2Frefs%5Eheads%5E{}%2F".format(projectID, contributorTfid, nameToken, projectID, repoID, permbranchList[k])
only the contributor tfid here is unknown for me.
Using this rest api endpoint, I have to obtain the permissiontoken
later, using permisisontoken using the json
branchPermissionbody = {
"token": "{}".format(permissionToken),
"merge": True,
"accessControlEntries": [
{
"descriptor": "Microsoft.TeamFoundation.Identity;{}".format(descriptorIdentifier),
"deny": 4,
"extendedinfo": {}
}
]
}
I am making a post request to post the restriction on the branches
There are two ways to get the TeamFoundationId.
You can use below REST API to get the groups in your organization.
https://vssps.dev.azure.com/{orgname}/_apis/graph/groups?api-version=5.1-preview.1
Then use Ctrl + F to search the groups in the certain project. The originid is the TeamFoundationId. More details information about this REST API, you can refer to https://learn.microsoft.com/zh-cn/rest/api/azure/devops/graph/groups?view=azure-devops-rest-5.1.
Also you can use F12 to manual catch the TeamFoundationId. Log in to Project settings-> Repositories, then click F12 to open the Network console. Clear sessions then change the group permission. You can get the TeamFoundationId in the Request body or Response body.

Resources