Skip to content

Escapes special characters on path segments when using Invoke-MgGraphRequest #2455

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

Merged
merged 6 commits into from
Nov 27, 2023
Merged
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
Original file line number Diff line number Diff line change
@@ -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());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ private async Task ReportResponseStatusASync(HttpMessageFormatter responseMessag
/// <returns></returns>
private HttpRequestMessage GetRequest(HttpClient httpClient, Uri uri)
{

var requestUri = PrepareUri(httpClient, uri);
var httpMethod = GetHttpMethod(Method);
// create the base WebRequest object
Expand Down Expand Up @@ -346,7 +347,6 @@ private HttpRequestMessage GetRequest(HttpClient httpClient, Uri uri)
request.Headers.Add(HttpKnownHeaderNames.UserAgent, GraphRequestSession.UserAgent);
}
}

return request;
}

Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
35 changes: 35 additions & 0 deletions src/Authentication/Authentication/Helpers/EncodeUriPath.cs
Original file line number Diff line number Diff line change
@@ -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
{
/// <summary>
/// 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
/// </summary>
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;
}
}
}