Skip to content

Commit

Permalink
Fix access token serialization/deserialization (openhab#3083)
Browse files Browse the repository at this point in the history
Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>
  • Loading branch information
jlaur authored Sep 15, 2022
1 parent cda7b09 commit 27c2887
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 6 deletions.
6 changes: 6 additions & 0 deletions bundles/org.openhab.core.auth.oauth2client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
<artifactId>org.openhab.core.io.net</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.core.bundles</groupId>
<artifactId>org.openhab.core.test</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
import static org.openhab.core.auth.oauth2client.internal.StorageRecordType.*;

import java.security.GeneralSecurityException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeParseException;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
Expand Down Expand Up @@ -236,13 +239,17 @@ private class StorageFacade implements AutoCloseable {

public StorageFacade(Storage<String> storage) {
this.storage = storage;
// Add adapters for LocalDateTime
// Add adapters for Instant
gson = new GsonBuilder()
.registerTypeAdapter(LocalDateTime.class,
(JsonDeserializer<LocalDateTime>) (json, typeOfT, context) -> LocalDateTime
.parse(json.getAsString()))
.registerTypeAdapter(LocalDateTime.class,
(JsonSerializer<LocalDateTime>) (date, type,
.registerTypeAdapter(Instant.class, (JsonDeserializer<Instant>) (json, typeOfT, context) -> {
try {
return Instant.parse(json.getAsString());
} catch (DateTimeParseException e) {
return LocalDateTime.parse(json.getAsString()).atZone(ZoneId.systemDefault()).toInstant();
}
})
.registerTypeAdapter(Instant.class,
(JsonSerializer<Instant>) (date, type,
jsonSerializationContext) -> new JsonPrimitive(date.toString()))
.setPrettyPrinting().create();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/**
* Copyright (c) 2010-2022 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.core.auth.oauth2client;

import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
import org.openhab.core.auth.client.oauth2.AccessTokenResponse;
import org.openhab.core.auth.oauth2client.internal.OAuthStoreHandlerImpl;
import org.openhab.core.auth.oauth2client.internal.StorageRecordType;
import org.openhab.core.storage.Storage;
import org.openhab.core.storage.StorageService;
import org.openhab.core.test.storage.VolatileStorage;

/**
* The {@link OAuthStoreHandlerTest} contains tests for
* {@link org.openhab.core.auth.oauth2client.OAuthStoreHandlerImpl}
*
* @author Jacob Laursen - Initial contribution
*/
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
@NonNullByDefault
public class OAuthStoreHandlerTest {
private @Mock @NonNullByDefault({}) StorageService storageService;

private static final String STORE_NAME = "StorageHandler.For.OAuthClientService";
private @NonNullByDefault({}) Storage<String> storage;
private @NonNullByDefault({}) OAuthStoreHandlerImpl storeHandler;

@BeforeEach
public void initialize() throws IOException {
storage = new VolatileStorage<>();
Mockito.doReturn(storage).when(storageService).getStorage(STORE_NAME);
storeHandler = new OAuthStoreHandlerImpl(storageService);
}

@Test
public void loadAccessTokenResponseWhenCreatedOnIsLocalDateTime() throws GeneralSecurityException {
final String handle = "test";
final String createdOn = "2022-08-14T21:21:05.568991";
final Instant expected = LocalDateTime.parse(createdOn).atZone(ZoneId.systemDefault()).toInstant();

storage.put(StorageRecordType.ACCESS_TOKEN_RESPONSE.getKey(handle), getJsonforCreatedOn(createdOn));
AccessTokenResponse response = storeHandler.loadAccessTokenResponse(handle);

assertThat(response, is(notNullValue()));
if (response != null) {
assertThat(response.getCreatedOn(), is(expected));
}
}

@Test
public void loadAccessTokenResponseWhenCreatedOnIsInstant() throws GeneralSecurityException {
final String handle = "test";
final String createdOn = "2022-08-14T19:21:05.568991Z";
final Instant expected = Instant.parse(createdOn);

storage.put(StorageRecordType.ACCESS_TOKEN_RESPONSE.getKey(handle), getJsonforCreatedOn(createdOn));
AccessTokenResponse response = storeHandler.loadAccessTokenResponse(handle);

assertThat(response, is(notNullValue()));
if (response != null) {
assertThat(response.getCreatedOn(), is(expected));
}
}

private String getJsonforCreatedOn(String createdOn) {
return "{\"accessToken\": \"x\", \"tokenType\": \"Bearer\", \"expiresIn\": 2592000, \"refreshToken\": \"x\", \"createdOn\": \""
+ createdOn + "\"}";
}
}

0 comments on commit 27c2887

Please sign in to comment.