protected override void ProcessRecord()
        {
            source = new CancellationTokenSource();
            var messageWriter = new CmdletMessageWriter(this);
            CancellationToken cancellationToken = source.Token;

            var endPoint = string.Empty;

            using (var authManager = new AuthenticationManager())
            {
                endPoint = authManager.GetAzureADLoginEndPoint(AzureEnvironment);
            }

            Task.Factory.StartNew(() =>
            {
                var deviceCodeApplication = PublicClientApplicationBuilder.Create(PnPConnection.PnPManagementShellClientId).WithAuthority($"{endPoint}/organizations/").WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient").Build();
                deviceCodeApplication.AcquireTokenWithDeviceCode(new[] { "https://graph.microsoft.com/.default" }, codeResult =>
                {
                    if (Utilities.OperatingSystem.IsWindows())
                    {
                        ClipboardService.SetText(codeResult.UserCode);
                        messageWriter.WriteMessage($"Provide consent for the PnP Management Shell application to access SharePoint.\n\nWe opened a browser and navigated to {codeResult.VerificationUrl}\n\nEnter code: {codeResult.UserCode} (we copied this code to your clipboard)");
                        BrowserHelper.GetWebBrowserPopup(codeResult.VerificationUrl, "Provide consent for the PnP Management Shell application");
                    }
                    else
                    {
                        messageWriter.WriteMessage($"Please provide consent for the PnP Management Shell application by navigating to\n\n{codeResult.VerificationUrl}\n\nEnter code: {codeResult.UserCode}.");
                    }
                    return(Task.FromResult(0));
                }).ExecuteAsync(cancellationToken).GetAwaiter().GetResult();
                messageWriter.Finished = true;
            }, cancellationToken);
            messageWriter.Start();
        }
Exemple #2
0
        private void StartConsentFlow(string loginEndPoint, AzureADApp azureApp, string redirectUri, string token, HttpClient httpClient, PSObject record, CmdletMessageWriter messageWriter, List <PermissionScope> scopes)
        {
            Host.UI.WriteLine(ConsoleColor.Yellow, Host.UI.RawUI.BackgroundColor, $"Starting consent flow.");

            var resource = scopes.FirstOrDefault(s => s.resourceAppId == PermissionScopes.ResourceAppId_Graph) != null ? $"https://{AzureAuthHelper.GetGraphEndPoint(AzureEnvironment)}/.default" : "https://microsoft.sharepoint-df.com/.default";

            var consentUrl = $"{loginEndPoint}/{Tenant}/v2.0/adminconsent?client_id={azureApp.AppId}&scope={resource}&redirect_uri={redirectUri}";


            if (OperatingSystem.IsWindows() && !NoPopup)
            {
                var waitTime = 60;
                // CmdletMessageWriter.WriteFormattedWarning(this, $"Waiting {waitTime} seconds to launch the consent flow in a popup window.\n\nThis wait is required to make sure that Azure AD is able to initialize all required artifacts. You can always navigate to the consent page manually:\n\n{consentUrl}");

                var progressRecord = new ProgressRecord(1, "Please wait...", $"Waiting {waitTime} seconds to launch the consent flow in a popup window. This wait is required to make sure that Azure AD is able to initialize all required artifacts.");

                for (var i = 0; i < waitTime; i++)
                {
                    progressRecord.PercentComplete = Convert.ToInt32((Convert.ToDouble(i) / Convert.ToDouble(waitTime)) * 100);
                    WriteProgress(progressRecord);
                    // if (Convert.ToDouble(i) % Convert.ToDouble(10) > 0)
                    // {
                    //     Host.UI.Write(ConsoleColor.Yellow, Host.UI.RawUI.BackgroundColor, "-");
                    // }
                    // else
                    // {
                    //     Host.UI.Write(ConsoleColor.Yellow, Host.UI.RawUI.BackgroundColor, $"[{i}]");
                    // }
                    System.Threading.Thread.Sleep(1000);

                    // Check if CTRL+C has been pressed and if so, abort the wait
                    if (Stopping)
                    {
                        Host.UI.WriteLine("Wait cancelled. You can provide consent manually by navigating to");
                        Host.UI.WriteLine(consentUrl);
                        break;
                    }
                }
                progressRecord.RecordType = ProgressRecordType.Completed;
                WriteProgress(progressRecord);

                if (!Stopping)
                {
                    // Host.UI.WriteLine(ConsoleColor.Yellow, Host.UI.RawUI.BackgroundColor, $"[{waitTime}]");

                    // Host.UI.WriteLine();

                    if (ParameterSpecified(nameof(Interactive)))
                    {
                        using (var authManager = AuthenticationManager.CreateWithInteractiveLogin(azureApp.AppId, (url, port) =>
                        {
                            BrowserHelper.OpenBrowserForInteractiveLogin(url, port, true, cancellationTokenSource);
                        }, Tenant, "You successfully provided consent", "You failed to provide consent.", AzureEnvironment))
                        {
                            authManager.GetAccessToken(resource, Microsoft.Identity.Client.Prompt.Consent);
                        }
                    }
                    else
                    {
                        BrowserHelper.GetWebBrowserPopup(consentUrl, "Please provide consent", new[] { ("https://pnp.github.io/powershell/consent.html", BrowserHelper.UrlMatchType.StartsWith) }, cancellationTokenSource: cancellationTokenSource, cancelOnClose: false);
        internal static PnPConnection InstantiateDeviceLoginConnection(string url, bool launchBrowser, CmdletMessageWriter messageWriter, AzureEnvironment azureEnvironment, CancellationToken cancellationToken)
        {
            var connectionUri = new Uri(url);
            var scopes        = new[] { $"{connectionUri.Scheme}://{connectionUri.Authority}//.default" }; // the second double slash is not a typo.

            PnP.Framework.AuthenticationManager authManager = null;
            if (PnPConnection.CachedAuthenticationManager != null)
            {
                authManager = PnPConnection.CachedAuthenticationManager;
                PnPConnection.CachedAuthenticationManager = null;
            }
            else
            {
                Func <DeviceCodeResult, Task> deviceCodeCallback = (deviceCodeResult) =>
                {
                    if (launchBrowser)
                    {
                        if (Utilities.OperatingSystem.IsWindows())
                        {
                            ClipboardService.SetText(deviceCodeResult.UserCode);
                            messageWriter.WriteMessage($"\n\nCode {deviceCodeResult.UserCode} has been copied to your clipboard\n\n");
                            BrowserHelper.GetWebBrowserPopup(deviceCodeResult.VerificationUrl, "Please log in");
                        }
                        else
                        {
                            messageWriter.WriteMessage($"\n\n{deviceCodeResult.Message}\n\n");
                        }
                    }
                    else
                    {
                        messageWriter.WriteMessage($"\n\n{deviceCodeResult.Message}\n\n");
                    }
                    return(Task.FromResult(0));
                };

                authManager = new PnP.Framework.AuthenticationManager(PnPConnection.PnPManagementShellClientId, deviceCodeCallback, azureEnvironment);
            }
            using (authManager)
            {
                var clientContext = authManager.GetContext(url.ToString(), cancellationToken);
                var context       = PnPClientContext.ConvertFrom(clientContext);

                var connectionType = ConnectionType.O365;

                var spoConnection = new PnPConnection(context, connectionType, null, PnPConnection.PnPManagementShellClientId, null, url.ToString(), null, PnPPSVersionTag, InitializationType.DeviceLogin)
                {
                    ConnectionMethod = ConnectionMethod.DeviceLogin,
                    AzureEnvironment = azureEnvironment
                };
                return(spoConnection);
            }
        }
Exemple #4
0
        private void StartConsentFlow(string loginEndPoint, AzureApp azureApp, string redirectUri, string token, HttpClient httpClient, PSObject record)
        {
            var consentUrl = $"{loginEndPoint}/{Tenant}/v2.0/adminconsent?client_id={azureApp.AppId}&scope=https://microsoft.sharepoint-df.com/.default&redirect_uri={redirectUri}";


            if (OperatingSystem.IsWindows() && !NoPopup)
            {
                var waitTime = 60;
                CmdletMessageWriter.WriteFormattedWarning(this, $"Waiting {waitTime} seconds to launch consent flow in a popup window.\n\nThis wait is required to make sure that Azure AD is able to initialize all required artifacts. You can always navigate to the consent page manually:\n\n{consentUrl}");

                for (var i = 0; i < waitTime; i++)
                {
                    if (Convert.ToDouble(i) % Convert.ToDouble(10) > 0)
                    {
                        Host.UI.Write(ConsoleColor.Yellow, Host.UI.RawUI.BackgroundColor, "-");
                    }
                    else
                    {
                        Host.UI.Write(ConsoleColor.Yellow, Host.UI.RawUI.BackgroundColor, $"[{i}]");
                    }
                    System.Threading.Thread.Sleep(1000);

                    // Check if CTRL+C has been pressed and if so, abort the wait
                    if (Stopping)
                    {
                        break;
                    }
                }

                if (!Stopping)
                {
                    Host.UI.WriteLine(ConsoleColor.Yellow, Host.UI.RawUI.BackgroundColor, $"[{waitTime}]");

                    Host.UI.WriteLine();

                    BrowserHelper.GetWebBrowserPopup(consentUrl, "Please provide consent", new[] { (redirectUri, BrowserHelper.UrlMatchType.StartsWith) });
        internal static PnPConnection CreateWithDeviceLogin(string clientId, string url, string tenantId, bool launchBrowser, CmdletMessageWriter messageWriter, AzureEnvironment azureEnvironment, CancellationTokenSource cancellationTokenSource)
        {
            var connectionUri = new Uri(url);
            var scopes        = new[] { $"{connectionUri.Scheme}://{connectionUri.Authority}//.default" }; // the second double slash is not a typo.

            PnP.Framework.AuthenticationManager authManager = null;
            if (PnPConnection.CachedAuthenticationManager != null)
            {
                authManager = PnPConnection.CachedAuthenticationManager;
                PnPConnection.CachedAuthenticationManager = null;
            }
            else
            {
                authManager = PnP.Framework.AuthenticationManager.CreateWithDeviceLogin(clientId, tenantId, (deviceCodeResult) =>
                {
                    if (launchBrowser)
                    {
                        if (Utilities.OperatingSystem.IsWindows())
                        {
                            ClipboardService.SetText(deviceCodeResult.UserCode);
                            messageWriter.WriteWarning($"\n\nCode {deviceCodeResult.UserCode} has been copied to your clipboard\n\n");
                            BrowserHelper.GetWebBrowserPopup(deviceCodeResult.VerificationUrl, "Please log in", cancellationTokenSource: cancellationTokenSource, cancelOnClose: false);
                        }
                        else
                        {
                            messageWriter.WriteWarning($"\n\n{deviceCodeResult.Message}\n\n");
                        }
                    }
                    else
                    {
                        messageWriter.WriteWarning($"\n\n{deviceCodeResult.Message}\n\n");
                    }
                    return(Task.FromResult(0));
                }, azureEnvironment);
            }
            using (authManager)
            {
                try
                {
                    var clientContext = authManager.GetContext(url.ToString(), cancellationTokenSource.Token);

                    var context = PnPClientContext.ConvertFrom(clientContext);
                    context.ExecutingWebRequest += (sender, e) =>
                    {
                        e.WebRequestExecutor.WebRequest.UserAgent = $"NONISV|SharePointPnP|PnPPS/{((AssemblyFileVersionAttribute)Assembly.GetExecutingAssembly().GetCustomAttribute(typeof(AssemblyFileVersionAttribute))).Version} ({System.Environment.OSVersion.VersionString})";
                    };
                    var connectionType = ConnectionType.O365;

                    var spoConnection = new PnPConnection(context, connectionType, null, clientId, null, url.ToString(), null, PnPPSVersionTag, InitializationType.DeviceLogin)
                    {
                        ConnectionMethod = ConnectionMethod.DeviceLogin,
                        AzureEnvironment = azureEnvironment
                    };
                    return(spoConnection);
                }
                catch (Microsoft.Identity.Client.MsalServiceException msalServiceException)
                {
                    if (msalServiceException.Message.StartsWith("AADSTS50059:"))
                    {
                        cancellationTokenSource.Cancel();
                        throw new Exception("Please specify -Tenant with either the tenant id or hostname.");
                    }
                    else
                    {
                        throw;
                    }
                }
            }
        }