From c5ecd40b0710084447683f7e0a03146ca6105fa2 Mon Sep 17 00:00:00 2001 From: Manuel Plazas Palacio Date: Wed, 26 Jul 2023 09:03:13 +0200 Subject: [PATCH 1/7] Adding branding option to prevent http traffic. --- .../android/dependecyinjection/ViewModelModule.kt | 2 +- .../authentication/AuthenticationViewModel.kt | 9 ++++++++- .../presentation/authentication/LoginActivity.kt | 14 ++++++++++++++ owncloudApp/src/main/res/values/setup.xml | 4 ++++ owncloudApp/src/main/res/values/strings.xml | 1 + .../android/domain/exceptions/SSLErrorException.kt | 2 +- .../server/usecases/GetServerInfoAsyncUseCase.kt | 10 ++++++++-- 7 files changed, 37 insertions(+), 5 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/ViewModelModule.kt b/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/ViewModelModule.kt index c161d009285..d56393871b9 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/ViewModelModule.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/ViewModelModule.kt @@ -78,7 +78,7 @@ val viewModelModule = module { PassCodeViewModel(get(), get(), action) } - viewModel { AuthenticationViewModel(get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get()) } + viewModel { AuthenticationViewModel(get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get()) } viewModel { OAuthViewModel(get(), get(), get(), get()) } viewModel { SettingsViewModel(get()) } viewModel { SettingsSecurityViewModel(get(), get()) } diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/authentication/AuthenticationViewModel.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/authentication/AuthenticationViewModel.kt index c8114fc8ea5..770fa31c70a 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/authentication/AuthenticationViewModel.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/authentication/AuthenticationViewModel.kt @@ -25,6 +25,7 @@ import androidx.lifecycle.MediatorLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.owncloud.android.MainApp +import com.owncloud.android.R import com.owncloud.android.domain.authentication.oauth.RegisterClientUseCase import com.owncloud.android.domain.authentication.oauth.RequestTokenUseCase import com.owncloud.android.domain.authentication.oauth.model.ClientRegistrationInfo @@ -45,6 +46,7 @@ import com.owncloud.android.domain.webfinger.usecases.GetOwnCloudInstancesFromAu import com.owncloud.android.extensions.ViewModelExt.runUseCaseWithResult import com.owncloud.android.presentation.authentication.oauth.OAuthUtils import com.owncloud.android.presentation.common.UIResult +import com.owncloud.android.providers.ContextProvider import com.owncloud.android.providers.CoroutinesDispatcherProvider import com.owncloud.android.providers.WorkManagerProvider import kotlinx.coroutines.launch @@ -65,6 +67,7 @@ class AuthenticationViewModel( private val requestTokenUseCase: RequestTokenUseCase, private val registerClientUseCase: RegisterClientUseCase, private val coroutinesDispatcherProvider: CoroutinesDispatcherProvider, + private val contextProvider: ContextProvider, ) : ViewModel() { val codeVerifier: String = OAuthUtils().generateRandomCodeVerifier() @@ -99,7 +102,11 @@ class AuthenticationViewModel( showLoading = true, liveData = _serverInfo, useCase = getServerInfoAsyncUseCase, - useCaseParams = GetServerInfoAsyncUseCase.Params(serverPath = serverUrl, creatingAccount = creatingAccount) + useCaseParams = GetServerInfoAsyncUseCase.Params( + serverPath = serverUrl, + creatingAccount = creatingAccount, + secureConnectionEnforced = contextProvider.getBoolean(R.bool.enforce_secure_connection), + ) ) } diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/authentication/LoginActivity.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/authentication/LoginActivity.kt index c7370bd6c0c..2d840415aa1 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/authentication/LoginActivity.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/authentication/LoginActivity.kt @@ -50,6 +50,7 @@ import com.owncloud.android.domain.authentication.oauth.model.ResponseType import com.owncloud.android.domain.authentication.oauth.model.TokenRequest import com.owncloud.android.domain.exceptions.NoNetworkConnectionException import com.owncloud.android.domain.exceptions.OwncloudVersionNotSupportedException +import com.owncloud.android.domain.exceptions.SSLErrorException import com.owncloud.android.domain.exceptions.ServerNotReachableException import com.owncloud.android.domain.exceptions.StateMismatchException import com.owncloud.android.domain.exceptions.UnauthorizedException @@ -272,6 +273,7 @@ class LoginActivity : AppCompatActivity(), SslUntrustedCertDialog.OnSslUntrusted text = getString(R.string.error_no_network_connection) setCompoundDrawablesWithIntrinsicBounds(R.drawable.no_network, 0, 0, 0) } + else -> binding.webfingerStatusText.run { text = uiResult.getThrowableOrNull()?.parseError("", resources, true) setCompoundDrawablesWithIntrinsicBounds(R.drawable.common_error, 0, 0, 0) @@ -355,6 +357,7 @@ class LoginActivity : AppCompatActivity(), SslUntrustedCertDialog.OnSslUntrusted performGetAuthorizationCodeRequest(oidcServerConfiguration.authorizationEndpoint.toUri()) } } + else -> { binding.serverStatusText.run { text = getString(R.string.auth_unsupported_auth_method) @@ -379,14 +382,22 @@ class LoginActivity : AppCompatActivity(), SslUntrustedCertDialog.OnSslUntrusted when (uiResult.error) { is CertificateCombinedException -> showUntrustedCertDialog(uiResult.error) + is OwncloudVersionNotSupportedException -> binding.serverStatusText.run { text = getString(R.string.server_not_supported) setCompoundDrawablesWithIntrinsicBounds(R.drawable.common_error, 0, 0, 0) } + is NoNetworkConnectionException -> binding.serverStatusText.run { text = getString(R.string.error_no_network_connection) setCompoundDrawablesWithIntrinsicBounds(R.drawable.no_network, 0, 0, 0) } + + is SSLErrorException -> binding.serverStatusText.run { + text = getString(R.string.ssl_connection_not_secure) + setCompoundDrawablesWithIntrinsicBounds(R.drawable.common_error, 0, 0, 0) + } + else -> binding.serverStatusText.run { text = uiResult.error?.parseError("", resources, true) setCompoundDrawablesWithIntrinsicBounds(R.drawable.common_error, 0, 0, 0) @@ -430,6 +441,7 @@ class LoginActivity : AppCompatActivity(), SslUntrustedCertDialog.OnSslUntrusted } showOrHideBasicAuthFields(shouldBeVisible = false) } + else -> { binding.serverStatusText.isVisible = false binding.authStatusText.run { @@ -461,6 +473,7 @@ class LoginActivity : AppCompatActivity(), SslUntrustedCertDialog.OnSslUntrusted ) } } + is UIResult.Error -> { Timber.e(uiResult.error, "Client registration failed.") performGetAuthorizationCodeRequest(authorizationEndpoint) @@ -585,6 +598,7 @@ class LoginActivity : AppCompatActivity(), SslUntrustedCertDialog.OnSslUntrusted clientRegistrationInfo = clientRegistrationInfo ) } + is UIResult.Error -> { Timber.e(uiResult.error, "OAuth request to exchange authorization code for tokens failed") updateOAuthStatusIconAndText(uiResult.error) diff --git a/owncloudApp/src/main/res/values/setup.xml b/owncloudApp/src/main/res/values/setup.xml index 4f6d7cd33df..9930ea6728e 100644 --- a/owncloudApp/src/main/res/values/setup.xml +++ b/owncloudApp/src/main/res/values/setup.xml @@ -129,4 +129,8 @@ + + + false + diff --git a/owncloudApp/src/main/res/values/strings.xml b/owncloudApp/src/main/res/values/strings.xml index 7f47a1afe78..a6ca76ab99c 100644 --- a/owncloudApp/src/main/res/values/strings.xml +++ b/owncloudApp/src/main/res/values/strings.xml @@ -405,6 +405,7 @@ Login with oAuth2 Connecting to OAuth2 server… + Connection is not secure, http traffic is not allowed. The identity of the server could not be verified - The server certificate is not trusted - The server certificate expired diff --git a/owncloudDomain/src/main/java/com/owncloud/android/domain/exceptions/SSLErrorException.kt b/owncloudDomain/src/main/java/com/owncloud/android/domain/exceptions/SSLErrorException.kt index b2d94d34bed..3981feaf3c2 100644 --- a/owncloudDomain/src/main/java/com/owncloud/android/domain/exceptions/SSLErrorException.kt +++ b/owncloudDomain/src/main/java/com/owncloud/android/domain/exceptions/SSLErrorException.kt @@ -21,4 +21,4 @@ package com.owncloud.android.domain.exceptions import java.lang.Exception -class SSLErrorException : Exception() +class SSLErrorException(override val message: String? = null) : Exception(message) diff --git a/owncloudDomain/src/main/java/com/owncloud/android/domain/server/usecases/GetServerInfoAsyncUseCase.kt b/owncloudDomain/src/main/java/com/owncloud/android/domain/server/usecases/GetServerInfoAsyncUseCase.kt index 6e1f7f9dca0..8326cb4dca6 100644 --- a/owncloudDomain/src/main/java/com/owncloud/android/domain/server/usecases/GetServerInfoAsyncUseCase.kt +++ b/owncloudDomain/src/main/java/com/owncloud/android/domain/server/usecases/GetServerInfoAsyncUseCase.kt @@ -20,6 +20,7 @@ package com.owncloud.android.domain.server.usecases import com.owncloud.android.domain.BaseUseCaseWithResult +import com.owncloud.android.domain.exceptions.SSLErrorException import com.owncloud.android.domain.server.ServerInfoRepository import com.owncloud.android.domain.server.model.ServerInfo import com.owncloud.android.domain.server.model.ServerInfo.Companion.HTTPS_PREFIX @@ -27,16 +28,21 @@ import com.owncloud.android.domain.server.model.ServerInfo.Companion.HTTP_PREFIX import java.util.Locale class GetServerInfoAsyncUseCase( - private val serverInfoRepository: ServerInfoRepository + private val serverInfoRepository: ServerInfoRepository, ) : BaseUseCaseWithResult() { override fun run(params: Params): ServerInfo { val normalizedServerUrl = normalizeProtocolPrefix(params.serverPath).trimEnd(TRAILING_SLASH) - return serverInfoRepository.getServerInfo(normalizedServerUrl, params.creatingAccount) + val serverInfo = serverInfoRepository.getServerInfo(normalizedServerUrl, params.creatingAccount) + if (!serverInfo.isSecureConnection && params.secureConnectionEnforced) { + throw SSLErrorException("Connection is not secure, http traffic is not allowed.") + } + return serverInfo } data class Params( val serverPath: String, val creatingAccount: Boolean, + val secureConnectionEnforced: Boolean, ) /** From d6a4c0643e8f1577a8f848bbc73beab20c89b57f Mon Sep 17 00:00:00 2001 From: Manuel Plazas Palacio Date: Wed, 26 Jul 2023 13:37:31 +0200 Subject: [PATCH 2/7] Testing the http enforced. --- .../AuthenticationViewModelTest.kt | 5 ++- .../usecases/GetServerInfoAsyncUseCaseTest.kt | 33 ++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/owncloudApp/src/test/java/com/owncloud/android/presentation/viewmodels/authentication/AuthenticationViewModelTest.kt b/owncloudApp/src/test/java/com/owncloud/android/presentation/viewmodels/authentication/AuthenticationViewModelTest.kt index 60813efb16c..2ba4770cbe8 100644 --- a/owncloudApp/src/test/java/com/owncloud/android/presentation/viewmodels/authentication/AuthenticationViewModelTest.kt +++ b/owncloudApp/src/test/java/com/owncloud/android/presentation/viewmodels/authentication/AuthenticationViewModelTest.kt @@ -21,6 +21,7 @@ package com.owncloud.android.presentation.viewmodels.authentication +import com.owncloud.android.R import com.owncloud.android.domain.UseCaseResult import com.owncloud.android.domain.authentication.oauth.RegisterClientUseCase import com.owncloud.android.domain.authentication.oauth.RequestTokenUseCase @@ -125,6 +126,7 @@ class AuthenticationViewModelTest : ViewModelTest() { every { anyConstructed().generateRandomCodeVerifier() } returns "CODE VERIFIER" every { anyConstructed().generateCodeChallenge(any()) } returns "CODE CHALLENGE" every { anyConstructed().generateRandomState() } returns "STATE" + every { contextProvider.getBoolean(R.bool.enforce_secure_connection) } returns false testCoroutineDispatcher.pauseDispatcher() @@ -142,7 +144,8 @@ class AuthenticationViewModelTest : ViewModelTest() { requestTokenUseCase = requestTokenUseCase, registerClientUseCase = registerClientUseCase, workManagerProvider = workManagerProvider, - coroutinesDispatcherProvider = coroutineDispatcherProvider + coroutinesDispatcherProvider = coroutineDispatcherProvider, + contextProvider = contextProvider, ) } diff --git a/owncloudDomain/src/test/java/com/owncloud/android/domain/server/usecases/GetServerInfoAsyncUseCaseTest.kt b/owncloudDomain/src/test/java/com/owncloud/android/domain/server/usecases/GetServerInfoAsyncUseCaseTest.kt index 52fdc5b9a76..db84efae3f9 100644 --- a/owncloudDomain/src/test/java/com/owncloud/android/domain/server/usecases/GetServerInfoAsyncUseCaseTest.kt +++ b/owncloudDomain/src/test/java/com/owncloud/android/domain/server/usecases/GetServerInfoAsyncUseCaseTest.kt @@ -18,8 +18,10 @@ */ package com.owncloud.android.domain.server.usecases +import com.owncloud.android.domain.exceptions.SSLErrorException import com.owncloud.android.domain.server.ServerInfoRepository import com.owncloud.android.domain.server.usecases.GetServerInfoAsyncUseCase.Companion.TRAILING_SLASH +import com.owncloud.android.testutil.OC_INSECURE_SERVER_INFO_BASIC_AUTH import com.owncloud.android.testutil.OC_SECURE_SERVER_INFO_BASIC_AUTH import io.mockk.every import io.mockk.spyk @@ -32,7 +34,11 @@ class GetServerInfoAsyncUseCaseTest { private val repository: ServerInfoRepository = spyk() private val useCase = GetServerInfoAsyncUseCase((repository)) - private val useCaseParams = GetServerInfoAsyncUseCase.Params(serverPath = "http://demo.owncloud.com", false) + private val useCaseParams = GetServerInfoAsyncUseCase.Params( + serverPath = "http://demo.owncloud.com", + creatingAccount = false, + secureConnectionEnforced = false, + ) private val useCaseParamsWithSlash = useCaseParams.copy(serverPath = useCaseParams.serverPath.plus(TRAILING_SLASH)) @Test @@ -70,4 +76,29 @@ class GetServerInfoAsyncUseCaseTest { verify(exactly = 1) { repository.getServerInfo(useCaseParams.serverPath, false) } } + + @Test + fun `Should throw SSLErrorException when secureConnectionEnforced is true and ServerInfoRepository returns ServerInfo with isSecureConnection returning false`(){ + every { repository.getServerInfo(useCaseParams.serverPath, false) } returns OC_INSECURE_SERVER_INFO_BASIC_AUTH + + val useCaseResult = useCase.execute(useCaseParams.copy(secureConnectionEnforced = true)) + + assertTrue(useCaseResult.isError) + assertTrue(useCaseResult.getThrowableOrNull() is SSLErrorException) + + verify(exactly = 1) { repository.getServerInfo(useCaseParams.serverPath, false) } + } + + @Test + fun `Should work correctly when secureConnectionEnforced is true and ServerInfoRepository returns ServerInfo with isSecureConnection returning true`(){ + every { repository.getServerInfo(useCaseParams.serverPath, false) } returns OC_SECURE_SERVER_INFO_BASIC_AUTH + + val useCaseResult = useCase.execute(useCaseParams.copy(secureConnectionEnforced = true)) + + assertTrue(useCaseResult.isSuccess) + assertEquals(OC_SECURE_SERVER_INFO_BASIC_AUTH, useCaseResult.getDataOrNull()) + + verify(exactly = 1) { repository.getServerInfo(useCaseParams.serverPath, false) } + } + } From a2e9b4935520ae696db92e207ba7fee26b0f2172 Mon Sep 17 00:00:00 2001 From: Manuel Plazas Palacio Date: Wed, 26 Jul 2023 13:55:43 +0200 Subject: [PATCH 3/7] Solving klint bugs. --- .../server/usecases/GetServerInfoAsyncUseCaseTest.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/owncloudDomain/src/test/java/com/owncloud/android/domain/server/usecases/GetServerInfoAsyncUseCaseTest.kt b/owncloudDomain/src/test/java/com/owncloud/android/domain/server/usecases/GetServerInfoAsyncUseCaseTest.kt index db84efae3f9..c5727975bfd 100644 --- a/owncloudDomain/src/test/java/com/owncloud/android/domain/server/usecases/GetServerInfoAsyncUseCaseTest.kt +++ b/owncloudDomain/src/test/java/com/owncloud/android/domain/server/usecases/GetServerInfoAsyncUseCaseTest.kt @@ -78,8 +78,8 @@ class GetServerInfoAsyncUseCaseTest { } @Test - fun `Should throw SSLErrorException when secureConnectionEnforced is true and ServerInfoRepository returns ServerInfo with isSecureConnection returning false`(){ - every { repository.getServerInfo(useCaseParams.serverPath, false) } returns OC_INSECURE_SERVER_INFO_BASIC_AUTH + fun `Should throw SSLErrorException when secureConnectionEnforced is true and ServerInfoRepository returns ServerInfo with isSecureConnection returning false`() { + every { repository.getServerInfo(useCaseParams.serverPath, false) } returns OC_INSECURE_SERVER_INFO_BASIC_AUTH val useCaseResult = useCase.execute(useCaseParams.copy(secureConnectionEnforced = true)) @@ -90,8 +90,8 @@ class GetServerInfoAsyncUseCaseTest { } @Test - fun `Should work correctly when secureConnectionEnforced is true and ServerInfoRepository returns ServerInfo with isSecureConnection returning true`(){ - every { repository.getServerInfo(useCaseParams.serverPath, false) } returns OC_SECURE_SERVER_INFO_BASIC_AUTH + fun `Should work correctly when secureConnectionEnforced is true and ServerInfoRepository returns ServerInfo with isSecureConnection returning true`() { + every { repository.getServerInfo(useCaseParams.serverPath, false) } returns OC_SECURE_SERVER_INFO_BASIC_AUTH val useCaseResult = useCase.execute(useCaseParams.copy(secureConnectionEnforced = true)) From 59cb2a30c5643bc371eaf23a78561cc564a66225 Mon Sep 17 00:00:00 2001 From: Manuel Plazas Palacio Date: Wed, 26 Jul 2023 14:07:10 +0200 Subject: [PATCH 4/7] Added calens file. --- changelog/unreleased/4110 | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 changelog/unreleased/4110 diff --git a/changelog/unreleased/4110 b/changelog/unreleased/4110 new file mode 100644 index 00000000000..6fa55b21cb1 --- /dev/null +++ b/changelog/unreleased/4110 @@ -0,0 +1,6 @@ +Enhancement: Prevent http traffic with branding options + +Adding branding option for prevent http traffic. + +https://github.com/owncloud/android/issues/4066 +https://github.com/owncloud/android/pull/4110 \ No newline at end of file From 91baa0ca846c7785e84a0b16a882d7fe449e14bb Mon Sep 17 00:00:00 2001 From: manuelplazaspalacio Date: Wed, 26 Jul 2023 12:07:50 +0000 Subject: [PATCH 5/7] Calens changelog updated --- CHANGELOG.md | 39 +++++---------------------------------- 1 file changed, 5 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c58b91e05a3..8019ee64e66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,15 +14,12 @@ Summary * Change - Move file menu options filter to use case: [#4009](https://github.com/owncloud/android/issues/4009) * Change - Gradle Version Catalog: [#4035](https://github.com/owncloud/android/pull/4035) * Change - Remove "ignore" from the debug flavour Android manifest: [#4064](https://github.com/owncloud/android/pull/4064) -* Change - Not opening browser automatically in login: [#4067](https://github.com/owncloud/android/issues/4067) -* Change - Added new unit tests for providers: [#4073](https://github.com/owncloud/android/issues/4073) * Enhancement - Show "More" button for every file list item: [#2885](https://github.com/owncloud/android/issues/2885) * Enhancement - Added "Open in web" options to main file list: [#3860](https://github.com/owncloud/android/issues/3860) * Enhancement - Copy/move conflict solved by users: [#3935](https://github.com/owncloud/android/issues/3935) * Enhancement - Improve grid mode: [#4027](https://github.com/owncloud/android/issues/4027) -* Enhancement - Improve UX of creation dialog: [#4031](https://github.com/owncloud/android/issues/4031) * Enhancement - File name conflict starting by (1): [#4040](https://github.com/owncloud/android/pull/4040) -* Enhancement - Support "per app" language change on Android 13+: [#4082](https://github.com/owncloud/android/issues/4082) +* Enhancement - Prevent http traffic with branding options: [#4066](https://github.com/owncloud/android/issues/4066) Details ------- @@ -74,23 +71,6 @@ Details https://github.com/owncloud/android/pull/4064 -* Change - Not opening browser automatically in login: [#4067](https://github.com/owncloud/android/issues/4067) - - When there is a fixed bearer auth server URL via a branded parameter, the login screen won't - redirect automatically to the browser so that some problems in the authentication flow are - solved. - - https://github.com/owncloud/android/issues/4067 - https://github.com/owncloud/android/pull/4106 - -* Change - Added new unit tests for providers: [#4073](https://github.com/owncloud/android/issues/4073) - - Implementation of tests for the functions within ScopedStorageProvider and - OCSharedPreferencesProvider. - - https://github.com/owncloud/android/issues/4073 - https://github.com/owncloud/android/pull/4091 - * Enhancement - Show "More" button for every file list item: [#2885](https://github.com/owncloud/android/issues/2885) A 3-dot button has been added to every file, where the options that we have in the 3-dot menu in @@ -123,14 +103,6 @@ Details https://github.com/owncloud/android/issues/4027 https://github.com/owncloud/android/pull/4089 -* Enhancement - Improve UX of creation dialog: [#4031](https://github.com/owncloud/android/issues/4031) - - Creation dialog now shows an error message and disables the confirmation button when - forbidden characters are typed - - https://github.com/owncloud/android/issues/4031 - https://github.com/owncloud/android/pull/4097 - * Enhancement - File name conflict starting by (1): [#4040](https://github.com/owncloud/android/pull/4040) File conflicts now are named with suffix starting in (1) instead of (2). @@ -138,13 +110,12 @@ Details https://github.com/owncloud/android/issues/3946 https://github.com/owncloud/android/pull/4040 -* Enhancement - Support "per app" language change on Android 13+: [#4082](https://github.com/owncloud/android/issues/4082) +* Enhancement - Prevent http traffic with branding options: [#4066](https://github.com/owncloud/android/issues/4066) - The locales_config.xml file has been created for the application to detect the language that - the user wishes to choose. + Adding branding option for prevent http traffic. - https://github.com/owncloud/android/issues/4082 - https://github.com/owncloud/android/pull/4099 + https://github.com/owncloud/android/issues/4066 + https://github.com/owncloud/android/pull/4110 Changelog for ownCloud Android Client [4.0.0] (2023-05-29) ======================================= From 7ba114f72d4facf2119f95b4e15f9f28f816660a Mon Sep 17 00:00:00 2001 From: manuelplazaspalacio Date: Mon, 31 Jul 2023 06:18:43 +0000 Subject: [PATCH 6/7] Calens changelog updated --- CHANGELOG.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8019ee64e66..e20ce53a3bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,12 +14,14 @@ Summary * Change - Move file menu options filter to use case: [#4009](https://github.com/owncloud/android/issues/4009) * Change - Gradle Version Catalog: [#4035](https://github.com/owncloud/android/pull/4035) * Change - Remove "ignore" from the debug flavour Android manifest: [#4064](https://github.com/owncloud/android/pull/4064) +* Change - Added new unit tests for providers: [#4073](https://github.com/owncloud/android/issues/4073) * Enhancement - Show "More" button for every file list item: [#2885](https://github.com/owncloud/android/issues/2885) * Enhancement - Added "Open in web" options to main file list: [#3860](https://github.com/owncloud/android/issues/3860) * Enhancement - Copy/move conflict solved by users: [#3935](https://github.com/owncloud/android/issues/3935) * Enhancement - Improve grid mode: [#4027](https://github.com/owncloud/android/issues/4027) * Enhancement - File name conflict starting by (1): [#4040](https://github.com/owncloud/android/pull/4040) * Enhancement - Prevent http traffic with branding options: [#4066](https://github.com/owncloud/android/issues/4066) +* Enhancement - Support "per app" language change on Android 13+: [#4082](https://github.com/owncloud/android/issues/4082) Details ------- @@ -71,6 +73,14 @@ Details https://github.com/owncloud/android/pull/4064 +* Change - Added new unit tests for providers: [#4073](https://github.com/owncloud/android/issues/4073) + + Implementation of tests for the functions within ScopedStorageProvider and + OCSharedPreferencesProvider. + + https://github.com/owncloud/android/issues/4073 + https://github.com/owncloud/android/pull/4091 + * Enhancement - Show "More" button for every file list item: [#2885](https://github.com/owncloud/android/issues/2885) A 3-dot button has been added to every file, where the options that we have in the 3-dot menu in @@ -117,6 +127,14 @@ Details https://github.com/owncloud/android/issues/4066 https://github.com/owncloud/android/pull/4110 +* Enhancement - Support "per app" language change on Android 13+: [#4082](https://github.com/owncloud/android/issues/4082) + + The locales_config.xml file has been created for the application to detect the language that + the user wishes to choose. + + https://github.com/owncloud/android/issues/4082 + https://github.com/owncloud/android/pull/4099 + Changelog for ownCloud Android Client [4.0.0] (2023-05-29) ======================================= The following sections list the changes in ownCloud Android Client 4.0.0 relevant to From 039361995619c27c57046ae249ed6bb778aa9383 Mon Sep 17 00:00:00 2001 From: manuelplazaspalacio Date: Tue, 1 Aug 2023 06:15:08 +0000 Subject: [PATCH 7/7] Calens changelog updated --- CHANGELOG.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e20ce53a3bc..60675f6a75b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,11 +14,13 @@ Summary * Change - Move file menu options filter to use case: [#4009](https://github.com/owncloud/android/issues/4009) * Change - Gradle Version Catalog: [#4035](https://github.com/owncloud/android/pull/4035) * Change - Remove "ignore" from the debug flavour Android manifest: [#4064](https://github.com/owncloud/android/pull/4064) +* Change - Not opening browser automatically in login: [#4067](https://github.com/owncloud/android/issues/4067) * Change - Added new unit tests for providers: [#4073](https://github.com/owncloud/android/issues/4073) * Enhancement - Show "More" button for every file list item: [#2885](https://github.com/owncloud/android/issues/2885) * Enhancement - Added "Open in web" options to main file list: [#3860](https://github.com/owncloud/android/issues/3860) * Enhancement - Copy/move conflict solved by users: [#3935](https://github.com/owncloud/android/issues/3935) * Enhancement - Improve grid mode: [#4027](https://github.com/owncloud/android/issues/4027) +* Enhancement - Improve UX of creation dialog: [#4031](https://github.com/owncloud/android/issues/4031) * Enhancement - File name conflict starting by (1): [#4040](https://github.com/owncloud/android/pull/4040) * Enhancement - Prevent http traffic with branding options: [#4066](https://github.com/owncloud/android/issues/4066) * Enhancement - Support "per app" language change on Android 13+: [#4082](https://github.com/owncloud/android/issues/4082) @@ -73,6 +75,15 @@ Details https://github.com/owncloud/android/pull/4064 +* Change - Not opening browser automatically in login: [#4067](https://github.com/owncloud/android/issues/4067) + + When there is a fixed bearer auth server URL via a branded parameter, the login screen won't + redirect automatically to the browser so that some problems in the authentication flow are + solved. + + https://github.com/owncloud/android/issues/4067 + https://github.com/owncloud/android/pull/4106 + * Change - Added new unit tests for providers: [#4073](https://github.com/owncloud/android/issues/4073) Implementation of tests for the functions within ScopedStorageProvider and @@ -113,6 +124,14 @@ Details https://github.com/owncloud/android/issues/4027 https://github.com/owncloud/android/pull/4089 +* Enhancement - Improve UX of creation dialog: [#4031](https://github.com/owncloud/android/issues/4031) + + Creation dialog now shows an error message and disables the confirmation button when + forbidden characters are typed + + https://github.com/owncloud/android/issues/4031 + https://github.com/owncloud/android/pull/4097 + * Enhancement - File name conflict starting by (1): [#4040](https://github.com/owncloud/android/pull/4040) File conflicts now are named with suffix starting in (1) instead of (2).