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

Incorrect timezone in datetime properties #347

Closed
klightspeed opened this issue Oct 11, 2019 · 4 comments
Closed

Incorrect timezone in datetime properties #347

klightspeed opened this issue Oct 11, 2019 · 4 comments
Labels

Comments

@klightspeed
Copy link

The timezone is being stripped off the timestamps fetched from the Okta API, resulting in UTC times being incorrectly cast to local times.

The Resource.Get*Property methods are converting the values in _data to string then back to the target type, which for DateTime properties strips out the DateTime.Kind.

Project to replicate:
OktaDateTimeError.csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.2</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
    <PackageReference Include="Okta.Sdk" Version="1.4.1" />
    <PackageReference Include="System.Configuration.ConfigurationManager" Version="4.6.0" />
  </ItemGroup>
</Project>

Program.cs:

class Program
{
    static void Main(string[] args)
    {
        var clientconfig = new Okta.Sdk.Configuration.OktaClientConfiguration
        {
            OktaDomain = System.Configuration.ConfigurationManager.AppSettings["OktaDomain"],
            Token = System.Configuration.ConfigurationManager.AppSettings["Token"]
        };

        var userid = "00u1k7v2r6hSK4S0T357";

        var client = new Okta.Sdk.OktaClient(clientconfig);
        var webclient = new System.Net.WebClient();
        webclient.Headers.Add(System.Net.HttpRequestHeader.Authorization, $"SSWS {clientconfig.Token}");
        var httpdata = webclient.DownloadString($"{clientconfig.OktaDomain}/api/v1/users/{userid}");
        var reader = new Newtonsoft.Json.JsonTextReader(new System.IO.StringReader(httpdata)) 
        { 
            DateParseHandling = Newtonsoft.Json.DateParseHandling.None
        };
        var json = Newtonsoft.Json.Linq.JObject.Load(reader);
        var user = client.Users.GetUserAsync(userid).GetAwaiter().GetResult();
        var userdata = user.GetData();
        var userdatalastupdate = userdata["lastUpdated"];
        System.Console.WriteLine($"Timezone: {System.TimeZoneInfo.Local.DisplayName}");
        System.Console.WriteLine($"json.lastUpdate: {json["lastUpdated"]}");
        System.Console.WriteLine($"typeof(data.lastUpdated): {userdatalastupdate.GetType().FullName}");
        System.Console.WriteLine($"data.lastUpdated.ToString(\"o\"): {((System.DateTime)userdatalastupdate).ToString("o")}");
        System.Console.WriteLine($"data.lastUpdated.ToString(): {userdatalastupdate.ToString()}");
        System.Console.WriteLine($"user.LastUpdated.ToString(\"o\"): {user.LastUpdated?.ToString("o")}");
        System.Console.WriteLine($"user.LastUpdated.ToString(): {user.LastUpdated.ToString()}");
    }
}

Output:

Timezone: (UTC+10:00) Brisbane
json.lastUpdate: 2019-10-11T01:46:23.000Z
typeof(data.lastUpdated): System.DateTime
data.lastUpdated.ToString("o"): 2019-10-11T01:46:23.0000000Z
data.lastUpdated.ToString(): 11/10/2019 1:46:23 AM
user.LastUpdated.ToString("o"): 2019-10-11T01:46:23.0000000+10:00
user.LastUpdated.ToString(): 11/10/2019 1:46:23 AM +10:00
@laura-rodriguez
Copy link
Collaborator

@klightspeed
Copy link
Author

Yes, passing a serializer that does not parse dates does appear to be a workaround.

class Program
{
    static void Main(string[] args)
    {
        var clientconfig = new Okta.Sdk.Configuration.OktaClientConfiguration
        {
            OktaDomain = System.Configuration.ConfigurationManager.AppSettings["OktaDomain"],
            Token = System.Configuration.ConfigurationManager.AppSettings["Token"]
        };

        var serializer = new Okta.Sdk.Internal.DefaultSerializer(new Newtonsoft.Json.JsonSerializerSettings
        {
            DateParseHandling = Newtonsoft.Json.DateParseHandling.None
        });

        var userid = "00u1k7v2r6hSK4S0T357";

        var client = new Okta.Sdk.OktaClient(clientconfig, serializer: serializer);
        var webclient = new System.Net.WebClient();
        webclient.Headers.Add(System.Net.HttpRequestHeader.Authorization, $"SSWS {clientconfig.Token}");
        var httpdata = webclient.DownloadString($"{clientconfig.OktaDomain}/api/v1/users/{userid}");
        var reader = new Newtonsoft.Json.JsonTextReader(new System.IO.StringReader(httpdata)) 
        { 
            DateParseHandling = Newtonsoft.Json.DateParseHandling.None
        };
        var json = Newtonsoft.Json.Linq.JObject.Load(reader);
        var user = client.Users.GetUserAsync(userid).GetAwaiter().GetResult();
        var userdata = user.GetData();
        var userdatalastupdate = userdata["lastUpdated"];
        System.Console.WriteLine($"Timezone: {System.TimeZoneInfo.Local.DisplayName}");
        System.Console.WriteLine($"json.lastUpdate: {json["lastUpdated"]}");
        System.Console.WriteLine($"typeof(data.lastUpdated): {userdatalastupdate.GetType().FullName}");
        System.Console.WriteLine($"data.lastUpdated.ToString(\"o\"): {(userdatalastupdate as System.DateTime?)?.ToString("o")}");
        System.Console.WriteLine($"data.lastUpdated.ToString(): {userdatalastupdate.ToString()}");
        System.Console.WriteLine($"user.LastUpdated.ToString(\"o\"): {user.LastUpdated?.ToString("o")}");
        System.Console.WriteLine($"user.LastUpdated.ToString(): {user.LastUpdated.ToString()}");
    }
}

Output:

Timezone: (UTC+10:00) Brisbane
json.lastUpdate: 2019-10-11T01:46:23.000Z
typeof(data.lastUpdated): System.String
data.lastUpdated.ToString("o"):
data.lastUpdated.ToString(): 2019-10-11T01:46:23.000Z
user.LastUpdated.ToString("o"): 2019-10-11T01:46:23.0000000+00:00
user.LastUpdated.ToString(): 11/10/2019 1:46:23 AM +00:00

@laura-rodriguez
Copy link
Collaborator

I'm glad that helped. I'm going to close this issue, but feel free to reopen it if you still have issues.

@klightspeed
Copy link
Author

So basically if you want LastUpdated et al to be accurate, you need to pass a serializer that does not parse dates to the OktaClient serializer?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants