Introduction

Permissions are the most important part of web development, dealing with who can view something who cannot. In this article, I will elaborate on how to use permission levels in SPFX development.
To check whether a user is a Tenant admin:
  1. this.context.pageContext.legacyPageContext['isSiteOwner'];
To check whether user is an Site collection Administrator:
  1. this.context.pageContext.legacyPageContext.isSiteAdmin;
LegacyPageContext is a powerful context where we can get more info about Sharepoint for free. The available objects are:
  1. webServerRelativeUrl: "/sites/PublishPractice"
  2. webAbsoluteUrl: "https://mytest.sharepoint.com/sites/PublishPractice"
  3. viewId: ""
  4. webPropertyFlags2: 0
  5. listId: ""
  6. listPermsMask: null
  7. listUrl: ""
  8. listTitle: null
  9. listBaseTemplate: -1
  10. listBaseType: -1
  11. driveInfo: {}
  12. vanityUrls: {}
  13. multiGeoInfo: [{…}]
  14. viewOnlyExperienceEnabled: false
  15. blockDownloadsExperienceEnabled: false
  16. idleSessionSignOutEnabled: false
  17. activityBasedTimeoutEnabled: false
  18. activityMonitorModuleLinkEnabled: false
  19. isUnauthorizedTenant: false
  20. cdnPrefix: "static.sharepointonline.com/bld"
  21. cdnBaseUrl: null
  22. siteAbsoluteUrl: "https://mytest.sharepoint.com/sites/PublishPractice"
  23. siteId: "{94bba8b7-43e4-4603-8d02-81c220aa2379}"
  24. showNGSCDialogForSyncOnTS: true
  25. supportPoundStorePath: true
  26. supportPercentStorePath: true
  27. siteSubscriptionId: "b13ba969-995d-4554-bbc3-233141a9cade"
  28. tenantDisplayName: "mytest"
  29. isMultiGeoTenant: false
  30. isMultiGeoODBMode: false
  31. webDomain: "sharepoint.com"
  32. IsIEDisabledForItemsScope: false
  33. isSPO: true
  34. farmLabel: "IND_201_Content"
  35. contentDBName: "Content_809195"
  36. serverRequestPath: "/_layouts/15/workbench.aspx"
  37. layoutsUrl: "_layouts/15"
  38. webId: "{d7b179ac-ba57-4f35-b75b-df24bf906b66}"
  39. webTitle: "PublishPractice"
  40. webTemplate: "53"
  41. webTemplateConfiguration: "BLANKINTERNET#0"
  42. webDescription: ""
  43. tenantAppVersion: "1"
  44. isAppWeb: false
  45. webLogoUrl: "_layouts/15/images/siteicon.png"
  46. webLanguage: 1033
  47. webLanguageName: "en-US"
  48. currentLanguage: 1033
  49. currentUICultureName: "en-US"
  50. currentCultureName: "en-US"
  51. currentCultureLCID: 1033
  52. env: "prod"
  53. env2: "prod"
  54. nid: 12479
  55. fid: 195205
  56. serverTime: "2020-04-13T14:29:06.3446430Z"
  57. siteClientTag: "0$$16.0.20001.12019"
  58. crossDomainPhotosEnabled: true
  59. openInClient: false
  60. webUIVersion: 15
  61. webPermMasks: {High: 2147483647, Low: 4294967295}
  62. pageListId: null
  63. pageItemId: -1
  64. pagePermsMask: null
  65. pagePersonalizationScope: 1
  66. userEmail: "[email protected]"
  67. userId: 17
  68. userLoginName: "[email protected]"
  69. userDisplayName: "Madhan Thurai NC"
  70. isAnonymousGuestUser: false
  71. isEmailAuthenticationGuestUser: false
  72. isExternalGuestUser: false
  73. isShareByLinkEnabled: false
  74. FolderAnonymousLinkPermission: 5
  75. systemUserKey: "i:0h.f|membership|[email protected]"
  76. alertsEnabled: true
  77. siteServerRelativeUrl: "/sites/PublishPractice"
  78. allowSilverlightPrompt: "True"
  79. themeCacheToken: "/sites/PublishPractice::0:16.0.20001.12019"
  80. themedCssFolderUrl: null
  81. themedImageFileNames: null
  82. modernThemingEnabled: true
  83. isSiteAdmin: true
  84. isSiteOwner: true
  85. ExpFeatures: (63) [-836791292, 1624570697, 620877909, 1736388636, 867936057, -1796975952, 1288360470, 57945375, 273224740, -1793982464, 87445392, -2138906472, 67451592, 545980736, 2159493, 1879736340, 369377650, 830086336, 20206087, 0, 0, 1212153856, -1883956681, -2080757274, -1806289405, -533232128, -115767270, -936371879, -1065350031, 384368717, 1236488464, 192, 0, 1268512236, 1563207295, -64208227, -1172788480, 113054989, -721582382, -1518442702, 561838596, -23925256, 342968415, -951444149, 1076429836, 1747342597, 414355587, -1341637787, 721486338, 599792128, 1164151212, -1308421888, 387990056, 1275278338, 202377090, 405274688, 537925760, 1048716, 1157627916, 0, 0, 0, 0]
  86. experimentData: "BgABAAAXIHAIAScHBgEBAAB3Bwc"
  87. experimentDataLookup: []
  88. killSwitches: {3487BA96-793D-453F-AA6E-5252E0D81ED6: true, 925090C8-8AA6-4C6A-8BFE-1EF2E43038F0: true, F5580BB6-8B44-4428-B490-36B777B4D5F8: true, C50B5771-669C-4853-A87F-1093166E3FE6: true, 00AA590F-D7AC-48DF-B8C9-0546E0AB9803: true, …}
  89. CorrelationId: "e761489f-b043-0000-38a7-f45d0822bba0"
  90. hasManageWebPermissions: true
  91. isNoScriptEnabled: true
  92. groupId: null
  93. groupHasHomepage: true
  94. groupHasQuickLaunchConversationsLink: false
  95. departmentId: null
  96. hubSiteId: null
  97. sensitivityLabel: null
  98. restrictedToRegion: null
  99. hasPendingWebTemplateExtension: false
  100. disableRecommendedItems: false
  101. isGroupRelatedSite: false
  102. isArchived: false
  103. IBSegments: null
  104. hasAutogeneratedWebLogo: true
  105. isHubSite: false
  106. isWebWelcomePage: false
  107. siteClassification: ""
  108. hideSyncButtonOnODB: false
  109. showNGSCDialogForSyncOnODB: false
  110. sitePagesEnabled: false
  111. sitePagesFeatureVersion: 0
  112. featureInfo: {SitePages: {…}, SitePagesResources: {…}, MixedReality: {…}, MixedRealityResources: {…}, RecommendedItems: {…}, …}
  113. DesignPackageId: "00000000-0000-0000-0000-000000000000"
  114. groupType: null
  115. groupColor: "#ca5010"
  116. siteColor: "#ca5010"
  117. headerEmphasis: 0
  118. headerLayout: 0
  119. searchScope: 0
  120. searchBoxInNavBar: 1
  121. searchBoxPlaceholderText: null
  122. navigationInfo: null
  123. clientPersistedCacheKey: {CurrentKey: {…}, PreviousKey: {…}}
  124. guestsEnabled: false
  125. MenuData: {SettingsData: Array(4), SignOutUrl: "https://mytest.sharepoint.com/sites/PublishPractice/_layouts/15/SignOut.aspx"}
  126. RecycleBinItemCount: -1
  127. listItemCount: -1
  128. PublishingFeatureOn: true
  129. PreviewFeaturesEnabled: true
  130. disableAppViews: false
  131. disableFlows: false
  132. serverRedirectedUrl: null
  133. formDigestValue: "0x14FD2B0BD9FA5893C41D8807652990AA6C57E33C559B52EE5CD810FF87C12B1FD6D06577151CA9B4CBA88383B59C8FEF43690A2550225FA745E2F398D01EDA07,13 Apr 2020 14:29:06 -0000"
  134. IsHomepageModernized: false
  135. NextStepsFirstRunEnabled: false
  136. maximumFileSize: 15360
  137. formDigestTimeoutSeconds: 1800
  138. canUserCreateMicrosoftForm: false
  139. canUserCreateVisioDrawing: true
  140. readOnlyState: null
  141. isTenantDevSite: false
  142. preferUserTimeZone: false
  143. userTimeZoneData: null
  144. userTime24: false
  145. userFirstDayOfWeek: null
  146. webTimeZoneData: {Description: "(UTC+05:30) Chennai, Kolkata, Mumbai, New Delhi", Bias: -330, Id: 23, DaylightBias: -60, DaylightDate: {…}, …}
  147. webTime24: false
  148. webFirstDayOfWeek: 0
  149. aadTenantId: "b13ba969-995d-4554-bbc3-233141a9cade"
  150. aadUserId: "b4a0dbf7-ad0e-4526-aa7f-b74a291cec9c"
  151. aadInstanceUrl: "https://login.windows.net"
  152. aadSessionId: "V2!10032000892FF6FA!13230631649"
  153. msGraphEndpointUrl: "https://graph.microsoft.com"
  154. msMruEndpointUrl: "https://ocws.officeapps.live.com"
  155. allowInfectedDownload: true
  156. organizationNewsSiteReference: []
  157. companyPortalReference: null
  158. knowledgeHubSiteDetails: null
  159. spfx3rdPartyServicePrincipalId: "f6141ed2-79ff-419a-afa7-01f1b3dfe9b0"
  160. completenessUrls: null
  161. socialBarEnabled: true
  162. substrateOneDriveDisabled: null
  163. isGroupifyDisabled: false
  164. Has2019Era: true
  165. userVoiceForFeedbackEnabled: true
  166. substrateOneDriveMigrated: null
  167. userPrincipalName: "[email protected]"
  168. spfxOBOFlowEnabled: true
  169. publicCdnBaseUrl: "https://publiccdn.sharepointonline.com"
  170. SideBySideToken: "16.0.20001.12019"
  171. farmSettings: {ExternalService_powerappswebhostname: "web.powerapps.com", ExternalService_powerappscreatehostname: "create.powerapps.com", ExternalService_flowhostname: "flow.microsoft.com", ExternalService_flowservicehostname: "service.flow.microsoft.com", ExternalService_popularplatformsenable: "1", …}
  172. __proto__: Object
usualy we get pagecontext directly from sharepoint classic page as
  1. _spPageContextInfo
pagecontext from modern page as (Hacky way to get context)
  1. function getmodernpagecontext(url) {
  2. var request = new XMLHttpRequest();
  3. return new Promise(function(resolve, reject) {
  4. request.onreadystatechange = function() {
  5. if (request.readyState !== 4) return;
  6. if (request.status >= 200 && request.status < 300) {
  7. resolve(request);
  8. } else {
  9. reject({
  10. status: request.status,
  11. statusText: request.statusText
  12. });
  13. }
  14. };
  15. request.open('GET', url, true);
  16. request.setRequestHeader("Content-Type", "application/json;charset=utf-8");
  17. request.setRequestHeader("ACCEPT", "application/json; odata.metadata=verbose");
  18. request.setRequestHeader("ODATA-VERSION", "4.0");
  19. request.send();
  20. });
  21. }
  22. //Get the Request location from the browser URL
  23. var path = location.href.replace(location.search, "") + "?as=json";
  24. //Returns the current user, item, page and context information
  25. getmodernpagecontext(path).then(function(response) {
  26. console.log(JSON.parse(response.response));
  27. });
To check other permissions apart from sitecollection admin and tenant admin, import the below module in SPFx
  1. import { SPPermission } from '@microsoft/sp-page-context';
There are 3 methods to identify permissions, methods only return the boolean value. Before looking through the methods, first, initiate all of the permission objects to get context from the webpart.
  1. let permission = new SPPermission(this.context.pageContext.web.permissions.value);
hasPermission returns true if the given permission is available for the current user. It holds single value.
  1. const viewpage = permission.hasPermission(SPPermission.viewPages);
hasAllPermissions returns true if given permissions are available for the current user. If a single permission is not available, it returns false. It holds an array of values.
  1. const fullcontrol = permission.hasAllPermissions(SPPermission.fullMask,SPPermission.viewPages);
hasAnyPermissions returns true if any one of the given permissions are available for the current user. If a single permission is available, it returns true. It holds an array of values.
  1. const anycontrol = permission.hasAnyPermissions(SPPermission.fullMask,SPPermission.viewPages);
The available permissions are:
  1. emptyMask - Has no permissions on the Web site. Not available through the user interface.
  2. viewListItems - View items in lists, documents in document libraries, and view Web discussion comments.
  3. addListItems - Add items to lists, add documents to document libraries, and add Web discussion comments.
  4. editListItems - Edit items in lists, edit documents in document libraries, edit Web discussion comments in documents,* and customize web part Pages in document libraries.
  5. deleteListItems - Delete items from a list, documents from a document library, and Web discussion comments in documents.
  6. approveItems - Approve a minor version of a list item or document.
  7. openItems - View the source of documents with server-side file handlers.
  8. viewVersions - View past versions of a list item or document.
  9. deleteVersions - Delete past versions of a list item or document.
  10. cancelCheckout- Discard or check in a document that is checked out to another user.
  11. managePersonalViews - Create, change and delete personal views of lists.
  12. manageLists - Create and delete lists, add or remove columns in a list, and add or remove public views of a list.
  13. viewFormPages - View forms, views, and application pages, and enumerate lists.
  14. open - Allow users to open a Web site, list, or folder to access items inside that container.
  15. viewPages - View pages in a Web site.
  16. layoutsPage - View the layouts page?
  17. addAndCustomizePages - Add, change, or delete HTML pages or web part Pages, and edit the Web site using a SharePoint* Foundation–compatible editor.
  18. applyThemeAndBorder - Apply a theme or borders to the entire Web site.
  19. applyStyleSheets - Apply a style sheet (.css file) to the Web site.
  20. viewUsageData - View reports on Web site usage.
  21. createSSCSite - Create a Web site using Self-Service Site Creation.
  22. manageSubwebs - Create subsites such as team sites, Meeting Workspace sites, and Document Workspace sites.
  23. createGroups - Create a group of users that can be used anywhere within the site collection.
  24. managePermissions - Create and change permission levels on the Web site and assign permissions to users and groups.
  25. browseDirectories - Enumerate files and folders in a Web site using Microsoft Office SharePoint Designer 2007 and WebDAV interfaces.
  26. browserUserInfo - View information about users of the Web site.
  27. addDelPrivateWebParts - Add or remove personal web parts on a web part Page.
  28. updatePersonalWebParts - Update web parts to display personalized information.
  29. manageWeb - Use features that launch client applications; otherwise, users must work on documents locally and upload changes.
  30. useClientIntegration - Use SOAP, WebDAV, or Microsoft Office SharePoint Designer 2007 interfaces to access the Web site.
  31. useRemoteAPIs - Manage alerts for all users of the Web site.
  32. manageAlerts - Create e-mail alerts.
  33. createAlerts - Allows a user to change his or her user information, such as adding a picture.
  34. editMyUserInfo - Enumerate permissions on the Web site, list, folder, document, or list item.
  35. enumeratePermissions - Has all permissions on the Web site. Not available through the user interface.
  36. fullMask - full control
Let's be practical:
Open a command prompt and create a directory for the SPFx solution.
md spfx-SpfxPermissions
Navigate to the above-created directory.
cd spfx-SpfxPermissions
Run the Yeoman SharePoint Generator to create the solution.
yo @microsoft/sharepoint
Solution Name
Hit Enter for the default name (spfx-SpfxPermissions in this case) or type in any other name for your solution.
Selected choice - Hit Enter
Target for the component
Here, we can select the target environment where we are planning to deploy the client web part; i.e., SharePoint Online or SharePoint OnPremise (SharePoint 2016 onwards).
Selected choice - SharePoint Online only (latest).
Place of files
We may choose to use the same folder or create a subfolder for our solution.
Selected choice - same folder.
Deployment option
Selecting Y will allow the app to be deployed instantly to all sites and be accessible everywhere.
Selected choice - N (install on each site explicitly).
Permissions to access web APIs
Choose if the components in the solution require permission to access web APIs that are unique and not shared with other components in the tenant.
Selected choice - N (solution contains unique permissions)
Type of client-side component to create
We can choose to create a client-side web part or an extension. Choose the web part option.
Selected choice - WebPart
Web part name
Hit Enter to select the default name or type in any other name.
Selected choice - SpfxListView
Web part description
Hit Enter to select the default description or type in any other value.
Framework to use
Select any JavaScript framework to develop the component. Available choices are - No JavaScript Framework, React, and Knockout.
Selected choice - React
The Yeoman generator will perform a scaffolding process to generate the solution. The scaffolding process will take a significant amount of time.
Once the scaffolding process is completed, lock down the version of project dependencies by running the below command,
npm shrinkwrap
In SpfxPermissionsWebPart.ts
  1. public render(): void {
  2. const element: React.ReactElement<ISpfxPermissionsProps> = React.createElement(
  3. SpfxPermissions,
  4. {
  5. description: this.properties.description,
  6. context: this.context
  7. }
  8. );
  9. ReactDom.render(element, this.domElement);
  10. }
In SpfxPermissions.tsx
  1. import * as React from 'react';
  2. import { ISpfxPermissionsProps } from './ISpfxPermissionsProps';
  3. import { SPPermission } from '@microsoft/sp-page-context';
  4. interface Permissionstate {
  5. noadmin: boolean;
  6. siteadmin:boolean;
  7. tenantadmin:boolean;
  8. }
  9. export default class SpfxPermissions extends React.Component<ISpfxPermissionsProps, Permissionstate> {
  10. constructor(props: ISpfxPermissionsProps) {
  11. super(props);
  12. this.state = {
  13. noadmin: false,
  14. siteadmin:false,
  15. tenantadmin:false
  16. };
  17. }
  18. public componentDidMount(){
  19. this.UserSitePermission();
  20. }
  21. private UserSitePermission() {
  22. console.log(this.props.context.pageContext.web.permissions);
  23. console.log(this.props.context.pageContext.legacyPageContext);

  24. let sitecoladmin:boolean=this.props.context.pageContext.legacyPageContext.isSiteAdmin;
  25. let siteowner:boolean=this.props.context.pageContext.legacyPageContext['isSiteOwner'];
  26. let permission = new SPPermission(this.props.context.pageContext.web.permissions.value);
  27. let canEdit = permission.hasPermission(SPPermission.manageWeb);
  28. const fullcontrol = permission.hasAllPermissions(SPPermission.fullMask);
  29. const anycontrol = permission.hasAnyPermissions(SPPermission.fullMask);
  30. const viewpage = permission.hasPermission(SPPermission.viewPages);
  31. const nopermision = permission.hasPermission(SPPermission.emptyMask);
  32. this.setState({
  33. noadmin: nopermision,
  34. siteadmin:sitecoladmin,
  35. tenantadmin:siteowner
  36. });
  37. }
  38. public render(): React.ReactElement<ISpfxPermissionsProps> {
  39. if(this.state.siteadmin === true) {
  40. return (
  41. <div >
  42. I am site collection admin
  43. </div>
  44. );}
  45. else if(this.state.tenantadmin === true) {
  46. return (
  47. <div >
  48. I am Tenent admin
  49. </div>
  50. );}
  51. else {
  52. return (
  53. <div >
  54. I am not an Administrator
  55. </div>
  56. );}
  57. }}
In ISpfxPermissionsProps.ts
  1. import { WebPartContext } from "@microsoft/sp-webpart-base";
  2. export interface ISpfxPermissionsProps {
  3. description: string;
  4. context:WebPartContext;
  5. }
Expected Output

Conclusion

We learned how to hide/show webpart based on user permissions in SPFx. I hope this helps someone. Happy coding :)