Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 798ada16 authored by Mohammed Althaf T's avatar Mohammed Althaf T 😊
Browse files

Allow to override oicd values

parent 1649dff3
Loading
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -125,6 +125,30 @@ enum class IdentityProvider(
        }
    }

    fun getClientId(context: Context): String {
        return if (this == MURENA) {
            MurenaServerConfig.getClientId(context)
        } else {
            clientId
        }
    }

    fun getRedirectUri(context: Context): Uri {
        return if (this == MURENA) {
            retrieveUri(MurenaServerConfig.getRedirectUri(context)) ?: redirectUri
        } else {
            redirectUri
        }
    }

    fun getLogoutRedirectUri(context: Context): Uri? {
        return if (this == MURENA) {
            retrieveUri(MurenaServerConfig.getLogoutRedirectUri(context)) ?: logoutRedirectUri
        } else {
            logoutRedirectUri
        }
    }

    private fun getDiscoveryEndpoint(context: Context): Uri? {
        return if (this == MURENA) {
            retrieveUri(MurenaServerConfig.getDiscoveryUrl(context))
+4 −0
Original line number Diff line number Diff line
@@ -21,6 +21,10 @@ object Settings {
    const val PROXY_HOST = "proxy_host"         // String
    const val PROXY_PORT = "proxy_port"         // Integer

    const val MURENA_CLIENT_ID_OVERRIDE = "murena_client_id_override"
    const val MURENA_BASE_URL_PRODUCTION_OVERRIDE = "murena_base_url_production_override"
    const val MURENA_DISCOVERY_END_POINT_PRODUCTION_OVERRIDE = "murena_discovery_end_point_production_override"

    /**
     * Whether to ignore VPNs at internet connection detection, true by default because VPN connections
     * seem to include "VALIDATED" by default even without actual internet connection
+4 −5
Original line number Diff line number Diff line
@@ -8,10 +8,10 @@ import android.accounts.Account
import android.accounts.AccountManager
import android.content.Context
import android.os.Bundle
import at.bitfire.davdroid.BuildConfig
import at.bitfire.davdroid.R
import at.bitfire.davdroid.log.Logger
import at.bitfire.davdroid.settings.AccountSettings
import at.bitfire.davdroid.util.MurenaServerConfig
import at.bitfire.davdroid.util.setAndVerifyUserData
import com.owncloud.android.lib.common.accounts.AccountUtils.Constants

@@ -173,10 +173,9 @@ object AccountUtils {
            accountManager.getUserData(account, Constants.KEY_OC_BASE_URL) ?: return false

        val baseUrl = extractBaseUrl(urlData)
        val murenaBaseUrls = setOf(
            extractBaseUrl(BuildConfig.MURENA_BASE_URL_PRODUCTION),
            extractBaseUrl(BuildConfig.MURENA_BASE_URL_STAGING),
        )
        val murenaBaseUrls = MurenaServerConfig.getBaseUrls(context)
            .map(::extractBaseUrl)
            .toSet()

        // User can have their own Murena account set up with custom Nextcloud instance,
        // so a check for base URL is necessary.
+76 −0
Original line number Diff line number Diff line
@@ -38,15 +38,28 @@ import at.bitfire.davdroid.R
import at.bitfire.davdroid.databinding.FragmentEeloAuthenticatorBinding
import at.bitfire.davdroid.db.Credentials
import at.bitfire.davdroid.murenasso.MurenaSsoMigrationPreferences
import at.bitfire.davdroid.settings.Settings
import at.bitfire.davdroid.settings.SettingsManager
import at.bitfire.davdroid.ui.ShowUrlActivity
import at.bitfire.davdroid.ui.account.SettingsActivity
import at.bitfire.davdroid.util.MurenaServerConfig
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import dagger.hilt.EntryPoint
import dagger.hilt.InstallIn
import dagger.hilt.android.EntryPointAccessors
import dagger.hilt.components.SingletonComponent
import java.net.URI

class EeloAuthenticatorFragment : Fragment() {

    @EntryPoint
    @InstallIn(SingletonComponent::class)
    interface EeloAuthenticatorFragmentEntryPoint {
        fun settingsManager(): SettingsManager
    }

    private val model by viewModels<EeloAuthenticatorModel>()
    private val loginModel by activityViewModels<LoginModel>()

@@ -59,6 +72,17 @@ class EeloAuthenticatorFragment : Fragment() {
    private lateinit var serverUrlEditText: TextInputEditText
    private lateinit var passwordEditText: TextInputEditText
    private lateinit var passwordHolder: View
    private lateinit var murenaIdpOverrideContainer: View
    private lateinit var murenaClientIdEditText: TextInputEditText
    private lateinit var murenaBaseUrlEditText: TextInputEditText
    private lateinit var murenaDiscoveryEndpointEditText: TextInputEditText

    private val settings by lazy {
        EntryPointAccessors.fromApplication(
            requireContext(),
            EeloAuthenticatorFragmentEntryPoint::class.java
        ).settingsManager()
    }

    private val isReAuthenticating by lazy {
        requireActivity().intent.getBooleanExtra(SettingsActivity.EXTRA_IS_RE_AUTHENTICATING, false)
@@ -88,17 +112,24 @@ class EeloAuthenticatorFragment : Fragment() {
        serverUrlEditText = v.root.findViewById(R.id.urlpwd_server_uri)
        passwordEditText = v.root.findViewById(R.id.urlpwd_password)
        passwordHolder = v.root.findViewById(R.id.password_holder)
        murenaIdpOverrideContainer = v.root.findViewById(R.id.murena_idp_override_container)
        murenaClientIdEditText = v.root.findViewById(R.id.murena_client_id_override)
        murenaBaseUrlEditText = v.root.findViewById(R.id.murena_base_url_production_override)
        murenaDiscoveryEndpointEditText = v.root.findViewById(R.id.murena_discovery_end_point_production_override)

        passwordHolder.isVisible = !EeloAuthenticatorModel.ENABLE_OIDC_SUPPORT

        serverToggleButton.setOnClickListener { expandCollapse() }

        v.root.findViewById<View>(R.id.sign_in).setOnClickListener { login() }
        v.root.findViewById<View>(R.id.murena_idp_reset_button).setOnClickListener { resetMurenaOverrides() }

        val tfaButton = v.root.findViewById<View>(R.id.twofa_info_button)
        tfaButton.setOnClickListener { show2FAInfoDialog() }
        tfaButton.isVisible = !EeloAuthenticatorModel.ENABLE_OIDC_SUPPORT

        loadMurenaOverrides()

        userIdEditText.doOnTextChanged { text, _, _, _ ->
            val domain = computeDomain(text)
            if (domain.isEmpty()) {
@@ -119,10 +150,13 @@ class EeloAuthenticatorFragment : Fragment() {
            serverToggleButton.setCompoundDrawablesWithIntrinsicBounds(null, null , ContextCompat.getDrawable(requireContext(), R.drawable.ic_expand_less), null)
            serverUrlEditTextLayout.visibility = View.VISIBLE
            serverUrlEditText.isEnabled = true
            murenaIdpOverrideContainer.visibility = View.GONE
            passwordHolder.visibility = View.VISIBLE
        } else {
            serverToggleButton.setCompoundDrawablesWithIntrinsicBounds(null, null , ContextCompat.getDrawable(requireContext(), R.drawable.ic_expand_more), null)
            serverUrlEditTextLayout.visibility = View.GONE
            serverUrlEditText.isEnabled = false
            murenaIdpOverrideContainer.visibility = View.VISIBLE
        }
        return v.root
    }
@@ -229,6 +263,9 @@ class EeloAuthenticatorFragment : Fragment() {

    private fun login() {
        handleNoNetworkAvailable()
        if (!persistMurenaOverrides()) {
            return
        }

        val handleOpenIdAuth = EeloAuthenticatorModel.ENABLE_OIDC_SUPPORT && !toggleButtonState
        val userId = userIdEditText.text.toString()
@@ -328,6 +365,7 @@ class EeloAuthenticatorFragment : Fragment() {
            serverToggleButton.setCompoundDrawablesWithIntrinsicBounds(null, null , ContextCompat.getDrawable(requireContext(), R.drawable.ic_expand_less), null)
            serverUrlEditTextLayout.visibility = View.VISIBLE
            serverUrlEditText.isEnabled = true
            murenaIdpOverrideContainer.visibility = View.GONE
            toggleButtonState = true

            passwordHolder.visibility = View.VISIBLE
@@ -335,6 +373,7 @@ class EeloAuthenticatorFragment : Fragment() {
            serverToggleButton.setCompoundDrawablesWithIntrinsicBounds(null, null , ContextCompat.getDrawable(requireContext(), R.drawable.ic_expand_more), null)
            serverUrlEditTextLayout.visibility = View.GONE
            serverUrlEditText.isEnabled = false
            murenaIdpOverrideContainer.visibility = View.VISIBLE
            toggleButtonState = false

            if(!EeloAuthenticatorModel.ENABLE_OIDC_SUPPORT) {
@@ -358,4 +397,41 @@ class EeloAuthenticatorFragment : Fragment() {
            .show()

    }

    private fun loadMurenaOverrides() {
        murenaClientIdEditText.setText(settings.getString(Settings.MURENA_CLIENT_ID_OVERRIDE) ?: MurenaServerConfig.defaultClientId())
        murenaBaseUrlEditText.setText(settings.getString(Settings.MURENA_BASE_URL_PRODUCTION_OVERRIDE) ?: MurenaServerConfig.defaultProductionBaseUrl())
        murenaDiscoveryEndpointEditText.setText(settings.getString(Settings.MURENA_DISCOVERY_END_POINT_PRODUCTION_OVERRIDE) ?: MurenaServerConfig.defaultProductionDiscoveryUrl())
    }

    private fun persistMurenaOverrides(): Boolean {
        val clientId = murenaClientIdEditText.text?.toString()?.trim().orEmpty()
        val baseUrl = murenaBaseUrlEditText.text?.toString()?.trim().orEmpty()
        val discoveryUrl = murenaDiscoveryEndpointEditText.text?.toString()?.trim().orEmpty()

        if (clientId.isBlank()) {
            Toast.makeText(context, R.string.app_settings_murena_client_id, Toast.LENGTH_LONG).show()
            return false
        }

        persistOverride(Settings.MURENA_CLIENT_ID_OVERRIDE, clientId, MurenaServerConfig.defaultClientId())
        persistOverride(Settings.MURENA_BASE_URL_PRODUCTION_OVERRIDE, baseUrl, MurenaServerConfig.defaultProductionBaseUrl())
        persistOverride(Settings.MURENA_DISCOVERY_END_POINT_PRODUCTION_OVERRIDE, discoveryUrl, MurenaServerConfig.defaultProductionDiscoveryUrl())
        return true
    }

    private fun persistOverride(key: String, value: String, defaultValue: String) {
        if (value == defaultValue) {
            settings.remove(key)
        } else {
            settings.putString(key, value)
        }
    }

    private fun resetMurenaOverrides() {
        settings.remove(Settings.MURENA_CLIENT_ID_OVERRIDE)
        settings.remove(Settings.MURENA_BASE_URL_PRODUCTION_OVERRIDE)
        settings.remove(Settings.MURENA_DISCOVERY_END_POINT_PRODUCTION_OVERRIDE)
        loadMurenaOverrides()
    }
}
+3 −2
Original line number Diff line number Diff line
@@ -95,14 +95,15 @@ class OpenIdAuthenticationViewModel @Inject constructor(
        intent: Intent
    ) {
        authState = AuthState(serviceConfiguration)
        val context = getApplication<Application>()

        val loginHint = intent.getStringExtra(LoginActivity.USERNAME_HINT)

        val authRequest = AuthorizationRequest.Builder(
            serviceConfiguration,
            identityProvider!!.clientId,
            identityProvider!!.getClientId(context),
            ResponseTypeValues.CODE,
            identityProvider!!.redirectUri
            identityProvider!!.getRedirectUri(context)
        )
            .setScope(identityProvider!!.scope)
            .setLoginHint(sanitizeHint(loginHint))
Loading