From b2aeeab3277380ef449080457e3b671f592d4792 Mon Sep 17 00:00:00 2001 From: Simon Spielmann Date: Thu, 10 Nov 2022 18:07:02 +0100 Subject: [PATCH] Rework auth process Signed-off-by: Simon Spielmann --- .../icloud/internal/ICloudService.java | 7 ++- .../icloud/internal/ICloudSession.java | 9 ++- .../handler/ICloudAccountBridgeHandler.java | 19 ++----- .../icloud/internal/utilities/ListUtil.java | 55 +++++++++++++++++++ .../openhab/binding/icloud/TestICloud.java | 5 +- 5 files changed, 71 insertions(+), 24 deletions(-) create mode 100644 bundles/org.openhab.binding.icloud/src/main/java/org/openhab/binding/icloud/internal/utilities/ListUtil.java diff --git a/bundles/org.openhab.binding.icloud/src/main/java/org/openhab/binding/icloud/internal/ICloudService.java b/bundles/org.openhab.binding.icloud/src/main/java/org/openhab/binding/icloud/internal/ICloudService.java index 6723dcac9b91b..67b6b7d44d241 100644 --- a/bundles/org.openhab.binding.icloud/src/main/java/org/openhab/binding/icloud/internal/ICloudService.java +++ b/bundles/org.openhab.binding.icloud/src/main/java/org/openhab/binding/icloud/internal/ICloudService.java @@ -19,6 +19,7 @@ import java.util.Map; import java.util.UUID; +import org.openhab.binding.icloud.internal.utilities.ListUtil; import org.openhab.binding.icloud.internal.utilities.Pair; import org.openhab.core.storage.Storage; import org.slf4j.Logger; @@ -72,8 +73,7 @@ public ICloudService(String appleId, String password, Storage stateStora this.clientId = "auth-" + UUID.randomUUID().toString().toLowerCase(); this.session = new ICloudSession(stateStorage); - this.session.setDefaultHeaders(Pair.of("Accept", "*/*"), Pair.of("Origin", HOME_ENDPOINT), - Pair.of("Referer", HOME_ENDPOINT + "/")); + this.session.setDefaultHeaders(Pair.of("Origin", HOME_ENDPOINT), Pair.of("Referer", HOME_ENDPOINT + "/")); } /** @@ -221,7 +221,8 @@ public boolean validate2faCode(String code) throws IOException, InterruptedExcep Map requestBody = Map.of("securityCode", Map.of("code", code)); - List> headers = getAuthHeaders(); + List> headers = ListUtil.replaceEntries(getAuthHeaders(), + List.of(Pair.of("Accept", "application/json"))); addSessionHeaders(headers); diff --git a/bundles/org.openhab.binding.icloud/src/main/java/org/openhab/binding/icloud/internal/ICloudSession.java b/bundles/org.openhab.binding.icloud/src/main/java/org/openhab/binding/icloud/internal/ICloudSession.java index 112692b9ba887..45faa4da6ba0e 100644 --- a/bundles/org.openhab.binding.icloud/src/main/java/org/openhab/binding/icloud/internal/ICloudSession.java +++ b/bundles/org.openhab.binding.icloud/src/main/java/org/openhab/binding/icloud/internal/ICloudSession.java @@ -30,6 +30,7 @@ import java.util.List; import org.openhab.binding.icloud.internal.utilities.CustomCookieStore; +import org.openhab.binding.icloud.internal.utilities.ListUtil; import org.openhab.binding.icloud.internal.utilities.Pair; import org.openhab.core.storage.Storage; import org.slf4j.Logger; @@ -100,7 +101,8 @@ public String post(String url, String body, List> overrideH * Invoke an HTTP GET request to the given url. * * @param url URL to call. - * @param overrideHeaders  If not null the given headers are used instead of the standard headers set via + * @param overrideHeaders  If not null the given headers are used to replace corresponding entries of the standard + * headers set via * {@link #setDefaultHeaders(Pair...)} * @return Result body as {@link String}. * @throws IOException if I/O error occurred @@ -117,10 +119,7 @@ private String request(String method, String url, String body, List> requestHeaders = this.headers; - if (overrideHeaders != null) { - requestHeaders = overrideHeaders; - } + List> requestHeaders = ListUtil.replaceEntries(this.headers, overrideHeaders); for (Pair header : requestHeaders) { builder.header(header.getKey(), header.getValue()); diff --git a/bundles/org.openhab.binding.icloud/src/main/java/org/openhab/binding/icloud/internal/handler/ICloudAccountBridgeHandler.java b/bundles/org.openhab.binding.icloud/src/main/java/org/openhab/binding/icloud/internal/handler/ICloudAccountBridgeHandler.java index 924e99f5e620c..412694c0668cd 100644 --- a/bundles/org.openhab.binding.icloud/src/main/java/org/openhab/binding/icloud/internal/handler/ICloudAccountBridgeHandler.java +++ b/bundles/org.openhab.binding.icloud/src/main/java/org/openhab/binding/icloud/internal/handler/ICloudAccountBridgeHandler.java @@ -32,7 +32,6 @@ import org.openhab.binding.icloud.internal.json.response.ICloudDeviceInformation; import org.openhab.core.cache.ExpiringCache; import org.openhab.core.storage.Storage; -import org.openhab.core.test.storage.VolatileStorage; import org.openhab.core.thing.Bridge; import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.ThingStatus; @@ -108,16 +107,12 @@ public void initialize() { final String localAppleId = config.appleId; final String localPassword = config.password; - if (this.iCloudService == null) { - if (localAppleId != null && localPassword != null) { - // this.iCloudService = new ICloudService(localAppleId, localPassword, this.storage); - this.iCloudService = new ICloudService(localAppleId, localPassword, new VolatileStorage()); - } else { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, - "Apple ID/Password is not set!"); - return; - - } + if (localAppleId != null && localPassword != null) { + this.iCloudService = new ICloudService(localAppleId, localPassword, this.storage); + } else { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, + "Apple ID/Password is not set!"); + return; } updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_PENDING, "Wait for login"); @@ -244,8 +239,6 @@ private void checkLogin() { } if (iCloudService.requires2fa()) { // New code was requested. Wait for the user to update config. - String code = "999999"; - success = this.iCloudService.validate2faCode(code); logger.warn( "ICloud authentication requires 2-FA code. Please provide code in in thing configuration."); validate2faCode = true; diff --git a/bundles/org.openhab.binding.icloud/src/main/java/org/openhab/binding/icloud/internal/utilities/ListUtil.java b/bundles/org.openhab.binding.icloud/src/main/java/org/openhab/binding/icloud/internal/utilities/ListUtil.java new file mode 100644 index 0000000000000..c646efa7d884c --- /dev/null +++ b/bundles/org.openhab.binding.icloud/src/main/java/org/openhab/binding/icloud/internal/utilities/ListUtil.java @@ -0,0 +1,55 @@ +/** + * 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.binding.icloud.internal.utilities; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * This class implements util methods for list handling. + * + * @author Simon Spielmann - Initial contribution + * + */ +public abstract class ListUtil { + + private ListUtil() { + }; + + /** + * Replace entries in the given originalList with entries from replacements, if the have an equal key. + * + * @param Type of first pair element + * @param Type of second pair element + * @param originalList List with entries to replace + * @param replacements Replacement entries + * @return New list with replaced entries + */ + public static List> replaceEntries(List> originalList, List> replacements) { + List> result = new ArrayList<>(originalList); + if (replacements != null) { + Iterator> it = result.iterator(); + while (it.hasNext()) { + Pair requestHeader = it.next(); + for (Pair replacementHeader : replacements) { + if (requestHeader.getKey().equals(replacementHeader.getKey())) { + it.remove(); + } + } + } + result.addAll(replacements); + } + return result; + } +} diff --git a/bundles/org.openhab.binding.icloud/src/test/java/org/openhab/binding/icloud/TestICloud.java b/bundles/org.openhab.binding.icloud/src/test/java/org/openhab/binding/icloud/TestICloud.java index 33588a257474a..39f3457de649b 100644 --- a/bundles/org.openhab.binding.icloud/src/test/java/org/openhab/binding/icloud/TestICloud.java +++ b/bundles/org.openhab.binding.icloud/src/test/java/org/openhab/binding/icloud/TestICloud.java @@ -25,7 +25,6 @@ import org.openhab.binding.icloud.internal.ICloudService; import org.openhab.binding.icloud.internal.json.response.ICloudAccountDataResponse; import org.openhab.core.storage.json.internal.JsonStorage; -import org.openhab.core.test.storage.VolatileStorage; /** * @@ -49,8 +48,8 @@ public void testAuth() throws IOException, InterruptedException { JsonStorage stateStorage = new JsonStorage(jsonStorageFile, TestICloud.class.getClassLoader(), 0, 1000, 1000, List.of()); - // ICloudService service = new ICloudService(this.E_MAIL, this.PW, stateStorage); - ICloudService service = new ICloudService(this.E_MAIL, this.PW, new VolatileStorage<>()); + ICloudService service = new ICloudService(this.E_MAIL, this.PW, stateStorage); + // ICloudService service = new ICloudService(this.E_MAIL, this.PW, new VolatileStorage<>()); service.authenticate(false); if (service.requires2fa()) { System.out.print("Code: ");