November 19th, 2018

30DaysMSGraph – Day 19 – Use Case: Assign Permissions using Unified Groups

List of all posts in the #30DaysMSGraph series

In Day 18 we extended the base .Net Core console application to update the users (exchange online) mailbox settings in Office 365. Today we’ll extend the base console application to assign permissions to the users by adding them to the unified groups.  Note that it is not required to perform each of the daily Use Case samples in order to continue to the next.  Starting with the base console application from Day 15 will be sufficient if building from scratch, or as always, you can clone the completed version in the provided repo at bottom of this post. The application uses a client secret and the Microsoft Authentication Library (MSAL) to establish an authentication context with the Microsoft Graph API.

Today we will explore the process of adding user to the required Office 365 Groups in preparation for onboarding a user.

Add and validate user permissions in unified groups

In preparation for onboarding a user, once the user is created and appropriate license is applied, now we can add the permissions required for the user to various groups. In this post we will show you how to add users to Office 365 unified groups. By virtue of being part of these groups, the user will get permissions to access not just the group but also the associated SharePoint Online site. As of today (Nov 2018), Microsoft Graph does not support adding user permissions to SharePoint Online site. However, you can update the Azure AD App and assign permissions to SharePoint Online (in addition to Microsoft Graph) and then access SharePoint Online REST API to accomplish the task of assigning permissions. Note that this is outside the scope for today’s post.

You can use the Microsoft Graph endpoint /users/{id|userPrincipalName}/memberOf to get groups and directory roles that a user is a direct member of. You can find the Microsoft Graph documentation here.

You can use the Microsoft Graph endpoint /groups/{id}/members/$ref to add a user to a group. The documentation for this endpoint is here.

To use the above API the Azure AD App needs new permissions. As such the Azure AD App Registration needs to be updated to include the following application permissions: User.Read.All, Group.ReadWrite.All, Directory.Read.All, and Directory.ReadWrite.All

With the necessary permissions configured it is time to look at new the code required.

Get list of groups user is a member of

Below is a helper method added to PermissionHelper.cs class that will list out all the Groups that a user belongs to.

        //Returns a list of groups that the given user belongs to
        public async Task<List<ResultsItem>> UserMemberOf(string alias)
        {
            User user = FindByAlias(alias).Result;
            List<ResultsItem> items = new List<ResultsItem>();
            IUserMemberOfCollectionWithReferencesPage groupsCollection = await _graphClient.Users[user.Id].MemberOf.Request().GetAsync();
            if (groupsCollection?.Count > 0)
            {
                foreach (DirectoryObject dirObject in groupsCollection)
                {
                    if (dirObject is Group)
                    {
                        Group group = dirObject as Group;
                        items.Add(new ResultsItem
                        {
                            Display = group.DisplayName,
                            Id = group.Id
                        });
                    }
                }
            }
            return items;
        }

Identify a group and add user permissions to the group and the associated SharePoint Online Site

Below are two more helper methods that will help in adding a user to a unified group and also ensures the user is not already part of that group.
        //Adds the user to the given group if not already a member of
        public async Task AddUserToGroup(string alias, string groupId)
        {
            User user = FindByAlias(alias).Result;
            List<ResultsItem> items = UserMemberOf(alias).Result;
            if (items.FindIndex(f => f.Id == groupId) >= 0)
                Console.WriteLine("User already belongs to this group");
            else
                await _graphClient.Groups[groupId].Members.References.Request().AddAsync(user);
        }

        //Returns the first unified group with the given suffix
        public async Task<string> GetGroupByName(string groupNameSuffix)
        {
            var groups = await _graphClient.Groups.Request().Filter("groupTypes/any(c:c%20eq%20'unified') AND startswith(displayName,'" + groupNameSuffix + "')").Select("displayName,description,id").GetAsync();
            if (groups?.Count > 0)
            {
                return (groups[0] as Group).Id as string;
            }
            return null;
        }
Now that the helper methods are ready. You can call into these methods from the Program.cs class using below method:
        private static void PermissionHelperExampleScenario()
        {
            const string alias = "adelev";
            ListUnifiedGroupsForUser(alias);
            string groupId = GetUnifiedGroupStartswith("Contoso");
            AddUserToUnifiedGroup(alias, groupId);
            ListUnifiedGroupsForUser(alias);
        }

        private static void ListUnifiedGroupsForUser(string alias)
        {
            var permissionHelper = new PermissionHelper(_graphServiceClient);
            List<ResultsItem> items = permissionHelper.UserMemberOf(alias).Result;
            Console.WriteLine("User is member of "+ items.Count +" group(s).");
            foreach(ResultsItem item in items)
            {
                Console.WriteLine("  Group Name: "+ item.Display);
            }
        }

        private static string GetUnifiedGroupStartswith(string groupSuffix)
        {
            var permissionHelper = new PermissionHelper(_graphServiceClient);
            var groupId = permissionHelper.GetGroupByName(groupSuffix).Result;
            return groupId;
        }

        private static void AddUserToUnifiedGroup(string alias, string groupId)
        {
            var permissionHelper = new PermissionHelper(_graphServiceClient);
            permissionHelper.AddUserToGroup(alias, groupId).GetAwaiter().GetResult();
        }
In the above code the method PermissionHelperExampleScenario encapsulates today’s use case secnario. It first lists out all the unified groups that a given user belongs to. Then it identifies a new unified group. Then attemps to add the user to this new group. The code takes care of validating if the user is already part of this group. Finally to validate the use case, it lists out the groups that the user belongs to.
The complete set of instructions and code are on GitHub in the dotnetcore-console-sample repo for you try it yourself.

Try It Out

Navigate to the dotnetcore-console-sample repo.  Do one (or both) of the following:

Day 19 repo link

  1. Clone the repo and configure the project in the Day 19 subfolder.
  2. Follow the instructions in Day 19 to build the project from scratch yourself.

If you run into any issues while building or configuring the project please create a new Issue on the repo.

Join us tomorrow as we show you how to use Device Code Flow to authenticate user and use Microsoft Graph API in Day 20.