• No results found

The list of the user ’s attributes handled by the service is long, and for the sake of simplicity in Listing 6-1 you can see just a few of them. Some of the most important are

UserPrincipalName, Mail, and AccountEnabled. In the following sections, you will see how to handle users instances like this.

Reading users

To browse the list of users registered in an Office 365 tenant, you can make an HTTP GET request for the users endpoint of the Microsoft Graph, as illustrated in Listing 6-2.

LISTING 6-2 Code excerpt to enumerate the users registered in the current tenant

Click he re to vie w code imag e

/// <summary>

/// This method retrieves the list of users registered in Azure AD /// </summary>

/// <param name="numberOfItems">Defines the TOP number of items to retrieve</param>

/// <returns>The list of users in Azure AD</returns>

public static List<User> ListUsers(Int32 numberOfItems = 100) {

String jsonResponse = MicrosoftGraphHelper.MakeGetRequestForString(

String.Format("{0}users?$top={1}",

MicrosoftGraphHelper.MicrosoftGraphV1BaseUri, numberOfItems));

var usersList = JsonConvert.DeserializeObject<UsersList>(jsonResponse);

return (usersList.Users);

}

As you can see, the method internally leverages the helper method

MakeGetRequestForString that we used in Chapter 5. Notice the $top query string parameter to retrieve just a subset of users. By default, if you don’t specify any value for the $top

parameter, the query returns the top 100 items. The values allowed for the $top parameter are between 1 and 999. Thus, you cannot retrieve more than 999 users per query, but you can apply some partitioning rules using the $filter query string parameter to reduce the result set according to the filtering rules supported by the users collection.

Thus, if you would like to filter the result—for example, extracting only the users working in a specified department—you can use a code excerpt like the one illustrated in Listing 6-3.

LISTING 6-3 Code excerpt to enumerate all the users working in a specified department

Click he re to vie w code imag e

/// <summary>

/// This method retrieves the list of users working in a specific department /// </summary>

/// <param name="department">The department to filter the users on</param>

/// <param name="numberOfItems">Defines the TOP number of items to retrieve</param>

/// <returns>The list of users in Azure AD</returns>

public static List<User> ListUsersByDepartment(String department, Int32 numberOfItems = 100) {

String jsonResponse = MicrosoftGraphHelper.MakeGetRequestForString(

String.Format("{0}users?$filter=department%20eq%20'{1}'&$top={2}", MicrosoftGraphHelper.MicrosoftGraphV1BaseUri,

department, numberOfItems));

var usersList = JsonConvert.DeserializeObject<UsersList>(jsonResponse);

return (usersList.Users);

}

In Listing 6-3, you can see the OData $filter query string parameter, which selects those user items that have the department field equal to a specific filter value.

Another interesting filtering option is based on the userType property, which assumes a value of Guest for the external users. Thus, if you would like to select all the external users registered in the current tenant, you can use a query like the one defined in Listing 6-4.

LISTING 6-4 Code excerpt to enumerate all the external users for a target tenant

Click he re to vie w code imag e

/// <summary>

/// This method retrieves the list of all the external users for a tenant /// </summary>

/// <param name="numberOfItems">Defines the TOP number of items to retrieve</param>

/// <returns>The list of externa users in Azure AD</returns>

public static List<User> ListExternalUsers(Int32 numberOfItems = 100) {

String jsonResponse = MicrosoftGraphHelper.MakeGetRequestForString(

String.Format("{0}users?$filter=userType%20eq%20'Guest'&$top={1}", MicrosoftGraphHelper.MicrosoftGraphV1BaseUri,

numberOfItems));

var usersList = JsonConvert.DeserializeObject<UsersList>(jsonResponse);

return (usersList.Users);

}

Moreover, because the full user ’s profile could be big and rich in attributes, querying the list of users you will get back the following attributes by default: businessPhones,

displayName, givenName, id, jobTitle, mail, mobilePhone, officeLocation, preferredLanguage, surname, and userPrincipalName. You can leverage the OData $select query string parameter to change the default behavior of the service, selecting a custom set of attributes like the code excerpt in Listing 6-5 does.

LISTING 6-5 Code excerpt that retrieves a list of users with some custom fields

Click he re to vie w code imag e

/// <summary>

/// This method retrieves the list of users registered in Azure AD with custom fields

/// </summary>

/// <param name="fields">The list of fields to retrieve</param>

/// <param name="numberOfItems">Defines the TOP number of items to retrieve</param>

/// <returns>The list of users in Azure AD</returns>

public static List<User> ListUsers(String[] fields = null, Int32 numberOfItems

= 100) {

String selectFilter = String.Empty;

if (fields != null) {

selectFilter = "&$select=";

foreach (var field in fields) {

selectFilter += HttpUtility.UrlEncode(field) + ",";

} }

String jsonResponse = MicrosoftGraphHelper.MakeGetRequestForString(

String.Format("{0}users?$top={1}{2}",

MicrosoftGraphHelper.MicrosoftGraphV1BaseUri, numberOfItems,

selectFilter));

var usersList = JsonConvert.DeserializeObject<UsersList>(jsonResponse);

return (usersList.Users);

}

In Listing 6-6, you can see a code excerpt that invokes the helper method illustrated in Listing 6-5.

LISTING 6-6 Code excerpt that invokes the helper method illustrated in Listing 6-5

Click he re to vie w code imag e

var usersWithCustomAttributes = UsersGroupsHelper.ListUsers(

new String[] { "id", "userPrincipalName", "mail", "department", "country", "preferredLanguage",

"onPremisesImmutableId", "onPremisesSecurityIdentifier", "onPremisesSyncEnabled", "userType" },

600);

Another interesting option to consider is the capability to leverage some navigation properties of the user object. For example, every user has the manager navigation property that allows you to discover the manager of the current user, if any. Similarly, by using the directReports navigation property, you can see the list of the people managed by a specific user. From a SharePoint Online development perspective, it is important to underline that these properties and organizational relationships refer to those defined in Microsoft Azure Active Directory (Azure AD), and they are not necessarily the ones defined in the User Profile Service (UPS) of Microsoft SharePoint Online (SPO). Having the same values in Azure AD and in the UPS of SPO depends on the configuration of the UPS.

Note

If you want to learn more about the fields that are synchronized by default by the UPS in Microsoft SharePoint, you can read the article “Default user profile property mappings in SharePoint Server 2013,” which is available at the

following URL: https://technet.microsoft.com/library/hh147510.aspx. If you want to import custom properties in the UPS of SPO, you can refer to the “User

Profile Batch Update” sample that is available in the Office 365 Developer Patterns & Practices (PnP) project repository on GitHub. It can be found at the following friendly URL: http://aka.ms/PnPUserProfileBatchUpdateAPI.

In Listing 6-7, you can see the definition of a couple of helper methods to retrieve the manager and the direct reports of a user.

LISTING 6-7 Code excerpt to retrieve the manager and the direct reports of a user

Click he re to vie w code imag e

/// <summary>

/// This method returns the manager of a user /// </summary>

/// <param name="upn">The UPN of the user</param>

/// <returns>The user's manager</returns>

public static User GetUserManager(String upn) {

String jsonResponse = MicrosoftGraphHelper.MakeGetRequestForString(

String.Format("{0}users/{1}/manager",

MicrosoftGraphHelper.MicrosoftGraphV1BaseUri, upn));

var user = JsonConvert.DeserializeObject<User>(jsonResponse);

return (user);

}

/// <summary>

/// This method returns the direct reports of a user /// </summary>

/// <param name="upn">The UPN of the user</param>

/// <returns>The user's direct reports</returns>

public static List<User> GetUserDirectReports(String upn) {

String jsonResponse = MicrosoftGraphHelper.MakeGetRequestForString(

String.Format("b",

MicrosoftGraphHelper.MicrosoftGraphV1BaseUri, upn));

var directReports = JsonConvert.DeserializeObject<UsersList>(jsonResponse);

return (directReports.Users);

}

There are many other navigation properties that you can use to go through the users’

calendars, events, mailboxes and mail folders, drives on OneDrive for Business, and so on.

To access these navigation properties, you must have the proper account delegations and proper permissions in Azure AD. Aside from the authorization rules, you can apply to these items the same development techniques that you saw in Chapter 5 and that you will learn about in Chapter 7, “File services.”

Just as you can read a list of users, you can get a single user object. You just need to make an HTTP GET request providing, for example, the User Principal Name (UPN) just after the users endpoint. In Listing 6-8, you can see a sample helper method to accomplish this task.

LISTING 6-8 Code excerpt to retrieve a single user instance

Click he re to vie w code imag e

/// <summary>

/// This method retrieves a single user from Azure AD /// </summary>

/// <param name="upn">The UPN of the user to retrieve</param>

/// <returns>The user retrieved from Azure AD</returns>

public static User GetUser(String upn) {

String jsonResponse = MicrosoftGraphHelper.MakeGetRequestForString(

String.Format("{0}users/{1}",

MicrosoftGraphHelper.MicrosoftGraphV1BaseUri, upn));

var user = JsonConvert.DeserializeObject<User>(jsonResponse);

return (user);

}

From a user interface perspective, an interesting property of every user object is the photo.

In fact, modern UI applications often show the lists of users not as text but by using their profile pictures. For example, think about what happens in Skype for Business or in the web UI of the Contacts list in Office 365: you have a list of profile pictures, each one wrapped in a

circle. If you want to get the profile picture of a specific user, you have to leverage the photo property of that user. Specifically, to get the binary value of the photo, you have to query the

$value property of the photo by using the common OData syntax. In Listing 6-9, you can see a helper method that retrieves a user ’s photo as a stream of bytes.

LISTING 6-9 Code excerpt of a helper method to retrieve a user ’s photo as a stream of bytes

Click he re to vie w code imag e

/// <summary>

/// This method retrieves the photo of a single user from Azure AD /// </summary>

/// <param name="upn">The UPN of the user</param>

/// <returns>The user's photo retrieved from Azure AD</returns>

public static Stream GetUserPhoto(String upn) { String contentType = "image/png";

var result = MicrosoftGraphHelper.MakeGetRequestForStream(

String.Format("{0}users/{1}/photo/$value",

MicrosoftGraphHelper.MicrosoftGraphV1BaseUri, upn), contentType);

return (result);

}

The resulting stream can be used wherever you like. For example, in the sample application related to this chapter, the user ’s photo is used to reproduce the current user ’s profile picture in the Office 365 suite bar. To achieve this result, the sample application uses a dedicated action in an ASP.NET MVC controller where the stream is returned as a binary file together with a specific image content type (image/png).