DEV Community

Guido Zambarda
Guido Zambarda

Posted on • Originally published at iamguidozam.blog on

Secure your web parts using the PnP SecurityTrimmedControl

Introduction

Proceeding with the appointments with the PnP React controls today I want to talk about the SecurityTrimmedControl control.

If you’re interested you can find the code of this sample here.

The control is used to display a child control based on the permissions that the current user has on the current or the remote SharePoint site.

Visual appearance

Let’s begin setting a little bit of context to understand the examples I’ll be showing in a minute.

The control supports the permissions for the current user for the current site or for a target site so let’s define currentSite and remoteSite as the two aliases we’ll use to describe what’s in the screenshots.

Starting with the visual appearance, the first screenshot is taken from a user which is owner of the currentSite and also of the remoteSite.

The following screenshot is taken from a user which is a visitor for the currentSite and has no access to the remoteSite:

Next, there’s an example of a user which is part of the site members on the currentSite but has no access to the remoteSite.

The last screenshot sample is for a user which is in the currentSite‘s visitors group but it’s in the remoteSite‘s owners group:

Since this control is almost invisible, I will cover each of the instances in detail in the next section.

Show me the code

Prerequisites

To use the PnP React controls, first you need to install the package:

npm install @pnp/spfx-controls-react --save --save-exact
Enter fullscreen mode Exit fullscreen mode

After the installation of the package you can proceed with the following instructions to use the SecurityTrimmedControl.


To use the control you first need to import it and that can be done as following:

import { SecurityTrimmedControl, PermissionLevel } from "@pnp/spfx-controls-react/lib/SecurityTrimmedControl";
Enter fullscreen mode Exit fullscreen mode

Also, it’s required to import the SPPermission class from the @microsoft/sp-page-context package:

import { SPPermission } from '@microsoft/sp-page-context';
Enter fullscreen mode Exit fullscreen mode

Second thing to do is to declare at least the context property, in the components properties, to pass the web part context to the component. In the sample this is achieved as follows:

import { WebPartContext } from "@microsoft/sp-webpart-base";

export interface IPnPLocationPickerProps {
  context: WebPartContext;
}
Enter fullscreen mode Exit fullscreen mode

After importing the control and preparing the component properties you can start to use it. Let’s cover each of the instances from the sample solution in a little bit more detail.

Instances details

After showing a little bit of how the sample renders with different behaviors let’s discover what are the instances used in the web part.

Basic Instance

This is the instance with the minimal configuration required. The control uses some properties in each of the instances, those are the minimal required for the control to work. Let’s cover a little bit more in detail the minimal properties:

  • The context property will be set to the web part context one. As said before, in the component properties, we have defined the context property to be used in the control property.
  • The level property is used to define the permission level for the control instance, the currently available levels are the following:
    • currentWeb
    • currentList
    • remoteWeb
    • remoteListOrLib
    • remoteListItem
    • remoteFolder
  • The permissions property is used to define an array of the SharePoint permissions that the user must have to display the child control. To set this property you will need the SPPermission class, which I described previously how to import it. I won’t cover here all the possible values, if you’re interested in knowing more you can check the official documentation here.

After specifying the control’s properties you will need to specify the control that will be shown when the user has the required permissions. In the sample I’ve specified only a div with a text, but in a real world scenario this is the place where you would put the section/control to display only if the current user has specific permissions.

Following there’s the full code for the instance:

<SecurityTrimmedControl
  context={context as any}
  level={PermissionLevel.currentWeb}
  permissions={[SPPermission.viewPages]}>
  <div>
    {strings.CanViewPages}
  </div>
</SecurityTrimmedControl>
Enter fullscreen mode Exit fullscreen mode

Edit List Items

This instance shows the child control if the current user has editing permissions in the current web. To achieve that the level property must be set to PermissionLevel.currentWeb and the permissions property have to be set to SPPermission.editListItems.

<SecurityTrimmedControl
  context={context as any}
  level={PermissionLevel.currentWeb}
  permissions={[SPPermission.editListItems]}>
  <div>
    {strings.CanEditListItems}
  </div>
</SecurityTrimmedControl>
Enter fullscreen mode Exit fullscreen mode

Manage Permissions

The manage permissions instance shows what is the configuration to check that the current user has manage permissions on the current web.

<SecurityTrimmedControl
  context={context as any}
  level={PermissionLevel.currentWeb}
  permissions={[SPPermission.managePermissions]}>
  <div>
    {strings.CanManagePermissions}
  </div>
</SecurityTrimmedControl>
Enter fullscreen mode Exit fullscreen mode

Manage Remote Permissions

This instance shows how to check the permissions of the current user for a remote SharePoint site. To specify which is the remote site use the remoteSiteUrl property using the absolute site URL. To specify which are the permissions to check you will need to specify what is the level for a remote site using the PermissionLevel.remoteWeb value for the level property. Once the level property is set it’s time to define which are the permissions required using the permissions.

<SecurityTrimmedControl
  context={context as any}
  level={PermissionLevel.remoteWeb}
  permissions={[SPPermission.managePermissions]}
  remoteSiteUrl={siteUrl}>
  <div>
    {strings.CanManageRemotePermissions}
  </div>
</SecurityTrimmedControl>
Enter fullscreen mode Exit fullscreen mode

Edit Remote List Items

This instance shows how to perform a permission check against a list in a remote SharePoint site. To specify which is the remote list, after specifying the remoteSiteUrl property, use the relativeLibOrListUrl with the relative URL of the target list.

<SecurityTrimmedControl
  context={context as any}
  level={PermissionLevel.remoteListOrLib}
  permissions={[SPPermission.editListItems]}
  remoteSiteUrl={siteUrl}
  relativeLibOrListUrl={listUrl} >
  <div>
    {strings.CanEditRemoteListItems}
  </div>
</SecurityTrimmedControl>
Enter fullscreen mode Exit fullscreen mode

Enumerate Permissions on Remote List Item

A further customization of the control is to check the permissions against a specific list item on a remote SharePoint site. To check these permissions, after specifying the remoteSiteUrl, relativeLibOrListUrl, specify also the itemId property with the ID of the target list item.

<SecurityTrimmedControl
  context={context as any}
  level={PermissionLevel.remoteListItem}
  permissions={[SPPermission.enumeratePermissions]}
  remoteSiteUrl={siteUrl}
  relativeLibOrListUrl={listUrl}
  itemId={itemId}>
  <div>
    {strings.CanEnumeratePermissionsOnRemoteListItem}
  </div>
</SecurityTrimmedControl>
Enter fullscreen mode Exit fullscreen mode

Show Loading

This instance is used to demonstrate that’s possible to show a loading animation while retrieving the user permissions. In the sample solution I’ve defined the relativeLibOrListUrl to a non existent list, in this way the loading will be shown while attempting to retrieve the permissions. To show the loading indicator simply set the showLoadingAnimation to true.

<SecurityTrimmedControl
  context={context as any}
  level={PermissionLevel.remoteListOrLib}
  permissions={[SPPermission.viewPages]}
  showLoadingAnimation={true}
  // This list does not exist, so the control will show the loading animation trying to get the list
  relativeLibOrListUrl='/value-to-show-loading'>
  <div>
    {strings.CanViewPages}
  </div>
</SecurityTrimmedControl>
Enter fullscreen mode Exit fullscreen mode

No Permissions default behavior

This instance is used to demonstrate what is the default behavior of the control when the current user does not have the required permissions (in this case no manage permissions on the remote SharePoint site). The default behavior is to not display the child control and any other control.

<SecurityTrimmedControl
  context={context as any}
  level={PermissionLevel.remoteWeb}
  permissions={[SPPermission.managePermissions]}>
  <div>
    {strings.CanManagePermissions}
  </div>
</SecurityTrimmedControl>
Enter fullscreen mode Exit fullscreen mode

No Permissions Control

Instead of the previous instance, this one is used to demonstrate that’s possible to define a control to be shown when the user doesn’t meet the required permissions. To specify the control to be shown when the user doesn’t meet the requirements use the noPermissionsControl and set it to a JSX.Element.

<SecurityTrimmedControl
  context={context as any}
  level={PermissionLevel.remoteWeb}
  permissions={[SPPermission.managePermissions]}
  remoteSiteUrl='nonexistent/site'
  noPermissionsControl={<div className={styles.noPermissions}>{strings.NoPermissions}</div>}>
  <div>
    {strings.CanManagePermissions}
  </div>
</SecurityTrimmedControl>
Enter fullscreen mode Exit fullscreen mode

Conclusions

The SecurityTrimmedControl is an awesome control that enables an easy way to perform security checks without effort! Consider using it when you need to show or hide controls when the current user has specific set of permissions.

There are some other properties that I did not cover in this post, if you’re interested in knowing more check out the official documentation here.

Hope this helps!

Top comments (0)