diff --git a/src/Authentication/Authentication.Test/Helpers/EncodeUriPathTests.cs b/src/Authentication/Authentication.Test/Helpers/EncodeUriPathTests.cs new file mode 100644 index 0000000000..800cf62790 --- /dev/null +++ b/src/Authentication/Authentication.Test/Helpers/EncodeUriPathTests.cs @@ -0,0 +1,26 @@ + +using Xunit; +using System; +using Microsoft.Graph.PowerShell.Authentication.Helpers; + +namespace Microsoft.Graph.Authentication.Test.Helpers +{ + public class EncodeUriPathTests + { + private string url = "https://graph.microsoft.com/beta/users/first.last_foo.com#EXT#@contoso.onmicrosoft.com"; + private string encodedUrl = "https://graph.microsoft.com/beta/users/first.last_foo.com%23EXT%23%40contoso.onmicrosoft.com"; + + [Fact] + public void ShouldReturnAnEncodedUriGivenAUrlWithSpecialCharactersInPathSegments() + { + //arrange + Uri uri = new Uri(url); + + //act + Uri result = uri.EscapeDataStrings(); + + //assert + Assert.Equal(encodedUrl, result.ToString()); + } + } +} diff --git a/src/Authentication/Authentication/Cmdlets/InvokeMgGraphRequest.cs b/src/Authentication/Authentication/Cmdlets/InvokeMgGraphRequest.cs index 8f0ba357b5..86ebdad20c 100644 --- a/src/Authentication/Authentication/Cmdlets/InvokeMgGraphRequest.cs +++ b/src/Authentication/Authentication/Cmdlets/InvokeMgGraphRequest.cs @@ -294,6 +294,7 @@ private async Task ReportResponseStatusASync(HttpMessageFormatter responseMessag /// private HttpRequestMessage GetRequest(HttpClient httpClient, Uri uri) { + var requestUri = PrepareUri(httpClient, uri); var httpMethod = GetHttpMethod(Method); // create the base WebRequest object @@ -346,7 +347,6 @@ private HttpRequestMessage GetRequest(HttpClient httpClient, Uri uri) request.Headers.Add(HttpKnownHeaderNames.UserAgent, GraphRequestSession.UserAgent); } } - return request; } @@ -359,6 +359,7 @@ private HttpRequestMessage GetRequest(HttpClient httpClient, Uri uri) private Uri PrepareUri(HttpClient httpClient, Uri uri) { UriBuilder uriBuilder; + // For AbsoluteUri such as /beta/groups?$count=true, Get the scheme and host from httpClient // Then use them to compose a new Url with the URL fragment. if (uri.IsAbsoluteUri) @@ -401,8 +402,7 @@ private Uri PrepareUri(HttpClient httpClient, Uri uri) // set body to null to prevent later FillRequestStream Body = null; } - - return uriBuilder.Uri; + return uriBuilder.Uri.EscapeDataStrings(); } private void ThrowIfError(ErrorRecord error) diff --git a/src/Authentication/Authentication/Helpers/EncodeUriPath.cs b/src/Authentication/Authentication/Helpers/EncodeUriPath.cs new file mode 100644 index 0000000000..72d8790a19 --- /dev/null +++ b/src/Authentication/Authentication/Helpers/EncodeUriPath.cs @@ -0,0 +1,35 @@ +// ------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. +// ------------------------------------------------------------------------------ + +using System; +using System.Text; + +namespace Microsoft.Graph.PowerShell.Authentication.Helpers +{ + /// + /// Escape data string/url encode Uris that have paths containing special characters like #. + /// For a path like /beta/users/first.last_foo.com#EXT#@contoso.onmicrosoft.com, the last segment contains special characters that need to be escaped + /// + public static class EncodeUriPaths + { + public static Uri EscapeDataStrings(this Uri uri) + { + int counter = 0; + var pathSegments = uri.OriginalString.Split('/'); + StringBuilder sb = new StringBuilder(); + foreach (var segment in pathSegments) + { + //Skips the left part of the uri i.e https://graph.microsoft.com + if (counter > 2) + { + sb.Append('/'); + sb.Append(Uri.EscapeDataString(segment)); + } + counter++; + } + Uri escapedUri = new Uri(uri.GetLeftPart(UriPartial.Authority) + sb.ToString()); + return escapedUri; + } + } +} \ No newline at end of file