Commit ce1707bd authored by Sumit Pundir's avatar Sumit Pundir
Browse files

ui: eelo: distinguish b/w custom servers based on /e/ and others



Custom/Self-hosted based servers like pure NextCloud based and others do not have
mail server hosting sevices and syncing for their mail servers crashes the mail
application so distinguish and turn off syncs for them unlike /e/ based
custom servers which also implements a corresponding mail server with it.

Also, fix indentation for files.
Signed-off-by: default avatarSumit Pundir <pundirsumit11@gmail.com>
parent 1f14eef2
Pipeline #51048 canceled with stage
in 13 seconds
......@@ -14,14 +14,15 @@ import java.net.URI
class Credentials(
val userName: String? = null,
val password: String? = null,
val authState: AuthState? = null,
val authState: AuthState? = null,
val certificateAlias: String? = null,
val serverUri: URI? = null
val serverUri: URI? = null,
val isTypeEelo: Boolean = true
) {
enum class Type {
UsernamePassword,
OAuth,
OAuth,
ClientCertificate
}
......@@ -31,7 +32,7 @@ class Credentials(
type = when {
!certificateAlias.isNullOrEmpty() ->
Type.ClientCertificate
!userName.isNullOrEmpty() && (authState != null) ->
!userName.isNullOrEmpty() && (authState != null) ->
Type.OAuth
!userName.isNullOrEmpty() && !password.isNullOrEmpty() ->
Type.UsernamePassword
......
......@@ -61,7 +61,7 @@ class AccountDetailsFragment: Fragment() {
val config = loginModel.configuration ?: throw IllegalStateException()
model.name.value = loginModel.credentials?.userName ?:
config.calDAV?.email ?:
config.calDAV?.email ?:
loginModel.credentials?.certificateAlias
// CardDAV-specific
......@@ -89,15 +89,15 @@ class AccountDetailsFragment: Fragment() {
v.createAccount.visibility = View.GONE
model.createAccount(
activity!!,
activity!!,
name,
loginModel.credentials!!,
config,
GroupMethod.valueOf(groupMethodName)
).observe(this, Observer<Boolean> { success ->
if (success)
requireActivity().finish()
else {
if (success)
requireActivity().finish()
else {
Snackbar.make(requireActivity().findViewById(android.R.id.content), R.string.login_account_not_created, Snackbar.LENGTH_LONG).show()
v.createAccountProgress.visibility = View.GONE
......@@ -119,30 +119,30 @@ class AccountDetailsFragment: Fragment() {
} else
v.contactGroupMethod.isEnabled = true
if (activity!!.intent.getStringExtra(LoginActivity.SETUP_ACCOUNT_PROVIDER_TYPE) == LoginActivity.ACCOUNT_PROVIDER_EELO ||
if (activity!!.intent.getStringExtra(LoginActivity.SETUP_ACCOUNT_PROVIDER_TYPE) == LoginActivity.ACCOUNT_PROVIDER_EELO ||
activity!!.intent.getStringExtra(LoginActivity.SETUP_ACCOUNT_PROVIDER_TYPE) == LoginActivity.ACCOUNT_PROVIDER_GOOGLE) {
val name = model.name.value
val name = model.name.value
if (name.isNullOrBlank())
model.nameError.value = getString(R.string.login_account_name_required)
else {
val idx = v.contactGroupMethod.selectedItemPosition
val idx = v.contactGroupMethod.selectedItemPosition
val groupMethodName = resources.getStringArray(R.array.settings_contact_group_method_values)[idx]
model.createAccount(
activity!!,
model.createAccount(
activity!!,
name,
loginModel.credentials!!,
config,
config,
GroupMethod.valueOf(groupMethodName)
).observe(this, Observer<Boolean> { success ->
if (success) {
Toast.makeText(context, "Added account successfully", Toast.LENGTH_LONG).show()
requireActivity().setResult(Activity.RESULT_OK)
requireActivity().finish()
if (activity!!.intent.hasExtra(AccountManager
.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE) && activity!!.intent
.getParcelableExtra<AccountAuthenticatorResponse>(AccountManager
.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE) != null) {
Toast.makeText(context, "Added account successfully", Toast.LENGTH_LONG).show()
requireActivity().setResult(Activity.RESULT_OK)
requireActivity().finish()
if (activity!!.intent.hasExtra(AccountManager
.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE) && activity!!.intent
.getParcelableExtra<AccountAuthenticatorResponse>(AccountManager
.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE) != null) {
activity!!.intent
.getParcelableExtra<AccountAuthenticatorResponse>(AccountManager
.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE).onResult(null)
......@@ -155,7 +155,7 @@ class AccountDetailsFragment: Fragment() {
intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, getString(R.string.eelo_account_type))
activity!!.startService(intent)
}
}
}
})
}
}
......@@ -175,24 +175,24 @@ class AccountDetailsFragment: Fragment() {
val result = MutableLiveData<Boolean>()
val context = getApplication<Application>()
thread {
var accountType = context!!.getString(R.string.account_type)
var addressBookAccountType = context!!.getString(R.string.account_type_address_book)
var baseURL : String? = null
if (config.calDAV != null) {
baseURL = config.calDAV.principal.toString()
}
when (activity!!.intent.getStringExtra(LoginActivity.SETUP_ACCOUNT_PROVIDER_TYPE)) {
LoginActivity.ACCOUNT_PROVIDER_EELO -> {
var accountType = context!!.getString(R.string.account_type)
var addressBookAccountType = context!!.getString(R.string.account_type_address_book)
var baseURL : String? = null
if (config.calDAV != null) {
baseURL = config.calDAV.principal.toString()
}
when (activity!!.intent.getStringExtra(LoginActivity.SETUP_ACCOUNT_PROVIDER_TYPE)) {
LoginActivity.ACCOUNT_PROVIDER_EELO -> {
accountType = context!!.getString(R.string.eelo_account_type)
addressBookAccountType = context!!.getString(R.string.account_type_eelo_address_book)
baseURL = credentials.serverUri.toString()
addressBookAccountType = context!!.getString(R.string.account_type_eelo_address_book)
baseURL = credentials.serverUri.toString()
}
LoginActivity.ACCOUNT_PROVIDER_GOOGLE -> {
accountType = context!!.getString(R.string.google_account_type)
addressBookAccountType = context!!.getString(R.string.account_type_google_address_book)
baseURL = null
addressBookAccountType = context!!.getString(R.string.account_type_google_address_book)
baseURL = null
}
}
......@@ -203,35 +203,43 @@ class AccountDetailsFragment: Fragment() {
Logger.log.log(Level.INFO, "Creating Android account with initial config", arrayOf(account, userData))
val accountManager = AccountManager.get(context)
if (!accountManager.addAccountExplicitly(account, credentials.password, userData)) {
if (!accountManager.addAccountExplicitly(account, credentials.password, userData)) {
if (accountType == context.getString(R.string.google_account_type)) {
for (googleAccount in accountManager.getAccountsByType(context.getString(
R.string.google_account_type))) {
if (userData.get(AccountSettings.KEY_EMAIL_ADDRESS) == accountManager
.getUserData(account, AccountSettings.KEY_EMAIL_ADDRESS)) {
accountManager.setUserData(googleAccount, AccountSettings.KEY_AUTH_STATE,
userData.getString(AccountSettings.KEY_AUTH_STATE))
}
}
}
else {
for (googleAccount in accountManager.getAccountsByType(context.getString(
R.string.google_account_type))) {
if (userData.get(AccountSettings.KEY_EMAIL_ADDRESS) == accountManager
.getUserData(account, AccountSettings.KEY_EMAIL_ADDRESS)) {
accountManager.setUserData(googleAccount, AccountSettings.KEY_AUTH_STATE,
userData.getString(AccountSettings.KEY_AUTH_STATE))
}
}
}
else {
return@thread
}
}
if (!credentials.authState?.accessToken.isNullOrEmpty()) {
accountManager.setAuthToken(account, Constants.AUTH_TOKEN_TYPE, credentials.authState!!.accessToken)
}
if (!credentials.password.isNullOrEmpty()) {
accountManager.setPassword(account, credentials.password)
}
ContentResolver.setSyncAutomatically(account, context.getString(R.string.notes_authority), true)
ContentResolver.setSyncAutomatically(account, context.getString(R.string.email_authority), true)
ContentResolver.setSyncAutomatically(account, context.getString(R.string.media_authority), true)
ContentResolver.setSyncAutomatically(account, context.getString(R.string.app_data_authority), true)
}
}
if (!credentials.authState?.accessToken.isNullOrEmpty()) {
accountManager.setAuthToken(account, Constants.AUTH_TOKEN_TYPE, credentials.authState!!.accessToken)
}
if (!credentials.password.isNullOrEmpty()) {
accountManager.setPassword(account, credentials.password)
}
ContentResolver.setSyncAutomatically(account, context.getString(R.string.notes_authority), true)
/**
* Set Mail sync for custom servers not based on /e/ to be not syncable.
*/
if (!credentials.isTypeEelo)
ContentResolver.setIsSyncable(account, context.getString(R.string.email_authority), 0)
else
ContentResolver.setSyncAutomatically(account, context.getString(R.string.email_authority), true)
ContentResolver.setSyncAutomatically(account, context.getString(R.string.media_authority), true)
ContentResolver.setSyncAutomatically(account, context.getString(R.string.app_data_authority), true)
// add entries for account to service DB
Logger.log.log(Level.INFO, "Writing account configuration to database", config)
......@@ -292,9 +300,9 @@ class AccountDetailsFragment: Fragment() {
}
private fun insertService(db: AppDatabase, accountName: String, authState: String?, accountType: String, addressBookAccountType: String, type: String, info: DavResourceFinder.Configuration.ServiceInfo): Long {
// insert service
val service = Service(0, accountName, authState, accountType, addressBookAccountType, type, info.principal)
val serviceId = db.serviceDao().insertOrReplace(service)
// insert service
val service = Service(0, accountName, authState, accountType, addressBookAccountType, type, info.principal)
val serviceId = db.serviceDao().insertOrReplace(service)
// insert home sets
val homeSetDao = db.homeSetDao()
......@@ -309,7 +317,7 @@ class AccountDetailsFragment: Fragment() {
collectionDao.insertOrReplace(collection)
}
return serviceId
return serviceId
}
}
......
......@@ -10,6 +10,8 @@ import android.view.ViewGroup
import android.widget.Toast
import android.net.Uri
import android.net.ConnectivityManager
import android.text.method.LinkMovementMethod
import android.widget.RadioGroup
import foundation.e.accountmanager.R
import androidx.lifecycle.ViewModelProviders
......@@ -26,12 +28,14 @@ import foundation.e.accountmanager.model.Credentials
class EeloAuthenticatorFragment : Fragment() {
private lateinit var model: EeloAuthenticatorModel
private lateinit var model: EeloAuthenticatorModel
private lateinit var loginModel: LoginModel
val TOGGLE_BUTTON_CHECKED_KEY = "toggle_button_checked"
var toggleButtonState = false
var isTypeEelo = true
private fun isNetworkAvailable(): Boolean {
val connectivityManager = activity!!.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val activeNetworkInfo = connectivityManager.activeNetworkInfo
......@@ -41,21 +45,21 @@ class EeloAuthenticatorFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
model = ViewModelProviders.of(this).get(EeloAuthenticatorModel::class.java)
model = ViewModelProviders.of(this).get(EeloAuthenticatorModel::class.java)
loginModel = ViewModelProviders.of(requireActivity()).get(LoginModel::class.java)
if (!isNetworkAvailable()) {
if (!isNetworkAvailable()) {
Toast.makeText(context, "Please check your internet connection", Toast.LENGTH_LONG).show()
activity!!.finish()
}
val v = FragmentEeloAuthenticatorBinding.inflate(inflater, container, false)
val v = FragmentEeloAuthenticatorBinding.inflate(inflater, container, false)
v.lifecycleOwner = this
v.model = model
v.root.urlpwd_other_account_title_panel.setOnClickListener() { expandCollapse() }
v.root.urlpwd_other_account_title_panel.setOnClickListener() { expandCollapse() }
v.root.urlpwd_user_name.setOnFocusChangeListener() { v, hasFocus ->
v.root.urlpwd_user_name.setOnFocusChangeListener() { v, hasFocus ->
if (!hasFocus ) {
if (v.urlpwd_user_name.text.toString().contains("@")) {
val dns = v.urlpwd_user_name.text.toString().substringAfter("@")
......@@ -67,21 +71,33 @@ class EeloAuthenticatorFragment : Fragment() {
}
}
v.login.setOnClickListener { login() }
v.root.account_type_radio_group.setOnCheckedChangeListener(
RadioGroup.OnCheckedChangeListener{ group, checkedId ->
if(checkedId == R.id.custom_type)
isTypeEelo = false
})
v.login.setOnClickListener { login() }
// code below is to draw toggle button in its correct state and show or hide server url input field
v.root.learn_more_textview.setMovementMethod(LinkMovementMethod.getInstance())
// code below is to draw toggle button in its correct state and show or hide server url input field
//add by Vincent, 18/02/2019
if(savedInstanceState != null){
toggleButtonState = savedInstanceState.getBoolean(TOGGLE_BUTTON_CHECKED_KEY, false)
}
//This allow the button to be redraw in the correct state if user turn screen
//This allow the button to be redraw in the correct state if user turn screen
if(toggleButtonState == true) {
v.root.expand_collapse_button.setChecked(toggleButtonState)
v.root.account_type_layout.setVisibility(View.VISIBLE)
v.root.learn_more_textview.setVisibility(View.VISIBLE)
v.root.urlpwd_server_uri_layout.setVisibility(View.VISIBLE)
v.root.urlpwd_server_uri.setEnabled(true)
}else{
v.root.urlpwd_server_uri_layout.setVisibility(View.GONE)
v.root.learn_more_textview.setVisibility(View.GONE)
v.root.account_type_layout.setVisibility(View.GONE)
v.root.urlpwd_server_uri.setEnabled(false)
}
......@@ -98,15 +114,15 @@ class EeloAuthenticatorFragment : Fragment() {
Toast.makeText(context, "Please check your internet connection", Toast.LENGTH_LONG).show()
activity!!.finish()
}
if ((urlpwd_user_name.text.toString() != "") && (urlpwd_password.text.toString() != "")) {
if (validate())
requireFragmentManager().beginTransaction()
if ((urlpwd_user_name.text.toString() != "") && (urlpwd_password.text.toString() != "")) {
if (validate())
requireFragmentManager().beginTransaction()
.replace(android.R.id.content, DetectConfigurationFragment(), null)
.addToBackStack(null)
.commit()
} else {
Toast.makeText(context, "Please enter a valid username and password", Toast.LENGTH_LONG).show()
.addToBackStack(null)
.commit()
} else {
Toast.makeText(context, "Please enter a valid username and password", Toast.LENGTH_LONG).show()
}
}
......@@ -114,14 +130,14 @@ class EeloAuthenticatorFragment : Fragment() {
private fun validate(): Boolean {
var valid = false
var serverUrl = foundation.e.accountmanager.Constants.EELO_SYNC_URL
var serverUrl = foundation.e.accountmanager.Constants.EELO_SYNC_URL
fun validateUrl() {
if(toggleButtonState == true) {
serverUrl = view!!.urlpwd_server_uri.text.toString();
if(toggleButtonState == true) {
serverUrl = view!!.urlpwd_server_uri.text.toString();
} else {
serverUrl = foundation.e.accountmanager.Constants.EELO_SYNC_URL
serverUrl = foundation.e.accountmanager.Constants.EELO_SYNC_URL
}
model.baseUrlError.value = null
......@@ -139,17 +155,17 @@ class EeloAuthenticatorFragment : Fragment() {
when {
model.loginWithUrlAndTokens.value == true -> {
validateUrl()
model.loginWithUrlAndTokens.value == true -> {
validateUrl()
val userName = view!!.urlpwd_user_name.text.toString()
val password = view!!.urlpwd_password.text.toString()
val userName = view!!.urlpwd_user_name.text.toString()
val password = view!!.urlpwd_password.text.toString()
if (loginModel.baseURI != null) {
valid = true
loginModel.credentials = Credentials(userName.toLowerCase(), password, null, null, loginModel.baseURI)
}
}
if (loginModel.baseURI != null) {
valid = true
loginModel.credentials = Credentials(userName.toLowerCase(), password, null, null, loginModel.baseURI, isTypeEelo)
}
}
}
......@@ -160,16 +176,20 @@ class EeloAuthenticatorFragment : Fragment() {
* Show/Hide panel containing server's uri input field.
*/
private fun expandCollapse(){
//inverse state of Toggle button
//inverse state of Toggle button
expand_collapse_button.setChecked(!expand_collapse_button.isChecked())
if(expand_collapse_button.isChecked) {
urlpwd_server_uri_layout.setVisibility(View.VISIBLE)
account_type_layout.setVisibility(View.VISIBLE)
learn_more_textview.setVisibility(View.VISIBLE)
urlpwd_server_uri.setEnabled(true)
toggleButtonState = true;
}
else {
urlpwd_server_uri_layout.setVisibility(View.GONE)
account_type_layout.setVisibility(View.GONE)
learn_more_textview.setVisibility(View.GONE)
urlpwd_server_uri.setEnabled(false)
toggleButtonState = false;
}
......
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright © Ricki Hirner (bitfire web engineering).
~ All rights reserved. This program and the accompanying materials
~ are made available under the terms of the GNU Public License v3.0
......@@ -8,162 +7,219 @@
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="android.view.View"/>
<import type="android.view.View" />
<variable
name="model"
type="foundation.e.accountmanager.ui.setup.EeloAuthenticatorModel"/>
type="foundation.e.accountmanager.ui.setup.EeloAuthenticatorModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent">
<!-- We don't want the keyboard up when the user arrives in this initial screen -->
<View android:layout_height="0dp"
android:layout_width="0dp"
android:focusable="true"
android:focusableInTouchMode="true"
android:contentDescription="@null"
android:importantForAccessibility="no" tools:ignore="UnusedAttribute">
<requestFocus/>
</View>
<ScrollView android:layout_width="match_parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- We don't want the keyboard up when the user arrives in this initial screen -->
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="@null"
android:focusable="true"
android:focusableInTouchMode="true"
android:importantForAccessibility="no"
tools:ignore="UnusedAttribute">
<requestFocus />
</View>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout
android:id="@+id/login_type_urlpwd_details"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="16dp"
android:paddingTop="8dp">
<TextView
android:id="@+id/login_type_urlpwd_details"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="8dp"
android:paddingBottom="16dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp"
android:layout_marginTop="32dp"
android:layout_marginBottom="32dp"
android:gravity="center"
android:text="@string/login_eelo_title"
android:textColor="#000000"
android:textSize="22sp" />
<com.google.android.material.textfield.TextInputLayout
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
app:boxBackgroundColor="@android:color/white"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:paddingStart="16dp">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/urlpwd_user_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/login_email_address"
android:inputType="textEmailAddress" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
app:boxBackgroundColor="@android:color/white">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/urlpwd_user_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/login_email_address"
android:inputType="textEmailAddress" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
app:boxBackgroundColor="@android:color/white"
android:paddingEnd="16dp"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingEnd="16dp"
app:boxBackgroundColor="@android:color/white"
app:passwordToggleEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/urlpwd_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="monospace"
android:hint="@string/login_password"
android:inputType="textPassword" />
</com.google.android.material.textfield.TextInputLayout>
<LinearLayout
android:id="@+id/urlpwd_other_account_title_panel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:orientation="horizontal">