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

Support AM/PM in MSI token #7356

Merged
merged 7 commits into from
Jan 13, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 @@ -13,6 +13,7 @@
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Locale;

/**
* Type representing response from the local MSI token provider.
Expand All @@ -35,15 +36,11 @@ public final class MSIToken extends AccessToken {
* @param token the token string.
* @param expiresOn the expiration time.
*/
public MSIToken(String token, OffsetDateTime expiresOn) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a Breaking change ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is in the implmentation package so we should be fine

super(token, expiresOn);
}

@JsonCreator
private MSIToken(
@JsonProperty(value = "access_token") String token,
@JsonProperty(value = "expires_on") String expiresOn) {
this(token, EPOCH.plusSeconds(parseDateToEpochSeconds(expiresOn)));
super(token, EPOCH.plusSeconds(parseDateToEpochSeconds(expiresOn)));
this.accessToken = token;
this.expiresOn = expiresOn;
}
Expand All @@ -53,29 +50,27 @@ public String getToken() {
return accessToken;
}

@Override
public OffsetDateTime getExpiresAt() {
return EPOCH.plusSeconds(parseDateToEpochSeconds(this.expiresOn));
}

@Override
public boolean isExpired() {
OffsetDateTime now = OffsetDateTime.now();
OffsetDateTime expireOn = EPOCH.plusSeconds(parseDateToEpochSeconds(this.expiresOn));
return now.plusMinutes(5).isAfter(expireOn);
}

private static Long parseDateToEpochSeconds(String dateTime) {
ClientLogger logger = new ClientLogger(MSIToken.class);
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss XXX");
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("M/d/yyyy H:mm:ss XXX", Locale.US);
jianghaolu marked this conversation as resolved.
Show resolved Hide resolved
// This is the format for app service on Windows as of API version 2017-09-01.
// The format is changed to Unix timestamp in 2019-08-01 but this API version
// has not been deployed to Linux app services.
DateTimeFormatter dtf_windows = DateTimeFormatter.ofPattern("M/d/yyyy K:mm:ss a XXX", Locale.US);
jianghaolu marked this conversation as resolved.
Show resolved Hide resolved
try {
return Long.parseLong(dateTime);
} catch (NumberFormatException e) {
logger.error(e.getMessage());
}

try {
return Instant.from(dtf.parse(dateTime)).toEpochMilli() / 1000L;
return Instant.from(dtf.parse(dateTime)).getEpochSecond();
} catch (DateTimeParseException e) {
logger.error(e.getMessage());
}

try {
return Instant.from(dtf_windows.parse(dateTime)).getEpochSecond();
} catch (DateTimeParseException e) {
logger.error(e.getMessage());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.identity.implementation;

import com.azure.core.util.serializer.JacksonAdapter;
import com.azure.core.util.serializer.SerializerEncoding;
import org.junit.Assert;
import org.junit.Test;

import java.time.OffsetDateTime;
import java.time.ZoneOffset;

public class MSITokenTests {
private JacksonAdapter serializer = new JacksonAdapter();
private OffsetDateTime expected = OffsetDateTime.of(2020, 1, 10, 15, 1, 28, 0, ZoneOffset.UTC);

@Test
public void canParseLong() throws Exception {
String json = "{\"access_token\":\"fake_token\",\"expires_on\":\"1578668608\"}";
MSIToken token = serializer.deserialize(json, MSIToken.class, SerializerEncoding.JSON);
Assert.assertEquals(expected.toEpochSecond(), token.getExpiresAt().toEpochSecond());
}

@Test
public void canParseDateTime24Hr() throws Exception {
String json = "{\"access_token\":\"fake_token\",\"expires_on\":\"01/10/2020 15:03:28 +00:00\"}";
MSIToken token = serializer.deserialize(json, MSIToken.class, SerializerEncoding.JSON);
Assert.assertEquals(expected.toEpochSecond(), token.getExpiresAt().toEpochSecond());
}

@Test
public void canParseDateTime12Hr() throws Exception {
String json = "{\"access_token\":\"fake_token\",\"expires_on\":\"1/10/2020 3:03:28 PM +00:00\"}";
MSIToken token = serializer.deserialize(json, MSIToken.class, SerializerEncoding.JSON);
Assert.assertEquals(expected.toEpochSecond(), token.getExpiresAt().toEpochSecond());

json = "{\"access_token\":\"fake_token\",\"expires_on\":\"12/20/2019 4:58:20 AM +00:00\"}";
token = serializer.deserialize(json, MSIToken.class, SerializerEncoding.JSON);
expected = OffsetDateTime.of(2019, 12, 20, 4, 56, 20, 0, ZoneOffset.UTC);
Assert.assertEquals(expected.toEpochSecond(), token.getExpiresAt().toEpochSecond());

json = "{\"access_token\":\"fake_token\",\"expires_on\":\"1/1/2020 0:00:00 PM +00:00\"}";
token = serializer.deserialize(json, MSIToken.class, SerializerEncoding.JSON);
expected = OffsetDateTime.of(2020, 1, 1, 11, 58, 0, 0, ZoneOffset.UTC);
Assert.assertEquals(expected.toEpochSecond(), token.getExpiresAt().toEpochSecond());
}
}