Closed rcollette closed 1 month ago
Yet another workaround.
Set the ID property using reflection
private static readonly PropertyInfo? s_idAccessor =
typeof(AppAndInstanceConditionEvaluatorAppOrInstance).GetProperty(
name: "Id");
public static IdpDiscoveryPolicyRuleCondition CreateForUser(string mailAddress, string appId)
{
AppAndInstanceConditionEvaluatorAppOrInstance appInstance = new() { Type = AppAndInstanceType.APP };
// set the app instance id to appId using reflection since the Id property has a private setter
// See: https://github.com/okta/okta-sdk-dotnet/issues/718
s_idAccessor!.SetValue(appInstance, appId);
return new IdpDiscoveryPolicyRuleCondition
{
UserIdentifier = UserIdentifier.CreateForUser(mailAddress),
App = new AppAndInstancePolicyRuleCondition { Include = [appInstance] }
};
}
Newtonsoft doesn't serialize properties with private setters by default, so I added yet another converter.
using System;
using System.Reflection;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using Okta.Sdk.Model;
namespace Precisely.Identity.Api.HttpClient.Okta.Schema;
public class AppAndInstanceConditionEvaluatorAppOrInstanceConverter : JsonConverter
{
private static JsonSerializerSettings CloneSerializerSettings(JsonSerializer serializer)
{
return new JsonSerializerSettings
{
Culture = serializer.Culture,
DateFormatHandling = serializer.DateFormatHandling,
DateTimeZoneHandling = serializer.DateTimeZoneHandling,
DefaultValueHandling = serializer.DefaultValueHandling,
Formatting = serializer.Formatting,
NullValueHandling = serializer.NullValueHandling,
ObjectCreationHandling = serializer.ObjectCreationHandling,
ReferenceLoopHandling = serializer.ReferenceLoopHandling,
StringEscapeHandling = serializer.StringEscapeHandling,
TypeNameHandling = serializer.TypeNameHandling,
MetadataPropertyHandling = serializer.MetadataPropertyHandling,
Converters = [.. serializer.Converters]
};
}
public override object? ReadJson(
JsonReader reader,
Type objectType,
object? existingValue,
JsonSerializer serializer)
{
JsonSerializerSettings settings = CloneSerializerSettings(serializer);
settings.Converters.Remove(this); // Remove this converter to avoid recursion
JsonSerializer localSerializer = JsonSerializer.Create(settings);
return localSerializer.Deserialize(reader, objectType);
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(AppAndInstanceConditionEvaluatorAppOrInstance);
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value == null)
{
return;
}
JObject jObject = [];
DefaultContractResolver resolver = new() { NamingStrategy = new CamelCaseNamingStrategy() };
foreach (PropertyInfo prop in value.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
if (prop.CanRead)
{
object? propValue = prop.GetValue(value);
if (propValue != null)
{
jObject.Add(resolver.GetResolvedPropertyName(prop.Name), JToken.FromObject(propValue, serializer));
}
}
}
jObject.WriteTo(writer);
}
}
@rcollette Thanks for reporting this. I've added internal issue for tracking and prioritization.
OKTA-735160
Describe the bug?
When creating an IdpDiscoveryPolicyRule and attempting to set the rule to apply to a specific application, I am unable to set the Id property in AppAndInstanceConditionEvaluatorAppOrInstance, but it is clearly a valid property that can be set when calling the API as per the documentation at https://developer.okta.com/docs/reference/api/policy/#application-and-app-instance-condition-object.
What is expected to happen?
AppAndInstanceConditionEvaluatorAppOrInstance.Id should be settable.
What is the actual behavior?
It is not settable.
Reproduction Steps?
This is pretty straight forward. Reproduction isn't necessary.
Additional Information?
No response
.NET Version
8.0.300
SDK Version
7.0.6
OS version
Darwin MacBook-Pro-3.local 23.4.0 Darwin Kernel Version 23.4.0: Fri Mar 15 00:10:42 PDT 2024; root:xnu-10063.101.17~1/RELEASE_ARM64_T6000 arm64