Creation of classes and prepare assignment for algorithms

This commit is contained in:
J-Jamet
2018-04-26 22:00:11 +02:00
parent 9af182e0c3
commit d6fc29ec79
16 changed files with 425 additions and 25 deletions

View File

@@ -27,6 +27,7 @@ import android.preference.PreferenceManager;
import android.util.Log;
import com.kunzisoft.keepass.R;
import com.kunzisoft.keepass.crypto.engine.CipherEngine;
import com.kunzisoft.keepass.database.exception.ContentFileNotFoundException;
import com.kunzisoft.keepass.database.exception.InvalidDBException;
import com.kunzisoft.keepass.database.exception.InvalidPasswordException;
@@ -348,6 +349,20 @@ public class Database {
}
}
public PwEncryptionAlgorithm getEncryptionAlgorithm() {
return getPwDatabase().getEncryptionAlgorithm();
}
public void assignEncryptionAlgorithm(PwEncryptionAlgorithm algorithm) {
switch (getPwDatabase().getVersion()) {
case V4:
((PwDatabaseV4) getPwDatabase()).setEncryptionAlgorithm(algorithm);
// TODO Simplify
((PwDatabaseV4) getPwDatabase()).setDataEngine(algorithm.getCipherEngine());
((PwDatabaseV4) getPwDatabase()).setDataCipher(algorithm.getDataCipher());
}
}
public String getEncryptionAlgorithmName(Resources resources) {
return getPwDatabase().getEncryptionAlgorithm().getName(resources);
}

View File

@@ -131,7 +131,6 @@ public class PwDatabaseV4 extends PwDatabase<PwGroupV4, PwEntryV4> {
public void setDataEngine(CipherEngine dataEngine) {
this.dataEngine = dataEngine;
this.algorithm = dataEngine.getPwEncryptionAlgorithm();
}
public PwCompressionAlgorithm getCompressionAlgorithm() {

View File

@@ -22,6 +22,12 @@ package com.kunzisoft.keepass.database;
import android.content.res.Resources;
import com.kunzisoft.keepass.R;
import com.kunzisoft.keepass.crypto.engine.AesEngine;
import com.kunzisoft.keepass.crypto.engine.ChaCha20Engine;
import com.kunzisoft.keepass.crypto.engine.CipherEngine;
import com.kunzisoft.keepass.crypto.engine.TwofishEngine;
import java.util.UUID;
public enum PwEncryptionAlgorithm {
@@ -40,4 +46,28 @@ public enum PwEncryptionAlgorithm {
return resources.getString(R.string.chacha20);
}
}
public CipherEngine getCipherEngine() {
switch (this) {
default:
case AES_Rijndael:
return new AesEngine();
case Twofish:
return new TwofishEngine();
case ChaCha20:
return new ChaCha20Engine();
}
}
public UUID getDataCipher() {
switch (this) {
default:
case AES_Rijndael:
return AesEngine.CIPHER_UUID;
case Twofish:
return TwofishEngine.CIPHER_UUID;
case ChaCha20:
return ChaCha20Engine.CIPHER_UUID;
}
}
}

View File

@@ -123,6 +123,7 @@ public class ImporterV4 extends Importer {
try {
engine = CipherFactory.getInstance(db.getDataCipher());
db.setDataEngine(engine);
db.setEncryptionAlgorithm(engine.getPwEncryptionAlgorithm());
cipher = engine.getCipher(Cipher.DECRYPT_MODE, db.getFinalKey(), header.encryptionIV);
} catch (NoSuchAlgorithmException e) {
throw new IOException("Invalid algorithm.");

View File

@@ -402,7 +402,7 @@ public class NestedSettingsFragment extends PreferenceFragmentCompat
assert fragmentManager != null;
try { // don't check if we can
((SwitchPreference) preference).setChecked(false);
} catch (Exception e) {}
} catch (Exception ignored) {}
new UnderDevelopmentFeatureDialogFragment().show(getFragmentManager(), "underDevFeatureDialog");
return false;
});

View File

@@ -0,0 +1,31 @@
package com.kunzisoft.keepass.settings.preference;
import android.content.Context;
import android.support.v7.preference.DialogPreference;
import android.util.AttributeSet;
import com.kunzisoft.keepass.R;
public class AlgorithmListPreference extends DialogPreference {
public AlgorithmListPreference(Context context) {
this(context, null);
}
public AlgorithmListPreference(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.dialogPreferenceStyle);
}
public AlgorithmListPreference(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, defStyleAttr);
}
public AlgorithmListPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public int getDialogLayoutResource() {
return R.layout.pref_dialog_list_explanation;
}
}

View File

@@ -0,0 +1,195 @@
package com.kunzisoft.keepass.settings.preferenceDialogFragment;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RadioButton;
import android.widget.TextView;
import com.kunzisoft.keepass.R;
import com.kunzisoft.keepass.database.PwEncryptionAlgorithm;
import com.kunzisoft.keepass.database.edit.OnFinish;
import java.util.ArrayList;
import java.util.List;
public class DatabaseAlgorithmPreferenceDialogFragmentCompat extends DatabaseSavePreferenceDialogFragmentCompat {
private RecyclerView recyclerView;
private AlgorithmAdapter algorithmAdapter;
private OnAlgorithmClickCallback onAlgorithmClickCallback;
private PwEncryptionAlgorithm algorithmSelected;
public static DatabaseAlgorithmPreferenceDialogFragmentCompat newInstance(
String key) {
final DatabaseAlgorithmPreferenceDialogFragmentCompat
fragment = new DatabaseAlgorithmPreferenceDialogFragmentCompat();
final Bundle b = new Bundle(1);
b.putString(ARG_KEY, key);
fragment.setArguments(b);
return fragment;
}
@Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
recyclerView = view.findViewById(R.id.pref_dialog_list);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
algorithmAdapter = new AlgorithmAdapter();
recyclerView.setAdapter(algorithmAdapter);
}
public void setAlgorithm(List<PwEncryptionAlgorithm> algorithmList, PwEncryptionAlgorithm algorithm) {
if (algorithmAdapter != null)
algorithmAdapter.setAlgorithms(algorithmList, algorithm);
algorithmSelected = algorithm;
}
private class AlgorithmAdapter extends RecyclerView.Adapter<AlgorithmViewHolder> {
private LayoutInflater inflater;
private List<PwEncryptionAlgorithm> algorithms;
private PwEncryptionAlgorithm algorithmUsed;
private OnAlgorithmClickListener onAlgorithmClickListener;
public AlgorithmAdapter() {
this.inflater = LayoutInflater.from(getContext());
this.algorithms = new ArrayList<>();
this.algorithmUsed = null;
this.onAlgorithmClickListener = new OnAlgorithmClickListener();
}
@NonNull
@Override
public AlgorithmViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.list_nodes_group, parent, false);
return new AlgorithmViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull AlgorithmViewHolder holder, int position) {
PwEncryptionAlgorithm algorithm = this.algorithms.get(position);
holder.nameView.setText(algorithm.getName(getResources()));
if (algorithmUsed != null && algorithmUsed.equals(algorithm))
holder.radioButton.setChecked(true);
else
holder.radioButton.setChecked(false);
onAlgorithmClickListener.setAlgorithm(algorithm);
holder.container.setOnClickListener(onAlgorithmClickListener);
}
@Override
public int getItemCount() {
return algorithms.size();
}
public void setAlgorithms(List<PwEncryptionAlgorithm> algorithms, PwEncryptionAlgorithm algorithmUsed) {
this.algorithms.clear();
this.algorithms.addAll(algorithms);
this.algorithmUsed = algorithmUsed;
}
}
private class AlgorithmViewHolder extends RecyclerView.ViewHolder {
View container;
RadioButton radioButton;
TextView nameView;
public AlgorithmViewHolder(View itemView) {
super(itemView);
container = itemView.findViewById(R.id.pref_dialog_list_container);
radioButton = itemView.findViewById(R.id.pref_dialog_list_radio);
nameView = itemView.findViewById(R.id.pref_dialog_list_name);
}
}
private interface OnAlgorithmClickCallback {
void onAlgorithmClick(PwEncryptionAlgorithm algorithm);
}
private class OnAlgorithmClickListener implements View.OnClickListener {
private PwEncryptionAlgorithm algorithmClicked;
public void setAlgorithm(PwEncryptionAlgorithm algorithm) {
this.algorithmClicked = algorithm;
}
@Override
public void onClick(View view) {
if (onAlgorithmClickCallback != null)
onAlgorithmClickCallback.onAlgorithmClick(algorithmClicked);
algorithmSelected = algorithmClicked;
// Close the dialog when an element is clicked
onDialogClosed(true);
dismiss();
}
}
public void setOnAlgorithmClickCallback(OnAlgorithmClickCallback onAlgorithmClickCallback) {
this.onAlgorithmClickCallback = onAlgorithmClickCallback;
}
public PwEncryptionAlgorithm getAlgorithmSelected() {
return algorithmSelected;
}
@Override
public void onDialogClosed(boolean positiveResult) {
if ( positiveResult ) {
assert getContext() != null;
if (getAlgorithmSelected() != null) {
PwEncryptionAlgorithm newAlgorithm = getAlgorithmSelected();
PwEncryptionAlgorithm oldAlgorithm = database.getEncryptionAlgorithm();
database.assignDescription(newAlgorithm.getName(getResources()));
Handler handler = new Handler();
setAfterSaveDatabase(new AfterDescriptionSave(getContext(), handler, newAlgorithm, oldAlgorithm));
}
}
super.onDialogClosed(positiveResult);
}
private class AfterDescriptionSave extends OnFinish {
private PwEncryptionAlgorithm mNewAlgorithm;
private PwEncryptionAlgorithm mOldAlgorithm;
private Context mCtx;
AfterDescriptionSave(Context ctx, Handler handler, PwEncryptionAlgorithm newAlgorithm, PwEncryptionAlgorithm oldAlgorithm) {
super(handler);
mCtx = ctx;
mNewAlgorithm = newAlgorithm;
mOldAlgorithm = oldAlgorithm;
}
@Override
public void run() {
PwEncryptionAlgorithm algorithmToShow = mNewAlgorithm;
if (!mSuccess) {
displayMessage(mCtx);
database.assignEncryptionAlgorithm(mOldAlgorithm);
}
getPreference().setSummary(algorithmToShow.getName(mCtx.getResources()));
super.run();
}
}
}

View File

@@ -7,7 +7,7 @@ import android.view.View;
import com.kunzisoft.keepass.database.edit.OnFinish;
public class DatabaseDescriptionPreferenceDialogFragmentCompat extends DatabaseSavePreferenceDialogFragmentCompat {
public class DatabaseDescriptionPreferenceDialogFragmentCompat extends InputDatabaseSavePreferenceDialogFragmentCompat {
public static DatabaseDescriptionPreferenceDialogFragmentCompat newInstance(
String key) {
@@ -32,12 +32,12 @@ public class DatabaseDescriptionPreferenceDialogFragmentCompat extends DatabaseS
if ( positiveResult ) {
assert getContext() != null;
String dbDescription = getInputText();
String newDescription = getInputText();
String oldDescription = database.getDescription();
database.assignDescription(dbDescription);
database.assignDescription(newDescription);
Handler handler = new Handler();
setAfterSaveDatabase(new AfterDescriptionSave(getContext(), handler, dbDescription, oldDescription));
setAfterSaveDatabase(new AfterDescriptionSave(getContext(), handler, newDescription, oldDescription));
}
super.onDialogClosed(positiveResult);
@@ -64,7 +64,6 @@ public class DatabaseDescriptionPreferenceDialogFragmentCompat extends DatabaseS
if (!mSuccess) {
displayMessage(mCtx);
database.assignDescription(mOldDescription);
database.assignDescription(mOldDescription);
}
getPreference().setSummary(descriptionToShow);

View File

@@ -7,7 +7,7 @@ import android.view.View;
import com.kunzisoft.keepass.database.edit.OnFinish;
public class DatabaseNamePreferenceDialogFragmentCompat extends DatabaseSavePreferenceDialogFragmentCompat {
public class DatabaseNamePreferenceDialogFragmentCompat extends InputDatabaseSavePreferenceDialogFragmentCompat {
public static DatabaseNamePreferenceDialogFragmentCompat newInstance(
String key) {
@@ -32,12 +32,12 @@ public class DatabaseNamePreferenceDialogFragmentCompat extends DatabaseSavePref
if ( positiveResult ) {
assert getContext() != null;
String dbName = getInputText();
String newName = getInputText();
String oldName = database.getName();
database.assignName(dbName);
database.assignName(newName);
Handler handler = new Handler();
setAfterSaveDatabase(new AfterNameSave(getContext(), handler, dbName, oldName));
setAfterSaveDatabase(new AfterNameSave(getContext(), handler, newName, oldName));
}
super.onDialogClosed(positiveResult);

View File

@@ -0,0 +1,29 @@
package com.kunzisoft.keepass.settings.preferenceDialogFragment;
import android.view.View;
import android.widget.EditText;
import com.kunzisoft.keepass.R;
public class InputDatabaseSavePreferenceDialogFragmentCompat extends DatabaseSavePreferenceDialogFragmentCompat {
private EditText inputTextView;
@Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
inputTextView = view.findViewById(R.id.input_text);
}
public String getInputText() {
return this.inputTextView.getText().toString();
}
public void setInputText(String inputText) {
if (inputTextView != null && inputText != null) {
this.inputTextView.setText(inputText);
this.inputTextView.setSelection(this.inputTextView.getText().length());
}
}
}

View File

@@ -2,33 +2,21 @@ package com.kunzisoft.keepass.settings.preferenceDialogFragment;
import android.support.v7.preference.PreferenceDialogFragmentCompat;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import com.kunzisoft.keepass.R;
public abstract class InputPreferenceDialogFragmentCompat extends PreferenceDialogFragmentCompat {
private EditText inputTextView;
private TextView textExplanationView;
@Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
inputTextView = view.findViewById(R.id.input_text);
textExplanationView = view.findViewById(R.id.explanation_text);
}
public String getInputText() {
return this.inputTextView.getText().toString();
}
public void setInputText(String inputText) {
this.inputTextView.setText(inputText);
this.inputTextView.setSelection(this.inputTextView.getText().length());
}
public String getExplanationText() {
if (textExplanationView != null)
return textExplanationView.getText().toString();
@@ -37,7 +25,7 @@ public abstract class InputPreferenceDialogFragmentCompat extends PreferenceDial
}
public void setExplanationText(String explanationText) {
if (textExplanationView != null)
if (textExplanationView != null && explanationText != null)
this.textExplanationView.setText(explanationText);
}
}

View File

@@ -22,6 +22,7 @@ package com.kunzisoft.keepass.settings.preferenceDialogFragment;
import android.os.Bundle;
import android.support.v7.preference.DialogPreference;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import com.kunzisoft.keepass.R;
@@ -29,6 +30,8 @@ import com.kunzisoft.keepass.settings.preference.RoundsPreference;
public class RoundsFixPreferenceDialogFragmentCompat extends InputPreferenceDialogFragmentCompat {
private EditText inputTextView;
public static RoundsFixPreferenceDialogFragmentCompat newInstance(
String key) {
final RoundsFixPreferenceDialogFragmentCompat
@@ -44,6 +47,8 @@ public class RoundsFixPreferenceDialogFragmentCompat extends InputPreferenceDial
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
inputTextView = view.findViewById(R.id.input_text);
DialogPreference preference = getPreference();
if (preference instanceof RoundsPreference) {
setExplanationText(((RoundsPreference) preference).getExplanation());
@@ -75,4 +80,13 @@ public class RoundsFixPreferenceDialogFragmentCompat extends InputPreferenceDial
}
}
}
public String getInputText() {
return this.inputTextView.getText().toString();
}
public void setInputText(String inputText) {
this.inputTextView.setText(inputText);
this.inputTextView.setSelection(this.inputTextView.getText().length());
}
}

View File

@@ -28,7 +28,7 @@ import android.widget.Toast;
import com.kunzisoft.keepass.R;
import com.kunzisoft.keepass.database.edit.OnFinish;
public class RoundsPreferenceDialogFragmentCompat extends DatabaseSavePreferenceDialogFragmentCompat {
public class RoundsPreferenceDialogFragmentCompat extends InputDatabaseSavePreferenceDialogFragmentCompat {
public static RoundsPreferenceDialogFragmentCompat newInstance(
String key) {

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2018 Jeremy Jamet / Kunzisoft.
This file is part of KeePass DX.
KeePass DX is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
KeePass DX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/edit"
android:padding="20dp"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:importantForAutofill="noExcludeDescendants"
tools:targetApi="o">
<android.support.v7.widget.AppCompatTextView
android:id="@+id/explanation_text"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:gravity="center"
android:layout_marginBottom="8dp"
style="@style/KeepassDXStyle.TextAppearance.SmallTitle"/>
<android.support.v7.widget.AppCompatEditText
android:id="@+id/input_text"
android:layout_height="wrap_content"
android:layout_width="match_parent"/>
</LinearLayout>

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2018 Jeremy Jamet / Kunzisoft.
This file is part of KeePass DX.
KeePass DX is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
KeePass DX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:padding="20dp"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:importantForAutofill="noExcludeDescendants"
tools:targetApi="o">
<android.support.v7.widget.AppCompatTextView
android:id="@+id/explanation_text"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:gravity="center"
android:layout_marginBottom="8dp"
style="@style/KeepassDXStyle.TextAppearance.SmallTitle"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/pref_dialog_list"
android:layout_height="wrap_content"
android:layout_width="match_parent"/>
</LinearLayout>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pref_dialog_list_container"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<RadioButton
android:id="@+id/pref_dialog_list_radio"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/pref_dialog_list_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:layout_marginRight="8dp"
android:layout_marginEnd="8dp"/>
</LinearLayout>