Skip to content
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

AppAndInstanceConditionEvaluatorAppOrInstance ID property setter is private #718

Closed
rcollette opened this issue May 28, 2024 · 2 comments · Fixed by #739
Closed

AppAndInstanceConditionEvaluatorAppOrInstance ID property setter is private #718

rcollette opened this issue May 28, 2024 · 2 comments · Fixed by #739
Labels

Comments

@rcollette
Copy link

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

@rcollette rcollette added the bug label May 28, 2024
@rcollette
Copy link
Author

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);
    }
}

@bryanapellanes-okta
Copy link
Contributor

@rcollette Thanks for reporting this. I've added internal issue for tracking and prioritization.

OKTA-735160

bryanapellanes-okta added a commit that referenced this issue Oct 3, 2024
### Fixed

- Factors Api doesn't return factors setup on users (#650)
- AppAndInstanceConditionEvaluatorAppOrInstance ID property setter is private (#718)
- PolicyRule does not allow a null Priority to be specified. (#719)

### Changed

- ApiTokenApi
  - ListApiTokens
    - parameters removed.
- ApplicationTokensApi
  - ListOAuth2TokensForApplication
    - return type OAuth2Token changed to OAuth2RefreshToken.
  - GetOAuth2TokenForApplication
    - return type OAuth2Token changed to OAuth2RefreshToken.
- ApplicationUsersApi
  - AssignUserToApplication
    - parameter of type AppUser changed to AppUserAssignRequest.
  - UpdateApplicationUser
    - parameter of type AppUser changed to AppUserUpdateRequest.
- AuthenticatorApi
  - ListAuthenticators
    - return type Authenticator changed to AuthenticatorBase
- AuthorizationServerKeysApi
  - ListAuthorizationServerKeys
    - return type collection of JsonWebKey changed to collection of AuthorizationServerJsonWebKey.
  - RotateAuthorizationServerKeys
    - return type collection of JsonWebKey changed to collection of AuthorizationServerJsonWebKey.
- CustomTemplatesApi
  - ListEmailTemplates
    - return type EmailTemplate changed to EmailTemplateResponse.
  - GetEmailTemplate
    - return type EmailTemplate changed to EmailTemplateResponse.
  - GetEmailSettings
    - return type EmailSettings changed to EmailSettingsResponse.
- ThemesApi
  - ReplaceBrandTheme
    - parameter of type Theme changed to UpdateThemeRequest
- DeviceApi
  - ListDevices
    - return type collection of Device changed to collection of DeviceList.
- ApplicationConnectionsApi
  - GetDefaultProvisioningConnectionForApplication
    - return type ProvisioningConnection changed to ProvisioningConnectionResponse
  - UpdateDefaultProvisioningConnectionForApplication
    - return type ProvisioningConnection changed to ProvisioningConnectionResponse
- AuthenticatorApi methods that previously returned Authenticator now return AuthenticatorBase.
- GroupApi
  - ListGroupUsers
    - return type collection of User changed to collectio of GroupMember.
- RealmApi
  - CreateRealm
    - parameter of type Realm changed to CreateRealmRequest.
- UserFacorApi
  - ResendEnrollFactor 
    - parameter of type UserFactor changed to ResendUserFactor.
    - return type UserFactor changed to ResendUserFactor.
  - GetFactorTransactionStatus
    - return type VerifyUserFactorResponse changed to UserFactorPushTransaction 
  - VerifyFactor
    - parameter of type VerifyFactorRequest changed to UserFactorVerifyRequest
    - return type VerifyUserFactorResponse changed to UserFactorVerifyResponse 

### Moved

- AuthorizationServerApi functionality is now broken out into more specific API classes.
- GroupOwnerApi contains functionality previously in GroupsApi.

### Replaced

- CustomizationApi is replaced by CustomTemplatesApi, CusomPagesApi and BrandsApi.
- RealmApi.UpdateRealm is replaced by RealmApi.ReplaceRealm.
- ProvisioningConnection is replaced by ProvisioningConnectionRequest & ProvisioningConnectionResponse.
- VerifyFactorRequest is replaced by UserFactorVerifyRequest
- VerifyUserFactorResponse is replaced by UserFactorVerifyResponse 

### Removed
- SchemaApi methods removed:
  - GetAppUISchemaLinksAsync
- UserApi methods removed:
  - SetLinkedObjectForUser

### Added

- ApiTokenApi methods added:
  - UpsertApiToken
- ApplicationConnectionsApi methods added:
  - VerifyProvisioningConnectionForApplication
- AuthorizationAssocApi is a new API to maange authorization server associations.
- AuthorizationServerClaimsApi is a new API to manage authorization server claims.
- AuthroziationServerClientsApi is a new API to manage authorization server clients.
- AuthorizationServerKeysApi is a new API to manage authorization server keys.
- AuthorizationServerPoliciesApi is a new API to manage authorization server policies.
- AuthorizationServerRulesApi is a new API to manage authorization server rules.
- AuthorizationServerScopesApi is a new API to manage authorization server scopes.
- ApplicationGroupsApi methods added:
  - UpdateGroupAssignmentToApplication overload accepting a list of JsonPathOperation objects.
- BrandsApi is a new API to manage brands.
- CustomTemplatesApi is new API to manage custom templates.
- CustotmPagesApi is new API to manage custom pages.
- DirectoriesIntegrationApi is a new API to manage AD integrations.
- GroupOwnerApi is a new API to manage group owners.
- InlineHookApi methods added:
  - UpdateInlineHook
- OktaApplicationSettingsApi is a new API to manage Okta application settings.
- ThemesApi is a new API to manage themes.
- OrgSettingApi methods added:
  - GetThirdPartyAdminSetting
  - UpdateThirdPartyAdminSetting
  - GetClientPrivilegesSetting
  - AssignClientPrivilegesSetting
- RealAssignmentApi is a new API to manage realm assignments.
- SSFReceiverApi is a new API to manage the consumption of security events.
- SSFSecurityEventTokenApi is a new API to manage security event tokens.
- SSFTransmitterApi is a new API to manage security event transmitters.
- SessionApi methods added:
  - GetCurrentSession
  - CloseCurrentSession
  - RefreshCurrentSession
- UserApi methods added:
  - ReplaceLinkedObjectForUser
  - ListLinkedObjectsForUser
  - DeleteLinkedObjectForUser
- AttackProtectionApi methods added:
  - GetAuthenticatorSettings
  - ReplaceAuthenticatorSettings
- RoleAssignmentApi methods added:
  - ListRolesForClient
  - AssignRoleToClient
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants