Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature : Extend Get-PnPAccessToken with additional resources #1451

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,17 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- Added alias on `Copy-PnPFile` for `Copy-PnPFolder`. It could already be used to copy a folder, but to make this more clear, and as we already had a `Copy/Move-PnPFolder` as well, the same cmdlet is now also available under its alternative cmdlet name.
- Added `IsFluidEnabled` state to be returned with `Get-PnPTenant` cmdlet.
- Added `-IsFluidEnabled` to `Set-PnPTenant` cmdlet to enable/disable users from using Fluid components.
- Added `-ResourceTypeName` and `ResourceUrl` parameters to `Get-PnPAccessToken` to fetch access token of specified resource.

### Changed
- Improved `Get-PnPFile` cmdlet to handle large file downloads
- Updated `Sync-PnPSharePointUserProfilesFromAzureActiveDirectory` to also allow results from `Get-PnPAzureADUser -Delta` to be provided through `-Users`.
- A clearer error message will now be returned when using `Add-PnPListItem -List` and specifying an invalid list name.
- Response of `Add-PnPContentTypesFromContenTypeHub` is now returned in the root of the response as well as under Value as it was previously for backwards compatibility.
- Improved synopsis documentation for `Update-PnPUserType` cmdlet.
- Improved documentation of `Add-PnPField` , reflects the missing `-AddToAllContentTypes` parameter.
- Improved documentation of `Get-PnPTaxonomyItem` with addition of new example and removing obsolete parameters.
- Improved documentation of `Get-PnPTerm` , fixed typos.

### Fixed
- Fixed `Get-PnPGroupMember -User` not properly returning the specified user
Expand Down
56 changes: 54 additions & 2 deletions documentation/Get-PnPAccessToken.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ title: Get-PnPAccessToken
# Get-PnPAccessToken

## SYNOPSIS
Returns the current Microsoft Graph OAuth Access token
Returns the current Microsoft Graph OAuth Access token.
If a Resource Type Name or Resource URL is specified, it will fetch the access token of the specified resource.

## SYNTAX

```powershell
Get-PnPAccessToken [-Decoded] [<CommonParameters>]
Get-PnPAccessToken [-ResourceTypeName] [-ResourceUrl] [-Decoded] [<CommonParameters>]
```

## DESCRIPTION
Expand All @@ -30,8 +31,59 @@ Get-PnPAccessToken

Gets the OAuth 2.0 Access Token to consume the Microsoft Graph API

### EXAMPLE 2
```powershell
Get-PnPAccessToken -ResourceTypeName SharePoint
```

Gets the OAuth 2.0 Access Token to consume the SharePoint APIs and perform CSOM operations.

### EXAMPLE 3
```powershell
Get-PnPAccessToken -ResourceTypeName ARM
```

Gets the OAuth 2.0 Access Token to consume the Azure Resource Manager APIs and perform related operations. In PnP, you can use them in cmdlets related to Flow and PowerPlatform etc.

### EXAMPLE 4
```powershell
Get-PnPAccessToken -ResourceUrl "https://management.azure.com/.default"
```

Gets the OAuth 2.0 Access Token to consume the SharePoint APIs and perform CSOM operations.

## PARAMETERS

### -ResourceTypeName
Specify the Resource Type for which you want the access token.
If not specified, it will by default return Microsoft Graph access token.

```yaml
Type: SwitchParameter
Parameter Sets: Resource Type Name

Required: False
Position: Named
Default value: Graph
Accept pipeline input: False
Accept wildcard characters: False
```

### -ResourceUrl
Specify the Resource URL for which you want the access token.
If not specified, it will by default return Microsoft Graph access token.

```yaml
Type: SwitchParameter
Parameter Sets: Resource Url

Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```

### -Decoded
Returns the details from the access token in a decoded manner

Expand Down
42 changes: 39 additions & 3 deletions src/Commands/Base/GetAccessToken.cs
Original file line number Diff line number Diff line change
@@ -1,25 +1,61 @@
using System;
using System.Management.Automation;
using PnP.PowerShell.Commands.Attributes;
using PnP.PowerShell.Commands.Enums;

namespace PnP.PowerShell.Commands.Base
{
[Cmdlet(VerbsCommon.Get, "PnPAccessToken")]
[RequiredMinimalApiPermissions("https://graph.microsoft.com/.default")]
public class GetPnPAccessToken : PnPGraphCmdlet
{
private const string ResourceTypeParam = "Resource Type Name";
private const string ResourceUrlParam = "Resource Url";

[Parameter(Mandatory = false, ParameterSetName = ResourceTypeParam)]
public ResourceTypeName ResourceTypeName = ResourceTypeName.Graph;

[Parameter(Mandatory = false, ParameterSetName = ResourceUrlParam)]
public string ResourceUrl;

[Parameter(ParameterSetName = ResourceTypeParam)]
[Parameter(ParameterSetName = ResourceUrlParam)]
[Parameter(Mandatory = false)]
public SwitchParameter Decoded;

protected override void ExecuteCmdlet()
{
var accessTokenValue = AccessToken;

if (ParameterSetName == ResourceTypeParam)
{
accessTokenValue = null;

switch (ResourceTypeName)
{
case ResourceTypeName.Graph:
accessTokenValue = AccessToken;
break;
case ResourceTypeName.SharePoint:
accessTokenValue = TokenHandler.GetAccessToken(null, PnPConnection.Current?.Context?.Url?.TrimEnd('/') + "/.default");
break;
case ResourceTypeName.ARM:
accessTokenValue = TokenHandler.GetAccessToken(null, "https://management.azure.com/.default");
break;
}
}

else if (ParameterSetName == ResourceUrlParam)
{
accessTokenValue = TokenHandler.GetAccessToken(null, ResourceUrl);
}

if (Decoded.IsPresent)
{
WriteObject(new System.IdentityModel.Tokens.Jwt.JwtSecurityToken(AccessToken));
WriteObject(new System.IdentityModel.Tokens.Jwt.JwtSecurityToken(accessTokenValue));
}
else
{
WriteObject(AccessToken);
WriteObject(accessTokenValue);
}
}
}
Expand Down
18 changes: 14 additions & 4 deletions src/Commands/Base/TokenHandling.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,19 @@ internal static string GetAccessToken(Type cmdletType, string appOnlyDefaultScop
var authManager = contextSettings.AuthenticationManager;
if (authManager != null)
{
if (contextSettings.Type == Framework.Utilities.Context.ClientContextType.SharePointACSAppOnly)
{
// When connected using ACS, we cannot get a token for another endpoint
throw new PSInvalidOperationException("Trying to get a token for a different endpoint while being connected through an ACS token is not possible. Please connect differently.");
}

string[] requiredScopes = null;
var requiredScopesAttribute = (RequiredMinimalApiPermissions)Attribute.GetCustomAttribute(cmdletType, typeof(RequiredMinimalApiPermissions));
//RequiredMinimalApiPermissions requiredScopesAttribute = (RequiredMinimalApiPermissions)Attribute.GetCustomAttribute(cmdletType, typeof(RequiredMinimalApiPermissions));
RequiredMinimalApiPermissions requiredScopesAttribute = null;
if (cmdletType != null)
{
requiredScopesAttribute = (RequiredMinimalApiPermissions)Attribute.GetCustomAttribute(cmdletType, typeof(RequiredMinimalApiPermissions));
}
if (requiredScopesAttribute != null)
{
requiredScopes = requiredScopesAttribute.PermissionScopes;
Expand All @@ -67,10 +78,9 @@ internal static string GetAccessToken(Type cmdletType, string appOnlyDefaultScop
{
requiredScopes = new[] { appOnlyDefaultScope }; // override for app only
}
if (contextSettings.Type == Framework.Utilities.Context.ClientContextType.SharePointACSAppOnly)
if (requiredScopes == null && !string.IsNullOrEmpty(appOnlyDefaultScope))
{
// When connected using ACS, we cannot get a token for another endpoint
throw new PSInvalidOperationException("Trying to get a token for a different endpoint while being connected through an ACS token is not possible. Please connect differently.");
requiredScopes = new[] { appOnlyDefaultScope };
}
var accessToken = authManager.GetAccessTokenAsync(requiredScopes).GetAwaiter().GetResult();
return accessToken;
Expand Down
9 changes: 9 additions & 0 deletions src/Commands/Enums/ResourceTypeName.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace PnP.PowerShell.Commands.Enums
{
public enum ResourceTypeName
{
Graph = 1,
SharePoint = 2,
ARM = 3
}
}