diff --git a/vector/src/main/java/im/vector/widgets/WidgetsManager.java b/vector/src/main/java/im/vector/widgets/WidgetsManager.java index 7febcd4f50..3d66f3d2fa 100755 --- a/vector/src/main/java/im/vector/widgets/WidgetsManager.java +++ b/vector/src/main/java/im/vector/widgets/WidgetsManager.java @@ -19,7 +19,6 @@ package im.vector.widgets; import android.content.Context; -import android.support.v7.preference.PreferenceManager; import android.text.TextUtils; import com.google.gson.JsonObject; @@ -50,6 +49,7 @@ import im.vector.VectorApp; import im.vector.extensions.UrlExtensionsKt; import im.vector.settings.VectorLocale; +import im.vector.widgets.tokens.TokensStore; public class WidgetsManager { private static final String LOG_TAG = WidgetsManager.class.getSimpleName(); @@ -69,11 +69,6 @@ public class WidgetsManager { */ private static final String WIDGET_TYPE_JITSI = "jitsi"; - /** - * Widget preferences - */ - private static final String SCALAR_TOKEN_PREFERENCE_KEY = "SCALAR_TOKEN_PREFERENCE_KEY"; - private final IntegrationManagerConfig config; public WidgetsManager(IntegrationManagerConfig config) { @@ -533,9 +528,9 @@ public boolean isScalarUrl(Context context, String url) { * @param callback the asynchronous callback */ public void getScalarToken(final Context context, final MXSession session, final ApiCallback callback) { - final String preferenceKey = SCALAR_TOKEN_PREFERENCE_KEY + session.getMyUserId(); + final TokensStore tokensStore = new TokensStore(context); - final String scalarToken = PreferenceManager.getDefaultSharedPreferences(context).getString(preferenceKey, null); + final String scalarToken = tokensStore.getToken(session.getMyUserId(), config.getApiUrl()); if (null != scalarToken) { WidgetsRestClient widgetsRestClient = new WidgetsRestClient(context, config); @@ -576,10 +571,7 @@ public void onSuccess(Map response) { String token = response.get("scalar_token"); if (null != token) { - PreferenceManager.getDefaultSharedPreferences(context) - .edit() - .putString(preferenceKey, token) - .apply(); + tokensStore.setToken(session.getMyUserId(), config.getApiUrl(), token); } // Validate it (this mostly checks to see if the IM needs us to agree to some terms) @@ -616,11 +608,6 @@ public void onMatrixError(MatrixError e) { * @param session current session, to retrieve the current user */ public void clearScalarToken(Context context, final MXSession session) { - final String preferenceKey = SCALAR_TOKEN_PREFERENCE_KEY + session.getMyUserId(); - - PreferenceManager.getDefaultSharedPreferences(context) - .edit() - .remove(preferenceKey) - .apply(); + new TokensStore(context).clear(); } } diff --git a/vector/src/main/java/im/vector/widgets/tokens/TokensStore.kt b/vector/src/main/java/im/vector/widgets/tokens/TokensStore.kt new file mode 100644 index 0000000000..9f039cabbe --- /dev/null +++ b/vector/src/main/java/im/vector/widgets/tokens/TokensStore.kt @@ -0,0 +1,105 @@ +/* + * Copyright 2019 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.widgets.tokens + +import android.content.Context +import android.support.v7.preference.PreferenceManager +import androidx.core.content.edit +import org.matrix.androidsdk.core.JsonUtils + +class TokensStore(context: Context) { + + private val prefs = PreferenceManager.getDefaultSharedPreferences(context) + private val gson = JsonUtils.getBasicGson() + + private data class TokensStore( + // Keys are user Id + @JvmField + val userToServerTokens: MutableMap = mutableMapOf() + ) + + private data class ServerTokens( + // Keys are server Url, values are token + @JvmField + val serverTokens: MutableMap = mutableMapOf() + ) + + fun getToken(userId: String, serverUrl: String): String? { + handleMigration(userId) + + return readStore() + .userToServerTokens[userId] + ?.serverTokens + ?.get(serverUrl) + } + + private fun handleMigration(userId: String) { + val prefKey = SCALAR_TOKEN_LEGACY_PREFERENCE_KEY + userId + + val previousStoredToken = prefs.getString(prefKey, null) + + if (!previousStoredToken.isNullOrBlank()) { + // It was maybe a token for scalar.vector.im. If it is not the case, it will be invalid and will be replaced. + setToken(userId, "https://scalar.vector.im/api", previousStoredToken) + + prefs.edit { + remove(prefKey) + } + } + } + + fun setToken(userId: String, serverUrl: String, token: String) { + readStore() + .apply { + userToServerTokens.getOrPut(userId) { ServerTokens() } + .serverTokens[serverUrl] = token + } + .commit() + } + + private fun readStore(): TokensStore { + return prefs.getString(SCALAR_TOKENS_PREFERENCE_KEY, null) + ?.toModel() + ?: TokensStore() + } + + private fun TokensStore.commit() { + prefs.edit { + putString(SCALAR_TOKENS_PREFERENCE_KEY, this@commit.fromModel()) + } + } + + fun clear() { + prefs.edit { + remove(SCALAR_TOKENS_PREFERENCE_KEY) + } + } + + private fun String.toModel(): TokensStore? { + return gson.fromJson(this, TokensStore::class.java) + } + + private fun TokensStore.fromModel(): String? { + return gson.toJson(this) + } + + companion object { + private const val SCALAR_TOKEN_LEGACY_PREFERENCE_KEY = "SCALAR_TOKEN_PREFERENCE_KEY" + + private const val SCALAR_TOKENS_PREFERENCE_KEY = "SCALAR_TOKENS_PREFERENCE_KEY" + } +} \ No newline at end of file