From bd66bb807cca54115b74be557be6ce9ce9ce600e Mon Sep 17 00:00:00 2001
From: Gautam Sheth <gautam.sheth@staffbase.com>
Date: Mon, 7 Oct 2024 21:40:22 +0300
Subject: [PATCH] 3.0 - Access Token cmdlets related changes.

---
 CHANGELOG.md                               |   2 +
 MIGRATE-2.0-to-3.0.md                      |   3 +
 documentation/Get-PnPAccessToken.md        |  18 ++-
 documentation/Get-PnPAppAuthAccessToken.md |  51 -------
 documentation/Get-PnPGraphAccessToken.md   |  60 ---------
 documentation/Request-PnPAccessToken.md    | 146 ---------------------
 src/Commands/Base/GetAccessToken.cs        |  19 ++-
 src/Commands/Base/GetAppAuthAccessToken.cs |  18 ---
 src/Commands/Base/RequestAccessToken.cs    | 102 --------------
 src/Commands/Graph/GetGraphAccessToken.cs  |  28 ----
 10 files changed, 37 insertions(+), 410 deletions(-)
 delete mode 100644 documentation/Get-PnPAppAuthAccessToken.md
 delete mode 100644 documentation/Get-PnPGraphAccessToken.md
 delete mode 100644 documentation/Request-PnPAccessToken.md
 delete mode 100644 src/Commands/Base/GetAppAuthAccessToken.cs
 delete mode 100644 src/Commands/Base/RequestAccessToken.cs
 delete mode 100644 src/Commands/Graph/GetGraphAccessToken.cs

diff --git a/CHANGELOG.md b/CHANGELOG.md
index e33d27754..a91dfa47b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -21,6 +21,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
 - Added `-X509KeyStorageFlags` parameter to `Connect-PnPOnline` cmdlet which allows setting of how private keys are to be imported. [#4324](https://github.com/pnp/powershell/pull/4324)
 - Added `-RestrictContentOrgWideSearch` parameter to `Set-PnPSite` which allows for applying the Restricted Content Discoverability (RCD) setting to a site [#4335](https://github.com/pnp/powershell/pull/4335)
 - Added `-LaunchBrowser` parameter to `Register-PnPEntraIDAppForInteractiveLogin` and `Register-PnPEntraIDApp` cmdlets to open browser and continue app registration in the browser. [#4347](https://github.com/pnp/powershell/pull/4347) & [#4348](https://github.com/pnp/powershell/pull/4348)
+- Added `-Scopes` parameter to `Get-PnPAccessToken` cmdlet to retrieve access token with specific scopes.
 
 ### Changed
 
@@ -56,6 +57,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
 - Removed `Set-PnPLabel` and `Reset-PnPLabel` aliases. You need to use `Set-PnPRetentionLabel` and `Reset-PnPRetentionLabel` respectively. [#4387](https://github.com/pnp/powershell/pull/4387)
 - Removed `Get-PnPPowerPlatformConnector` alias. You need to use `Get-PnPPowerPlatformCustomConnector`. [#4387](https://github.com/pnp/powershell/pull/4387)
 - Removed `-IsFavoriteByDefault` parameter from `Add-PnPTeamsChannel` cmdlet. It was obsolete and not supported by Graph API. [#4387](https://github.com/pnp/powershell/pull/4387)
+- Removed `Get-PnPAppAuthAccessToken` , `Remove-PnPGraphAccessToken` and `Request-PnPAccessToken` cmdlets. Use `Get-PnPAccessToken` instead. 
  
 ### Contributors
 
diff --git a/MIGRATE-2.0-to-3.0.md b/MIGRATE-2.0-to-3.0.md
index 7f0391991..b437eaaeb 100644
--- a/MIGRATE-2.0-to-3.0.md
+++ b/MIGRATE-2.0-to-3.0.md
@@ -51,6 +51,9 @@ Recommend referring to these 2 links:
 | Set-PnPLabel | Use `Set-PnPRetentionLabel` |
 | Reset-PnPLabel | Use `Reset-PnPRetentionLabel` |
 | Add-PnPTeamsChannel | The parameter `IsFavoriteByDefault` has been removed as it was not supported by Graph API |
+| Get-PnPAppAuthAccessToken | It has been deleted. Use `Get-PnPAccessToken -ResourceTypeName SharePoint` instead to get SharePoint access token. |
+| Request-PnPAccessToken | It has been deleted. Use `Get-PnPAccessToken` instead. |
+| Get-PnPGraphAccessToken | It has been deleted. Use `Get-PnPAccessToken` instead. |
 
 ## Other notable changes
 
diff --git a/documentation/Get-PnPAccessToken.md b/documentation/Get-PnPAccessToken.md
index 14b79889d..79f3acb76 100644
--- a/documentation/Get-PnPAccessToken.md
+++ b/documentation/Get-PnPAccessToken.md
@@ -16,11 +16,11 @@ If a Resource Type Name or Resource URL is specified, it will fetch the access t
 ## SYNTAX
 
 ```powershell
-Get-PnPAccessToken [-ResourceTypeName] [-ResourceUrl] [-Decoded] [-Connection <PnPConnection>]
+Get-PnPAccessToken [-ResourceTypeName] [-ResourceUrl] [-Decoded] [-Scopes] [-Connection <PnPConnection>]
 ```
 
 ## DESCRIPTION
-Gets the OAuth 2.0 Access Token to consume the Microsoft Graph API. Doesn't work with all Connect-PnPOnline options. To retrieve the SharePoint Online access token, you can also use `Get-PnPAppAuthAccessToken`.
+Gets the OAuth 2.0 Access Token.
 
 ## EXAMPLES
 
@@ -118,6 +118,20 @@ Accept pipeline input: False
 Accept wildcard characters: False
 ```
 
+### -Scopes
+The scopes to retrieve the token for. Defaults to AllSites.FullControl
+
+```yaml
+Type: String[]
+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)
\ No newline at end of file
diff --git a/documentation/Get-PnPAppAuthAccessToken.md b/documentation/Get-PnPAppAuthAccessToken.md
deleted file mode 100644
index d8bb93bb9..000000000
--- a/documentation/Get-PnPAppAuthAccessToken.md
+++ /dev/null
@@ -1,51 +0,0 @@
----
-Module Name: PnP.PowerShell
-schema: 2.0.0
-applicable: SharePoint Online
-online version: https://pnp.github.io/powershell/cmdlets/Get-PnPAppAuthAccessToken.html
-external help file: PnP.PowerShell.dll-Help.xml
-title: Get-PnPAppAuthAccessToken
----
-  
-# Get-PnPAppAuthAccessToken
-
-## SYNOPSIS
-Returns the access token for SharePoint Online
-
-## SYNTAX
-
-```powershell
-Get-PnPAppAuthAccessToken [-Connection <PnPConnection>] 
-```
-
-## DESCRIPTION
-Returns the SharePoint Online access token from the current client context. This will only work in the App authentication flow (App+user or App-Only). For the Microsoft Graph access token, use `Get-PnPAccessToken` instead.
-
-## EXAMPLES
-
-### EXAMPLE 1
-```powershell
-$accessToken = Get-PnPAppAuthAccessToken
-```
-
-This will put the SharePoint Online access token from current context in the $accessToken variable
-
-## PARAMETERS
-
-### -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)
diff --git a/documentation/Get-PnPGraphAccessToken.md b/documentation/Get-PnPGraphAccessToken.md
deleted file mode 100644
index baf880815..000000000
--- a/documentation/Get-PnPGraphAccessToken.md
+++ /dev/null
@@ -1,60 +0,0 @@
----
-Module Name: PnP.PowerShell
-schema: 2.0.0
-applicable: SharePoint Online
-online version: https://pnp.github.io/powershell/cmdlets/Get-PnPGraphAccessToken.html
-external help file: PnP.PowerShell.dll-Help.xml
-title: Get-PnPGraphAccessToken
----
-  
-# Get-PnPGraphAccessToken
-
-## SYNOPSIS
-Returns the current OAuth Access token for the Microsoft Graph API
-
-## SYNTAX
-
-```powershell
-Get-PnPGraphAccessToken [-Decoded] 
-```
-
-## DESCRIPTION
-Gets the OAuth 2.0 Access Token to consume the Microsoft Graph API
-
-## EXAMPLES
-
-### EXAMPLE 1
-```powershell
-Get-PnPGraphAccessToken
-```
-
-Gets the OAuth 2.0 Access Token to consume the Microsoft Graph API
-
-### EXAMPLE 2
-```powershell
-Get-PnPGraphAccessToken -Decoded
-```
-
-Gets the full OAuth 2.0 Token to consume the Microsoft Graph API
-
-## PARAMETERS
-
-### -Decoded
-Returns the access token in a decoded manner
-
-```yaml
-Type: SwitchParameter
-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)
-
-
diff --git a/documentation/Request-PnPAccessToken.md b/documentation/Request-PnPAccessToken.md
deleted file mode 100644
index 034ebec17..000000000
--- a/documentation/Request-PnPAccessToken.md
+++ /dev/null
@@ -1,146 +0,0 @@
----
-Module Name: PnP.PowerShell
-title: Request-PnPAccessToken
-schema: 2.0.0
-applicable: SharePoint Online
-external help file: PnP.PowerShell.dll-Help.xml
-online version: https://pnp.github.io/powershell/cmdlets/Request-PnPAccessToken.html
----
- 
-# Request-PnPAccessToken
-
-## SYNOPSIS
-Requests an OAuth Access token.
-
-## SYNTAX
-
-```powershell
-Request-PnPAccessToken [-ClientId <String>] [-Resource <String>] [-Scopes <String[]]>] [-Decoded] [-Credentials <PSCredential>] [-TenantUrl <String>]
-```
-
-## DESCRIPTION
-Returns an access token using the password grant, using the PnP O365 Management Shell client id by default and the AllSites.FullControl scope by default.
-
-## EXAMPLES
-
-### EXAMPLE 1
-```powershell
-Request-PnPAccessToken
-```
-
-Returns the access token using the default client id and scope.
-
-### EXAMPLE 2
-```powershell
-Request-PnPAccessToken -ClientId 26e29fec-aa10-4f99-8381-d96cddc650c2
-```
-
-Returns the access token using the specified client id and the default scope of AllSites.FullControl
-
-### EXAMPLE 3
-```powershell
-Request-PnPAccessToken -ClientId 26e29fec-aa10-4f99-8381-d96cddc650c2 -Scopes Group.ReadWrite.All
-```
-
-Returns the access token using the specified client id and the specified scope.
-
-### EXAMPLE 4
-```powershell
-Request-PnPAccessToken -ClientId 26e29fec-aa10-4f99-8381-d96cddc650c2 -Scopes Group.ReadWrite.All, AllSites.FullControl
-```
-
-Returns the access token using the specified client id and the specified scopes.
-
-## PARAMETERS
-
-### -ClientId
-The Azure Application Client Id to use to retrieve the token. Defaults to the PnP Office 365 Management Shell.
-
-```yaml
-Type: String
-Parameter Sets: (All)
-Aliases: ApplicationId
-
-Required: False
-Position: Named
-Default value: 31359c7f-bd7e-475c-86db-fdb8c937548e
-Accept pipeline input: False
-Accept wildcard characters: False
-```
-
-### -Credentials
-Optional credentials to use when retrieving the access token. If not present you need to connect first with Connect-PnPOnline.
-
-```yaml
-Type: PSCredential
-Parameter Sets: (All)
-
-Required: False
-Position: Named
-Default value: None
-Accept pipeline input: False
-Accept wildcard characters: False
-```
-
-### -Decoded
-Returns the token in a decoded / human-readable manner.
-
-```yaml
-Type: SwitchParameter
-Parameter Sets: (All)
-
-Required: False
-Position: Named
-Default value: None
-Accept pipeline input: False
-Accept wildcard characters: False
-```
-
-### -Scopes
-The scopes to retrieve the token for. Defaults to AllSites.FullControl
-
-```yaml
-Type: String[]
-Parameter Sets: (All)
-
-Required: False
-Position: Named
-Default value: None
-Accept pipeline input: False
-Accept wildcard characters: False
-```
-
-### -TenantUrl
-Optional tenant URL to use when retrieving the access token. The Url should be in the shape of https://yourtenant.sharepoint.com. See examples for more info.
-
-```yaml
-Type: String
-Parameter Sets: (All)
-
-Required: False
-Position: Named
-Default value: None
-Accept pipeline input: False
-Accept wildcard characters: False
-```
-
-### -AzureEnvironment
-The Azure environment to use for authentication, the defaults to 'Production' which is the main Azure environment.
-
-```yaml
-Type: AzureEnvironment
-Parameter Sets: (All)
-Aliases:
-Accepted values: Production, PPE, China, Germany, USGovernment, USGovernmentHigh, USGovernmentDoD
-
-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)
-
diff --git a/src/Commands/Base/GetAccessToken.cs b/src/Commands/Base/GetAccessToken.cs
index ffb73aad8..b28fc5aeb 100644
--- a/src/Commands/Base/GetAccessToken.cs
+++ b/src/Commands/Base/GetAccessToken.cs
@@ -1,4 +1,5 @@
-using PnP.PowerShell.Commands.Enums;
+using Microsoft.SharePoint.Client;
+using PnP.PowerShell.Commands.Enums;
 using PnP.PowerShell.Commands.Utilities.Auth;
 using System;
 using System.Management.Automation;
@@ -6,8 +7,8 @@
 namespace PnP.PowerShell.Commands.Base
 {
     [Cmdlet(VerbsCommon.Get, "PnPAccessToken", DefaultParameterSetName = ResourceTypeParam)]
-    [OutputType(typeof(Microsoft.IdentityModel.JsonWebTokens.JsonWebToken), ParameterSetName = new[] { ResourceTypeParam_Decoded, ResourceUrlParam_Decoded })]
-    [OutputType(typeof(string), ParameterSetName = new[] { ResourceTypeParam, ResourceUrlParam })]
+    [OutputType(typeof(Microsoft.IdentityModel.JsonWebTokens.JsonWebToken), ParameterSetName = [ResourceTypeParam_Decoded, ResourceUrlParam_Decoded])]
+    [OutputType(typeof(string), ParameterSetName = [ResourceTypeParam, ResourceUrlParam])]
     public class GetPnPAccessToken : PnPGraphCmdlet
     {
         private const string ResourceTypeParam = "Resource Type Name";
@@ -27,6 +28,12 @@ public class GetPnPAccessToken : PnPGraphCmdlet
         [Parameter(Mandatory = true, ParameterSetName = ResourceTypeParam_Decoded)]
         [Parameter(Mandatory = true, ParameterSetName = ResourceUrlParam_Decoded)]
         public SwitchParameter Decoded;
+
+        [Parameter(Mandatory = false, ParameterSetName = ResourceTypeParam)]
+        [Parameter(Mandatory = false, ParameterSetName = ResourceTypeParam_Decoded)]
+        [Parameter(Mandatory = false, ParameterSetName = ResourceUrlParam)]
+        [Parameter(Mandatory = false, ParameterSetName = ResourceUrlParam_Decoded)]
+        public string[] Scopes = ["AllSites.FullControl"];
         protected override void ExecuteCmdlet()
         {
             string accessTokenValue = null;
@@ -57,6 +64,12 @@ protected override void ExecuteCmdlet()
                 accessTokenValue = TokenHandler.GetAccessToken(this, ResourceUrl, Connection);
             }
 
+            if (ParameterSpecified(nameof(Scopes)))
+            {
+                var authManager = Connection.Context.GetContextSettings().AuthenticationManager;
+                accessTokenValue = authManager.GetAccessTokenAsync(Scopes).GetAwaiter().GetResult();
+            }
+
             if (accessTokenValue == null)
             {
                 WriteError(new PSArgumentException("Unable to retrieve access token"), ErrorCategory.InvalidResult);
diff --git a/src/Commands/Base/GetAppAuthAccessToken.cs b/src/Commands/Base/GetAppAuthAccessToken.cs
deleted file mode 100644
index 949eb641e..000000000
--- a/src/Commands/Base/GetAppAuthAccessToken.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Management.Automation;
-
-using System;
-using PnP.PowerShell.Commands.Properties;
-using Microsoft.SharePoint.Client;
-
-namespace PnP.PowerShell.Commands.Base
-{
-    [Cmdlet(VerbsCommon.Get, "PnPAppAuthAccessToken")]
-    [OutputType(typeof(string))]
-    public class GetPnPAppAuthAccessToken : PnPSharePointCmdlet
-    {
-        protected override void ExecuteCmdlet()
-        {
-            WriteObject(ClientContext.GetAccessToken());
-        }
-    }
-}
diff --git a/src/Commands/Base/RequestAccessToken.cs b/src/Commands/Base/RequestAccessToken.cs
deleted file mode 100644
index 5ddf47caa..000000000
--- a/src/Commands/Base/RequestAccessToken.cs
+++ /dev/null
@@ -1,102 +0,0 @@
-using PnP.Framework;
-using System;
-using System.Linq;
-using System.Management.Automation;
-using System.Security;
-using Microsoft.SharePoint.Client;
-
-namespace PnP.PowerShell.Commands.Base
-{
-    [Cmdlet(VerbsLifecycle.Request, "PnPAccessToken")]
-    public class RequestAccessToken : PnPConnectedCmdlet
-    {
-        [Parameter(Mandatory = false)]
-        [Alias("ApplicationId")]
-        public string ClientId;
-
-        [Parameter(Mandatory = false)]
-        public string[] Scopes = new string[] { "AllSites.FullControl" };
-
-        [Parameter(Mandatory = false)]
-        public SwitchParameter Decoded;
-
-        [Parameter(Mandatory = false)]
-        public PSCredential Credentials;
-
-        [Parameter(Mandatory = false)]
-        public string TenantUrl;
-
-        [Parameter(Mandatory = false)]
-        public AzureEnvironment AzureEnvironment;
-
-        protected override void ProcessRecord()
-        {
-            Uri tenantUri = null;
-            if (string.IsNullOrEmpty(TenantUrl) && Connection != null)
-            {
-                var uri = new Uri(Connection.Url);
-                var uriParts = uri.Host.Split('.');
-                if (uriParts[0].ToLower().EndsWith("-admin"))
-                {
-                    tenantUri =
-                        new Uri(
-                            $"{uri.Scheme}://{uriParts[0].ToLower().Replace("-admin", "")}.{string.Join(".", uriParts.Skip(1))}{(!uri.IsDefaultPort ? ":" + uri.Port : "")}");
-                }
-                else
-                {
-                    tenantUri = new Uri($"{uri.Scheme}://{uri.Authority}");
-                }
-            }
-            else if (!string.IsNullOrEmpty(TenantUrl))
-            {
-                tenantUri = new Uri(TenantUrl);
-            }
-            else
-            {
-                throw new InvalidOperationException("Either a connection needs to be made by Connect-PnPOnline or TenantUrl and Credentials needs to be specified");
-            }
-
-            var tenantId = Microsoft.SharePoint.Client.TenantExtensions.GetTenantIdByUrl(tenantUri.ToString());
-            SecureString password;
-            string username;
-            AuthenticationManager authManager = null;
-            if (ParameterSpecified(nameof(Credentials)))
-            {
-                password = Credentials.Password;
-                username = Credentials.UserName;
-                authManager = new AuthenticationManager(ClientId, username, password, azureEnvironment: AzureEnvironment);
-            }
-            else if (Connection != null)
-            {
-                authManager = Connection.Context.GetContextSettings().AuthenticationManager;
-            }
-            else
-            {
-                throw new InvalidOperationException("Either a connection needs to be made by Connect-PnPOnline or Credentials needs to be specified");
-            }
-
-            var token = string.Empty;
-
-            using (authManager)
-            {
-                if (ParameterSpecified(nameof(Scopes)))
-                {
-                    token = authManager.GetAccessTokenAsync(Scopes).GetAwaiter().GetResult();
-                }
-                else
-                {
-                    token = authManager.GetAccessTokenAsync(Connection.Url).GetAwaiter().GetResult();
-                }
-            }
-
-            if (Decoded.IsPresent)
-            {
-                WriteObject(new Microsoft.IdentityModel.JsonWebTokens.JsonWebToken(token));
-            }
-            else
-            {
-                WriteObject(token);
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Commands/Graph/GetGraphAccessToken.cs b/src/Commands/Graph/GetGraphAccessToken.cs
deleted file mode 100644
index 8ede5cda5..000000000
--- a/src/Commands/Graph/GetGraphAccessToken.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System.Management.Automation;
-
-namespace PnP.PowerShell.Commands.Base
-{
-    [Cmdlet(VerbsCommon.Get, "PnPGraphAccessToken", DefaultParameterSetName = ParameterSet_Encoded)]
-    [OutputType(typeof(string), ParameterSetName = new[] { ParameterSet_Encoded })]
-    [OutputType(typeof(Microsoft.IdentityModel.JsonWebTokens.JsonWebToken), ParameterSetName = new[] { ParameterSet_Decoded })]
-    public class GetGraphAccessToken : PnPGraphCmdlet
-    {
-        public const string ParameterSet_Decoded = "Decoded (JwtSecurityToken)";
-        public const string ParameterSet_Encoded = "Encoded (string)";
-
-        [Parameter(Mandatory = true, ParameterSetName = ParameterSet_Decoded)]
-        public SwitchParameter Decoded;
-
-        protected override void ExecuteCmdlet()
-        {
-            if (Decoded.IsPresent)
-            {
-                WriteObject(new Microsoft.IdentityModel.JsonWebTokens.JsonWebToken(AccessToken));
-            }
-            else
-            {
-                WriteObject(AccessToken);
-            }
-        }
-    }
-}
\ No newline at end of file