From a74f97ff81e2c50af81e8ea27277c6098cd94786 Mon Sep 17 00:00:00 2001 From: = <=> Date: Wed, 22 Jun 2022 00:19:12 +0200 Subject: [PATCH 1/3] Added Get-PnPSensitivityLabel --- CHANGELOG.md | 1 + documentation/Get-PnPSensitivityLabel.md | 94 +++++++++++++++++++ src/Commands/Base/BasePSCmdlet.cs | 8 +- src/Commands/Model/AzureAD/User.cs | 2 + src/Commands/Model/Graph/GraphException.cs | 5 +- .../Purview/InformationProtectionLabel.cs | 31 ++++++ src/Commands/Purview/GetSensitivityLabel.cs | 57 +++++++++++ src/Commands/Utilities/REST/GraphHelper.cs | 2 + 8 files changed, 196 insertions(+), 4 deletions(-) create mode 100644 documentation/Get-PnPSensitivityLabel.md create mode 100644 src/Commands/Model/Graph/Purview/InformationProtectionLabel.cs create mode 100644 src/Commands/Purview/GetSensitivityLabel.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index b423e2d2e..3dba1c244 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,6 +57,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - Added `-SharingCapability` parameter to the `New-PnPTenantSite` cmdlet to update the Sharing capabilties of the newly provisioned classic site collection. [#1994](https://github.com/pnp/powershell/pull/1994) - Added optional `-IncludeAllLists` to `Get-PnPSiteScriptFromWeb` which will include the JSON definition of all custom lists of the current site in the output [#1987](https://github.com/pnp/powershell/pull/1987) - Added `-UpdateChildren` parameter to `Add-PnPFieldToContentType` cmdlet. This allows users to skip pushing the fields to child content types. [#1092](https://github.com/pnp/powershell/pull/1992) +- Added `Get-PnPSensitivityLabel` cmdlet to retrieve Microsoft Purview sensitivity labels available on the tenant ### Changed diff --git a/documentation/Get-PnPSensitivityLabel.md b/documentation/Get-PnPSensitivityLabel.md new file mode 100644 index 000000000..735862a60 --- /dev/null +++ b/documentation/Get-PnPSensitivityLabel.md @@ -0,0 +1,94 @@ +--- +Module Name: PnP.PowerShell +schema: 2.0.0 +applicable: SharePoint Online +online version: https://pnp.github.io/powershell/cmdlets/Get-PnPSensitivityLabel.html +external help file: PnP.PowerShell.dll-Help.xml +title: Get-PnPSensitivityLabel +--- + +# Get-PnPSensitivityLabel + +## SYNOPSIS +Gets the Microsoft Purview sensitivity labels that are available within the tenant + +## SYNTAX + +```powershell +Get-PnPSensitivityLabel [-Identity ] [-User ] [-Connection ] [] +``` + +## DESCRIPTION +This cmdlet allows retrieval of the available Microsoft Purview sensitivity labels in the currently connected tenant. You can retrieve all the labels, a specific label or all the labels available to a specific user. + +## EXAMPLES + +### EXAMPLE 1 +```powershell +Get-PnPSensitivityLabel +``` + +Returns all the Microsoft Purview sensitivitiy labels that exist on the tenant + +### EXAMPLE 2 +```powershell +Get-PnPSensitivityLabel -User johndoe@tenant.onmicrosoft.com +``` + +Returns all Microsoft Purview sensitivitiy labels which are available to the provided user + +### EXAMPLE 3 +```powershell +Get-PnPSensitivityLabel -Identity 47e66706-8627-4979-89f1-fa7afeba2884 +``` + +Returns a specific Microsoft Purview sensitivitiy label by its id + +## PARAMETERS + +### -Identity +The Id of the Microsoft Purview sensitivity label to retrieve + +```yaml +Type: Guid +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -User +The UPN, Id or instance of an Azure AD user for which you would like to retrieve the Microsoft Purview sensitivity labels available to this user + +```yaml +Type: SwitchParameter +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Connection +Optional connection to be used by the cmdlet. Retrieve the value for this parameter by either specifying -ReturnConnection on Connect-PnPOnline or by executing Get-PnPConnection. + +```yaml +Type: PnPConnection +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +## RELATED LINKS + +[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) +[Microsoft Graph documentation](https://docs.microsoft.com/graph/api/informationprotectionpolicy-list-labels) \ No newline at end of file diff --git a/src/Commands/Base/BasePSCmdlet.cs b/src/Commands/Base/BasePSCmdlet.cs index f16d0927c..72de479a7 100644 --- a/src/Commands/Base/BasePSCmdlet.cs +++ b/src/Commands/Base/BasePSCmdlet.cs @@ -52,6 +52,8 @@ protected override void ProcessRecord() } catch (PnP.PowerShell.Commands.Model.Graph.GraphException gex) { + var errorMessage = gex.Error.Message; + if (gex.Error.Code == "Authorization_RequestDenied") { if (!string.IsNullOrEmpty(gex.AccessToken)) @@ -59,7 +61,11 @@ protected override void ProcessRecord() TokenHandler.ValidateTokenForPermissions(GetType(), gex.AccessToken); } } - throw new PSInvalidOperationException(gex.Error.Message); + if(string.IsNullOrWhiteSpace(errorMessage) && gex.HttpResponse != null && gex.HttpResponse.StatusCode == System.Net.HttpStatusCode.Forbidden) + { + errorMessage = "Access denied. Check for the required permissions."; + } + throw new PSInvalidOperationException(errorMessage); } } diff --git a/src/Commands/Model/AzureAD/User.cs b/src/Commands/Model/AzureAD/User.cs index 501020f68..3148bc298 100644 --- a/src/Commands/Model/AzureAD/User.cs +++ b/src/Commands/Model/AzureAD/User.cs @@ -80,6 +80,8 @@ public class User /// PnP PowerShell Azure Active Directory User object internal static User CreateFrom(PnP.Framework.Graph.Model.User entity) { + if(entity == null) return null; + var user = new User { UserPrincipalName = entity.UserPrincipalName, diff --git a/src/Commands/Model/Graph/GraphException.cs b/src/Commands/Model/Graph/GraphException.cs index b62fb8cf7..22a7bb682 100644 --- a/src/Commands/Model/Graph/GraphException.cs +++ b/src/Commands/Model/Graph/GraphException.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.Net; -using System.Text; namespace PnP.PowerShell.Commands.Model.Graph { @@ -10,6 +8,8 @@ public class GraphException : Exception public GraphError Error { get; set; } public string AccessToken { get; set; } + + public System.Net.Http.HttpResponseMessage HttpResponse { get; set; } } public class GraphError @@ -23,6 +23,5 @@ public class GraphError public Dictionary AdditionalData { get; set; } public string ThrowSite { get; set; } - } } diff --git a/src/Commands/Model/Graph/Purview/InformationProtectionLabel.cs b/src/Commands/Model/Graph/Purview/InformationProtectionLabel.cs new file mode 100644 index 000000000..dd036c699 --- /dev/null +++ b/src/Commands/Model/Graph/Purview/InformationProtectionLabel.cs @@ -0,0 +1,31 @@ +using System.Text.Json.Serialization; + +namespace PnP.PowerShell.Commands.Model.Graph.Purview +{ + public class InformationProtectionLabel + { + [JsonPropertyName("id")] + public string Id { get; set; } + + [JsonPropertyName("name")] + public string Name { get; set; } + + [JsonPropertyName("description")] + public string Description { get; set; } + + [JsonPropertyName("color")] + public string Color { get; set; } + + [JsonPropertyName("sensitivity")] + public int Sensitivity { get; set; } + + [JsonPropertyName("tooltip")] + public string Tooltip { get; set; } + + [JsonPropertyName("isActive")] + public bool IsActive { get; set; } + + [JsonPropertyName("parent")] + public object Parent { get; set; } + } +} \ No newline at end of file diff --git a/src/Commands/Purview/GetSensitivityLabel.cs b/src/Commands/Purview/GetSensitivityLabel.cs new file mode 100644 index 000000000..1558b3551 --- /dev/null +++ b/src/Commands/Purview/GetSensitivityLabel.cs @@ -0,0 +1,57 @@ +using PnP.PowerShell.Commands.Attributes; +using PnP.PowerShell.Commands.Base; +using PnP.PowerShell.Commands.Base.PipeBinds; +using PnP.PowerShell.Commands.Utilities.REST; +using System; +using System.Collections.Generic; +using System.Management.Automation; + +namespace PnP.PowerShell.Commands.PowerPlatform.PowerAutomate +{ + [Cmdlet(VerbsCommon.Get, "PnPSensitivityLabel")] + [RequiredMinimalApiPermissions("InformationProtectionPolicy.Read.All")] + [OutputType(typeof(IEnumerable))] + [OutputType(typeof(Model.Graph.Purview.InformationProtectionLabel))] + public class GetSensitivityLabel : PnPGraphCmdlet + { + [Parameter(Mandatory = false)] + public AzureADUserPipeBind User; + + [Parameter(Mandatory = false)] + public Guid Identity; + + protected override void ExecuteCmdlet() + { + string url; + if (ParameterSpecified(nameof(User))) + { + var user = User.GetUser(AccessToken); + + if(user == null) + { + WriteWarning("Provided user not found"); + return; + } + + url = $"/beta/users/{user.UserPrincipalName}/informationProtection/policy/labels"; + } + else + { + url = "/beta/informationProtection/policy/labels"; + } + + if (ParameterSpecified(nameof(Identity))) + { + url += $"/{Identity}"; + + var labels = GraphHelper.GetAsync(Connection, url, AccessToken).GetAwaiter().GetResult(); + WriteObject(labels, false); + } + else + { + var labels = GraphHelper.GetResultCollectionAsync(Connection, url, AccessToken).GetAwaiter().GetResult(); + WriteObject(labels, true); + } + } + } +} \ No newline at end of file diff --git a/src/Commands/Utilities/REST/GraphHelper.cs b/src/Commands/Utilities/REST/GraphHelper.cs index a7370f1ba..9d129ae27 100644 --- a/src/Commands/Utilities/REST/GraphHelper.cs +++ b/src/Commands/Utilities/REST/GraphHelper.cs @@ -349,6 +349,8 @@ private static async Task SendMessageAsync(PnPConnection connection, Htt var errorContent = await response.Content.ReadAsStringAsync(); var exception = JsonSerializer.Deserialize(errorContent, new JsonSerializerOptions() { IgnoreNullValues = true, PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); exception.AccessToken = accessToken; + exception.HttpResponse = response; + throw exception; } } From 425232796ed4573034f8edd03869bd3382104b4c Mon Sep 17 00:00:00 2001 From: = <=> Date: Wed, 22 Jun 2022 00:21:10 +0200 Subject: [PATCH 2/3] Added PR reference --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3dba1c244..5e2fee0df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,7 +57,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - Added `-SharingCapability` parameter to the `New-PnPTenantSite` cmdlet to update the Sharing capabilties of the newly provisioned classic site collection. [#1994](https://github.com/pnp/powershell/pull/1994) - Added optional `-IncludeAllLists` to `Get-PnPSiteScriptFromWeb` which will include the JSON definition of all custom lists of the current site in the output [#1987](https://github.com/pnp/powershell/pull/1987) - Added `-UpdateChildren` parameter to `Add-PnPFieldToContentType` cmdlet. This allows users to skip pushing the fields to child content types. [#1092](https://github.com/pnp/powershell/pull/1992) -- Added `Get-PnPSensitivityLabel` cmdlet to retrieve Microsoft Purview sensitivity labels available on the tenant +- Added `Get-PnPSensitivityLabel` cmdlet to retrieve Microsoft Purview sensitivity labels available on the tenant [#2023](https://github.com/pnp/powershell/pull/2023) ### Changed From 3be333b05a9b0c33394c63d422cfcfb4df3561fa Mon Sep 17 00:00:00 2001 From: = <=> Date: Wed, 22 Jun 2022 00:25:05 +0200 Subject: [PATCH 3/3] Adding documentation to model --- .../Purview/InformationProtectionLabel.cs | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/Commands/Model/Graph/Purview/InformationProtectionLabel.cs b/src/Commands/Model/Graph/Purview/InformationProtectionLabel.cs index dd036c699..f4a680093 100644 --- a/src/Commands/Model/Graph/Purview/InformationProtectionLabel.cs +++ b/src/Commands/Model/Graph/Purview/InformationProtectionLabel.cs @@ -2,29 +2,57 @@ namespace PnP.PowerShell.Commands.Model.Graph.Purview { + /// + /// Describes the information protection label that details how to properly apply a sensitivity label to information. The informationProtectionLabel resource describes the configuration of sensitivity labels that apply to a user or tenant. + /// + /// public class InformationProtectionLabel { + /// + /// The label ID is a globally unique identifier (GUID) + /// [JsonPropertyName("id")] public string Id { get; set; } + /// + /// The plaintext name of the label. + /// [JsonPropertyName("name")] public string Name { get; set; } + /// + /// The admin-defined description for the label. + /// [JsonPropertyName("description")] public string Description { get; set; } + /// + /// The color that the UI should display for the label, if configured. + /// [JsonPropertyName("color")] public string Color { get; set; } + /// + /// The sensitivity value of the label, where lower is less sensitive. + /// [JsonPropertyName("sensitivity")] public int Sensitivity { get; set; } + /// + /// The tooltip that should be displayed for the label in a UI. + /// [JsonPropertyName("tooltip")] public string Tooltip { get; set; } + /// + /// Indicates whether the label is active or not. Active labels should be hidden or disabled in UI. + /// [JsonPropertyName("isActive")] - public bool IsActive { get; set; } + public bool? IsActive { get; set; } + /// + /// The parent label associated with a child label. Null if label has no parent. + /// [JsonPropertyName("parent")] public object Parent { get; set; } }