diff --git a/app/src/main/java/com/herbron/moodl/Activities/HomeActivity.java b/app/src/main/java/com/herbron/moodl/Activities/HomeActivity.java index 4375d55..2781394 100644 --- a/app/src/main/java/com/herbron/moodl/Activities/HomeActivity.java +++ b/app/src/main/java/com/herbron/moodl/Activities/HomeActivity.java @@ -28,6 +28,7 @@ import com.herbron.moodl.Activities.HomeActivityFragments.Summary; import com.herbron.moodl.Activities.HomeActivityFragments.Watchlist; import com.herbron.moodl.BalanceSwitchManagerInterface; import com.herbron.moodl.BalanceUpdateInterface; +import com.herbron.moodl.DataManagers.DatabaseManager; import com.herbron.moodl.DataManagers.PreferencesManager; import com.herbron.moodl.PlaceholderManager; import com.herbron.moodl.R; @@ -59,7 +60,6 @@ public class HomeActivity extends AppCompatActivity implements BalanceUpdateInte super.onCreate(savedInstanceState); /**Interface setup**/ - Window w = getWindow(); setContentView(R.layout.activity_currency_summary); diff --git a/app/src/main/java/com/herbron/moodl/Activities/HomeActivityFragments/Summary.java b/app/src/main/java/com/herbron/moodl/Activities/HomeActivityFragments/Summary.java index d896b39..056c71b 100644 --- a/app/src/main/java/com/herbron/moodl/Activities/HomeActivityFragments/Summary.java +++ b/app/src/main/java/com/herbron/moodl/Activities/HomeActivityFragments/Summary.java @@ -70,7 +70,7 @@ public class Summary extends Fragment implements BalanceSwitchManagerInterface, private LinearLayout currencyLayout; private PreferencesManager preferencesManager; - private com.herbron.moodl.DataManagers.BalanceManager balanceManager; + private BalanceManager balanceManager; private SwipeRefreshLayout refreshLayout; private Dialog loadingDialog; private String defaultCurrency; diff --git a/app/src/main/java/com/herbron/moodl/Activities/SettingsActivity.java b/app/src/main/java/com/herbron/moodl/Activities/SettingsActivity.java index df1dceb..2ae23cc 100644 --- a/app/src/main/java/com/herbron/moodl/Activities/SettingsActivity.java +++ b/app/src/main/java/com/herbron/moodl/Activities/SettingsActivity.java @@ -46,6 +46,10 @@ import com.herbron.moodl.FingerprintToolkit.FingerprintHandler; import com.herbron.moodl.MoodlBox; import com.herbron.moodl.R; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + import java.io.BufferedReader; import java.io.File; import java.io.FileReader; @@ -468,21 +472,34 @@ public class SettingsActivity extends AppCompatPreferenceActivity { checkPermissions(); SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.getDefault()); Date currentDate = new Date(); - String fileName = getString(R.string.app_name) + "_" + formatter.format(currentDate) + ".backup"; + String fileName = "Bakup_" + formatter.format(currentDate) + ".moodl"; DatabaseManager databaseManager = new DatabaseManager(getContext()); + if(enterPasswordCheckbox.isChecked()) + { + DataCrypter.updateKey(textInputLayoutPassword.getEditText().getText().toString()); + } + File backupFile = new File(textViewFilePath.getText() + "/" + fileName); try (PrintWriter printWriter = new PrintWriter(new FileWriter(backupFile, true))) { - if(enterPasswordCheckbox.isChecked()) - { - DataCrypter.updateKey(textInputLayoutPassword.getEditText().getText().toString()); - printWriter.write(DataCrypter.encrypt(getActivity(), databaseManager.getBackupData())); - } - else - { - printWriter.write(databaseManager.getBackupData()); + try { + JSONObject backupJson = new JSONObject(); + + if(enterPasswordCheckbox.isChecked()) + { + backupJson.put("encodeChecker", DataCrypter.encrypt(getContext(), "NaukVerification")); + } + else + { + backupJson.put("encodeChecker", "NaukVerification"); + } + backupJson.put("transactions", databaseManager.getBackupData(getContext(),enterPasswordCheckbox.isChecked())); + + printWriter.write(backupJson.toString()); + } catch (JSONException e) { + Log.d("moodl", "Error while creating backup json " + e.getMessage()); } printWriter.close(); @@ -542,6 +559,10 @@ public class SettingsActivity extends AppCompatPreferenceActivity { } }); + final CheckBox enterPasswordCheckbox = dialogView.findViewById(R.id.checkboxEnterPassword); + final CheckBox wipeCheckbox = dialogView.findViewById(R.id.checkboxWipeData); + final TextInputLayout textInputLayoutPassword = dialogView.findViewById(R.id.textInputLayoutPassword); + dialogBuilder.setTitle(getString(R.string.restoreBackup)); dialogBuilder.setPositiveButton(getString(R.string.confirm), new DialogInterface.OnClickListener() { @Override @@ -551,6 +572,16 @@ public class SettingsActivity extends AppCompatPreferenceActivity { DatabaseManager databaseManager = new DatabaseManager(context); + if(enterPasswordCheckbox.isChecked()) + { + DataCrypter.updateKey(textInputLayoutPassword.getEditText().getText().toString()); + } + + if(wipeCheckbox.isChecked()) + { + databaseManager.wipeTransactions(); + } + File backupFile = new File(textViewFilePath.getText().toString()); try { @@ -564,13 +595,37 @@ public class SettingsActivity extends AppCompatPreferenceActivity { completeFile += str; } - String[] results = completeFile.split(Pattern.quote("]")); + try { + JSONObject backupJson = new JSONObject(completeFile); + String checker; - for(int i = 0; i < results.length; i++) - { - String[] columnValues = results[i].split(Pattern.quote(";@")); + if(enterPasswordCheckbox.isChecked()) + { + checker = DataCrypter.decrypt(getContext(), backupJson.getString("encodeChecker")); + } + else + { + checker = backupJson.getString("encodeChecker"); + } - databaseManager.addRowTransaction(columnValues); + if(checker.equals("NaukVerification")) + { + JSONArray transactionsArray = backupJson.getJSONArray("transactions"); + + for(int i = 0; i < transactionsArray.length(); i++) + { + JSONObject transactionObject = transactionsArray.getJSONObject(i); + + databaseManager.addRowTransaction(transactionObject, getContext(), enterPasswordCheckbox.isChecked()); + } + } + else + { + textInputLayoutPassword.setError("Wrong password"); + } + + } catch (JSONException e) { + Log.d("moodl", "Error while creating backup json " + e); } } catch (IOException e) { diff --git a/app/src/main/java/com/herbron/moodl/DataManagers/CurrencyData/CurrencyDetailsList.java b/app/src/main/java/com/herbron/moodl/DataManagers/CurrencyData/CurrencyDetailsList.java index e17a047..9d53637 100644 --- a/app/src/main/java/com/herbron/moodl/DataManagers/CurrencyData/CurrencyDetailsList.java +++ b/app/src/main/java/com/herbron/moodl/DataManagers/CurrencyData/CurrencyDetailsList.java @@ -56,7 +56,6 @@ public class CurrencyDetailsList { if (response.length() > 0) { processDetailResult(response, callBack); - upToDate = true; } } }, @@ -109,6 +108,8 @@ public class CurrencyDetailsList { sortDetails(); + upToDate = true; + callBack.onSuccess(); } diff --git a/app/src/main/java/com/herbron/moodl/DataManagers/DataCrypter.java b/app/src/main/java/com/herbron/moodl/DataManagers/DataCrypter.java index 60de06f..2abe2ce 100644 --- a/app/src/main/java/com/herbron/moodl/DataManagers/DataCrypter.java +++ b/app/src/main/java/com/herbron/moodl/DataManagers/DataCrypter.java @@ -4,10 +4,10 @@ import android.content.Context; import android.util.Log; import com.herbron.moodl.R; - -import org.apache.commons.codec.binary.Base64; +import android.util.Base64; import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; @@ -20,19 +20,19 @@ import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; + public class DataCrypter { private static Key aesKey; public static void updateKey(String key) { - for(int i = 0; key.getBytes().length < 32; i++) - { - key += "0"; - } - try { - aesKey = new SecretKeySpec(key.getBytes("UTF-8"), "AES"); + byte[] keyByte = key.getBytes("UTF-8"); + byte[] finalKey = new byte[32]; + System.arraycopy(keyByte, 0, finalKey, 0, keyByte.length); + + aesKey = new SecretKeySpec(finalKey, "AES"); } catch (UnsupportedEncodingException e) { Log.d("moodl", "Error while creating encryption key " + e.getMessage()); } @@ -49,9 +49,10 @@ public class DataCrypter { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); cipher.init(Cipher.ENCRYPT_MODE, aesKey, ivParameterSpec); - byte[] encryptedBytes = cipher.doFinal(data.getBytes()); + byte[] encryptedBytes = cipher.doFinal(data.getBytes("UTF-8")); + + encryptedData = Base64.encodeToString(encryptedBytes, Base64.DEFAULT); - encryptedData = Base64.encodeBase64String(encryptedBytes); } catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException | UnsupportedEncodingException @@ -63,4 +64,26 @@ public class DataCrypter { return encryptedData; } + + public static String decrypt(Context context, String data) + { + String decryptedData = null; + + try { + IvParameterSpec ivParameterSpec = new IvParameterSpec(context.getString(R.string.ivKey).getBytes("UTF-8")); + + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); + cipher.init(Cipher.ENCRYPT_MODE, aesKey, ivParameterSpec); + + byte[] dataBytes = Base64.decode(data, Base64.DEFAULT); + decryptedData = new String(dataBytes, StandardCharsets.UTF_8); + + } catch(NoSuchPaddingException | NoSuchAlgorithmException + | InvalidKeyException | UnsupportedEncodingException + | InvalidAlgorithmParameterException e) { + e.printStackTrace(); + } + + return decryptedData; + } } diff --git a/app/src/main/java/com/herbron/moodl/DataManagers/DatabaseManager.java b/app/src/main/java/com/herbron/moodl/DataManagers/DatabaseManager.java index bb9635d..ae9507a 100644 --- a/app/src/main/java/com/herbron/moodl/DataManagers/DatabaseManager.java +++ b/app/src/main/java/com/herbron/moodl/DataManagers/DatabaseManager.java @@ -5,10 +5,15 @@ import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; +import android.util.Log; import com.herbron.moodl.DataManagers.CurrencyData.Currency; import com.herbron.moodl.DataManagers.CurrencyData.Transaction; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -152,36 +157,82 @@ public class DatabaseManager extends SQLiteOpenHelper{ db.close(); } - public String getBackupData() + public JSONArray getBackupData(Context context, boolean encryptData) { String selectQuerry = "SELECT * FROM " + TABLE_MANUAL_CURRENCIES; SQLiteDatabase db = this.getWritableDatabase(); Cursor result = db.rawQuery(selectQuerry, null); - String backupData = ""; + JSONArray transactionsArray = new JSONArray(); while(result.moveToNext()) { + JSONObject transactionJson = new JSONObject(); + for(int i = 0; i < result.getColumnCount(); i++) { - backupData += result.getString(i) + ";@"; + try { + if(result.getString(i) != null) + { + if(encryptData) + { + transactionJson.put(result.getColumnName(i), DataCrypter.encrypt(context, result.getString(i))); + } + else + { + transactionJson.put(result.getColumnName(i), result.getString(i)); + } + } + else + { + transactionJson.put(result.getColumnName(i), ""); + } + } catch (JSONException e) { + Log.d("moodl", "Error while creating a json transaction"); + } } - backupData += "\n"; + transactionsArray.put(transactionJson); } - return backupData; + return transactionsArray; } - public void addRowTransaction(String[] rowValues) + public void wipeTransactions() + { + SQLiteDatabase db = this.getWritableDatabase(); + db.execSQL("DELETE FROM "+ TABLE_MANUAL_CURRENCIES); + } + + public void addRowTransaction(JSONObject rawValues, Context context, boolean decrypt) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); - values.put(KEY_CURRENCY_SYMBOL, rowValues[1]); - values.put(KEY_CURRENCY_BALANCE, rowValues[3]); - values.put(KEY_CURRENCY_DATE, rowValues[4]); - values.put(KEY_CURRENCY_PURCHASED_PRICE, rowValues[5]); + try { + if(decrypt) + { + values.put(KEY_CURRENCY_SYMBOL, DataCrypter.decrypt(context, rawValues.getString(KEY_CURRENCY_SYMBOL))); + values.put(KEY_CURRENCY_NAME, DataCrypter.decrypt(context, rawValues.getString(KEY_CURRENCY_NAME))); + values.put(KEY_CURRENCY_BALANCE, DataCrypter.decrypt(context, rawValues.getString(KEY_CURRENCY_BALANCE))); + values.put(KEY_CURRENCY_DATE, DataCrypter.decrypt(context, rawValues.getString(KEY_CURRENCY_DATE))); + values.put(KEY_CURRENCY_PURCHASED_PRICE, DataCrypter.decrypt(context, rawValues.getString(KEY_CURRENCY_PURCHASED_PRICE))); + values.put(KEY_CURRENCY_IS_MINED, DataCrypter.decrypt(context, rawValues.getString(KEY_CURRENCY_IS_MINED))); + values.put(KEY_CURRENCY_FEES, DataCrypter.decrypt(context, rawValues.getString(KEY_CURRENCY_FEES))); + } + else + { + values.put(KEY_CURRENCY_SYMBOL, rawValues.getString(KEY_CURRENCY_SYMBOL)); + values.put(KEY_CURRENCY_NAME, rawValues.getString(KEY_CURRENCY_NAME)); + values.put(KEY_CURRENCY_BALANCE, rawValues.getString(KEY_CURRENCY_BALANCE)); + values.put(KEY_CURRENCY_DATE, rawValues.getString(KEY_CURRENCY_DATE)); + values.put(KEY_CURRENCY_PURCHASED_PRICE, rawValues.getString(KEY_CURRENCY_PURCHASED_PRICE)); + values.put(KEY_CURRENCY_IS_MINED, rawValues.getString(KEY_CURRENCY_IS_MINED)); + values.put(KEY_CURRENCY_FEES, rawValues.getString(KEY_CURRENCY_FEES)); + } + } catch (JSONException e) { + Log.d("moodl", "Error while inserting transaction"); + } db.insert(TABLE_MANUAL_CURRENCIES, null, values); db.close(); diff --git a/app/src/main/res/layout/dialog_export_data.xml b/app/src/main/res/layout/dialog_export_data.xml index 962baaf..e330227 100644 --- a/app/src/main/res/layout/dialog_export_data.xml +++ b/app/src/main/res/layout/dialog_export_data.xml @@ -17,10 +17,10 @@ android:background="@drawable/background_filepath"/> + android:text="@string/enter_password"/> + android:text="@string/wipe_data"/> + android:text="@string/enter_password"/> Exporter les entrées manuelles Importer de nouvelles entrées Synchronisation - Conserver les données + Supprimer les données actuelles Restaurer les transactions manuelles Restaurer les clefs d\'API - Entrerr un mot de passe + Entrer un mot de passe Mot de passe Réglages Sauvegarder diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 80e0bd8..ef89a40 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -203,7 +203,7 @@ This field cannot be blank This field must be a number This field must be positive - Conserve current data + Wipe current data Restore manual entries Restore API keys Enter password