Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information.
// ------------------------------------------------------------------------------

using Newtonsoft.Json.Linq;
using System.IO;
using System.Management.Automation;

namespace Microsoft.Graph.PowerShell.Authentication.Cmdlets
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using Microsoft.Graph.PowerShell.Authentication.Models;
using Microsoft.Graph.PowerShell.Authentication.Properties;
using Microsoft.PowerShell.Commands;
using Newtonsoft.Json;
using System;
using System.Collections;
using System.Globalization;
Expand All @@ -18,6 +17,7 @@
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using static Microsoft.Graph.PowerShell.Authentication.Helpers.AsyncHelpers;
Expand Down Expand Up @@ -580,7 +580,7 @@ private long SetRequestContent(HttpRequestMessage request, IDictionary content)
}

// Covert all dictionaries to Json
var body = JsonConvert.SerializeObject(content);
var body = JsonSerializer.Serialize(content);
return SetRequestContent(request, body);
}

Expand Down
10 changes: 7 additions & 3 deletions src/Authentication/Authentication/Cmdlets/SetMgGraphOption.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// ------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information.
// ------------------------------------------------------------------------------

using Newtonsoft.Json;
using System.IO;
using System.Management.Automation;
using System.Text.Json;

namespace Microsoft.Graph.PowerShell.Authentication.Cmdlets
{
Expand All @@ -14,6 +13,11 @@ public class SetMgGraphOption : PSCmdlet
[Parameter]
public bool EnableLoginByWAM { get; set; }

private static readonly JsonSerializerOptions jsonSerializerOptions = new JsonSerializerOptions
{
WriteIndented = true
};

protected override void BeginProcessing()
{
base.BeginProcessing();
Expand All @@ -27,7 +31,7 @@ protected override void ProcessRecord()
GraphSession.Instance.GraphOption.EnableWAMForMSGraph = EnableLoginByWAM;
WriteDebug($"Signin by Web Account Manager (WAM) is {(EnableLoginByWAM ? "enabled" : "disabled")}.");
}
File.WriteAllText(Constants.GraphOptionsFilePath, JsonConvert.SerializeObject(GraphSession.Instance.GraphOption, Formatting.Indented));
File.WriteAllText(Constants.GraphOptionsFilePath, JsonSerializer.Serialize(GraphSession.Instance.GraphOption, jsonSerializerOptions));
}

protected override void EndProcessing()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
using Microsoft.Graph.PowerShell.Authentication.Helpers;
using Microsoft.Graph.PowerShell.Authentication.Interfaces;
using Microsoft.Graph.PowerShell.Authentication.Models;
using Newtonsoft.Json;
using System;
using System.IO;
using System.Management.Automation;
using System.Text.Json;
using RequestContext = Microsoft.Graph.PowerShell.Authentication.Models.RequestContext;

namespace Microsoft.Graph.PowerShell.Authentication.Common
Expand Down Expand Up @@ -40,7 +40,7 @@ internal static GraphSession CreateInstance(IDataStore dataStore = null)
if (File.Exists(Constants.GraphOptionsFilePath))
{
// Deserialize the JSON into the GraphOption instance
graphOptions = JsonConvert.DeserializeObject<GraphOption>(File.ReadAllText(Constants.GraphOptionsFilePath));
graphOptions = JsonSerializer.Deserialize<GraphOption>(File.ReadAllText(Constants.GraphOptionsFilePath));
}

return new GraphSession
Expand Down
17 changes: 14 additions & 3 deletions src/Authentication/Authentication/Common/GraphSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
using Microsoft.Graph.PowerShell.Authentication.Helpers;
using Microsoft.Graph.PowerShell.Authentication.Interfaces;
using Microsoft.Graph.PowerShell.Authentication.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Xml.Serialization;

namespace Microsoft.Graph.PowerShell.Authentication.Common
Expand Down Expand Up @@ -155,6 +156,12 @@ public void Save(IFileProvider provider)
}
}

private static readonly JsonSerializerOptions jsonSerializerOptions = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
WriteIndented = true,
Converters = { new GraphSettingsConverter() }
};
/// <summary>
/// Safely deserializes JSON string to an object.
/// </summary>
Expand All @@ -169,7 +176,11 @@ internal bool TryDeserializeObject<T>(string serialization, out T result, JsonCo
bool success = false;
try
{
result = converter == null ? JsonConvert.DeserializeObject<T>(serialization) : JsonConvert.DeserializeObject<T>(serialization, converter);
if (!(converter is GraphSettingsConverter))
{
jsonSerializerOptions.Converters.Add(converter);
}
result = converter == null ? JsonSerializer.Deserialize<T>(serialization) : JsonSerializer.Deserialize<T>(serialization, jsonSerializerOptions);
success = true;
}
catch (JsonException)
Expand Down Expand Up @@ -303,7 +314,7 @@ public bool TryRemoveEnvironment(string name, out IGraphEnvironment environment)
/// <returns>A JSON string.</returns>
public override string ToString()
{
return JsonConvert.SerializeObject(this, Formatting.Indented, new GraphSettingsConverter());
return JsonSerializer.Serialize(this, jsonSerializerOptions);
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,42 @@

using Microsoft.Graph.PowerShell.Authentication.Interfaces;
using Microsoft.Graph.PowerShell.Authentication.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Microsoft.Graph.PowerShell.Authentication.Common
{
/// <summary>
/// A <see cref="JsonConverter"/> for <see cref="GraphSettings"/>.
/// </summary>
internal class GraphSettingsConverter: JsonConverter
internal class GraphSettingsConverter : JsonConverter<IGraphEnvironment>
{
public override bool CanWrite => true;
public override bool CanRead => true;
public override bool CanConvert(Type objectType)
public override IGraphEnvironment Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return objectType == typeof(IGraphEnvironment);
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (objectType == typeof(IGraphEnvironment))
if (typeToConvert == typeof(IGraphEnvironment))
{
return serializer.Deserialize<GraphEnvironment>(reader);
return JsonSerializer.Deserialize<GraphEnvironment>(ref reader, options);
}
else if (objectType == typeof(Dictionary<string, IGraphEnvironment>))
else if (typeToConvert == typeof(Dictionary<string, IGraphEnvironment>))
{
var tempResult = serializer.Deserialize<Dictionary<string, GraphEnvironment>>(reader);
var tempResult = JsonSerializer.Deserialize<Dictionary<string, GraphEnvironment>>(ref reader, options);
var result = new Dictionary<string, IGraphEnvironment>(StringComparer.OrdinalIgnoreCase);
foreach (var key in tempResult.Keys)
{
result[key] = tempResult[key];
}

return result;
return (IGraphEnvironment)(object)result;
}

return serializer.Deserialize(reader);
throw new JsonException($"Cannot convert to {typeToConvert}");
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
public override void Write(Utf8JsonWriter writer, IGraphEnvironment value, JsonSerializerOptions options)
{
serializer.Serialize(writer, value);
JsonSerializer.Serialize(writer, value, options);
}
}
}
53 changes: 14 additions & 39 deletions src/Authentication/Authentication/Helpers/StringUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
using System.Management.Automation;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Microsoft.Graph.PowerShell.Authentication.Helpers
{
Expand Down Expand Up @@ -66,6 +67,13 @@ internal static string FormatDictionary(this IDictionary content)
return bodyBuilder.ToString();
}


private static readonly JsonSerializerOptions _jsonSerializerOptions = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
/// <summary>
/// Convert a JSON string back to an object of type <see cref="PSObject"/> or
/// <see cref="Hashtable"/> depending on parameter <paramref name="returnHashtable"/>.
Expand All @@ -87,48 +95,15 @@ public static object ConvertFromJson(this string jsonString, bool returnHashtabl
error = null;
try
{
// JsonConvert.DeserializeObject does not throw an exception when an invalid Json array is passed.
// This issue is being tracked by https://github.com/JamesNK/Newtonsoft.Json/issues/1930.
// To work around this, we need to identify when jsonString is a Json array, and then try to parse it via JArray.Parse().

// If jsonString starts with '[' (ignoring white spaces).
if (Regex.Match(jsonString, @"^\s*\[").Success)
if (maxDepth != null)
{
// JArray.Parse() will throw a JsonException if the array is invalid.
// This will be caught by the catch block below, and then throw an
// ArgumentException - this is done to have same behavior as the JavaScriptSerializer.
JArray.Parse(jsonString);

// Please note that if the Json array is valid, we don't do anything,
// we just continue the deserialization.
_jsonSerializerOptions.MaxDepth = maxDepth.Value;
}

var obj = JsonConvert.DeserializeObject(
jsonString,
new JsonSerializerSettings
{
// This TypeNameHandling setting is required to be secure.
TypeNameHandling = TypeNameHandling.None,
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
MaxDepth = maxDepth
});

switch (obj)
if (returnHashtable)
{
case JObject dictionary:
// JObject is a IDictionary
/* Note: Do not use Ternary operator as HashTable is implicitly convertible to PsObject, thus the ternary operation below, always returns a PSObject.
* return returnHashtable ? PopulateHashTableFromJDictionary(dictionary, out error) : PopulateFromJDictionary(dictionary, new DuplicateMemberHashSet(), out error);
* https://github.com/PowerShell/PowerShell/blob/73f852da4252eabe4097ab48a7b67c5d147a01f3/src/System.Management.Automation/engine/MshObject.cs#L965
*/
return returnHashtable
? PopulateHashTableFromJDictionary(dictionary, out error)
: (object)PopulateFromJDictionary(dictionary, new DuplicateMemberHashSet(), out error);
case JArray list:
return returnHashtable ? PopulateHashTableFromJArray(list, out error) : (object)PopulateFromJArray(list, out error);
default:
return obj;
return JsonSerializer.Deserialize<Hashtable>(jsonString, _jsonSerializerOptions);
}
var obj = JsonSerializer.Deserialize<PSObject>(jsonString, _jsonSerializerOptions);
}
catch (JsonException je)
{
Expand Down
Loading