diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..60153b0 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,25 @@ +language: android +sudo: required +dist: precise +jdk: oraclejdk8 + +env: + global: + - ANDROID_API_LEVEL=28 + - EMULATOR_API_LEVEL=21 + - ANDROID_BUILD_TOOLS_VERSION=28.0.3 + - ANDROID_ABI=armeabi-v7a + - ANDROID_TAG=google_apis + +android: + components: + - tools + - platform-tools + - build-tools-$ANDROID_BUILD_TOOLS_VERSION + - android-$ANDROID_API_LEVEL + - extra-android-support + - extra-android-m2repository + - extra-google-m2repository + +script: + - ./SecurePass/gradlew build --stacktrace \ No newline at end of file diff --git a/APP/.idea/caches/build_file_checksums.ser b/APP/.idea/caches/build_file_checksums.ser deleted file mode 100644 index 6f29fd1..0000000 Binary files a/APP/.idea/caches/build_file_checksums.ser and /dev/null differ diff --git a/APP/.idea/codeStyles/Project.xml b/APP/.idea/codeStyles/Project.xml deleted file mode 100644 index d5ec3da..0000000 --- a/APP/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/APP/.idea/codeStyles/codeStyleConfig.xml b/APP/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index a55e7a1..0000000 --- a/APP/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/APP/.idea/dbnavigator.xml b/APP/.idea/dbnavigator.xml deleted file mode 100644 index b2c7134..0000000 --- a/APP/.idea/dbnavigator.xml +++ /dev/null @@ -1,453 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/APP/.idea/markdown-navigator.xml b/APP/.idea/markdown-navigator.xml deleted file mode 100644 index 3e62462..0000000 --- a/APP/.idea/markdown-navigator.xml +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/APP/.idea/markdown-navigator/profiles_settings.xml b/APP/.idea/markdown-navigator/profiles_settings.xml deleted file mode 100644 index 57927c5..0000000 --- a/APP/.idea/markdown-navigator/profiles_settings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/APP/.idea/misc.xml b/APP/.idea/misc.xml deleted file mode 100644 index 8b6ef25..0000000 --- a/APP/.idea/misc.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/APP/.idea/runConfigurations.xml b/APP/.idea/runConfigurations.xml deleted file mode 100644 index 7f68460..0000000 --- a/APP/.idea/runConfigurations.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/APP/.idea/vcs.xml b/APP/.idea/vcs.xml deleted file mode 100644 index 6c0b863..0000000 --- a/APP/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/APP/app/src/androidTest/java/javinator9889/securepass/DatabaseTest.java b/APP/app/src/androidTest/java/javinator9889/securepass/DatabaseTest.java deleted file mode 100644 index 4d12c95..0000000 --- a/APP/app/src/androidTest/java/javinator9889/securepass/DatabaseTest.java +++ /dev/null @@ -1,86 +0,0 @@ -package javinator9889.securepass; - -import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; - -import org.junit.After; -import org.junit.Before; -import org.junit.runner.RunWith; - -import java.util.Map; - -import javinator9889.securepass.io.database.DatabaseManager; -import javinator9889.securepass.io.database.operations.CommonOperations; - -/** - * Created by Javinator9889 on 20/05/2018. - */ -@RunWith(AndroidJUnit4.class) -public class DatabaseTest { - private Context context = InstrumentationRegistry.getTargetContext(); - - private CommonOperations op; - - @Before - public void initParams() { - DatabaseManager manager = DatabaseManager.newInstance(context, "1234"); - this.op = CommonOperations.newInstance(manager); - } - -// @Test -// public void insertIntoDB() { -// long defaultCategoryId = op.registerDefaultCategory(); -// long newAccountId = op.registerNewAccount("cuenta", "password", -// "icono", "descripción", defaultCategoryId); -// long newCategoryId = op.registerNewCategory("cat2"); -// long newQRCodeId = op.registerQRCode(newAccountId, "qr1", "desc", -// "1234"); -// long newSecurityCodeId = op.registerNewSecurityCodeSource("sec1"); -// long newFieldForSecCodeId = op.registerNewFieldForSecurityCodeSource("12345", -// false, -// newSecurityCodeId); -// op.updateInformationForCategory("cat3", newCategoryId); -// op.updateInformationForEntry("cuent", "pass", "icon", -// "desc", newCategoryId, newAccountId); -// op.updateInformationForQRCode(newAccountId, "qr1,2", "descq", "data", -// newQRCodeId); -// op.updateInformationForSecurityCode("secCode", newSecurityCodeId); -// op.updateInformationForField("12321", true, newFieldForSecCodeId, -// newSecurityCodeId); -// printer(); -// op.registerNewAccount("cuenta", "password", "icono", -// "descripción", defaultCategoryId); -// op.registerNewCategory("cat2"); -// op.registerQRCode(newAccountId, "qr1", "desc", -// "1234"); -// op.registerNewSecurityCodeSource("sec1"); -// op.registerNewFieldForSecurityCodeSource("12345",false, -// newSecurityCodeId); -// printer(); -// op.deleteCategory(newCategoryId); -// op.deleteEntry(newAccountId); -// op.deleteQRCode(newQRCodeId); -// op.deleteSecurityCode(newSecurityCodeId); -// op.deleteField(newFieldForSecCodeId); -// printer(); -// } - - private void printer() { - for (Map objectMap : op.getAllCategories()) - System.out.println(objectMap); - for (Map objectMap : op.getAllEntries()) - System.out.println(objectMap); - for (Map objectMap : op.getAllQRCodes()) - System.out.println(objectMap); - for (Map objectMap : op.getAllSecurityCodes()) - System.out.println(objectMap); - for (Map objectMap : op.getAllFields()) - System.out.println(objectMap); - } - - @After - public void closeConnection() { - op.finishConnection(); - } -} diff --git a/APP/app/src/androidTest/java/javinator9889/securepass/DriveTest.java b/APP/app/src/androidTest/java/javinator9889/securepass/DriveTest.java deleted file mode 100644 index d74ce9f..0000000 --- a/APP/app/src/androidTest/java/javinator9889/securepass/DriveTest.java +++ /dev/null @@ -1,30 +0,0 @@ -package javinator9889.securepass; - -import android.content.Context; -import android.content.Intent; -import android.support.test.InstrumentationRegistry; -import android.util.Log; - -import org.junit.Test; - -import javinator9889.securepass.data.container.ClassContainer; -import javinator9889.securepass.errors.GoogleDriveNotAvailableException; -//import javinator9889.securepass.backup.drive.CreateFileInAppFolder; - -/** - * Created by Javinator9889 on 21/04/2018. - */ -public class DriveTest { -// @Test -// public void createFileInAppFolder() throws Exception { -// try { -// Context baseContext = InstrumentationRegistry.getTargetContext(); -// Intent intent = new Intent(baseContext, CreateFileInAppFolder.class); -// ClassContainer container = DataClassForTests.CONTAINER_TEST_CLASS(); -// intent.putExtra("data", container); -// baseContext.startActivity(intent); -// } catch (GoogleDriveNotAvailableException e) { -// Log.e("GMS", "Google Play Services are not available on this device", e); -// } -// } -} diff --git a/APP/app/src/main/java/javinator9889/securepass/DataClassForTests.java b/APP/app/src/main/java/javinator9889/securepass/DataClassForTests.java deleted file mode 100644 index f356f9e..0000000 --- a/APP/app/src/main/java/javinator9889/securepass/DataClassForTests.java +++ /dev/null @@ -1,62 +0,0 @@ -package javinator9889.securepass; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javinator9889.securepass.data.container.ClassContainer; -import javinator9889.securepass.data.entry.Category; -import javinator9889.securepass.data.entry.Entry; -import javinator9889.securepass.data.entry.QRCode; -import javinator9889.securepass.data.secret.Field; -import javinator9889.securepass.data.secret.SecurityCode; - -/** - * Created by Javinator9889 on 21/04/2018. - */ -public class DataClassForTests { - // DO NOT LET ANYONE INIT THIS CLASS - private DataClassForTests(){} - -// public static ClassContainer CONTAINER_TEST_CLASS() { -// ClassContainer container = new ClassContainer(); -// List categories = new ArrayList<>(); -// List entries = new ArrayList<>(); -// List qrCodes = new ArrayList<>(); -// List fields = new ArrayList<>(); -// List securityCodes = new ArrayList<>(); -// Map preferences = new HashMap<>(); -// -// categories.add(new Category(1, "Category_1")); -// categories.add(new Category(2, "Category_2")); -// -// entries.add(new Entry(1, "Account_1", "password_1", -// "icon_1", "description_1", new Category())); -// entries.add(new Entry(2, "Account_2", "password_2", -// "icon_2", "description_2", new Category())); -// -// qrCodes.add(new QRCode(1, "qrcode_1", "description_1", "qrdata", -// entries.get(0))); -// qrCodes.add(new QRCode(2, "qrcode_2", "description_2", "qrdata2", -// entries.get(1))); -// -// fields.add(new Field(1, "field_1", false, -// new SecurityCode(1, "account_1"))); -// fields.add(new Field(2, "field_2", true, -// new SecurityCode(2, "account_2"))); -// -// securityCodes.add(new SecurityCode(1, "account_1")); -// securityCodes.add(new SecurityCode(2, "account_2")); -// -// preferences.put("test_val", true); -// -// container.setCategories(categories); -// container.setEntries(entries); -// container.setQrCodes(qrCodes); -// container.setFields(fields); -// container.setSecurityCodes(securityCodes); -// container.setUserSharedPreferences(preferences); -// return container; -// } -} diff --git a/APP/app/src/main/java/javinator9889/securepass/data/entry/Entry.java b/APP/app/src/main/java/javinator9889/securepass/data/entry/Entry.java deleted file mode 100644 index 5735a41..0000000 --- a/APP/app/src/main/java/javinator9889/securepass/data/entry/Entry.java +++ /dev/null @@ -1,239 +0,0 @@ -package javinator9889.securepass.data.entry; - -import java.io.Serializable; - -import androidx.annotation.NonNull; -import javinator9889.securepass.data.entry.fields.IImage; -import javinator9889.securepass.data.entry.fields.IPassword; -import javinator9889.securepass.data.entry.fields.IText; -import javinator9889.securepass.objects.GeneralObjectContainer; -import javinator9889.securepass.objects.ObjectContainer; - -/** - * Created by Javinator9889 on 29/03/2018. - */ -public class Entry implements Serializable { - private long mId; - private GeneralObjectContainer mImages; - private GeneralObjectContainer mPasswords; - private GeneralObjectContainer mSmallTexts; - private GeneralObjectContainer mLongTexts; - private String mIcon; - private Category mCategory; - private String mName; - - /** - * Public Entry constructor which contains some different fields - * - * @param id entry ID - * @param images array containing {@link IImage} classes - * @param passwords array containing {@link IPassword} classes - * @param smallTexts array containing {@link IText} classes - see - * {@link javinator9889.securepass.data.entry.fields.SmallText} - * @param longTexts array containing {@link IText} classes - see - * {@link javinator9889.securepass.data.entry.fields.LongText} - * @param icon entry icon - * @param category entry category - * @param name entry name - * @see javinator9889.securepass.data.entry.fields.Image - * @see javinator9889.securepass.data.entry.fields.Password - * @see javinator9889.securepass.data.entry.fields.Text - * @see javinator9889.securepass.data.entry.fields.SmallText - * @see javinator9889.securepass.data.entry.fields.LongText - * @see Category - */ - public Entry(long id, - @NonNull IImage[] images, - @NonNull IPassword[] passwords, - @NonNull IText[] smallTexts, - @NonNull IText[] longTexts, - @NonNull String icon, - @NonNull Category category, - @NonNull String name) { - this.mId = id; - this.mIcon = icon; - this.mCategory = category; - this.mName = name; - this.mImages = new ObjectContainer<>(images); - this.mPasswords = new ObjectContainer<>(passwords); - this.mSmallTexts = new ObjectContainer<>(smallTexts); - this.mLongTexts = new ObjectContainer<>(longTexts); - } - - /** - * Obtains current entry ID - * - * @return long with the ID - */ - public long getId() { - return mId; - } - - /** - * Obtains current entry name - * - * @return String with the name - */ - public String getName() { - return mName; - } - - /** - * Updates entry name - * - * @param name new name - */ - public void setName(String name) { - this.mName = name; - } - - /** - * Obtains all available images inside entry - * - * @return a {@link GeneralObjectContainer} with the images - * @see IImage - * @see javinator9889.securepass.data.entry.fields.Image - * @see GeneralObjectContainer - * @see ObjectContainer - */ - public GeneralObjectContainer getImages() { - return mImages; - } - - /** - * Obtains all available long texts inside entry - * - * @return a {@link GeneralObjectContainer} with texts - * @see IText - * @see javinator9889.securepass.data.entry.fields.Text - * @see javinator9889.securepass.data.entry.fields.LongText - * @see GeneralObjectContainer - * @see ObjectContainer - */ - public GeneralObjectContainer getLongTexts() { - return mLongTexts; - } - - /** - * Obtains all available passwords inside entry - * - * @return a {@link GeneralObjectContainer} with passwords - * @see IPassword - * @see javinator9889.securepass.data.entry.fields.Password - * @see GeneralObjectContainer - * @see ObjectContainer - */ - public GeneralObjectContainer getPasswords() { - return mPasswords; - } - - /** - * Obtains all available small texts inside entry - * - * @return a {@link GeneralObjectContainer} with texts - * @see IText - * @see javinator9889.securepass.data.entry.fields.Text - * @see javinator9889.securepass.data.entry.fields.SmallText - * @see GeneralObjectContainer - * @see ObjectContainer - */ - public GeneralObjectContainer getSmallTexts() { - return mSmallTexts; - } - - /** - * Add a new image to the entry - * - * @param image new image - * @see IImage - * @see javinator9889.securepass.data.entry.fields.Image - */ - public void addImage(IImage image) { - this.mImages.storeObject(image); - } - - /** - * Add a new password to the entry - * - * @param password new password - * @see IPassword - * @see javinator9889.securepass.data.entry.fields.Password - */ - public void addPassword(IPassword password) { - this.mPasswords.storeObject(password); - } - - /** - * Add a new small text to the entry - * - * @param smallText new text - * @see IText - * @see javinator9889.securepass.data.entry.fields.Text - * @see javinator9889.securepass.data.entry.fields.SmallText - */ - public void addSmallText(IText smallText) { - this.mSmallTexts.storeObject(smallText); - } - - /** - * Add a new long text to the entry - * - * @param longText new text - * @see IText - * @see javinator9889.securepass.data.entry.fields.Text - * @see javinator9889.securepass.data.entry.fields.LongText - */ - public void addLongText(IText longText) { - this.mLongTexts.storeObject(longText); - } - - /** - * Obtains current entry icon - * - * @return String with the icon - */ - public String getIcon() { - return mIcon; - } - - /** - * Sets a new icon for the entry - * - * @param icon new icon - */ - public void setIcon(String icon) { - this.mIcon = icon; - } - - /** - * Gets current entry category - * - * @return Category in which this entry is stored - * @see Category - */ - public Category getCategory() { - return mCategory; - } - - /** - * Updates current entry category - * - * @param category new category - * @see Category - */ - public void setCategory(Category category) { - this.mCategory = category; - } - - @Override - public String toString() { - return "Entry ID: " + mId + - "\nEntry mPasswords: " + mPasswords.toString() + - "\nEntry mIcon: " + mIcon + - "\nEntry mName: " + mName + - "\nEntry mCategory: " + mCategory.toString() + - "\nEntry small texts: " + mSmallTexts.toString() + - "\nEntry long texts: " + mLongTexts.toString() + - "\nEntry mImages: " + mImages.toString(); - } -} diff --git a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/LongText.java b/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/LongText.java deleted file mode 100644 index a6c33f5..0000000 --- a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/LongText.java +++ /dev/null @@ -1,28 +0,0 @@ -package javinator9889.securepass.data.entry.fields; - -import java.io.Serializable; - -import androidx.annotation.NonNull; - -/** - * Created by Javinator9889 on 16/08/2018. - */ -public class LongText extends Text implements Serializable { - /** - * Public available constructor that uses {@link Text#Text(long, String, String) super} - * constructor - * - * @param id long text ID - * @param text long text text - * @param fieldDescription description - */ - public LongText(long id, @NonNull String text, @NonNull String fieldDescription) { - super(id, text, fieldDescription); - } - - @Override - public String toString() { - return "Text: " + getText() + "\nID: " + getTextID() + "\nField description: " - + getFieldDescription(); - } -} diff --git a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/SmallText.java b/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/SmallText.java deleted file mode 100644 index 732c0bf..0000000 --- a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/SmallText.java +++ /dev/null @@ -1,28 +0,0 @@ -package javinator9889.securepass.data.entry.fields; - -import java.io.Serializable; - -import androidx.annotation.NonNull; - -/** - * Created by Javinator9889 on 16/08/2018. - */ -public class SmallText extends Text implements Serializable { - /** - * Public available constructor that uses {@link Text#Text(long, String, String) super} - * constructor - * - * @param id long text ID - * @param text long text text - * @param fieldDescription description - */ - public SmallText(long id, @NonNull String text, @NonNull String fieldDescription) { - super(id, text, fieldDescription); - } - - @Override - public String toString() { - return "Text: " + getText() + "\nID: " + getTextID() + "\nField description: " + - getFieldDescription(); - } -} diff --git a/APP/app/src/main/java/javinator9889/securepass/io/database/operations/CommonOperations.java b/APP/app/src/main/java/javinator9889/securepass/io/database/operations/CommonOperations.java deleted file mode 100644 index cf5f2dc..0000000 --- a/APP/app/src/main/java/javinator9889/securepass/io/database/operations/CommonOperations.java +++ /dev/null @@ -1,820 +0,0 @@ -package javinator9889.securepass.io.database.operations; - -import android.content.ContentValues; -import android.util.Log; - -import net.sqlcipher.Cursor; -import net.sqlcipher.database.SQLiteDatabase; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import javinator9889.securepass.data.configuration.IConfigFields; -import javinator9889.securepass.data.entry.fields.IImage; -import javinator9889.securepass.data.entry.fields.IPassword; -import javinator9889.securepass.data.entry.fields.IText; -import javinator9889.securepass.io.database.DatabaseManager; -import javinator9889.securepass.objects.GeneralObjectContainer; -import javinator9889.securepass.util.values.Constants.SQL; -import javinator9889.securepass.util.values.DatabaseTables; - -/** - * Created by Javinator9889 on 29/03/2018. - */ -public class CommonOperations { - private static final String TAG = "Database Operations"; - private SQLiteDatabase mDatabase; - - /** - * Public constructor for creating this class - use this instad of - * {@link #newInstance(DatabaseManager)} - * - * @param databaseInstance instance of the {@link DatabaseManager} object - * @see DatabaseManager - */ - public CommonOperations(DatabaseManager databaseInstance) { - try { - databaseInstance.getDatabaseInitializer().join(); - this.mDatabase = databaseInstance.getDatabaseInstance(); - } catch (InterruptedException e) { - Log.e(getTag(), "Error while trying to join thread \"" - + SQL.DB_INIT_THREAD_NAME + "\". Interrupted exception. Full trace:"); - e.printStackTrace(); - } - } - - /** - * Public class loader - uses {@link #CommonOperations(DatabaseManager) private constructor} - * - * @param databaseManagerInstance instance of the {@link DatabaseManager} object - * @return CommonOperations - * @deprecated use {@link #CommonOperations(DatabaseManager)} instead - */ - @Deprecated - public static CommonOperations newInstance(DatabaseManager databaseManagerInstance) { - return new CommonOperations(databaseManagerInstance); - } - - /** - * Method for changing the database password - * - * @param newDatabasePassword new password - * @see SQLiteDatabase#changePassword(String) - */ - public void changeDatabasePassword(@NonNull String newDatabasePassword) { - this.mDatabase.changePassword(newDatabasePassword); - } - - /** - * Registers the default ("Global") category - * - * @return long with the category ID (should be '1') - * @see SQLiteDatabase#insertWithOnConflict(String, String, ContentValues, int) - */ - public long registerDefaultCategory() { - ContentValues params = new ContentValues(); - params.put(SQL.CATEGORY.C_ID, 1); - params.put(SQL.CATEGORY.C_NAME, "Global"); - return mDatabase.insertWithOnConflict(SQL.CATEGORY.NAME, null, params, - SQLiteDatabase.CONFLICT_IGNORE); - } - - /** - * Gets the tag for {@link Log} output - should be overridden - * - * @return String with the tag name - */ - public String getTag() { - return TAG; - } - - /** - * Tries to insert the data at the specified table - * - * @param tableName the table to insert the row - * @param params map containing the initial values - * @return the row ID or -1 if any error occurred - * @see SQLiteDatabase#insert(String, String, ContentValues) - * @see ContentValues - */ - protected long insert(@NonNull String tableName, @NonNull ContentValues params) { - return mDatabase.insert(tableName, null, params); - } - - /** - * Tries to insert the data at the specified table ignoring conflicts - * - * @param tableName the table to insert the row - * @param params map containing the initial values - * @return the row ID or -1 if any error occurred - * @see SQLiteDatabase#insertWithOnConflict(String, String, ContentValues, int) - * @see SQLiteDatabase#CONFLICT_IGNORE - * @see ContentValues - */ - protected long insertIgnoreOnConflict(@NonNull String tableName, - @NonNull ContentValues params) { - return mDatabase.insertWithOnConflict(tableName, null, params, SQLiteDatabase - .CONFLICT_IGNORE); - } - - /** - * Tries to insert the data at the specified table aborting when conflicts occur - * - * @param tableName the table to insert the row - * @param params map containing the initial values - * @return the row ID or -1 if any error occurred - * @see SQLiteDatabase#insertWithOnConflict(String, String, ContentValues, int) - * @see SQLiteDatabase#CONFLICT_ABORT - * @see ContentValues - */ - protected long insertAbortOnConflict(@NonNull String tableName, @NonNull ContentValues params) { - return mDatabase.insertWithOnConflict(tableName, null, params, SQLiteDatabase - .CONFLICT_ABORT); - } - - /** - * Tries to insert the data at the specified table doing nothing with conflicts - * - * @param tableName the table to insert the row - * @param params map containing the initial values - * @return the row ID or -1 if any error ocurred - * @see SQLiteDatabase#insertWithOnConflict(String, String, ContentValues, int) - * @see SQLiteDatabase#CONFLICT_NONE - * @see ContentValues - */ - protected long insertNoneOnConflit(@NonNull String tableName, @NonNull ContentValues params) { - return mDatabase.insertWithOnConflict(tableName, null, params, SQLiteDatabase - .CONFLICT_NONE); - } - - /** - * Tries to insert the data at the specified table failing with conflicts - * - * @param tableName the table to insert the row - * @param params map containing the initial values - * @return the row ID or -1 if any error occurred - * @see SQLiteDatabase#insertWithOnConflict(String, String, ContentValues, int) - * @see SQLiteDatabase#CONFLICT_FAIL - * @see ContentValues - */ - protected long insertFailOnConflict(@NonNull String tableName, @NonNull ContentValues params) { - return mDatabase.insertWithOnConflict(tableName, null, params, SQLiteDatabase - .CONFLICT_FAIL); - } - - /** - * Tries to insert the data at the specified table replacing conflicts - * - * @param tableName the table to insert the row - * @param params map containing the initial values - * @return the row ID or -1 if any error occurred - * @see SQLiteDatabase#insertWithOnConflict(String, String, ContentValues, int) - * @see SQLiteDatabase#CONFLICT_REPLACE - * @see ContentValues - */ - protected long insertReplaceOnConflict(@NonNull String tableName, - @NonNull ContentValues params) { - return mDatabase.insertWithOnConflict(tableName, null, params, SQLiteDatabase - .CONFLICT_REPLACE); - } - - /** - * Tries to insert the data at the specified table rolling back on conflicts - * - * @param tableName the table to insert the row - * @param params map containing the initial values - * @return the row ID or -1 if any error occurred - * @see SQLiteDatabase#insertWithOnConflict(String, String, ContentValues, int) - * @see SQLiteDatabase#CONFLICT_ROLLBACK - * @see ContentValues - */ - protected long insertRollbackOnConflict(@NonNull String tableName, - @NonNull ContentValues params) { - return mDatabase.insertWithOnConflict(tableName, null, params, SQLiteDatabase - .CONFLICT_ROLLBACK); - } - - /** - * Updates table information if exists - * - * @param tableName table name to modify - * @param values new values to insert - * @param whereClause SQL where clause - * @param whereArgs SQL where args (probably it is an ID) - * @return the affected rows - * @throws net.sqlcipher.SQLException If the SQL string is invalid for some reason - * @throws IllegalStateException if the database is not open - */ - protected int update(@NonNull String tableName, - @NonNull ContentValues values, - @NonNull String whereClause, - @NonNull String[] whereArgs) { - return mDatabase.update(tableName, values, whereClause, whereArgs); - } - - /** - * Deletes all columns for a given ID of a table - * - * @param tableName table to delete values - * @param idFieldName table column name which contains the ID - * @param id ID of the row to delete - * @return the number of rows affected - * @throws net.sqlcipher.SQLException If the SQL string is invalid for some reason - * @throws IllegalStateException if the database is not open - */ - protected int delete(@NonNull String tableName, @NonNull String idFieldName, long id) { - String whereClause = idFieldName + "=?"; - return mDatabase.delete(tableName, whereClause, setSelectionArgs(id)); - } - - /** - * Registers a new entry - * - * @param entryName entry name (non null) - * @param icon entry icon (non null) - * @param entryParentCategoryId category id of the entry - * @param configurationId configuration id of the entry - * @param entryPasswords nullable array of passwords - * @param entrySmallTexts nullable array of small texts - * @param entryLongTexts nullable array of long texts - * @param entryImages nullable array of images - * @return long with the entry ID - * @see javinator9889.securepass.data.entry.Entry - * @see IPassword - * @see IText - * @see IImage - */ - public long registerNewEntry(@NonNull String entryName, - @NonNull String icon, - long entryParentCategoryId, - long configurationId, - @Nullable IPassword[] entryPasswords, - @Nullable IText[] entrySmallTexts, - @Nullable IText[] entryLongTexts, - @Nullable IImage[] entryImages) { - ContentValues params = setParams(DatabaseTables.ENTRY, entryName, icon, - entryParentCategoryId, configurationId); - long entryId = mDatabase.insert(SQL.ENTRY.NAME, null, params); - if (entryPasswords != null) { - for (IPassword password : entryPasswords) { - ContentValues passwordParams = setParams(DatabaseTables.PASSWORD, - password.getPassword(), password.getFieldDescription(), entryId, - entryParentCategoryId); - long passwordId = - mDatabase.insert(SQL.PASSWORD.NAME, null, passwordParams); - password.setPasswordID(passwordId); - } - } - if (entrySmallTexts != null) { - for (IText smallText : entrySmallTexts) { - ContentValues smallTextParams = setParams(DatabaseTables.SMALL_TEXT, - smallText.getText(), smallText.getFieldDescription(), entryId, - entryParentCategoryId); - long smallTextId = - mDatabase.insert(SQL.SMALL_TEXT.NAME, null, smallTextParams); - smallText.setTextID(smallTextId); - } - } - if (entryLongTexts != null) { - for (IText longText : entryLongTexts) { - ContentValues longTextParams = setParams(DatabaseTables.LONG_TEXT, - longText.getText(), longText.getFieldDescription(), entryId, - entryParentCategoryId); - long longTextId = - mDatabase.insert(SQL.LONG_TEXT.NAME, null, longTextParams); - longText.setTextID(longTextId); - } - } - if (entryImages != null) { - for (IImage image : entryImages) { - ContentValues imageParams = setParams(DatabaseTables.IMAGE, - image.getImageSource(), image.getFieldDescription(), entryId, - entryParentCategoryId); - long imageId = - mDatabase.insert(SQL.IMAGE.NAME, null, imageParams); - image.setImageID(imageId); - } - } - return entryId; - } - - /** - * Registers a new category - * - * @param name category name - * @return long with the category ID - * @see javinator9889.securepass.data.entry.Category - */ - public long registerNewCategory(@NonNull String name) { - ContentValues params = setParams(DatabaseTables.CATEGORY, name); - return mDatabase.insert(SQL.CATEGORY.NAME, null, params); - } - - /** - * Registers a new QR Code - * - * @param sourceEntryId parent entry ID - * @param name QR Code name - * @param description QR Code description (nullable) - * @param qrData QR Code data - * @return long with the QRCode ID - * @see javinator9889.securepass.data.entry.QRCode - */ - public long registerQRCode(long sourceEntryId, - @NonNull String name, - @Nullable String description, - @NonNull String qrData) { - ContentValues params = setParams(DatabaseTables.QR_CODE, name, description, qrData, - sourceEntryId); - return mDatabase.insert(SQL.QR_CODE.NAME, null, params); - } - - /** - * Registers a new Security Code - * - * @param securityCodeName name of the security code - * @return long with the security code ID - * @see javinator9889.securepass.data.secret.SecurityCode - */ - public long registerNewSecurityCodeSource(@NonNull String securityCodeName) { - ContentValues params = setParams(DatabaseTables.SECURITY_CODE, - securityCodeName); - return mDatabase.insert(SQL.SECURITY_CODE.NAME, null, params); - } - - /** - * Registers a new Field of a Security Code - * - * @param fieldCode the field data - * @param isCodeUsed whether the code is already used or not - * @param parentSecurityCodeId Security Code ID - * @return long with the field ID - * @see javinator9889.securepass.data.secret.Field - * @see #registerNewSecurityCodeSource(String) - */ - public long registerNewFieldForSecurityCodeSource(@NonNull String fieldCode, - boolean isCodeUsed, - long parentSecurityCodeId) { - ContentValues params = setParams(DatabaseTables.FIELD, - fieldCode, isCodeUsed, parentSecurityCodeId); - return mDatabase.insert(SQL.FIELD.NAME, null, params); - } - - /** - * Registers a new configuration - * - * @param configurationName the name - * @param configurations Container with the configurations - * @return long with the configuration ID - * @see GeneralObjectContainer - * @see javinator9889.securepass.objects.ObjectContainer - * @see IConfigFields - */ - public long registerNewConfiguration(@NonNull String configurationName, - @NonNull GeneralObjectContainer - configurations) { - ContentValues params = setParams(DatabaseTables.CONFIGURATION, configurationName); - long configId = mDatabase.insert(SQL.CONFIGURATION.NAME, null, params); - for (IConfigFields configurationField : configurations) { - configurationField.setConfigId(configId); - ContentValues configurationFieldParams = setParams(configurationField.getTableType(), - configurationField.getDescription(), - configurationField.getSortOrder(), - configId); - long configFieldId = mDatabase.insert(configurationField.getTableName(), null, - configurationFieldParams); - configurationField.setFieldId(configFieldId); - } - return configId; - } - - /** - * Removes the given entry from the database - * - * @param entryID ID of the entry to delete - * @see javinator9889.securepass.data.entry.Entry - */ - public void deleteEntry(long entryID) { - String[] selectionArgs = setSelectionArgs(entryID); - mDatabase.delete(SQL.ENTRY.NAME, SQL.DB_DELETE_ENTRY_WHERE_CLAUSE, selectionArgs); - } - - /** - * Removes the given category from the database - * - * @param categoryID ID of the category to delete - * @see javinator9889.securepass.data.entry.Category - */ - public void deleteCategory(long categoryID) { - String[] selectionArgs = setSelectionArgs(categoryID); - ContentValues entryUpdatedValues = new ContentValues(); - entryUpdatedValues.put(SQL.ENTRY.E_PARENT_CATEGORY, 0); - mDatabase.update( - SQL.ENTRY.NAME, entryUpdatedValues, - SQL.DB_UPDATE_FOR_DELETED_CATEGORY_WHERE_CLAUSE, - selectionArgs); - mDatabase.delete(SQL.CATEGORY.NAME, SQL.DB_DELETE_CATEGORY_WHERE_CLAUSE, selectionArgs); - } - - /** - * Removes the given QRCode from the database - * - * @param qrID ID of the QRCode to delete - * @see javinator9889.securepass.data.entry.QRCode - */ - public void deleteQRCode(long qrID) { - String[] selectionArgs = setSelectionArgs(qrID); - mDatabase.delete(SQL.QR_CODE.NAME, SQL.DB_DELETE_QR_CODE_WHERE_CLAUSE, selectionArgs); - } - - /** - * Removes the given security code from the database - * - * @param securityCodeID ID of the security code to remove - * @see javinator9889.securepass.data.secret.SecurityCode - */ - public void deleteSecurityCode(long securityCodeID) { - String[] selectionArgs = setSelectionArgs(securityCodeID); - mDatabase.delete(SQL.FIELD.NAME, - SQL.DB_DELETE_FIELD_FROM_SECURITY_CODE_WHERE_CLAUSE, selectionArgs); - mDatabase.delete(SQL.SECURITY_CODE.NAME, SQL.DB_DELETE_SECURITY_CODE_WHERE_CLAUSE, - selectionArgs); - } - - /** - * Removes the given field from the database - * - * @param fieldCodeID ID of the field to remove - * @see javinator9889.securepass.data.secret.Field - */ - public void deleteField(long fieldCodeID) { - String[] selectionArgs = setSelectionArgs(fieldCodeID); - mDatabase.delete(SQL.FIELD.NAME, SQL.DB_DELETE_FIELD_WHERE_CLAUSE, selectionArgs); - } - - /** - * Updates the given entry data - * - * @param entryName new entry name - * @param icon new entry icon - * @param entryParentCategoryId new parent entry category ID - * @param entryId current entry ID - * @param configurationId new - * @param entryPasswords - * @param entrySmallTexts - * @param entryLongTexts - * @param entryImages - */ - public void updateInformationForEntry(@NonNull String entryName, - @NonNull String icon, - long entryParentCategoryId, - long entryId, - long configurationId, - @Nullable IPassword[] entryPasswords, - @Nullable IText[] entrySmallTexts, - @Nullable IText[] entryLongTexts, - @Nullable IImage[] entryImages) { - ContentValues params = setParams(DatabaseTables.ENTRY, entryName, icon, - entryParentCategoryId, configurationId); - String[] selectionArgs = setSelectionArgs(entryId); - mDatabase.update(SQL.ENTRY.NAME, params, SQL.DB_UPDATE_ENTRY_WHERE_CLAUSE, - selectionArgs); - if (entryPasswords != null) { - for (IPassword password : entryPasswords) { - ContentValues passwordParams = setParams(DatabaseTables.PASSWORD, - password.getPassword(), password.getFieldDescription(), entryId, - entryParentCategoryId); - String[] passwordSelectionArgs = setSelectionArgs(password.getPasswordID()); - mDatabase.update(SQL.PASSWORD.NAME, passwordParams, - SQL.DB_UPDATE_PASSWORD_WHERE_CLAUSE, passwordSelectionArgs); - } - } - if (entrySmallTexts != null) { - for (IText smallText : entrySmallTexts) { - ContentValues smallTextParams = setParams(DatabaseTables.SMALL_TEXT, - smallText.getText(), smallText.getFieldDescription(), entryId, - entryParentCategoryId); - String[] smallTextSelectionArgs = setSelectionArgs(smallText.getTextID()); - mDatabase.update(SQL.SMALL_TEXT.NAME, smallTextParams, - SQL.DB_UPDATE_SMALL_TEXT_WHERE_CLAUSE, smallTextSelectionArgs); - } - } - if (entryLongTexts != null) { - for (IText longText : entryLongTexts) { - ContentValues longTextParams = setParams(DatabaseTables.LONG_TEXT, - longText.getText(), longText.getFieldDescription(), entryId, - entryParentCategoryId); - String[] longTextSelectionArgs = setSelectionArgs(longText.getTextID()); - mDatabase.update(SQL.LONG_TEXT.NAME, longTextParams, - SQL.DB_UPDATE_LONG_TEXT_WHERE_CLAUSE, longTextSelectionArgs); - } - } - if (entryImages != null) { - for (IImage image : entryImages) { - ContentValues imageParams = setParams(DatabaseTables.IMAGE, - image.getImageSource(), image.getFieldDescription(), entryId, - entryParentCategoryId); - String[] imageSelectionArgs = setSelectionArgs(image.getImageID()); - mDatabase.update(SQL.IMAGE.NAME, imageParams, - SQL.DB_UPDATE_IMAGE_WHERE_CLAUSE, imageSelectionArgs); - } - } - } - - public void updateInformationForCategory(@NonNull String categoryName, long categoryId) { - ContentValues params = setParams(DatabaseTables.CATEGORY, categoryName); - String[] selectionArgs = setSelectionArgs(categoryId); - mDatabase.update(SQL.CATEGORY.NAME, params, SQL.DB_UPDATE_CATEGORY_WHERE_CLAUSE, - selectionArgs); - } - - public void updateInformationForQRCode(long sourceEntryId, @NonNull String name, - @Nullable String description, @NonNull String qrData, - long qrCodeId) { - ContentValues params = setParams(DatabaseTables.QR_CODE, name, - description, - qrData, - sourceEntryId); - String[] selectionArgs = setSelectionArgs(qrCodeId); - mDatabase.update(SQL.QR_CODE.NAME, params, SQL.DB_UPDATE_QR_CODE_WHERE_CLAUSE, - selectionArgs); - } - - public void updateInformationForSecurityCode(@NonNull String newSecurityCodeName, - long securityCodeId) { - ContentValues params = setParams(DatabaseTables.SECURITY_CODE, - newSecurityCodeName); - String[] selectionArgs = setSelectionArgs(securityCodeId); - mDatabase.update(SQL.SECURITY_CODE.NAME, params, SQL.DB_UPDATE_SECURITY_CODE_WHERE_CLAUSE, - selectionArgs); - } - - public void updateInformationForField(@NonNull String newFieldCode, - boolean isCodeUsed, - long fieldId, long securityCodeId) { - ContentValues params = setParams(DatabaseTables.FIELD, newFieldCode, - isCodeUsed, securityCodeId); - String[] selectionArgs = setSelectionArgs(fieldId); - mDatabase.update(SQL.FIELD.NAME, params, SQL.DB_UPDATE_FIELD_WHERE_CLAUSE, selectionArgs); - } - - private Map getValuesFromCursor(Cursor sourceData, DatabaseTables type) { - Map result = new HashMap<>(); - switch (type) { - case CATEGORY: - long categoryId = sourceData.getLong( - sourceData.getColumnIndexOrThrow(SQL.CATEGORY.C_ID)); - String categoryName = sourceData.getString( - sourceData.getColumnIndexOrThrow(SQL.CATEGORY.C_NAME)); - result.put(SQL.CATEGORY.C_ID, categoryId); - result.put(SQL.CATEGORY.C_NAME, categoryName); - return result; - case ENTRY: - long entryId = sourceData.getLong( - sourceData.getColumnIndexOrThrow(SQL.ENTRY.E_ID)); - String entryName = sourceData.getString( - sourceData.getColumnIndexOrThrow(SQL.ENTRY.E_NAME) - ); - String entryIcon = sourceData.getString( - sourceData.getColumnIndexOrThrow(SQL.ENTRY.E_ICON) - ); - String entryParentCategory = sourceData.getString( - sourceData - .getColumnIndexOrThrow(SQL.ENTRY.E_PARENT_CATEGORY) - ); - result.put(SQL.ENTRY.E_ID, entryId); - result.put(SQL.ENTRY.E_NAME, entryName); - result.put(SQL.ENTRY.E_ICON, entryIcon); - result.put(SQL.ENTRY.E_PARENT_CATEGORY, entryParentCategory); - return result; - case QR_CODE: - long qrCodeId = sourceData.getLong( - sourceData.getColumnIndexOrThrow(SQL.QR_CODE.Q_ID) - ); - String qrCodeName = sourceData.getString( - sourceData.getColumnIndexOrThrow(SQL.QR_CODE.Q_NAME) - ); - String qrCodeData = sourceData.getString( - sourceData.getColumnIndexOrThrow(SQL.QR_CODE.Q_DATA) - ); - String qrCodeDescription = sourceData.getString( - sourceData - .getColumnIndexOrThrow(SQL.QR_CODE.Q_DESCRIPTION) - ); - long qrCodeParentEntryId = sourceData.getLong( - sourceData.getColumnIndexOrThrow(SQL.QR_CODE.Q_PARENT_ENTRY) - ); - result.put(SQL.QR_CODE.Q_ID, qrCodeId); - result.put(SQL.QR_CODE.Q_NAME, qrCodeName); - result.put(SQL.QR_CODE.Q_DATA, qrCodeData); - result.put(SQL.QR_CODE.Q_DESCRIPTION, qrCodeDescription); - result.put(SQL.QR_CODE.Q_PARENT_ENTRY, qrCodeParentEntryId); - return result; - case SECURITY_CODE: - long securityCodeId = sourceData.getLong( - sourceData.getColumnIndexOrThrow(SQL.SECURITY_CODE.S_ID) - ); - String securityCodeName = sourceData.getString( - sourceData.getColumnIndexOrThrow(SQL.SECURITY_CODE.S_ACCOUNT_NAME) - ); - result.put(SQL.SECURITY_CODE.S_ID, securityCodeId); - result.put(SQL.SECURITY_CODE.S_ACCOUNT_NAME, securityCodeName); - return result; - case FIELD: - long fieldId = sourceData.getLong( - sourceData.getColumnIndexOrThrow(SQL.FIELD.F_ID) - ); - String fieldCode = sourceData.getString( - sourceData.getColumnIndexOrThrow(SQL.FIELD.F_CODE) - ); - boolean isFieldUsed = sourceData.getInt( - sourceData.getColumnIndexOrThrow(SQL.FIELD.F_USED) - ) == 1; - long fieldParentSecurityCode = sourceData.getLong( - sourceData.getColumnIndexOrThrow(SQL.FIELD.F_PARENT_SECURITY_CODE) - ); - result.put(SQL.FIELD.F_ID, fieldId); - result.put(SQL.FIELD.F_CODE, fieldCode); - result.put(SQL.FIELD.F_USED, isFieldUsed); - result.put(SQL.FIELD.F_PARENT_SECURITY_CODE, fieldParentSecurityCode); - return result; - default: - return result; - } - } - - public List> getAllCategories() { - String sortOrder = SQL.CATEGORY.C_ID + " DESC"; - Cursor categoriesCursor = mDatabase.query(SQL.CATEGORY.NAME, - null, - null, - null, - null, - null, - sortOrder); - List> itemsObtained = new ArrayList<>(); - while (categoriesCursor.moveToNext()) { - itemsObtained.add(getValuesFromCursor(categoriesCursor, DatabaseTables.CATEGORY)); - } - categoriesCursor.close(); - return itemsObtained; - } - - public List> getAllEntries() { - String sortOrder = SQL.ENTRY.E_ID + " DESC"; - Cursor entriesCursor = mDatabase.query(SQL.ENTRY.NAME, - null, - null, - null, - null, - null, - sortOrder); - List> entriesList = new ArrayList<>(); - while (entriesCursor.moveToNext()) { - entriesList.add(getValuesFromCursor(entriesCursor, DatabaseTables.ENTRY)); - } - entriesCursor.close(); - return entriesList; - } - - public List> getAllQRCodes() { - String sortOrder = SQL.QR_CODE.Q_ID + " DESC"; - Cursor qrCodesCursor = mDatabase.query(SQL.QR_CODE.NAME, - null, - null, - null, - null, - null, - sortOrder); - List> qrCodesList = new ArrayList<>(); - while (qrCodesCursor.moveToNext()) { - qrCodesList.add(getValuesFromCursor(qrCodesCursor, DatabaseTables.QR_CODE)); - } - qrCodesCursor.close(); - return qrCodesList; - } - - public List> getAllSecurityCodes() { - String sortOrder = SQL.SECURITY_CODE.S_ID + " DESC"; - Cursor securityCodesCursor = mDatabase.query(SQL.SECURITY_CODE.NAME, - null, - null, - null, - null, - null, - sortOrder); - List> securityCodesList = new ArrayList<>(); - while (securityCodesCursor.moveToNext()) { - securityCodesList.add(getValuesFromCursor(securityCodesCursor, - DatabaseTables.SECURITY_CODE)); - } - securityCodesCursor.close(); - return securityCodesList; - } - - public List> getAllFields() { - String sortOrder = SQL.FIELD.F_ID + " DESC"; - Cursor fieldsCursor = mDatabase.query(SQL.FIELD.NAME, - null, - null, - null, - null, - null, - sortOrder); - List> fieldsList = new ArrayList<>(); - while (fieldsCursor.moveToNext()) { - fieldsList.add(getValuesFromCursor(fieldsCursor, DatabaseTables.FIELD)); - } - fieldsCursor.close(); - return fieldsList; - } - - public void finishConnection() { - mDatabase.close(); - } - - private ContentValues setParams(DatabaseTables table, Object... values) { - ContentValues params = new ContentValues(); - switch (table) { - case CATEGORY: - params.put(SQL.CATEGORY.C_NAME, (String) values[0]); - break; - case ENTRY: - params.put(SQL.ENTRY.E_NAME, (String) values[0]); - params.put(SQL.ENTRY.E_ICON, (String) values[1]); - params.put(SQL.ENTRY.E_PARENT_CATEGORY, (long) values[2]); - params.put(SQL.ENTRY.E_PARENT_CONFIGURATION, (long) values[3]); - break; - case QR_CODE: - params.put(SQL.QR_CODE.Q_NAME, (String) values[0]); - params.put(SQL.QR_CODE.Q_DESCRIPTION, (String) values[1]); - params.put(SQL.QR_CODE.Q_DATA, (String) values[2]); - params.put(SQL.QR_CODE.Q_PARENT_ENTRY, (long) values[3]); - break; - case SECURITY_CODE: - params.put(SQL.SECURITY_CODE.S_ACCOUNT_NAME, (String) values[0]); - break; - case FIELD: - params.put(SQL.FIELD.F_CODE, (String) values[0]); - params.put(SQL.FIELD.F_USED, (boolean) values[1]); - params.put(SQL.FIELD.F_PARENT_SECURITY_CODE, (long) values[2]); - break; - case PASSWORD: - params.put(SQL.PASSWORD.P_PASSWORD, (String) values[0]); - params.put(SQL.PASSWORD.P_DESCRIPTION, (String) values[1]); - params.put(SQL.PASSWORD.P_PARENT_ENTRY, (long) values[2]); - params.put(SQL.PASSWORD.P_PARENT_CATEGORY, (long) values[3]); - break; - case IMAGE: - params.put(SQL.IMAGE.I_SOURCE, (String) values[0]); - params.put(SQL.IMAGE.I_DESCRIPTION, (String) values[1]); - params.put(SQL.IMAGE.I_PARENT_ENTRY, (long) values[2]); - params.put(SQL.IMAGE.I_PARENT_CATEGORY, (long) values[3]); - break; - case SMALL_TEXT: - params.put(SQL.SMALL_TEXT.S_TEXT, (String) values[0]); - params.put(SQL.SMALL_TEXT.S_DESCRIPTION, (String) values[1]); - params.put(SQL.SMALL_TEXT.S_PARENT_ENTRY, (long) values[2]); - params.put(SQL.SMALL_TEXT.S_PARENT_CATEGORY, (long) values[3]); - break; - case LONG_TEXT: - params.put(SQL.LONG_TEXT.L_TEXT, (String) values[0]); - params.put(SQL.LONG_TEXT.L_DESCRIPTION, (String) values[1]); - params.put(SQL.LONG_TEXT.L_PARENT_ENTRY, (long) values[2]); - params.put(SQL.LONG_TEXT.L_PARENT_CATEGORY, (long) values[3]); - break; - case CONFIGURATION: - params.put(SQL.CONFIGURATION.C_NAME, (String) values[0]); - break; - case PASS_CONFIG: - params.put(SQL.PASS_CONFIG.F_DESCRIPTION, (String) values[0]); - params.put(SQL.PASS_CONFIG.F_SORT_ORDER, (int) values[1]); - params.put(SQL.PASS_CONFIG.F_PARENT_CONFIG_ID, (long) values[2]); - break; - case SMALL_TEXT_CONFIG: - params.put(SQL.SMALL_TEXT_CONFIG.F_DESCRIPTION, (String) values[0]); - params.put(SQL.SMALL_TEXT_CONFIG.F_SORT_ORDER, (int) values[1]); - params.put(SQL.SMALL_TEXT_CONFIG.F_PARENT_CONFIG_ID, (long) values[2]); - break; - case LONG_TEXT_CONFIG: - params.put(SQL.LONG_TEXT_CONFIG.F_DESCRIPTION, (String) values[0]); - params.put(SQL.LONG_TEXT_CONFIG.F_SORT_ORDER, (int) values[1]); - params.put(SQL.LONG_TEXT_CONFIG.F_PARENT_CONFIG_ID, (long) values[2]); - break; - case IMAGES_CONFIG: - params.put(SQL.IMAGES_CONFIG.F_DESCRIPTION, (String) values[0]); - params.put(SQL.IMAGES_CONFIG.F_SORT_ORDER, (int) values[1]); - params.put(SQL.IMAGES_CONFIG.F_PARENT_CONFIG_ID, (long) values[2]); - break; - } - return params; - } - - private String[] setSelectionArgs(long id) { - return new String[]{String.valueOf(id)}; - } -} diff --git a/APP/app/src/main/java/javinator9889/securepass/io/database/operations/entry/EntryOperations.java b/APP/app/src/main/java/javinator9889/securepass/io/database/operations/entry/EntryOperations.java deleted file mode 100644 index 4c98427..0000000 --- a/APP/app/src/main/java/javinator9889/securepass/io/database/operations/entry/EntryOperations.java +++ /dev/null @@ -1,307 +0,0 @@ -package javinator9889.securepass.io.database.operations.entry; - -import android.content.ContentValues; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import javinator9889.securepass.data.configuration.Configuration; -import javinator9889.securepass.data.entry.Category; -import javinator9889.securepass.data.entry.fields.IImage; -import javinator9889.securepass.data.entry.fields.IPassword; -import javinator9889.securepass.data.entry.fields.IText; -import javinator9889.securepass.data.entry.fields.LongText; -import javinator9889.securepass.data.entry.fields.SmallText; -import javinator9889.securepass.io.database.DatabaseManager; -import javinator9889.securepass.io.database.operations.CommonOperations; -import javinator9889.securepass.util.values.Constants.SQL.ENTRY; - -/** - * Copyright © 2018 - present | APP by Javinator9889 - * - * This program 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. - * - * This program 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 this program. If not, see https://www.gnu.org/licenses/. - * - * Created by Javinator9889 on 28/10/2018 - APP. - */ -public class EntryOperations extends CommonOperations implements - IEntrySetOperations, IEntryGetOperations { - private static final String TAG = "Entry Operations"; - private static final String TABLE_NAME = ENTRY.NAME; - private static final String NAME = ENTRY.E_NAME; - private static final String ICON = ENTRY.E_ICON; - private static final String CATEGORY = ENTRY.E_PARENT_CATEGORY; - private static final String CONFIGURATION = ENTRY.E_PARENT_CONFIGURATION; - - /** - * Available constructor, matching - * {@link CommonOperations#CommonOperations(DatabaseManager) super} one - * - * @param databaseManager instance of the {@link DatabaseManager} object - * @see DatabaseManager - */ - public EntryOperations(@NonNull DatabaseManager databaseManager) { - super(databaseManager); - } - - /** - * {@inheritDoc} - */ - @Override - public String getTag() { - return TAG; - } - - /** - * Registers a new simple entry - * - * @param parentCategoryId category ID - * @param configId configuration ID - * @param entryName entry name - * @param icon entry icon - * @return long with the new entry ID - * @see Category - * @see Configuration - */ - @Override - public long registerNewEntry(long parentCategoryId, - long configId, - @NonNull String entryName, - @NonNull String icon) { - ContentValues params = setParams(entryName, icon, parentCategoryId, configId); - } - - /** - * Registers a new entry with passwords - uses - * {@link #registerNewEntry(long, long, String, String)} and - * {@link #updatePasswords(long, IPassword[])} - * - * @param parentCategoryId category ID - * @param configId configuration ID - * @param entryName entry name - * @param icon entry icon - * @param passwords array of passwords - * @return long with the new entry ID - * @see Category - * @see Configuration - * @see IPassword - */ - @Override - public long registerNewEntry(long parentCategoryId, - long configId, - @NonNull String entryName, - @NonNull String icon, - @NonNull IPassword[] passwords) { - return 0; - } - - /** - * Registers a new entry with long or small texts - uses - * {@link #registerNewEntry(long, long, String, String)} and - * {@link #updateLongTexts(long, IText[])} or {@link #updateSmallTexts(long, IText[])} - * - * @param parentCategoryId category ID - * @param configId configuration ID - * @param entryName entry name - * @param icon entry icon - * @param texts array of texts - * @return long with the new entry ID - * @see Category - * @see Configuration - * @see IText - * @see SmallText - * @see LongText - */ - @Override - public long registerNewEntry(long parentCategoryId, - long configId, - @NonNull String entryName, - @NonNull String icon, - @NonNull IText[] texts) { - return 0; - } - - /** - * Registers a new entry with iamges - uses - * {@link #registerNewEntry(long, long, String, String)} and - * {@link #updateImages(long, IImage[])} - * - * @param parentCategoryId category ID - * @param configId configuration ID - * @param entryName entry name - * @param icon entry icon - * @param images array of images - * @return long with the new entry ID - * @see Category - * @see Configuration - * @see IImage - */ - @Override - public long registerNewEntry(long parentCategoryId, - long configId, - @NonNull String entryName, - @NonNull String icon, - @NonNull IImage[] images) { - return 0; - } - - /** - * Updates entry name - * - * @param entryId entry ID - * @param name new name - */ - @Override - public void updateName(long entryId, - @NonNull String name) { - - } - - /** - * Updates entry icon - * - * @param entryId entry ID - * @param icon new icon - */ - @Override - public void updateIcon(long entryId, - @NonNull String icon) { - - } - - /** - * Updates entry category - * - * @param entryId entry ID - * @param categoryId new category ID - */ - @Override - public void updateCategory(long entryId, - long categoryId) { - - } - - /** - * Updates entry configuration - * - * @param entryId entry ID - * @param configurationId new configuration ID - */ - @Override - public void updateConfiguration(long entryId, - long configurationId) { - - } - - /** - * Updates entry passwords - if null, removes passwords - * - * @param entryId entry ID - * @param passwords new passwords - * @see #removePasswords(long) - */ - @Override - public void updatePasswords(long entryId, - @Nullable IPassword[] passwords) { - - } - - /** - * Updates entry small texts - if null, removes texts - * - * @param entryId entry ID - * @param smallTexts new small texts - * @see #removeSmallTexts(long) - */ - @Override - public void updateSmallTexts(long entryId, - @Nullable IText[] smallTexts) { - - } - - /** - * Updates entry long texts - if null, removes texts - * - * @param entryId entry ID - * @param longTexts new long texts - */ - @Override - public void updateLongTexts(long entryId, - @Nullable IText[] longTexts) { - - } - - /** - * Updates entry images - if null, removes images - * - * @param entryId entry ID - * @param images new images - * @see #removeImages(long) - */ - @Override - public void updateImages(long entryId, - @Nullable IImage[] images) { - - } - - /** - * Removes passwords for the given ID - * - * @param entryId entry ID - */ - @Override - public void removePasswords(long entryId) { - - } - - /** - * Removes small texts for the given ID - * - * @param entryId entry ID - */ - @Override - public void removeSmallTexts(long entryId) { - - } - - /** - * Removes long texts for the given ID - * - * @param entryId entry ID - */ - @Override - public void removeLongTexts(long entryId) { - - } - - /** - * Removes images for the given ID - * - * @param entryId entry ID - */ - @Override - public void removeImages(long entryId) { - - } - - private ContentValues setParams(@NonNull String entryName, - @NonNull String entryIcon, - long categoryId, - long configurationId) { - ContentValues params = new ContentValues(4); - params.put(NAME, entryName); - params.put(ICON, entryIcon); - params.put(CATEGORY, categoryId); - params.put(CONFIGURATION, configurationId); - return params; - } -} diff --git a/APP/app/src/main/java/javinator9889/securepass/io/database/operations/entry/IEntrySetOperations.java b/APP/app/src/main/java/javinator9889/securepass/io/database/operations/entry/IEntrySetOperations.java deleted file mode 100644 index fcfaa60..0000000 --- a/APP/app/src/main/java/javinator9889/securepass/io/database/operations/entry/IEntrySetOperations.java +++ /dev/null @@ -1,192 +0,0 @@ -package javinator9889.securepass.io.database.operations.entry; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import javinator9889.securepass.data.entry.fields.IImage; -import javinator9889.securepass.data.entry.fields.IPassword; -import javinator9889.securepass.data.entry.fields.IText; - -/** - * Copyright © 2018 - present | APP by Javinator9889 - * - * This program 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. - * - * This program 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 this program. If not, see https://www.gnu.org/licenses/. - * - * Created by Javinator9889 on 28/10/2018 - APP. - */ -public interface IEntrySetOperations { - /** - * Registers a new simple entry - * - * @param parentCategoryId category ID - * @param configId configuration ID - * @param entryName entry name - * @param icon entry icon - * @return long with the new entry ID - * @see javinator9889.securepass.data.entry.Category - * @see javinator9889.securepass.data.configuration.Configuration - */ - long registerNewEntry(long parentCategoryId, long configId, @NonNull String entryName, - @NonNull String icon); - - /** - * Registers a new entry with passwords - uses - * {@link #registerNewEntry(long, long, String, String)} and - * {@link #updatePasswords(long, IPassword[])} - * - * @param parentCategoryId category ID - * @param configId configuration ID - * @param entryName entry name - * @param icon entry icon - * @param passwords array of passwords - * @return long with the new entry ID - * @see javinator9889.securepass.data.entry.Category - * @see javinator9889.securepass.data.configuration.Configuration - * @see IPassword - */ - long registerNewEntry(long parentCategoryId, long configId, @NonNull String entryName, - @NonNull String icon, @NonNull IPassword[] passwords); - - /** - * Registers a new entry with long or small texts - uses - * {@link #registerNewEntry(long, long, String, String)} and - * {@link #updateLongTexts(long, IText[])} or {@link #updateSmallTexts(long, IText[])} - * - * @param parentCategoryId category ID - * @param configId configuration ID - * @param entryName entry name - * @param icon entry icon - * @param texts array of texts - * @return long with the new entry ID - * @see javinator9889.securepass.data.entry.Category - * @see javinator9889.securepass.data.configuration.Configuration - * @see IText - * @see javinator9889.securepass.data.entry.fields.SmallText - * @see javinator9889.securepass.data.entry.fields.LongText - */ - long registerNewEntry(long parentCategoryId, long configId, @NonNull String entryName, - @NonNull String icon, @NonNull IText[] texts); - - /** - * Registers a new entry with iamges - uses - * {@link #registerNewEntry(long, long, String, String)} and - * {@link #updateImages(long, IImage[])} - * - * @param parentCategoryId category ID - * @param configId configuration ID - * @param entryName entry name - * @param icon entry icon - * @param images array of images - * @return long with the new entry ID - * @see javinator9889.securepass.data.entry.Category - * @see javinator9889.securepass.data.configuration.Configuration - * @see IImage - */ - long registerNewEntry(long parentCategoryId, long configId, @NonNull String entryName, - @NonNull String icon, @NonNull IImage[] images); - - /** - * Updates entry name - * - * @param entryId entry ID - * @param name new name - */ - void updateName(long entryId, @NonNull String name); - - /** - * Updates entry icon - * - * @param entryId entry ID - * @param icon new icon - */ - void updateIcon(long entryId, @NonNull String icon); - - /** - * Updates entry category - * - * @param entryId entry ID - * @param categoryId new category ID - */ - void updateCategory(long entryId, long categoryId); - - /** - * Updates entry configuration - * - * @param entryId entry ID - * @param configurationId new configuration ID - */ - void updateConfiguration(long entryId, long configurationId); - - /** - * Updates entry passwords - if null, removes passwords - * - * @param entryId entry ID - * @param passwords new passwords - * @see #removePasswords(long) - */ - void updatePasswords(long entryId, @Nullable IPassword[] passwords); - - /** - * Updates entry small texts - if null, removes texts - * - * @param entryId entry ID - * @param smallTexts new small texts - * @see #removeSmallTexts(long) - */ - void updateSmallTexts(long entryId, @Nullable IText[] smallTexts); - - /** - * Updates entry long texts - if null, removes texts - * - * @param entryId entry ID - * @param longTexts new long texts - */ - void updateLongTexts(long entryId, @Nullable IText[] longTexts); - - /** - * Updates entry images - if null, removes images - * - * @param entryId entry ID - * @param images new images - * @see #removeImages(long) - */ - void updateImages(long entryId, @Nullable IImage[] images); - - /** - * Removes passwords for the given ID - * - * @param entryId entry ID - */ - void removePasswords(long entryId); - - /** - * Removes small texts for the given ID - * - * @param entryId entry ID - */ - void removeSmallTexts(long entryId); - - /** - * Removes long texts for the given ID - * - * @param entryId entry ID - */ - void removeLongTexts(long entryId); - - /** - * Removes images for the given ID - * - * @param entryId entry ID - */ - void removeImages(long entryId); -} diff --git a/APP/app/src/main/res/font/raleway.ttf b/APP/app/src/main/res/font/raleway.ttf deleted file mode 100644 index e570a2d..0000000 Binary files a/APP/app/src/main/res/font/raleway.ttf and /dev/null differ diff --git a/APP/app/src/main/res/font/raleway_semibold.ttf b/APP/app/src/main/res/font/raleway_semibold.ttf deleted file mode 100644 index ed0a8b9..0000000 Binary files a/APP/app/src/main/res/font/raleway_semibold.ttf and /dev/null differ diff --git a/APP/gradle/wrapper/gradle-wrapper.jar b/APP/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 13372ae..0000000 Binary files a/APP/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/DESIGN/DATABASE/Database files/.gitignore b/DESIGN/DATABASE/Database files/.gitignore index 3792793..5435022 100644 --- a/DESIGN/DATABASE/Database files/.gitignore +++ b/DESIGN/DATABASE/Database files/.gitignore @@ -1,2 +1,2 @@ -# MySQL Workbench backup files +# MySQL Workbench backup files *.bak \ No newline at end of file diff --git a/DESIGN/DATABASE/Database files/DATABASE_SCRIPT.sql b/DESIGN/DATABASE/Database files/DATABASE_SCRIPT.sql index 52619de..cf7f6c3 100644 --- a/DESIGN/DATABASE/Database files/DATABASE_SCRIPT.sql +++ b/DESIGN/DATABASE/Database files/DATABASE_SCRIPT.sql @@ -66,12 +66,11 @@ CREATE TABLE IF NOT EXISTS `Password` ( `field_desc` VARCHAR(45) NOT NULL, `sortOrder` INT NOT NULL, `idEntry` INT NOT NULL, - `cidCategory` INT NOT NULL, - PRIMARY KEY (`idPassword`, `idEntry`, `cidCategory`), - INDEX `fk_Password` (`idEntry` ASC, `cidCategory` ASC), + PRIMARY KEY (`idPassword`, `idEntry`), + INDEX `fk_Password` (`idEntry` ASC), CONSTRAINT `fk_Password_Entry1` - FOREIGN KEY (`idEntry` , `cidCategory`) - REFERENCES `Entry` (`idEntry` , `cidCategory`) + FOREIGN KEY (`idEntry`) + REFERENCES `Entry` (`idEntry`) ON DELETE CASCADE ON UPDATE NO ACTION); @@ -81,12 +80,11 @@ CREATE TABLE IF NOT EXISTS `SmallText` ( `field_desc` VARCHAR(45) NOT NULL, `sortOrder` INT NOT NULL, `idEntry` INT NOT NULL, - `cidCategory` INT NOT NULL, - PRIMARY KEY (`idSmallText`, `idEntry`, `cidCategory`), - INDEX `fk_SmallText` (`idEntry` ASC, `cidCategory` ASC), + PRIMARY KEY (`idSmallText`, `idEntry`), + INDEX `fk_SmallText` (`idEntry` ASC), CONSTRAINT `fk_SmallText_Entry1` - FOREIGN KEY (`idEntry` , `cidCategory`) - REFERENCES `Entry` (`idEntry` , `cidCategory`) + FOREIGN KEY (`idEntry`) + REFERENCES `Entry` (`idEntry`) ON DELETE CASCADE ON UPDATE NO ACTION); @@ -96,12 +94,11 @@ CREATE TABLE IF NOT EXISTS `Image` ( `field_desc` VARCHAR(45) NOT NULL, `sortOrder` INT NOT NULL, `idEntry` INT NOT NULL, - `cidCategory` INT NOT NULL, - PRIMARY KEY (`idImage`, `idEntry`, `cidCategory`), - INDEX `fk_Image` (`idEntry` ASC, `cidCategory` ASC), + PRIMARY KEY (`idImage`, `idEntry`), + INDEX `fk_Image` (`idEntry` ASC), CONSTRAINT `fk_Image_Entry1` - FOREIGN KEY (`idEntry` , `cidCategory`) - REFERENCES `Entry` (`idEntry` , `cidCategory`) + FOREIGN KEY (`idEntry`) + REFERENCES `Entry` (`idEntry`) ON DELETE CASCADE ON UPDATE NO ACTION); @@ -111,12 +108,11 @@ CREATE TABLE IF NOT EXISTS `LongText` ( `field_desc` VARCHAR(45) NOT NULL, `sortOrder` INT NOT NULL, `idEntry` INT NOT NULL, - `cidCategory` INT NOT NULL, - PRIMARY KEY (`idLongText`, `idEntry`, `cidCategory`), - INDEX `fk_LongText` (`idEntry` ASC, `cidCategory` ASC), + PRIMARY KEY (`idLongText`, `idEntry`), + INDEX `fk_LongText` (`idEntry` ASC), CONSTRAINT `fk_LongText_Entry1` - FOREIGN KEY (`idEntry` , `cidCategory`) - REFERENCES `Entry` (`idEntry` , `cidCategory`) + FOREIGN KEY (`idEntry`) + REFERENCES `Entry` (`idEntry`) ON DELETE CASCADE ON UPDATE NO ACTION); diff --git a/DESIGN/DATABASE/ER Model/ER Model.svg b/DESIGN/DATABASE/ER Model/ER Model.svg index 1fb545a..826d5ce 100644 --- a/DESIGN/DATABASE/ER Model/ER Model.svg +++ b/DESIGN/DATABASE/ER Model/ER Model.svg @@ -1,2573 +1,2573 @@ - - - - - ER Model for SecurePass - - - - - - - - - - - - - Página-1 - - - - Entidad - Application - - - - - - - - - - - - - - - - - Application - - Entidad.4 - Entry - - - - - - - - - - - - - - Entry - - - - - - - - - - - - - - - - - - - - - - Atributo - ID - - Hoja.6 - - - - - - - - - - - - - - - - - ID - - - - - - - - - - - - - - - - - - - - - - Atributo.11 - Icon - - Hoja.12 - - - - - - - - - - - Icon - - - Entidad.15 - Category - - - - - - - - - - - - - - Category - - - - - - - - - - - - - - - - - - - - - - Atributo.16 - ID - - Hoja.17 - - - - - - - - - - - - - - - - - ID - - - - - - - - - - - - - - - - - - - - - - - Atributo.18 - Name - - Hoja.19 - - - - - - - - - - - Name - - - - - - - - - - - - - - - - - - - - - - - Atributo.20 - Password - - Hoja.21 - - - - - - - - - - - - - - - - - Password - - - Entidad.22 - QR code - - - - - - - - - - - - - - QR code - - - - - - - - - - - - - - - - - - - - - - - Atributo.23 - ID - - Hoja.24 - - - - - - - - - - - - - - - - - ID - - - - - - - - - - - - - - - - - - - - - - - Atributo.25 - Data - - Hoja.26 - - - - - - - - - - - Data - - - - - - - - - - - - - - - - - - - - - - - Atributo.27 - Name - - Hoja.28 - - - - - - - - - - - Name - - - - - - - - - - - - - - - - - - - - - - - Atributo.29 - Description - - Hoja.30 - - - - - - - - - - - Description - - - Entidad.31 - Security codes - - - - - - - - - - - - - - Security codes - - - - - - - - - - - - - - - - - - - - - - - Atributo.32 - ID - - Hoja.33 - - - - - - - - - - - - - - - - - ID - - - - - - - - - - - - - - - - - - - - - - - Atributo.36 - Account name - - Hoja.37 - - - - - - - - - - - Account name - - - Entidad.38 - Fields - - - - - - - - - - - - - - Fields - - - - - - - - - - - - - - - - - - - - - - - Atributo.39 - Code - - Hoja.40 - - - - - - - - - - - - - - - - - Code - - - - - - - - - - - - - - - - - - - - - - - Atributo.41 - Used - - Hoja.42 - - - - - - - - - - - Used - - - Relación - stores - - - - - - - - - - - stores - - - - - - - - - Conector de relación - - - - - - Relación.54 - has - - - - - - - - - - - has - - - - - - - - - Conector de relación.55 - - - - - - - - - - - - - Conector de relación.60 - - - - - - Relación.65 - saves - - - - - - - - - - - saves - - - - - - - - - Conector de relación.66 - - - - - - - - - - - - - Conector de relación.71 - - - - - - Relación.76 - has - - - - - - - - - - - has - - - - - - - - - Conector de relación.77 - - - - - - - - - - - - - Conector de relación.87 - - - - - - Relación.92 - composed by - - - - - - - - - - - composed by - - - - - - - - - Conector de relación.93 - - - - - - - - - - - - - Conector de relación.98 - - - - - - Hoja.103 - 0, …, 1 - - - - 0, …, 1 - - Hoja.104 - 0, …, n - - - - 0, …, n - - Hoja.106 - 0, …, 1 - - - - 0, …, 1 - - Hoja.107 - 0, …, n - - - - 0, …, n - - Hoja.108 - 1 - - - - 1 - - Hoja.109 - 0, …, n - - - - 0, …, n - - Hoja.110 - 0, …, 1 - - - - 0, …, 1 - - Hoja.111 - 1, …, n - - - - 1, …, n - - Hoja.112 - 1 - - - - 1 - - Hoja.113 - 1, …, n - - - - 1, …, n - - Relación.114 - is contained - - - - - - - - - - - is contained - - - - - - - - - Conector de relación.115 - - - - - - Hoja.239 - 0, …, n - - - - 0, …, n - - Hoja.240 - 1 - - - - 1 - - - - - - - - - Conector de relación.246 - - - - - - - - - - - - - Conector de relación.251 - - - - - - Entidad.256 - Password - - - - - - - - - - - - - - Password - - Entidad.257 - SmallText - - - - - - - - - - - - - - SmallText - - Entidad.258 - Image - - - - - - - - - - - - - - Image - - Entidad.259 - LongText - - - - - - - - - - - - - - LongText - - - - - - - - - - - - - - - - - - - - - Atributo.260 - Password - - Hoja.261 - - - - - - - - - - - Password - - - - - - - - - - - - - - - - - - - - - - Atributo.262 - Field description - - Hoja.263 - - - - - - - - - - - Field description - - - - - - - - - - - - - - - - - - - - - - - - Atributo.264 - ID - - Hoja.265 - - - - - - - - - - - ID - - - - - - - - - - - - - - - - - - - - - - - - Atributo.266 - ID - - Hoja.267 - - - - - - - - - - - ID - - - - - - - - - - - - - - - - - - - - - - - Atributo.268 - Text - - Hoja.269 - - - - - - - - - - - Text - - - - - - - - - - - - - - - - - - - - - - - Atributo.270 - Field description - - Hoja.271 - - - - - - - - - - - Field description - - - - - - - - - - - - - - - - - - - - - - - - Atributo.272 - ID - - Hoja.273 - - - - - - - - - - - ID - - - - - - - - - - - - - - - - - - - - - - - Atributo.274 - Source - - Hoja.275 - - - - - - - - - - - Source - - - - - - - - - - - - - - - - - - - - - - - Atributo.276 - Field description - - Hoja.277 - - - - - - - - - - - Field description - - - - - - - - - - - - - - - - - - - - - - - - Atributo.278 - ID - - Hoja.279 - - - - - - - - - - - ID - - - - - - - - - - - - - - - - - - - - - - - Atributo.280 - Text - - Hoja.281 - - - - - - - - - - - Text - - - - - - - - - - - - - - - - - - - - - - - Atributo.282 - Field description - - Hoja.283 - - - - - - - - - - - Field description - - - Relación.289 - composed by - - - - - - - - - - - composed by - - - - - - - - - Conector de relación.290 - - - - - - - - - - - - - Conector de relación.295 - - - - - - - - - - - - - Conector de relación.305 - - - - - - - - - - - - - Conector de relación.310 - - - - - - - - - - - - - Conector de relación.315 - - - - - - Hoja.320 - 1 - - - - 1 - - Hoja.321 - 0, …, n - - - - 0, …, n - - Hoja.322 - 0, …, n - - - - 0, …, n - - Hoja.323 - 0, …, n - - - - 0, …, n - - Hoja.324 - 0, …, n - - - - 0, …, n - - - - - - - - - - - - - - - - - - - - - - Atributo.325 - sortOrder - - Hoja.326 - - - - - - - - - - - sortOrder - - - - - - - - - - - - - - - - - - - - - - - Atributo.327 - sortOrder - - Hoja.328 - - - - - - - - - - - sortOrder - - - - - - - - - - - - - - - - - - - - - - - Atributo.329 - sortOrder - - Hoja.330 - - - - - - - - - - - sortOrder - - - - - - - - - - - - - - - - - - - - - - - Atributo.331 - sortOrder - - Hoja.332 - - - - - - - - - - - sortOrder - - - Entidad.333 - Configuration - - - - - - - - - - - - - - Configuration - - - - - - - - - - - - - - - - - - - - - - - Atributo.334 - ID - - Hoja.335 - - - - - - - - - - - ID - - - - - - - - - - - - - - - - - - - - - - - Atributo.336 - configName - - Hoja.337 - - - - - - - - - - - configName - - - Entidad.338 - PassConfig - - - - - - - - - - - - - - PassConfig - - Entidad.339 - SmallTextConfig - - - - - - - - - - - - - - SmallTextConfig - - Entidad.340 - LongTextConfig - - - - - - - - - - - - - - LongTextConfig - - Entidad.341 - ImagesConfig - - - - - - - - - - - - - - ImagesConfig - - - - - - - - - - - - - - - - - - - - - - - Atributo.342 - ID - - Hoja.343 - - - - - - - - - - - ID - - - - - - - - - - - - - - - - - - - - - - - Atributo.344 - desc - - Hoja.345 - - - - - - - - - - - desc - - - - - - - - - - - - - - - - - - - - - - - Atributo.346 - sortOrder - - Hoja.347 - - - - - - - - - - - sortOrder - - - - - - - - - - - - - - - - - - - - - - - - Atributo.348 - ID - - Hoja.349 - - - - - - - - - - - ID - - - - - - - - - - - - - - - - - - - - - - - Atributo.350 - desc - - Hoja.351 - - - - - - - - - - - desc - - - - - - - - - - - - - - - - - - - - - - - Atributo.352 - sortOrder - - Hoja.353 - - - - - - - - - - - sortOrder - - - - - - - - - - - - - - - - - - - - - - - - Atributo.354 - ID - - Hoja.355 - - - - - - - - - - - ID - - - - - - - - - - - - - - - - - - - - - - - Atributo.356 - desc - - Hoja.357 - - - - - - - - - - - desc - - - - - - - - - - - - - - - - - - - - - - - Atributo.358 - sortOrder - - Hoja.359 - - - - - - - - - - - sortOrder - - - - - - - - - - - - - - - - - - - - - - - - Atributo.360 - ID - - Hoja.361 - - - - - - - - - - - ID - - - - - - - - - - - - - - - - - - - - - - - Atributo.362 - desc - - Hoja.363 - - - - - - - - - - - desc - - - - - - - - - - - - - - - - - - - - - - - Atributo.364 - sortOrder - - Hoja.365 - - - - - - - - - - - sortOrder - - - - - - - - - - Conector de relación.366 - - - - - - - - - - - - - Conector de relación.371 - - - - - - - - - - - - - Conector de relación.376 - - - - - - - - - - - - - Conector de relación.381 - - - - - - Hoja.386 - 0, …, n - - - - 0, …, n - - Hoja.387 - 0, …, n - - - - 0, …, n - - Hoja.388 - 0, …, n - - - - 0, …, n - - Hoja.389 - 0, …, n - - - - 0, …, n - - Hoja.390 - 1 - - - - 1 - - Hoja.391 - 1 - - - - 1 - - Hoja.392 - 1 - - - - 1 - - Hoja.393 - 1 - - - - 1 - - Relación.394 - is structured - - - - - - - - - - - is structured - - - - - - - - - Conector de relación.395 - - - - - - - - - - - - - Conector de relación.400 - - - - - - Hoja.405 - 1 - - - - 1 - - Hoja.406 - 0, …, n - - - - 0, …, n - - + + + + + ER Model for SecurePass + + + + + + + + + + + + + Página-1 + + + + Entidad + Application + + + + + + + + + + + + + + + + + Application + + Entidad.4 + Entry + + + + + + + + + + + + + + Entry + + + + + + + + + + + + + + + + + + + + + + Atributo + ID + + Hoja.6 + + + + + + + + + + + + + + + + + ID + + + + + + + + + + + + + + + + + + + + + + Atributo.11 + Icon + + Hoja.12 + + + + + + + + + + + Icon + + + Entidad.15 + Category + + + + + + + + + + + + + + Category + + + + + + + + + + + + + + + + + + + + + + Atributo.16 + ID + + Hoja.17 + + + + + + + + + + + + + + + + + ID + + + + + + + + + + + + + + + + + + + + + + + Atributo.18 + Name + + Hoja.19 + + + + + + + + + + + Name + + + + + + + + + + + + + + + + + + + + + + + Atributo.20 + Password + + Hoja.21 + + + + + + + + + + + + + + + + + Password + + + Entidad.22 + QR code + + + + + + + + + + + + + + QR code + + + + + + + + + + + + + + + + + + + + + + + Atributo.23 + ID + + Hoja.24 + + + + + + + + + + + + + + + + + ID + + + + + + + + + + + + + + + + + + + + + + + Atributo.25 + Data + + Hoja.26 + + + + + + + + + + + Data + + + + + + + + + + + + + + + + + + + + + + + Atributo.27 + Name + + Hoja.28 + + + + + + + + + + + Name + + + + + + + + + + + + + + + + + + + + + + + Atributo.29 + Description + + Hoja.30 + + + + + + + + + + + Description + + + Entidad.31 + Security codes + + + + + + + + + + + + + + Security codes + + + + + + + + + + + + + + + + + + + + + + + Atributo.32 + ID + + Hoja.33 + + + + + + + + + + + + + + + + + ID + + + + + + + + + + + + + + + + + + + + + + + Atributo.36 + Account name + + Hoja.37 + + + + + + + + + + + Account name + + + Entidad.38 + Fields + + + + + + + + + + + + + + Fields + + + + + + + + + + + + + + + + + + + + + + + Atributo.39 + Code + + Hoja.40 + + + + + + + + + + + + + + + + + Code + + + + + + + + + + + + + + + + + + + + + + + Atributo.41 + Used + + Hoja.42 + + + + + + + + + + + Used + + + Relación + stores + + + + + + + + + + + stores + + + + + + + + + Conector de relación + + + + + + Relación.54 + has + + + + + + + + + + + has + + + + + + + + + Conector de relación.55 + + + + + + + + + + + + + Conector de relación.60 + + + + + + Relación.65 + saves + + + + + + + + + + + saves + + + + + + + + + Conector de relación.66 + + + + + + + + + + + + + Conector de relación.71 + + + + + + Relación.76 + has + + + + + + + + + + + has + + + + + + + + + Conector de relación.77 + + + + + + + + + + + + + Conector de relación.87 + + + + + + Relación.92 + composed by + + + + + + + + + + + composed by + + + + + + + + + Conector de relación.93 + + + + + + + + + + + + + Conector de relación.98 + + + + + + Hoja.103 + 0, …, 1 + + + + 0, …, 1 + + Hoja.104 + 0, …, n + + + + 0, …, n + + Hoja.106 + 0, …, 1 + + + + 0, …, 1 + + Hoja.107 + 0, …, n + + + + 0, …, n + + Hoja.108 + 1 + + + + 1 + + Hoja.109 + 0, …, n + + + + 0, …, n + + Hoja.110 + 0, …, 1 + + + + 0, …, 1 + + Hoja.111 + 1, …, n + + + + 1, …, n + + Hoja.112 + 1 + + + + 1 + + Hoja.113 + 1, …, n + + + + 1, …, n + + Relación.114 + is contained + + + + + + + + + + + is contained + + + + + + + + + Conector de relación.115 + + + + + + Hoja.239 + 0, …, n + + + + 0, …, n + + Hoja.240 + 1 + + + + 1 + + + + + + + + + Conector de relación.246 + + + + + + + + + + + + + Conector de relación.251 + + + + + + Entidad.256 + Password + + + + + + + + + + + + + + Password + + Entidad.257 + SmallText + + + + + + + + + + + + + + SmallText + + Entidad.258 + Image + + + + + + + + + + + + + + Image + + Entidad.259 + LongText + + + + + + + + + + + + + + LongText + + + + + + + + + + + + + + + + + + + + + Atributo.260 + Password + + Hoja.261 + + + + + + + + + + + Password + + + + + + + + + + + + + + + + + + + + + + Atributo.262 + Field description + + Hoja.263 + + + + + + + + + + + Field description + + + + + + + + + + + + + + + + + + + + + + + + Atributo.264 + ID + + Hoja.265 + + + + + + + + + + + ID + + + + + + + + + + + + + + + + + + + + + + + + Atributo.266 + ID + + Hoja.267 + + + + + + + + + + + ID + + + + + + + + + + + + + + + + + + + + + + + Atributo.268 + Text + + Hoja.269 + + + + + + + + + + + Text + + + + + + + + + + + + + + + + + + + + + + + Atributo.270 + Field description + + Hoja.271 + + + + + + + + + + + Field description + + + + + + + + + + + + + + + + + + + + + + + + Atributo.272 + ID + + Hoja.273 + + + + + + + + + + + ID + + + + + + + + + + + + + + + + + + + + + + + Atributo.274 + Source + + Hoja.275 + + + + + + + + + + + Source + + + + + + + + + + + + + + + + + + + + + + + Atributo.276 + Field description + + Hoja.277 + + + + + + + + + + + Field description + + + + + + + + + + + + + + + + + + + + + + + + Atributo.278 + ID + + Hoja.279 + + + + + + + + + + + ID + + + + + + + + + + + + + + + + + + + + + + + Atributo.280 + Text + + Hoja.281 + + + + + + + + + + + Text + + + + + + + + + + + + + + + + + + + + + + + Atributo.282 + Field description + + Hoja.283 + + + + + + + + + + + Field description + + + Relación.289 + composed by + + + + + + + + + + + composed by + + + + + + + + + Conector de relación.290 + + + + + + + + + + + + + Conector de relación.295 + + + + + + + + + + + + + Conector de relación.305 + + + + + + + + + + + + + Conector de relación.310 + + + + + + + + + + + + + Conector de relación.315 + + + + + + Hoja.320 + 1 + + + + 1 + + Hoja.321 + 0, …, n + + + + 0, …, n + + Hoja.322 + 0, …, n + + + + 0, …, n + + Hoja.323 + 0, …, n + + + + 0, …, n + + Hoja.324 + 0, …, n + + + + 0, …, n + + + + + + + + + + + + + + + + + + + + + + Atributo.325 + sortOrder + + Hoja.326 + + + + + + + + + + + sortOrder + + + + + + + + + + + + + + + + + + + + + + + Atributo.327 + sortOrder + + Hoja.328 + + + + + + + + + + + sortOrder + + + + + + + + + + + + + + + + + + + + + + + Atributo.329 + sortOrder + + Hoja.330 + + + + + + + + + + + sortOrder + + + + + + + + + + + + + + + + + + + + + + + Atributo.331 + sortOrder + + Hoja.332 + + + + + + + + + + + sortOrder + + + Entidad.333 + Configuration + + + + + + + + + + + + + + Configuration + + + + + + + + + + + + + + + + + + + + + + + Atributo.334 + ID + + Hoja.335 + + + + + + + + + + + ID + + + + + + + + + + + + + + + + + + + + + + + Atributo.336 + configName + + Hoja.337 + + + + + + + + + + + configName + + + Entidad.338 + PassConfig + + + + + + + + + + + + + + PassConfig + + Entidad.339 + SmallTextConfig + + + + + + + + + + + + + + SmallTextConfig + + Entidad.340 + LongTextConfig + + + + + + + + + + + + + + LongTextConfig + + Entidad.341 + ImagesConfig + + + + + + + + + + + + + + ImagesConfig + + + + + + + + + + + + + + + + + + + + + + + Atributo.342 + ID + + Hoja.343 + + + + + + + + + + + ID + + + + + + + + + + + + + + + + + + + + + + + Atributo.344 + desc + + Hoja.345 + + + + + + + + + + + desc + + + + + + + + + + + + + + + + + + + + + + + Atributo.346 + sortOrder + + Hoja.347 + + + + + + + + + + + sortOrder + + + + + + + + + + + + + + + + + + + + + + + + Atributo.348 + ID + + Hoja.349 + + + + + + + + + + + ID + + + + + + + + + + + + + + + + + + + + + + + Atributo.350 + desc + + Hoja.351 + + + + + + + + + + + desc + + + + + + + + + + + + + + + + + + + + + + + Atributo.352 + sortOrder + + Hoja.353 + + + + + + + + + + + sortOrder + + + + + + + + + + + + + + + + + + + + + + + + Atributo.354 + ID + + Hoja.355 + + + + + + + + + + + ID + + + + + + + + + + + + + + + + + + + + + + + Atributo.356 + desc + + Hoja.357 + + + + + + + + + + + desc + + + + + + + + + + + + + + + + + + + + + + + Atributo.358 + sortOrder + + Hoja.359 + + + + + + + + + + + sortOrder + + + + + + + + + + + + + + + + + + + + + + + + Atributo.360 + ID + + Hoja.361 + + + + + + + + + + + ID + + + + + + + + + + + + + + + + + + + + + + + Atributo.362 + desc + + Hoja.363 + + + + + + + + + + + desc + + + + + + + + + + + + + + + + + + + + + + + Atributo.364 + sortOrder + + Hoja.365 + + + + + + + + + + + sortOrder + + + + + + + + + + Conector de relación.366 + + + + + + + + + + + + + Conector de relación.371 + + + + + + + + + + + + + Conector de relación.376 + + + + + + + + + + + + + Conector de relación.381 + + + + + + Hoja.386 + 0, …, n + + + + 0, …, n + + Hoja.387 + 0, …, n + + + + 0, …, n + + Hoja.388 + 0, …, n + + + + 0, …, n + + Hoja.389 + 0, …, n + + + + 0, …, n + + Hoja.390 + 1 + + + + 1 + + Hoja.391 + 1 + + + + 1 + + Hoja.392 + 1 + + + + 1 + + Hoja.393 + 1 + + + + 1 + + Relación.394 + is structured + + + + + + + + + + + is structured + + + + + + + + + Conector de relación.395 + + + + + + + + + + + + + Conector de relación.400 + + + + + + Hoja.405 + 1 + + + + 1 + + Hoja.406 + 0, …, n + + + + 0, …, n + + diff --git a/DESIGN/REQUIREMENTS/.gitignore b/DESIGN/REQUIREMENTS/.gitignore index bc94f2f..39db78a 100644 --- a/DESIGN/REQUIREMENTS/.gitignore +++ b/DESIGN/REQUIREMENTS/.gitignore @@ -1,6 +1,6 @@ -# DOCX files (Microsoft Word) -*.docx - -# Certificate files -*.p12 +# DOCX files (Microsoft Word) +*.docx + +# Certificate files +*.p12 *.crt \ No newline at end of file diff --git a/LICENSE b/LICENSE index 94a9ed0..818433e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,674 +1,674 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program 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. - - This program 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 this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program 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. + + This program 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 this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/README.md b/README.md index 17b8e9d..81d2cfc 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ -# SecurePass -Store and keep your passwords and accounts secure +# SecurePass +Store and keep your passwords and accounts secure + +[![Build Status](https://travis-ci.com/Javinator9889/SecurePass.svg?branch=database)](https://travis-ci.com/Javinator9889/SecurePass) diff --git a/APP/.gitignore b/SecurePass/.gitignore similarity index 65% rename from APP/.gitignore rename to SecurePass/.gitignore index f22146b..9eb2564 100644 --- a/APP/.gitignore +++ b/SecurePass/.gitignore @@ -1,6 +1,7 @@ # Built application files *.apk *.ap_ +*.aab # Files for the ART/Dalvik VM *.dex @@ -32,25 +33,46 @@ proguard/ # Android Studio captures folder captures/ -# Intellij +# IntelliJ *.iml .idea/workspace.xml .idea/tasks.xml .idea/gradle.xml +.idea/assetWizardSettings.xml .idea/dictionaries .idea/libraries +.idea/caches +.idea # Keystore files +# Uncomment the following lines if you do not want to check your keystore files in. *.jks +*.keystore # External native build folder generated in Android Studio 2.2 and later .externalNativeBuild # Google Services (e.g. APIs or Firebase) google-services.json -*.json # Freeline freeline.py freeline/ freeline_project_description.json + +# fastlane +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output +fastlane/readme.md + +# Version control +vcs.xml + +# lint +lint/intermediates/ +lint/generated/ +lint/outputs/ +lint/tmp/ +# lint/reports/ \ No newline at end of file diff --git a/APP/AppBeforeMigratingAndroidX.zip b/SecurePass/AppBeforeMigratingAndroidX.zip similarity index 100% rename from APP/AppBeforeMigratingAndroidX.zip rename to SecurePass/AppBeforeMigratingAndroidX.zip diff --git a/APP/app/.gitignore b/SecurePass/app/.gitignore similarity index 100% rename from APP/app/.gitignore rename to SecurePass/app/.gitignore diff --git a/SecurePass/app/.gradle/4.4/fileChanges/last-build.bin b/SecurePass/app/.gradle/4.4/fileChanges/last-build.bin new file mode 100644 index 0000000..f76dd23 Binary files /dev/null and b/SecurePass/app/.gradle/4.4/fileChanges/last-build.bin differ diff --git a/SecurePass/app/.gradle/4.4/fileHashes/fileHashes.bin b/SecurePass/app/.gradle/4.4/fileHashes/fileHashes.bin new file mode 100644 index 0000000..99dda35 Binary files /dev/null and b/SecurePass/app/.gradle/4.4/fileHashes/fileHashes.bin differ diff --git a/SecurePass/app/.gradle/4.4/fileHashes/fileHashes.lock b/SecurePass/app/.gradle/4.4/fileHashes/fileHashes.lock new file mode 100644 index 0000000..c09ad84 Binary files /dev/null and b/SecurePass/app/.gradle/4.4/fileHashes/fileHashes.lock differ diff --git a/SecurePass/app/application.iml b/SecurePass/app/application.iml new file mode 100644 index 0000000..97519c6 --- /dev/null +++ b/SecurePass/app/application.iml @@ -0,0 +1,223 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SecurePass/app/application.iml.bak b/SecurePass/app/application.iml.bak new file mode 100644 index 0000000..fef3c9a --- /dev/null +++ b/SecurePass/app/application.iml.bak @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SecurePass/app/build.gradle b/SecurePass/app/build.gradle new file mode 100644 index 0000000..cbb57c0 --- /dev/null +++ b/SecurePass/app/build.gradle @@ -0,0 +1,142 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 28 + defaultConfig { + applicationId "javinator9889.securepass" + minSdkVersion 19 + targetSdkVersion 28 + versionCode 160 + versionName "d0.48" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + multiDexEnabled true + } + /*flavorDimensions "versions" + productFlavors { + development { + versionNameSuffix "-d" + dimension "versions" + } + final_release { + dimension "versions" + } + }*/ + buildTypes { + release { + //shrinkResources true + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + // Android X configuration for more interoperability + configurations.all { + resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9' + resolutionStrategy.eachDependency { DependencyResolveDetails details -> + def requested = details.requested + if (requested.group == "com.android.support") { + if (!requested.name.startsWith("multidex")) { + details.useVersion "26.+" + } + } + } + } + buildToolsVersion '28.0.3' + + dexOptions { + } + + compileOptions { + sourceCompatibility = '1.8' + targetCompatibility = '1.8' + } + + defaultConfig { + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + // The following argument makes the Android Test Orchestrator run its + // "pm clear" command after each test invocation. This command ensures + // that the app's state is completely cleared between tests. + testInstrumentationRunnerArguments clearPackageData: 'true' + } + + testOptions { + execution 'ANDROIDX_TEST_ORCHESTRATOR' + } +} + +dependencies { + implementation fileTree(include: ['*.jar'], dir: 'libs') + implementation 'androidx.appcompat:appcompat:1.0.2' + // Libs from AppCompat with different versions - incompatibilities with Google Play Services + implementation 'androidx.mediarouter:mediarouter:1.0.0' + implementation 'androidx.legacy:legacy-support-v4:1.0.0' + implementation 'androidx.recyclerview:recyclerview:1.0.0' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation 'com.google.android.material:material:1.0.0' + implementation 'androidx.core:core:1.0.1' + implementation 'androidx.legacy:legacy-support-v4:1.0.0' + implementation 'androidx.viewpager:viewpager:1.0.0' + implementation 'androidx.fragment:fragment:1.0.0' + implementation 'androidx.legacy:legacy-support-core-ui:1.0.0' + implementation 'androidx.legacy:legacy-support-core-utils:1.0.0' + implementation 'androidx.annotation:annotation:1.0.1' + implementation 'androidx.customview:customview:1.0.0' + implementation 'androidx.browser:browser:1.0.0' + implementation 'androidx.multidex:multidex:2.0.1' + // Test implementation libs + testImplementation 'androidx.test:core:1.1.0' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test:runner:1.1.1' + androidTestUtil 'androidx.test:orchestrator:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' + // User compilations and libraries + // SQLCipher - https://guardianproject.info/code/sqlcipher/ + implementation 'net.zetetic:android-database-sqlcipher:3.5.9@aar' + // AppIntro - https://github.com/apl-devs/AppIntro + implementation 'com.github.paolorotolo:appintro:v5.1.0' + // Google Play Services - https://developers.google.com/android/guides/setup + implementation 'com.google.android.gms:play-services-drive:16.0.0' + implementation 'com.google.android.gms:play-services-auth:16.0.1' + implementation 'com.google.android.gms:play-services-identity:16.0.0' + implementation 'com.google.android.gms:play-services-base:16.1.0' + implementation 'com.google.android.gms:play-services-gcm:16.0.0' + // Material Dialog - https://github.com/afollestad/material-dialogs + implementation 'com.afollestad.material-dialogs:core:0.9.6.0' + // Google Guava - https://github.com/google/guava + implementation 'com.google.guava:guava:24.1-jre' + // Markwon - https://github.com/noties/Markwon + implementation 'ru.noties:markwon:1.0.4' + // SharedChamber - https://github.com/afiqiqmal/SharedChamber + implementation 'com.github.afiqiqmal:SharedChamber:2.5.0' + // CloudRail - https://github.com/CloudRail/cloudrail-si-android-sdk + implementation 'com.cloudrail:cloudrail-si-android:2.21.6' + // SmartTabLayout - https://github.com/ogaclejapan/SmartTabLayout + implementation 'com.ogaclejapan.smarttablayout:library:1.6.1@aar' + implementation 'com.ogaclejapan.smarttablayout:utils-v4:1.6.1@aar' + // AutoValue - https://github.com/google/auto/tree/master/value + annotationProcessor 'com.google.auto.value:auto-value:1.5.2' + annotationProcessor 'com.ryanharter.auto.value:auto-value-parcel:0.2.5' + compileOnly 'com.jakewharton.auto.value:auto-value-annotations:1.4' + implementation 'com.ryanharter.auto.value:auto-value-parcel-adapter:0.2.6' + // Android Iconics - https://github.com/mikepenz/Android-Iconics + implementation 'com.mikepenz:iconics-core:3.1.0@aar' + implementation 'com.mikepenz:material-design-iconic-typeface:2.2.0.5@aar' + implementation 'com.mikepenz:iconics-views:3.1.0' + // TextLayoutBuilder - https://github.com/facebook/TextLayoutBuilder + // implementation 'com.facebook.fbui.textlayoutbuilder:textlayoutbuilder:1.4.0' + // android-fab - https://github.com/markormesher/android-fab + implementation 'uk.co.markormesher:android-fab:2.4.1' + // FileToBytesExporter - https://github.com/Javinator9889/FileToBytesExporter + implementation 'com.github.javinator9889:filetobytesexporter:1.0.5' + + // Threading Tools - https://github.com/Javinator9889/ThreadingTools + implementation 'com.github.javinator9889:threadingtools:1.0' + // HKDF - https://github.com/patrickfav/hkdf + implementation group: 'at.favre.lib', name: 'hkdf', version: '1.0.0' + // scrypt - https://github.com/wg/scrypt + implementation group: 'com.lambdaworks', name: 'scrypt', version: '1.4.0' + // LocaleManager - https://github.com/Javinator9889/LocaleManager + implementation 'com.github.javinator9889:localemanager:1.1X' + // StreamSupport - https://github.com/stefan-zobel/streamsupport + implementation 'net.sourceforge.streamsupport:streamsupport:1.7.0' +} diff --git a/APP/app/build.gradle b/SecurePass/app/build.gradle.old similarity index 75% rename from APP/app/build.gradle rename to SecurePass/app/build.gradle.old index ce678bc..aa65f30 100644 --- a/APP/app/build.gradle +++ b/SecurePass/app/build.gradle.old @@ -1,127 +1,147 @@ -apply plugin: 'com.android.application' - -android { - compileSdkVersion 28 - defaultConfig { - applicationId "javinator9889.securepass" - minSdkVersion 19 - targetSdkVersion 28 - versionCode 157 - versionName "d0.47.81" - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - multiDexEnabled true - } - /*flavorDimensions "versions" - productFlavors { - development { - versionNameSuffix "-d" - dimension "versions" - } - final_release { - dimension "versions" - } - }*/ - buildTypes { - release { - //shrinkResources true - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } - /*compileOptions { - targetCompatibility JavaVersion.VERSION_1_8 - sourceCompatibility JavaVersion.VERSION_1_8 - }*/ -// configurations.all { -// resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9'; -// resolutionStrategy.eachDependency { DependencyResolveDetails details -> -// def requested = details.requested -// if (requested.group == "com.android.support") { -// if (!requested.name.startsWith("multidex")) { -// details.useVersion "26.+" -// } -// } -// } -// } - // Android X configuration for more interoperability - configurations.all { - resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9' - resolutionStrategy.eachDependency { DependencyResolveDetails details -> - def requested = details.requested - if (requested.group == "com.android.support") { - if (!requested.name.startsWith("multidex")) { - details.useVersion "26.+" - } - } - } - } - buildToolsVersion '28.0.3' - dexOptions { - } - compileOptions { - sourceCompatibility = '1.8' - targetCompatibility = '1.8' - } -} - -dependencies { - implementation fileTree(include: ['*.jar'], dir: 'libs') - implementation 'androidx.appcompat:appcompat:1.0.0' - // Libs from AppCompat with different versions - incompatibilities with Google Play Services - implementation 'androidx.mediarouter:mediarouter:1.0.0' - implementation 'androidx.legacy:legacy-support-v4:1.0.0' - implementation 'androidx.recyclerview:recyclerview:1.0.0' - implementation 'androidx.constraintlayout:constraintlayout:1.1.3' - implementation 'com.google.android.material:material:1.0.0' - implementation 'androidx.core:core:1.0.0' - implementation 'androidx.legacy:legacy-support-v4:1.0.0' - implementation 'androidx.viewpager:viewpager:1.0.0' - implementation 'androidx.fragment:fragment:1.0.0' - implementation 'androidx.legacy:legacy-support-core-ui:1.0.0' - implementation 'androidx.legacy:legacy-support-core-utils:1.0.0' - implementation 'androidx.annotation:annotation:1.0.0' - implementation 'androidx.customview:customview:1.0.0' - implementation 'androidx.browser:browser:1.0.0' - implementation 'androidx.multidex:multidex:2.0.0' - // Test implementation libs - testImplementation 'junit:junit:4.12' - androidTestImplementation 'androidx.test:runner:1.1.0-beta02' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0-beta02' - // User compilations and libraries - // SQLCipher - https://guardianproject.info/code/sqlcipher/ - implementation 'net.zetetic:android-database-sqlcipher:3.5.9@aar' - // AppIntro - https://github.com/apl-devs/AppIntro - implementation 'com.github.paolorotolo:appintro:v5.1.0' - // Google Play Services - https://developers.google.com/android/guides/setup - implementation 'com.google.android.gms:play-services-drive:16.0.0' - implementation 'com.google.android.gms:play-services-auth:16.0.1' - implementation 'com.google.android.gms:play-services-identity:16.0.0' - implementation 'com.google.android.gms:play-services-base:16.0.1' - implementation 'com.google.android.gms:play-services-gcm:16.0.0' - // Material Dialog - https://github.com/afollestad/material-dialogs - implementation 'com.afollestad.material-dialogs:core:0.9.6.0' - // Google Guava - https://github.com/google/guava - implementation 'com.google.guava:guava:24.1-jre' - // Markwon - https://github.com/noties/Markwon - implementation 'ru.noties:markwon:1.0.4' - // SharedChamber - https://github.com/afiqiqmal/SharedChamber - implementation 'com.github.afiqiqmal:SharedChamber:2.5.0' - // CloudRail - https://github.com/CloudRail/cloudrail-si-android-sdk - implementation 'com.cloudrail:cloudrail-si-android:2.21.6' - // SmartTabLayout - https://github.com/ogaclejapan/SmartTabLayout - implementation 'com.ogaclejapan.smarttablayout:library:1.6.1@aar' - implementation 'com.ogaclejapan.smarttablayout:utils-v4:1.6.1@aar' - // AutoValue - https://github.com/google/auto/tree/master/value - annotationProcessor 'com.google.auto.value:auto-value:1.5.2' - annotationProcessor 'com.ryanharter.auto.value:auto-value-parcel:0.2.5' - compileOnly 'com.jakewharton.auto.value:auto-value-annotations:1.4' - implementation 'com.ryanharter.auto.value:auto-value-parcel-adapter:0.2.6' - // Android Iconics - https://github.com/mikepenz/Android-Iconics - implementation "com.mikepenz:iconics-core:3.1.0@aar" - implementation 'com.mikepenz:material-design-iconic-typeface:2.2.0.5@aar' - implementation "com.mikepenz:iconics-views:3.1.0" - // TextLayoutBuilder - https://github.com/facebook/TextLayoutBuilder -// implementation 'com.facebook.fbui.textlayoutbuilder:textlayoutbuilder:1.4.0' - // android-fab - https://github.com/markormesher/android-fab - implementation 'uk.co.markormesher:android-fab:2.4.1' -} +apply plugin: 'com.android.application' + +android { + compileSdkVersion 28 + defaultConfig { + applicationId "javinator9889.securepass" + minSdkVersion 19 + targetSdkVersion 28 + versionCode 160 + versionName "d0.48" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + multiDexEnabled true + } + /*flavorDimensions "versions" + productFlavors { + development { + versionNameSuffix "-d" + dimension "versions" + } + final_release { + dimension "versions" + } + }*/ + buildTypes { + release { + //shrinkResources true + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + /*compileOptions { + targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_1_8 + }*/ +// configurations.all { +// resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9'; +// resolutionStrategy.eachDependency { DependencyResolveDetails details -> +// def requested = details.requested +// if (requested.group == "com.android.support") { +// if (!requested.name.startsWith("multidex")) { +// details.useVersion "26.+" +// } +// } +// } +// } + // Android X configuration for more interoperability + configurations.all { + resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9' + resolutionStrategy.eachDependency { DependencyResolveDetails details -> + def requested = details.requested + if (requested.group == "com.android.support") { + if (!requested.name.startsWith("multidex")) { + details.useVersion "26.+" + } + } + } + } + buildToolsVersion '28.0.3' + dexOptions { + } + compileOptions { + sourceCompatibility = '1.8' + targetCompatibility = '1.8' +// sourceCompatibility JavaVersion.VERSION_1_8 +// targetCompatibility JavaVersion.VERSION_1_8 + } + defaultConfig { + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + // The following argument makes the Android Test Orchestrator run its + // "pm clear" command after each test invocation. This command ensures + // that the app's state is completely cleared between tests. + testInstrumentationRunnerArguments clearPackageData: 'true' + } +} + +dependencies { + implementation fileTree(include: ['*.jar'], dir: 'libs') + implementation 'androidx.appcompat:appcompat:1.0.2' + // Libs from AppCompat with different versions - incompatibilities with Google Play Services + implementation 'androidx.mediarouter:mediarouter:1.0.0' + implementation 'androidx.legacy:legacy-support-v4:1.0.0' + implementation 'androidx.recyclerview:recyclerview:1.0.0' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation 'com.google.android.material:material:1.0.0' + implementation 'androidx.core:core:1.0.1' + implementation 'androidx.legacy:legacy-support-v4:1.0.0' + implementation 'androidx.viewpager:viewpager:1.0.0' + implementation 'androidx.fragment:fragment:1.0.0' + implementation 'androidx.legacy:legacy-support-core-ui:1.0.0' + implementation 'androidx.legacy:legacy-support-core-utils:1.0.0' + implementation 'androidx.annotation:annotation:1.0.0' + implementation 'androidx.customview:customview:1.0.0' + implementation 'androidx.browser:browser:1.0.0' + implementation 'androidx.multidex:multidex:2.0.0' + // Test implementation libs + testImplementation 'androidx.test:core:1.0.0' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test:runner:1.1.0' + androidTestUtil 'androidx.test:orchestrator:1.1.0' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0' + // User compilations and libraries + // SQLCipher - https://guardianproject.info/code/sqlcipher/ + implementation 'net.zetetic:android-database-sqlcipher:3.5.9@aar' + // AppIntro - https://github.com/apl-devs/AppIntro + implementation 'com.github.paolorotolo:appintro:v5.1.0' + // Google Play Services - https://developers.google.com/android/guides/setup + implementation 'com.google.android.gms:play-services-drive:16.0.0' + implementation 'com.google.android.gms:play-services-auth:16.0.1' + implementation 'com.google.android.gms:play-services-identity:16.0.0' + implementation 'com.google.android.gms:play-services-base:16.0.1' + implementation 'com.google.android.gms:play-services-gcm:16.0.0' + // Material Dialog - https://github.com/afollestad/material-dialogs + implementation 'com.afollestad.material-dialogs:core:0.9.6.0' + // Google Guava - https://github.com/google/guava + implementation 'com.google.guava:guava:24.1-jre' + // Markwon - https://github.com/noties/Markwon + implementation 'ru.noties:markwon:1.0.4' + // SharedChamber - https://github.com/afiqiqmal/SharedChamber + implementation 'com.github.afiqiqmal:SharedChamber:2.5.0' + // CloudRail - https://github.com/CloudRail/cloudrail-si-android-sdk + implementation 'com.cloudrail:cloudrail-si-android:2.21.6' + // SmartTabLayout - https://github.com/ogaclejapan/SmartTabLayout + implementation 'com.ogaclejapan.smarttablayout:library:1.6.1@aar' + implementation 'com.ogaclejapan.smarttablayout:utils-v4:1.6.1@aar' + // AutoValue - https://github.com/google/auto/tree/master/value + annotationProcessor 'com.google.auto.value:auto-value:1.5.2' + annotationProcessor 'com.ryanharter.auto.value:auto-value-parcel:0.2.5' + compileOnly 'com.jakewharton.auto.value:auto-value-annotations:1.4' + implementation 'com.ryanharter.auto.value:auto-value-parcel-adapter:0.2.6' + // Android Iconics - https://github.com/mikepenz/Android-Iconics + implementation 'com.mikepenz:iconics-core:3.1.0@aar' + implementation 'com.mikepenz:material-design-iconic-typeface:2.2.0.5@aar' + implementation 'com.mikepenz:iconics-views:3.1.0' + // TextLayoutBuilder - https://github.com/facebook/TextLayoutBuilder + // implementation 'com.facebook.fbui.textlayoutbuilder:textlayoutbuilder:1.4.0' + // android-fab - https://github.com/markormesher/android-fab + implementation 'uk.co.markormesher:android-fab:2.4.1' + // FileToBytesExporter - https://github.com/Javinator9889/FileToBytesExporter + implementation 'com.github.javinator9889:filetobytesexporter:1.0.4' + // Threading Tools - https://github.com/Javinator9889/ThreadingTools + implementation 'com.github.javinator9889:threadingtools:1.0' + // HKDF - https://github.com/patrickfav/hkdf + implementation group: 'at.favre.lib', name: 'hkdf', version: '1.0.0' + // scrypt - https://github.com/wg/scrypt + implementation group: 'com.lambdaworks', name: 'scrypt', version: '1.4.0' +} diff --git a/SecurePass/app/build/generated/source/buildConfig/debug/javinator9889/securepass/BuildConfig.java b/SecurePass/app/build/generated/source/buildConfig/debug/javinator9889/securepass/BuildConfig.java new file mode 100644 index 0000000..a5232e5 --- /dev/null +++ b/SecurePass/app/build/generated/source/buildConfig/debug/javinator9889/securepass/BuildConfig.java @@ -0,0 +1,13 @@ +/** + * Automatically generated file. DO NOT MODIFY + */ +package javinator9889.securepass; + +public final class BuildConfig { + public static final boolean DEBUG = Boolean.parseBoolean("true"); + public static final String APPLICATION_ID = "javinator9889.securepass"; + public static final String BUILD_TYPE = "debug"; + public static final String FLAVOR = ""; + public static final int VERSION_CODE = 160; + public static final String VERSION_NAME = "d0.48"; +} diff --git a/SecurePass/app/class.bck b/SecurePass/app/class.bck new file mode 100644 index 0000000..3a41f0d Binary files /dev/null and b/SecurePass/app/class.bck differ diff --git a/SecurePass/app/debug/app-debug.apk b/SecurePass/app/debug/app-debug.apk new file mode 100644 index 0000000..74d817c Binary files /dev/null and b/SecurePass/app/debug/app-debug.apk differ diff --git a/APP/app/debug/output.json b/SecurePass/app/debug/output.json similarity index 100% rename from APP/app/debug/output.json rename to SecurePass/app/debug/output.json diff --git a/APP/app/proguard-rules.pro b/SecurePass/app/proguard-rules.pro similarity index 97% rename from APP/app/proguard-rules.pro rename to SecurePass/app/proguard-rules.pro index f1b4245..6e7ffa9 100644 --- a/APP/app/proguard-rules.pro +++ b/SecurePass/app/proguard-rules.pro @@ -1,21 +1,21 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/APP/app/src/androidTest/java/javinator9889/securepass/CipherTest.java b/SecurePass/app/src/androidTest/java/javinator9889/securepass/CipherTest.java similarity index 92% rename from APP/app/src/androidTest/java/javinator9889/securepass/CipherTest.java rename to SecurePass/app/src/androidTest/java/javinator9889/securepass/CipherTest.java index 54bd8b1..2e38624 100644 --- a/APP/app/src/androidTest/java/javinator9889/securepass/CipherTest.java +++ b/SecurePass/app/src/androidTest/java/javinator9889/securepass/CipherTest.java @@ -1,86 +1,84 @@ -package javinator9889.securepass; - -import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; - -import com.google.common.io.ByteStreams; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Arrays; - -import javinator9889.securepass.data.container.ClassContainer; -import javinator9889.securepass.data.entry.Category; -import javinator9889.securepass.data.entry.Entry; -import javinator9889.securepass.data.entry.QRCode; -import javinator9889.securepass.data.secret.Field; -import javinator9889.securepass.data.secret.SecurityCode; -import javinator9889.securepass.util.cipher.FileCipherOld; - -/** - * Created by Javinator9889 on 20/04/2018. - */ -@RunWith(AndroidJUnit4.class) -public class CipherTest { - private Context context = InstrumentationRegistry.getTargetContext(); - private String password = "random_password"; - private String filename = context.getFilesDir().getAbsolutePath() + "/class.bck"; - private String iv_filename = context.getFilesDir().getAbsolutePath() + "/iv"; - private byte[] iv; - -// @Test -// public void storeAClassInFile() throws Exception { -// FileCipherOld cipher = FileCipherOld.newInstance(password, null); -// iv = cipher.getIv(); -// System.out.println(Arrays.toString(iv)); -// storeIv(); -// ClassContainer container = DataClassForTests.CONTAINER_TEST_CLASS(); -// -// OutputStream stream = new FileOutputStream(filename); -// Map encrypted = cipher.encrypt(container, stream); -// CipherOutputStream createdStream = encrypted.values().iterator().next(); -// SealedObject createdObject = encrypted.keySet().iterator().next(); -// -// ObjectOutputStream outputStream = new ObjectOutputStream(createdStream); -// outputStream.writeObject(createdObject); -// outputStream.close(); -// stream.close(); -// } - - @Test - public void readContentsFromFile() throws Exception { - readIv(); - FileCipherOld cipher = FileCipherOld.newInstance(password, iv); - System.out.println(Arrays.toString(iv)); - InputStream stream = new FileInputStream(filename); - ClassContainer restoredBackup = (ClassContainer) cipher.decrypt(stream); - for (Category category : restoredBackup.getCategories()) - System.out.println(category.toString()); - for (Entry entry : restoredBackup.getEntries()) - System.out.println(entry.toString()); - for (QRCode qrCode : restoredBackup.getQrCodes()) - System.out.println(qrCode.toString()); - for (Field field : restoredBackup.getFields()) - System.out.println(field.toString()); - for (SecurityCode code : restoredBackup.getSecurityCodes()) - System.out.println(code.toString()); - System.out.println(restoredBackup.getUserSharedPreferences().toString()); - } - - private void storeIv() throws Exception { - OutputStream ivStream = new FileOutputStream(iv_filename); - ivStream.write(iv); - ivStream.close(); - } - - private void readIv() throws Exception { - InputStream ivStream = new FileInputStream(iv_filename); - this.iv = ByteStreams.toByteArray(ivStream); - } -} +package javinator9889.securepass; + +import android.content.Context; + +import com.google.common.io.ByteStreams; + +import org.junit.Test; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Arrays; + +import androidx.test.InstrumentationRegistry; +import javinator9889.securepass.data.container.ClassContainer; +import javinator9889.securepass.data.entry.Category; +import javinator9889.securepass.data.entry.Entry; +import javinator9889.securepass.data.entry.QRCode; +import javinator9889.securepass.data.secret.Field; +import javinator9889.securepass.data.secret.SecurityCode; +import javinator9889.securepass.util.cipher.FileCipherOld; + +/** + * Created by Javinator9889 on 20/04/2018. - test must be updated + */ +@Deprecated +public class CipherTest { + private Context context = InstrumentationRegistry.getTargetContext(); + private String password = "random_password"; + private String filename = context.getFilesDir().getAbsolutePath() + "/class.bck"; + private String iv_filename = context.getFilesDir().getAbsolutePath() + "/iv"; + private byte[] iv; + +// @Test +// public void storeAClassInFile() throws Exception { +// FileCipherOld cipher = FileCipherOld.getInstance(password, null); +// iv = cipher.getIv(); +// System.out.println(Arrays.toString(iv)); +// storeIv(); +// ClassContainer container = DataClassForTests.CONTAINER_TEST_CLASS(); +// +// OutputStream stream = new FileOutputStream(filename); +// Map encrypted = cipher.encrypt(container, stream); +// CipherOutputStream createdStream = encrypted.values().iterator().next(); +// SealedObject createdObject = encrypted.keySet().iterator().next(); +// +// ObjectOutputStream outputStream = new ObjectOutputStream(createdStream); +// outputStream.writeObject(createdObject); +// outputStream.close(); +// stream.close(); +// } + + @Test + public void readContentsFromFile() throws Exception { + readIv(); + FileCipherOld cipher = FileCipherOld.newInstance(password, iv); + System.out.println(Arrays.toString(iv)); + InputStream stream = new FileInputStream(filename); + ClassContainer restoredBackup = (ClassContainer) cipher.decrypt(stream); + for (Category category : restoredBackup.getCategories()) + System.out.println(category.toString()); + for (Entry entry : restoredBackup.getEntries()) + System.out.println(entry.toString()); + for (QRCode qrCode : restoredBackup.getQrCodes()) + System.out.println(qrCode.toString()); + for (Field field : restoredBackup.getFields()) + System.out.println(field.toString()); + for (SecurityCode code : restoredBackup.getSecurityCodes()) + System.out.println(code.toString()); + System.out.println(restoredBackup.getUserSharedPreferences().toString()); + } + + private void storeIv() throws Exception { + OutputStream ivStream = new FileOutputStream(iv_filename); + ivStream.write(iv); + ivStream.close(); + } + + private void readIv() throws Exception { + InputStream ivStream = new FileInputStream(iv_filename); + this.iv = ByteStreams.toByteArray(ivStream); + } +} diff --git a/APP/app/src/androidTest/java/javinator9889/securepass/DatabaseExceptionTesting.java b/SecurePass/app/src/androidTest/java/javinator9889/securepass/DatabaseExceptionTesting.java similarity index 86% rename from APP/app/src/androidTest/java/javinator9889/securepass/DatabaseExceptionTesting.java rename to SecurePass/app/src/androidTest/java/javinator9889/securepass/DatabaseExceptionTesting.java index 2313f10..091b5b7 100644 --- a/APP/app/src/androidTest/java/javinator9889/securepass/DatabaseExceptionTesting.java +++ b/SecurePass/app/src/androidTest/java/javinator9889/securepass/DatabaseExceptionTesting.java @@ -1,80 +1,76 @@ -package javinator9889.securepass; - -import android.content.ContentValues; -import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; - -import com.google.common.hash.Hashing; - -import net.sqlcipher.Cursor; -import net.sqlcipher.database.SQLiteDatabase; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.io.File; -import java.io.IOException; -import java.nio.charset.StandardCharsets; - -import javinator9889.securepass.io.database.DatabaseManager; - -/** - * Created by Javinator9889 on 03/09/2018. - */ -@RunWith(AndroidJUnit4.class) -public class DatabaseExceptionTesting { - private final Context mContext = InstrumentationRegistry.getTargetContext(); - - @Test - public void wrongPassword() { - SQLiteDatabase.loadLibs(mContext); - String databaseTempFilePath = mContext.getCacheDir().getAbsolutePath() + "/test.db"; - File databaseTempFile = new File(databaseTempFilePath); - try { - databaseTempFile.delete(); - databaseTempFile.createNewFile(); - } catch (IOException e) { - System.err.println(e.getMessage()); - } - String firstPass = Hashing.sha256().hashString("password", StandardCharsets.UTF_8).toString(); - String secondPass = Hashing.sha256().hashString("1234", StandardCharsets.UTF_8).toString(); -// DatabaseManager manager = DatabaseManager.newInstance(mContext, firstPass); -// try { -// manager.getDatabaseInitializer().join(); -// manager.getDatabaseInstance().close(); -// } catch (InterruptedException e) { -// System.err.println(e.getMessage()); -// } -// manager = DatabaseManager.newInstance(mContext, secondPass); -// try { -// manager.getDatabaseInitializer().join(); -// manager.getDatabaseInstance().close(); -// } catch (InterruptedException e) { -// System.err.println(e.getMessage()); -// } - SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(databaseTempFilePath, secondPass, null); - db.execSQL("CREATE TABLE IF NOT EXISTS `Category` (\n" + - " `idCategory` INT NOT NULL DEFAULT 0,\n" + - " `name` VARCHAR(45) NULL,\n" + - " PRIMARY KEY (`idCategory`));"); -// ContentValues values = new ContentValues(); -// values.put("name", "name"); -// long id = db.insert("Category", null, values); - db.close(); - System.out.println("Database created"); - SQLiteDatabase db1 = SQLiteDatabase.openDatabase(databaseTempFilePath, firstPass, null, SQLiteDatabase.OPEN_READONLY); -// Cursor query = db1.rawQuery("SELECT * FROM Category WHERE idCategory = ?", new String[]{String.valueOf(id)}); -// Cursor query = db1.rawQuery("SELECT * FROM ? WHERE type=?", new String[]{"dbname.sqlite_master", "'table'"}); - Cursor c = db1.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null); - if (c.moveToFirst()) { - while ( !c.isAfterLast() ) { - System.out.println("Table Name=> "+c.getString(0)); - c.moveToNext(); - } - } -// db1.changePassword("password"); - db1.close(); - System.err.println("Invalid password used"); - } -} +package javinator9889.securepass; + +import android.content.Context; + +import com.google.common.hash.Hashing; + +import net.sqlcipher.Cursor; +import net.sqlcipher.database.SQLiteDatabase; + +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +import androidx.test.InstrumentationRegistry; + +/** + * Created by Javinator9889 on 03/09/2018. - test must be updated + */ +@Deprecated +public class DatabaseExceptionTesting { + private final Context mContext = InstrumentationRegistry.getTargetContext(); + + @Test + public void wrongPassword() { + SQLiteDatabase.loadLibs(mContext); + String databaseTempFilePath = mContext.getCacheDir().getAbsolutePath() + "/test.db"; + File databaseTempFile = new File(databaseTempFilePath); + try { + databaseTempFile.delete(); + databaseTempFile.createNewFile(); + } catch (IOException e) { + System.err.println(e.getMessage()); + } + String firstPass = Hashing.sha256().hashString("password", StandardCharsets.UTF_8).toString(); + String secondPass = Hashing.sha256().hashString("1234", StandardCharsets.UTF_8).toString(); +// DatabaseManager manager = DatabaseManager.getInstance(mContext, firstPass); +// try { +// manager.getDatabaseInitializer().join(); +// manager.getDatabaseInstance().close(); +// } catch (InterruptedException e) { +// System.err.println(e.getMessage()); +// } +// manager = DatabaseManager.getInstance(mContext, secondPass); +// try { +// manager.getDatabaseInitializer().join(); +// manager.getDatabaseInstance().close(); +// } catch (InterruptedException e) { +// System.err.println(e.getMessage()); +// } + SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(databaseTempFilePath, secondPass, null); + db.execSQL("CREATE TABLE IF NOT EXISTS `Category` (\n" + + " `idCategory` INT NOT NULL DEFAULT 0,\n" + + " `name` VARCHAR(45) NULL,\n" + + " PRIMARY KEY (`idCategory`));"); +// ContentValues values = new ContentValues(); +// values.put("name", "name"); +// long id = db.insert("Category", null, values); + db.close(); + System.out.println("Database created"); + SQLiteDatabase db1 = SQLiteDatabase.openDatabase(databaseTempFilePath, firstPass, null, SQLiteDatabase.OPEN_READONLY); +// Cursor query = db1.rawQuery("SELECT * FROM Category WHERE idCategory = ?", new String[]{String.valueOf(id)}); +// Cursor query = db1.rawQuery("SELECT * FROM ? WHERE type=?", new String[]{"dbname.sqlite_master", "'table'"}); + Cursor c = db1.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null); + if (c.moveToFirst()) { + while ( !c.isAfterLast() ) { + System.out.println("Table Name=> "+c.getString(0)); + c.moveToNext(); + } + } +// db1.changePassword("password"); + db1.close(); + System.err.println("Invalid password used"); + } +} diff --git a/APP/app/src/androidTest/java/javinator9889/securepass/DriveUploadTest.java b/SecurePass/app/src/androidTest/java/javinator9889/securepass/DriveUploadTest.java similarity index 65% rename from APP/app/src/androidTest/java/javinator9889/securepass/DriveUploadTest.java rename to SecurePass/app/src/androidTest/java/javinator9889/securepass/DriveUploadTest.java index 82a168b..ac459fc 100644 --- a/APP/app/src/androidTest/java/javinator9889/securepass/DriveUploadTest.java +++ b/SecurePass/app/src/androidTest/java/javinator9889/securepass/DriveUploadTest.java @@ -1,24 +1,23 @@ -package javinator9889.securepass; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.support.test.InstrumentationRegistry; - -import org.junit.Test; - -import javinator9889.securepass.backup.drive.DriveUploader; -import javinator9889.securepass.backup.drive.IDriveUploader; -import javinator9889.securepass.views.fragments.DriveContent; - -/** - * Created by Javinator9889 on 21/09/2018. - */ -public class DriveUploadTest { - @Test - public void uploadDb() { - Context appContext = InstrumentationRegistry.getTargetContext(); - Intent driveIntent = new Intent(appContext, DriveContent.class); - appContext.startActivity(driveIntent); - } -} +package javinator9889.securepass; + +import android.content.Context; +import android.content.Intent; + +import org.junit.Test; + +import androidx.test.InstrumentationRegistry; +import javinator9889.securepass.views.fragments.DriveContent; + +/** + * Created by Javinator9889 on 21/09/2018. - deprecated + * @deprecated + */ +@Deprecated +public class DriveUploadTest { + @Test + public void uploadDb() { + Context appContext = InstrumentationRegistry.getTargetContext(); + Intent driveIntent = new Intent(appContext, DriveContent.class); + appContext.startActivity(driveIntent); + } +} diff --git a/APP/app/src/androidTest/java/javinator9889/securepass/ExampleInstrumentedTest.java b/SecurePass/app/src/androidTest/java/javinator9889/securepass/ExampleInstrumentedTest.java similarity index 73% rename from APP/app/src/androidTest/java/javinator9889/securepass/ExampleInstrumentedTest.java rename to SecurePass/app/src/androidTest/java/javinator9889/securepass/ExampleInstrumentedTest.java index 43890d1..b29c00c 100644 --- a/APP/app/src/androidTest/java/javinator9889/securepass/ExampleInstrumentedTest.java +++ b/SecurePass/app/src/androidTest/java/javinator9889/securepass/ExampleInstrumentedTest.java @@ -1,26 +1,24 @@ -package javinator9889.securepass; - -import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import static org.junit.Assert.*; - -/** - * Instrumented test, which will execute on an Android device. - * - * @see Testing documentation - */ -@RunWith(AndroidJUnit4.class) -public class ExampleInstrumentedTest { - @Test - public void useAppContext() throws Exception { - // Context of the app under test. - Context appContext = InstrumentationRegistry.getTargetContext(); - - assertEquals("javinator9889.securepass", appContext.getPackageName()); - } -} +package javinator9889.securepass; + +import android.content.Context; + +import org.junit.Test; + +import androidx.test.InstrumentationRegistry; + +import static org.junit.Assert.assertEquals; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +public class ExampleInstrumentedTest { + @Test + public void useAppContext() throws Exception { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("javinator9889.securepass", appContext.getPackageName()); + } +} diff --git a/SecurePass/app/src/androidTest/java/javinator9889/securepass/database/BasicOperations.java b/SecurePass/app/src/androidTest/java/javinator9889/securepass/database/BasicOperations.java new file mode 100644 index 0000000..47c6628 --- /dev/null +++ b/SecurePass/app/src/androidTest/java/javinator9889/securepass/database/BasicOperations.java @@ -0,0 +1,83 @@ +package javinator9889.securepass.database; + +import android.util.Log; + +import net.sqlcipher.database.SQLiteException; + +import org.junit.Test; + +import java.util.Random; + +import javinator9889.securepass.io.database.operations.CommonOperations; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 05/11/2018 - APP. + */ +public class BasicOperations extends DatabaseTests { + private CommonOperations mOperations; + private String mPassword; + private String mTag; +// private BasicOperations mInstance; + + public BasicOperations() { + super(); + mPassword = String.valueOf(new Random().nextInt(123456789)); + mOperations = generateOperations(mPassword); + mTag = mOperations.getTag(); + Log.i(mTag, "Password: " + mPassword); + } + +// @Before +// public void setup() { +// mInstance = new BasicOperations(); +// } + + @Test + public void test() { + BasicOperations mInstance = new BasicOperations(); + try { + mInstance.changePassword(); + long id = mInstance.registerDefaultCategory(); + System.out.println("ID: " + id); + } catch (SQLiteException e) { + System.err.println("Error occurred"); + e.printStackTrace(); + } finally { + mInstance.finish(); + } + } + + public void changePassword() { + mPassword = String.valueOf(new Random().nextInt(123456789)); + mOperations.changeDatabasePassword(mPassword); + Log.i(mTag, "New password: " + mPassword); + } + + public long registerDefaultCategory() { + return mOperations.registerDefaultCategory(); + } + + public void finish() { + mOperations.finishConnection(); + } + +// @After +// public void end() { +// mInstance.finish(); +// } +} diff --git a/SecurePass/app/src/androidTest/java/javinator9889/securepass/database/DatabaseTests.java b/SecurePass/app/src/androidTest/java/javinator9889/securepass/database/DatabaseTests.java new file mode 100644 index 0000000..ef9105f --- /dev/null +++ b/SecurePass/app/src/androidTest/java/javinator9889/securepass/database/DatabaseTests.java @@ -0,0 +1,59 @@ +package javinator9889.securepass.database; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.test.platform.app.InstrumentationRegistry; +import javinator9889.securepass.io.database.DatabaseManager; +import javinator9889.securepass.io.database.operations.CommonOperations; +import javinator9889.securepass.util.values.Constants; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 05/11/2018 - APP. + */ +public abstract class DatabaseTests { + public static final String PASSWORD = "password"; + private Context mContext; + + DatabaseTests() { + this(true); + } + + protected DatabaseTests(boolean removePrevious) { + mContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + if (removePrevious) + removePreviousDB(); + } + + private void removePreviousDB() { + mContext.getDatabasePath(Constants.SQL.DB_FILENAME).delete(); + } + + public Context getContext() { + return mContext; + } + + public CommonOperations generateOperations(@NonNull String password) { + DatabaseManager instance = DatabaseManager.getInstance(mContext, password); + return new CommonOperations(instance); + } + + public DatabaseManager generateInstance(@NonNull String password) { + return DatabaseManager.getInstance(mContext, password); + } +} diff --git a/SecurePass/app/src/androidTest/java/javinator9889/securepass/database/TestCategoryOperations.java b/SecurePass/app/src/androidTest/java/javinator9889/securepass/database/TestCategoryOperations.java new file mode 100644 index 0000000..a22bfbd --- /dev/null +++ b/SecurePass/app/src/androidTest/java/javinator9889/securepass/database/TestCategoryOperations.java @@ -0,0 +1,101 @@ +/* + * Copyright © 2018 - present | SecurePass by Javinator9889 + + * This program 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. + + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + + * Created by Javinator9889 on 29/12/18 - SecurePass. + */ +package javinator9889.securepass.database; + +import android.util.Log; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import javinator9889.securepass.io.database.operations.category.CategoryOperations; +import javinator9889.securepass.io.database.operations.category.ICategoryGetOperations; +import javinator9889.securepass.io.database.operations.category.ICategorySetOperations; + +import static java.lang.Thread.sleep; + +public class TestCategoryOperations extends DatabaseTests { + private ICategoryGetOperations mGetOperations; + private ICategorySetOperations mSetOperations; + private CategoryOperations mOperations; + private int mCategorySuffix = 1; + public static final String TAG = "CategoryOperations"; + + public TestCategoryOperations() { +// super(); + } + + private TestCategoryOperations(boolean removePrevious) { + super(removePrevious); + } + + @Before + public void preload() { +// new TestCategoryOperations(); + new TestCategoryOperations(false); + CategoryOperations operations = new CategoryOperations(super.generateInstance(PASSWORD)); + mGetOperations = operations; + mSetOperations = operations; + mOperations = operations; + registerNewCategory(); + } + + public void registerNewCategory() { + String categoryName = "newCategory" + mCategorySuffix; + long id = mSetOperations.registerNewCategory(categoryName); + Log.d(TAG, "ID: " + id); + getAll(); + Log.d(TAG, "Recently created category name: " + mGetOperations.getCategoryName(id)); + mCategorySuffix = ((int) id) + 1; + } + + @Test + public void updateCategoryName() throws InterruptedException { + String newCategoryName = "updatedCategory"; + mSetOperations.updateCategoryName(mCategorySuffix - 1, newCategoryName); + mSetOperations.apply(); + sleep(1); // Wait until the update is done + Log.d(TAG, "New name: " + newCategoryName); + Log.d(TAG, "Category: " + mGetOperations.getCategoryName(mCategorySuffix - 1)); + getAll(); + } + + @Test + public void deleteCategory() { + Log.d(TAG, "Deleting ID: " + (mCategorySuffix -1)); + mSetOperations.removeCategory(mCategorySuffix - 1); + Log.d(TAG, "Deleted: " + (mCategorySuffix - 1)); + getAll(); + } + + @Test + public void getAll() { + Log.d(TAG, mGetOperations.getAllCategories().toString()); + } + + @Test + public void getCategoryName() { + Log.d(TAG, mGetOperations.getCategoryName(mCategorySuffix - 1)); + } + + @After + public void finish() { + mOperations.finishConnection(); + } +} diff --git a/SecurePass/app/src/androidTest/java/javinator9889/securepass/database/TestConfigFieldsOperations.java b/SecurePass/app/src/androidTest/java/javinator9889/securepass/database/TestConfigFieldsOperations.java new file mode 100644 index 0000000..856b3dc --- /dev/null +++ b/SecurePass/app/src/androidTest/java/javinator9889/securepass/database/TestConfigFieldsOperations.java @@ -0,0 +1,74 @@ +/* + * Copyright © 2019 - present | SecurePass by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 23/01/2019 - SecurePass. + */ +package javinator9889.securepass.database; + +import android.util.Log; + +import org.junit.Test; + +import javinator9889.securepass.io.database.DatabaseManager; +import javinator9889.securepass.io.database.operations.configuration.configurationfields.IConfigFieldsGetOperations; +import javinator9889.securepass.io.database.operations.configuration.configurationfields.IConfigFieldsSetOperations; +import javinator9889.securepass.io.database.operations.configuration.configurationfields.imagesconfig.ImagesConfigOperations; +import javinator9889.securepass.io.database.operations.configuration.configurationfields.longtextconfig.LongTextConfigOperations; +import javinator9889.securepass.io.database.operations.configuration.configurationfields.passconfig.PassConfigOperations; +import javinator9889.securepass.io.database.operations.configuration.configurationfields.smalltextconfig.SmallTextConfigOperations; + +public class TestConfigFieldsOperations extends TestConfigOperations { + private static final String TAG = "ConfigFieldsOperations"; + + @Test + public void createFields() { + super.registerConfiguration(); +// DatabaseManager instance = super.generateInstance("password"); + Log.i(TAG, "Configuration ID: " + (mConfigurationSuffix - 1)); + register((int) (Math.random() * 100), mInstance, mConfigurationSuffix - 1); + showAll(mInstance); + } + + private void register(int amount, DatabaseManager instance, long id) { + IConfigFieldsSetOperations imageSetOperations = new ImagesConfigOperations(instance); + IConfigFieldsSetOperations passSetOperations = new PassConfigOperations(instance); + IConfigFieldsSetOperations smallTextOperations = new SmallTextConfigOperations(instance); + IConfigFieldsSetOperations longTextOperations = new LongTextConfigOperations(instance); + + registerFields(imageSetOperations, amount, id, "image_"); + registerFields(passSetOperations, amount, id, "password_"); + registerFields(smallTextOperations, amount, id, "smalltext_"); + registerFields(longTextOperations, amount, id, "longtext_"); + } + + private void showAll(DatabaseManager instance) { + IConfigFieldsGetOperations getOperations = new ImagesConfigOperations(instance); + Log.i(TAG, getOperations.getAllConfigFields().toString()); + getOperations = new PassConfigOperations(instance); + Log.i(TAG, getOperations.getAllConfigFields().toString()); + getOperations = new SmallTextConfigOperations(instance); + Log.i(TAG, getOperations.getAllConfigFields().toString()); + getOperations = new LongTextConfigOperations(instance); + Log.i(TAG, getOperations.getAllConfigFields().toString()); + } + + private void registerFields(IConfigFieldsSetOperations field, + int amount, + long configId, + String prefix) { + for (int i = 1; i <= amount; i++) { + field.registerNewConfigField(prefix + i, i, configId); + } + } +} diff --git a/SecurePass/app/src/androidTest/java/javinator9889/securepass/database/TestConfigOperations.java b/SecurePass/app/src/androidTest/java/javinator9889/securepass/database/TestConfigOperations.java new file mode 100644 index 0000000..220e51a --- /dev/null +++ b/SecurePass/app/src/androidTest/java/javinator9889/securepass/database/TestConfigOperations.java @@ -0,0 +1,95 @@ +/* + * Copyright © 2019 - present | SecurePass by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 23/01/2019 - SecurePass. + */ +package javinator9889.securepass.database; + +import android.util.Log; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import javinator9889.securepass.io.database.DatabaseManager; +import javinator9889.securepass.io.database.operations.configuration.ConfigurationOperations; +import javinator9889.securepass.io.database.operations.configuration.IConfigurationGetOperations; +import javinator9889.securepass.io.database.operations.configuration.IConfigurationSetOperations; +import javinator9889.securepass.io.database.operations.configuration.configurationfields.IConfigFieldsSetOperations; +import javinator9889.securepass.io.database.operations.configuration.configurationfields.imagesconfig.ImagesConfigOperations; + +import static java.lang.Thread.sleep; + +public class TestConfigOperations extends DatabaseTests { + private IConfigurationGetOperations mGetOperations; + private IConfigurationSetOperations mSetOperations; + private ConfigurationOperations mOperations; + protected int mConfigurationSuffix = 1; + protected DatabaseManager mInstance; + private static final String TAG = "ConfigurationOperations"; + + @Before + public void preload() { + mInstance = super.generateInstance(PASSWORD); + mOperations = new ConfigurationOperations(mInstance); + mSetOperations = mOperations; + mGetOperations = mOperations; + } + + @Test + public void registerConfiguration() { + long id = mSetOperations.registerNewConfiguration("configuration" + mConfigurationSuffix); + Log.i(TAG, "New configuration: " + id); + getAll(); + mConfigurationSuffix = ((int) id) + 1; + Log.i(TAG, "Recently created configuration name: " + getConfigurationNameById(id)); +// IConfigFieldsSetOperations image = new ImagesConfigOperations(mInstance); +// image.registerNewConfigField("image description", 1, id); +// Log.i(TAG, ((ImagesConfigOperations) image).getAllConfigFields().toString()); + } + + @Test + public void changeConfigurationName() throws InterruptedException { + registerConfiguration(); + long id = mConfigurationSuffix - 1; + String name = "updatedConfiguration" + id; + mSetOperations.updateConfigurationName(id, name); + mSetOperations.apply(); + sleep(1000); + Log.i(TAG, "Category new name: " + getConfigurationNameById(id)); + getAll(); + } + + @Test + public void removeConfiguration() { + registerConfiguration(); + long id = mConfigurationSuffix - 1; + Log.i(TAG, "Deleting ID: " + id); + mSetOperations.removeConfiguration(id); + getAll(); + } + + @After + public void finish() { + mOperations.finishConnection(); + } + + private String getConfigurationNameById(long id) { + return mGetOperations.getConfigurationName(id); + } + + private void getAll() { + Log.d(TAG, mGetOperations.getAllConfigurations().toString()); + } +} diff --git a/SecurePass/app/src/androidTest/java/javinator9889/securepass/database/TestEntryOperations.java b/SecurePass/app/src/androidTest/java/javinator9889/securepass/database/TestEntryOperations.java new file mode 100644 index 0000000..201d57e --- /dev/null +++ b/SecurePass/app/src/androidTest/java/javinator9889/securepass/database/TestEntryOperations.java @@ -0,0 +1,97 @@ +/* + * Copyright © 2019 - present | SecurePass by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 25/01/2019 - SecurePass. + */ +package javinator9889.securepass.database; + +import android.util.Log; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import javinator9889.securepass.io.database.DatabaseManager; +import javinator9889.securepass.io.database.operations.entry.EntryOperations; +import javinator9889.securepass.io.database.operations.entry.IEntryGetOperations; +import javinator9889.securepass.io.database.operations.entry.IEntrySetOperations; +import javinator9889.securepass.io.database.operations.entry.image.ImageOperations; +import javinator9889.securepass.io.database.operations.entry.password.PasswordOperations; +import javinator9889.securepass.io.database.operations.entry.text.longtext.LongTextOperations; +import javinator9889.securepass.io.database.operations.entry.text.smalltext.SmallTextOperations; + +public class TestEntryOperations extends TestConfigOperations { + private static final String TAG = "TestEntryOperations"; + private DatabaseManager mInstance; + private EntryOperations mOperations; + private IEntryGetOperations mGetOperations; + private IEntrySetOperations mSetOperations; + private long mEntryId; + + @Before + @Override + public void preload() { + mInstance = super.generateInstance(PASSWORD); + mOperations = new EntryOperations(mInstance); + mGetOperations = mOperations; + mSetOperations = mOperations; + super.preload(); + } + + @Test + public void registerEntry() { + super.registerConfiguration(); + Log.i(TAG, "Configuration ID: " + (mConfigurationSuffix - 1)); + Log.i(TAG, "Category ID: (default) 0"); + long id = mSetOperations.registerNewEntry(0, (mConfigurationSuffix - 1), "First entry", + "Entry icon"); + mEntryId = id; + Log.i(TAG, "Recently created entry ID: " + id); + getAll(); + } + + @Test + public void registerEntryFields() { + registerEntry(); + PasswordOperations password = new PasswordOperations(mInstance); + LongTextOperations longText = new LongTextOperations(mInstance); + SmallTextOperations smallText = new SmallTextOperations(mInstance); + ImageOperations image = new ImageOperations(mInstance); + int fieldsToCreate = (int) (Math.random() * 100); + Log.i(TAG, "Creating " + fieldsToCreate + " fields"); + for (int i = 0; i < fieldsToCreate; i++) { + password.registerNewPassword("password" + i, "Password #" + i, i, mEntryId); + longText.registerNewText("long text " + i, "Text #" + i, i, mEntryId); + smallText.registerNewText("small text " + i, "SText #" + i, i, mEntryId); + image.registerNewImage("image " + i, "Image #" + i, i, mEntryId); + } + Log.i(TAG, password.getAllPasswords().toString()); + Log.i(TAG, longText.getAllLongTexts().toString()); + Log.i(TAG, smallText.getAllSmallTexts().toString()); + Log.i(TAG, image.getAllImages().toString()); + } + + @After + public void finish() { + mOperations.finishConnection(); + } + + protected long getEntryId() { + return mEntryId; + } + + private void getAll() { + Log.i(TAG, mGetOperations.getAllEntries().toString()); + } +} diff --git a/SecurePass/app/src/androidTest/java/javinator9889/securepass/database/TestQRCodeOperations.java b/SecurePass/app/src/androidTest/java/javinator9889/securepass/database/TestQRCodeOperations.java new file mode 100644 index 0000000..745e78b --- /dev/null +++ b/SecurePass/app/src/androidTest/java/javinator9889/securepass/database/TestQRCodeOperations.java @@ -0,0 +1,94 @@ +/* + * Copyright © 2019 - present | SecurePass by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 05/02/2019 - SecurePass. + */ +package javinator9889.securepass.database; + +import android.util.Log; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import javinator9889.securepass.io.database.DatabaseManager; +import javinator9889.securepass.io.database.operations.entry.qrcode.IQRCodeGetOperations; +import javinator9889.securepass.io.database.operations.entry.qrcode.IQRCodeSetOperations; +import javinator9889.securepass.io.database.operations.entry.qrcode.QRCodeOperations; +import javinator9889.securepass.objects.ObjectContainer; + +import static java.lang.Thread.sleep; + +public class TestQRCodeOperations extends TestEntryOperations { + private static final String TAG = "TestQRCodeOperations"; + private DatabaseManager mInstance; + private QRCodeOperations mOperations; + private IQRCodeSetOperations mSetOperations; + private IQRCodeGetOperations mGetOperations; + + @Before + public void preload() { + super.preload(); + mInstance = generateInstance(PASSWORD); + mOperations = new QRCodeOperations(mInstance); + mSetOperations = mOperations; + mGetOperations = mOperations; + } + + @Test + public void registerQRCode() { + long id = mSetOperations.registerNewQRCode(getEntryId(), + "QRCodeName", + "QRDescription", + "QRCodeData"); + Log.i(TAG, "Created ID: " + id); + getAll(); + } + + @Test + public void registerQRCodes() throws Exception { + int qrCodesToCreate = (int) (Math.random() * 95); + Log.i(TAG, "Creating " + qrCodesToCreate + " QRCodes"); + ObjectContainer ids = new ObjectContainer<>(qrCodesToCreate); + for (int i = 0; i < qrCodesToCreate; i++) { + long id = mSetOperations.registerNewQRCode(getEntryId(), + "QRCode#" + i, + "QRCode " + i + " description", + String.valueOf(Math.random() * 123456789)); + ids.storeObject(id); + } + getAll(); + ids.forEach(id -> { + mSetOperations.updateDescription(id, "NewQRCodeDescription"); + mSetOperations.updateName(id, "NewQRCodeName#" + id); + mSetOperations.updateQrCodeData(id, String.valueOf(Math.random() * 123987456)); + }); + mSetOperations.apply(); + sleep(1000); + getAll(); + ids.forEach(id -> mSetOperations.removeQRCode(id)); + getAll(); + } + + @Override + @After + public void finish() { + super.finish(); + mOperations.finishConnection(); + } + + private void getAll() { + Log.d(TAG, mGetOperations.getAllQRCodes().toString()); + } +} diff --git a/SecurePass/app/src/androidTest/java/javinator9889/securepass/database/TestSecurityCodeOperations.java b/SecurePass/app/src/androidTest/java/javinator9889/securepass/database/TestSecurityCodeOperations.java new file mode 100644 index 0000000..1b7721c --- /dev/null +++ b/SecurePass/app/src/androidTest/java/javinator9889/securepass/database/TestSecurityCodeOperations.java @@ -0,0 +1,102 @@ +/* + * Copyright © 2019 - present | SecurePass by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 29/01/2019 - SecurePass. + */ +package javinator9889.securepass.database; + +import android.util.Log; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import javinator9889.securepass.io.database.DatabaseManager; +import javinator9889.securepass.io.database.operations.securitycode.ISecurityCodeGetOperations; +import javinator9889.securepass.io.database.operations.securitycode.ISecurityCodeSetOperations; +import javinator9889.securepass.io.database.operations.securitycode.SecurityCodeOperations; +import javinator9889.securepass.io.database.operations.securitycode.field.FieldOperations; +import javinator9889.securepass.io.database.operations.securitycode.field.IFieldGetOperations; +import javinator9889.securepass.io.database.operations.securitycode.field.IFieldSetOperations; +import javinator9889.securepass.objects.ObjectContainer; + +import static java.lang.Thread.sleep; + + +public class TestSecurityCodeOperations extends DatabaseTests { + private static final String TAG = "TestSecurityCodeOperations"; + private DatabaseManager mInstance; + private SecurityCodeOperations mOperations; + private FieldOperations mFields; + private long mId; + private ISecurityCodeSetOperations mSetOperations; + private ISecurityCodeGetOperations mGetOperations; + private IFieldSetOperations mFSetOperations; + private IFieldGetOperations mFGetOperations; + + @Before + public void preload() { + mInstance = super.generateInstance(PASSWORD); + mOperations = new SecurityCodeOperations(mInstance); + mSetOperations = mOperations; + mGetOperations = mOperations; + mFields = new FieldOperations(mInstance); + mFSetOperations = mFields; + mFGetOperations = mFields; + } + + @Test + public void registerSecurityCode() { + mId = mSetOperations.registerNewSecurityCode("testSecurityCode"); + Log.i(TAG, "Recently created SecurityCode ID: " + mId); + getAllSecurityCodes(); + } + + @Test + public void registerSecurityCodeFields() throws Exception { + registerSecurityCode(); + int fieldsToCreate = (int) (Math.random() * 95); + Log.i(TAG, "Creating " + fieldsToCreate + " fields"); + ObjectContainer ids = new ObjectContainer<>(fieldsToCreate); + for (int i = 0; i < fieldsToCreate; i++) { + long id = mFSetOperations.registerNewField(mId, "field#" + i, false); + ids.storeObject(id); + } + Log.d(TAG, ids.toString()); + getAllFields(); + ids.forEach(id -> { + mFSetOperations.updateFieldCode(id, "updatedField#" + id); + mFSetOperations.updateFieldCodeBeenUsed(id, (Math.random() > Math.random())); + }); + mFSetOperations.apply(); + sleep(1000); + getAllFields(); + ids.forEach(id -> mFSetOperations.removeField(id)); + getAllFields(); + } + + @After + public void finish() { + mOperations.finishConnection(); + mFields.finishConnection(); + } + + private void getAllSecurityCodes() { + Log.i(TAG, mGetOperations.getAllSecurityCodes().toString()); + } + + private void getAllFields() { + Log.i(TAG, mFGetOperations.getAllFields().toString()); + } +} diff --git a/SecurePass/app/src/androidTest/java/javinator9889/securepass/keystore/PasswordWorker.java b/SecurePass/app/src/androidTest/java/javinator9889/securepass/keystore/PasswordWorker.java new file mode 100644 index 0000000..bb4d1ef --- /dev/null +++ b/SecurePass/app/src/androidTest/java/javinator9889/securepass/keystore/PasswordWorker.java @@ -0,0 +1,57 @@ +package javinator9889.securepass.keystore; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.KeyStoreException; +import java.security.UnrecoverableEntryException; +import java.util.Arrays; + +import androidx.test.platform.app.InstrumentationRegistry; +import javinator9889.securepass.util.cipher.keystore.IPasswordCipher; +import javinator9889.securepass.util.cipher.keystore.PasswordCipher; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + *

+ * This program 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. + *

+ * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + *

+ * Created by Javinator9889 on 11/11/2018 - APP. + */ +public class PasswordWorker { + private IPasswordCipher mCipher; + + @Before + public void setup() throws KeyStoreException, InvalidAlgorithmParameterException { + mCipher = new PasswordCipher(InstrumentationRegistry.getInstrumentation() + .getTargetContext(), "test"); + mCipher.createNewKeys(); + } + + @Test + public void test() throws UnrecoverableEntryException, InvalidKeyException { + String password = "passwordToBeEncryptedUsingRSAAndPasswordCipher"; + System.out.println("Password: " + password); + byte[] cipheredPassword = mCipher.encryptPassword(password.getBytes()); + System.out.println("Ciphered & signed password: \n\n" + Arrays.toString(cipheredPassword)); + String recoveredPassword = mCipher.decryptPassword(cipheredPassword); + System.out.println("Recovered password: " + recoveredPassword); + } + + @After + public void finalizeTest() { + mCipher.deleteKey(); + } +} diff --git a/APP/app/src/main/AndroidManifest.xml b/SecurePass/app/src/main/AndroidManifest.xml similarity index 92% rename from APP/app/src/main/AndroidManifest.xml rename to SecurePass/app/src/main/AndroidManifest.xml index b6ee995..71843f5 100644 --- a/APP/app/src/main/AndroidManifest.xml +++ b/SecurePass/app/src/main/AndroidManifest.xml @@ -1,35 +1,33 @@ - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/APP/app/src/androidTest/java/javinator9889/securepass/DataClassForTests.java b/SecurePass/app/src/main/java/javinator9889/securepass/DataClassForTests.java similarity index 97% rename from APP/app/src/androidTest/java/javinator9889/securepass/DataClassForTests.java rename to SecurePass/app/src/main/java/javinator9889/securepass/DataClassForTests.java index f356f9e..41c0d00 100644 --- a/APP/app/src/androidTest/java/javinator9889/securepass/DataClassForTests.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/DataClassForTests.java @@ -1,62 +1,62 @@ -package javinator9889.securepass; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javinator9889.securepass.data.container.ClassContainer; -import javinator9889.securepass.data.entry.Category; -import javinator9889.securepass.data.entry.Entry; -import javinator9889.securepass.data.entry.QRCode; -import javinator9889.securepass.data.secret.Field; -import javinator9889.securepass.data.secret.SecurityCode; - -/** - * Created by Javinator9889 on 21/04/2018. - */ -public class DataClassForTests { - // DO NOT LET ANYONE INIT THIS CLASS - private DataClassForTests(){} - -// public static ClassContainer CONTAINER_TEST_CLASS() { -// ClassContainer container = new ClassContainer(); -// List categories = new ArrayList<>(); -// List entries = new ArrayList<>(); -// List qrCodes = new ArrayList<>(); -// List fields = new ArrayList<>(); -// List securityCodes = new ArrayList<>(); -// Map preferences = new HashMap<>(); -// -// categories.add(new Category(1, "Category_1")); -// categories.add(new Category(2, "Category_2")); -// -// entries.add(new Entry(1, "Account_1", "password_1", -// "icon_1", "description_1", new Category())); -// entries.add(new Entry(2, "Account_2", "password_2", -// "icon_2", "description_2", new Category())); -// -// qrCodes.add(new QRCode(1, "qrcode_1", "description_1", "qrdata", -// entries.get(0))); -// qrCodes.add(new QRCode(2, "qrcode_2", "description_2", "qrdata2", -// entries.get(1))); -// -// fields.add(new Field(1, "field_1", false, -// new SecurityCode(1, "account_1"))); -// fields.add(new Field(2, "field_2", true, -// new SecurityCode(2, "account_2"))); -// -// securityCodes.add(new SecurityCode(1, "account_1")); -// securityCodes.add(new SecurityCode(2, "account_2")); -// -// preferences.put("test_val", true); -// -// container.setCategories(categories); -// container.setEntries(entries); -// container.setQrCodes(qrCodes); -// container.setFields(fields); -// container.setSecurityCodes(securityCodes); -// container.setUserSharedPreferences(preferences); -// return container; -// } -} +package javinator9889.securepass; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javinator9889.securepass.data.container.ClassContainer; +import javinator9889.securepass.data.entry.Category; +import javinator9889.securepass.data.entry.Entry; +import javinator9889.securepass.data.entry.QRCode; +import javinator9889.securepass.data.secret.Field; +import javinator9889.securepass.data.secret.SecurityCode; + +/** + * Created by Javinator9889 on 21/04/2018. + */ +public class DataClassForTests { + // DO NOT LET ANYONE INIT THIS CLASS + private DataClassForTests(){} + +// public static ClassContainer CONTAINER_TEST_CLASS() { +// ClassContainer container = new ClassContainer(); +// List categories = new ArrayList<>(); +// List entries = new ArrayList<>(); +// List qrCodes = new ArrayList<>(); +// List fields = new ArrayList<>(); +// List securityCodes = new ArrayList<>(); +// Map preferences = new HashMap<>(); +// +// categories.add(new Category(1, "Category_1")); +// categories.add(new Category(2, "Category_2")); +// +// entries.add(new Entry(1, "Account_1", "password_1", +// "icon_1", "description_1", new Category())); +// entries.add(new Entry(2, "Account_2", "password_2", +// "icon_2", "description_2", new Category())); +// +// qrCodes.add(new QRCode(1, "qrcode_1", "description_1", "qrdata", +// entries.get(0))); +// qrCodes.add(new QRCode(2, "qrcode_2", "description_2", "qrdata2", +// entries.get(1))); +// +// fields.add(new Field(1, "field_1", false, +// new SecurityCode(1, "account_1"))); +// fields.add(new Field(2, "field_2", true, +// new SecurityCode(2, "account_2"))); +// +// securityCodes.add(new SecurityCode(1, "account_1")); +// securityCodes.add(new SecurityCode(2, "account_2")); +// +// preferences.put("test_val", true); +// +// container.setCategories(categories); +// container.setEntries(entries); +// container.setQrCodes(qrCodes); +// container.setFields(fields); +// container.setSecurityCodes(securityCodes); +// container.setUserSharedPreferences(preferences); +// return container; +// } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/Generator.java b/SecurePass/app/src/main/java/javinator9889/securepass/Generator.java new file mode 100644 index 0000000..deaeaa9 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/Generator.java @@ -0,0 +1,145 @@ +package javinator9889.securepass; + +import com.github.javinator9889.exporter.FileToBytesExporter; +import com.google.common.hash.HashCode; +import com.google.common.hash.Hashing; +import com.lambdaworks.crypto.SCryptUtil; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.Signature; +import java.security.SignatureException; +import java.util.Arrays; + +import androidx.annotation.NonNull; +import javinator9889.securepass.util.scrypt.Scrypt; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 05/11/2018 - APP. + */ +public class Generator { + private static final String SIGNATURE = "SHA256withRSA"; + /** + * Do not let anyone use this class + */ + private Generator() {} + + /** + * Generates a bytes file from given file. + * + * @param args {@code String[]} containing, at 0: "filename"; at 1: output file path. + * @throws IOException when an error occurs (see {@link FileToBytesExporter#readSource()} & + * {@link FileToBytesExporter#writeObject(File)}). + */ + public static void main(String[] args) throws Exception { + exportDB(); + /*if (args.length <= 1) + throw new IllegalArgumentException("At least two arguments must be included " + + "(filename & output file)"); + FileToBytesExporter exporter = new FileToBytesExporter(args[0]); + exporter.readSource(true); + exporter.writeObject(new File(args[1]));*/ + /*String ANDROID_KEY_STORE = "AndroidKeyStore"; + String ALGORITHM_RSA = "RSA"; + KeyPair keyPair; + KeyPairGenerator generator = KeyPairGenerator.getInstance(ALGORITHM_RSA); + generator.initialize(2048, new SecureRandom()); + keyPair = generator.generateKeyPair(); + String data = "hola1234"; + byte[] s = sign(data, keyPair.getPrivate()); + System.out.println(Arrays.toString(s)); + System.out.println(verifySignature(s, keyPair.getPublic())); + System.out.println(new String(s));*/ + String password = "ThisIsAPassword"; + /*byte[] bytesPass = password.getBytes(StandardCharsets.UTF_8); + SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); + byte[] salt = new byte[16]; + secureRandom.nextBytes(salt); + for (int n = 14; n < 22; ++n) { + long startTime = System.currentTimeMillis(); + SCrypt.scrypt(bytesPass, salt, 1 << n, 8, 1, 32); + long endTime = System.currentTimeMillis(); + long ms = (endTime - startTime); + System.out.printf("N = 2^%d\t%d ms\n", n, ms); + }*/ + /*int N = 1 << 15; + System.out.println(N); + Scrypt scryptUtil = new Scrypt(); + scryptUtil.scrypt(password); + String scryptUtilHash = scryptUtil.getHash(); + byte[] key = scryptUtil.getKey(); +// byte[] key = SCrypt.scrypt(password.getBytes(StandardCharsets.UTF_8), salt, N, 8, 4, 32); + System.out.println(Arrays.toString(key)); + System.out.println(key.length); + System.out.println(key.length * 8); + System.out.println(scryptUtilHash); + Scrypt checker = new Scrypt(scryptUtilHash); + System.out.println(checker.check(password)); + for (int i = 0; i < 10; ++i) { + String scrypt = SCryptUtil.scrypt(password, N, 8, 4); + System.out.println(scrypt); + boolean validate = SCryptUtil.check(password, scrypt); + System.out.println(validate); +// System.out.println(Arrays.toString(scrypt.getBytes())); +// System.out.println(scrypt.getBytes().length); + } + HashCode hash = Hashing.sha256().hashString(password, StandardCharsets.UTF_8); + System.out.println(hash.toString()); + System.out.println(Arrays.toString(hash.asBytes())); + System.out.println(hash.asBytes().length); + System.out.println(hash.asBytes().length * 8); + System.out.println(hash.bits());*/ + } + + private static byte[] sign(@NonNull String data, @NonNull PrivateKey privateKeyEntry) + throws InvalidKeyException, SignatureException { + try { + Signature signature = Signature.getInstance(SIGNATURE); + signature.initSign(privateKeyEntry); + signature.update(data.getBytes()); + return signature.sign(); + } catch (NoSuchAlgorithmException ignored) { + return null; + } + } + + private static boolean verifySignature(@NonNull byte[] data, @NonNull PublicKey + privateKeyEntry) throws Exception { + Signature s = Signature.getInstance(SIGNATURE); + s.initVerify(privateKeyEntry); + s.update(data); + return s.verify(data); + } + + private static void exportDB() throws Exception { + String path = "D:\\\\\\Nextcloud\\AndroidApps\\SecurePass\\APP\\app\\src\\main\\res" + + "\\raw\\"; + String source = "database_script_readable.sql"; + String dest = "database_scriptabase_script.osql"; +// FileToBytesExporter exporter = new FileToBytesExporter(source, path); +// exporter.readSource(true); +// exporter.writeObject(new File(path + dest)); + String data = FileToBytesExporter.readSource(new File(path, source)); + FileToBytesExporter.writeObject(data, new File(path, dest)); + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/SecurePass.java b/SecurePass/app/src/main/java/javinator9889/securepass/SecurePass.java similarity index 85% rename from APP/app/src/main/java/javinator9889/securepass/SecurePass.java rename to SecurePass/app/src/main/java/javinator9889/securepass/SecurePass.java index 732cd3a..4bcbbfc 100644 --- a/APP/app/src/main/java/javinator9889/securepass/SecurePass.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/SecurePass.java @@ -1,35 +1,38 @@ -package javinator9889.securepass; - -import android.app.Application; - -import com.chamber.java.library.SharedChamber; - -import androidx.annotation.NonNull; -import javinator9889.securepass.util.resources.PreferencesManager; - -/** - * Created by Javinator9889 on 25/03/2018. - * Main application - class with different parameters useful for app packages - */ - -public class SecurePass extends Application { - private static SecurePass APPLICATION_INSTANCE; - //private Context applicationContext; - - @NonNull - public static SecurePass getApplicationInstance() { - return APPLICATION_INSTANCE; - } - - @Override - public void onCreate() { - super.onCreate(); - APPLICATION_INSTANCE = this; - PreferencesManager.instantiate(this); - SharedChamber.initChamber(this); - } - - public static int getNumberOfProcessors() { - return Runtime.getRuntime().availableProcessors(); - } -} +package javinator9889.securepass; + +import android.app.Application; + +import com.chamber.java.library.SharedChamber; + +import org.jetbrains.annotations.Contract; + +import androidx.annotation.NonNull; +import javinator9889.securepass.util.resources.PreferencesManager; + +/** + * Created by Javinator9889 on 25/03/2018. + * Main application - class with different parameters useful for app packages + */ + +public class SecurePass extends Application { + private static SecurePass APPLICATION_INSTANCE; + //private Context applicationContext; + + @Contract(pure = true) + @NonNull + public static SecurePass getApplicationInstance() { + return APPLICATION_INSTANCE; + } + + @Override + public void onCreate() { + super.onCreate(); + APPLICATION_INSTANCE = this; + PreferencesManager.instantiate(this); +// SharedChamber.initChamber(this); + } + + public static int getNumberOfProcessors() { + return Runtime.getRuntime().availableProcessors(); + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/backup/BackupManager.java b/SecurePass/app/src/main/java/javinator9889/securepass/backup/BackupManager.java similarity index 96% rename from APP/app/src/main/java/javinator9889/securepass/backup/BackupManager.java rename to SecurePass/app/src/main/java/javinator9889/securepass/backup/BackupManager.java index 8a6e258..809f8ba 100644 --- a/APP/app/src/main/java/javinator9889/securepass/backup/BackupManager.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/backup/BackupManager.java @@ -1,56 +1,56 @@ -package javinator9889.securepass.backup; - -import android.app.Activity; -import android.content.Context; - -import androidx.annotation.NonNull; -import javinator9889.securepass.backup.drive.DriveDownloader; -import javinator9889.securepass.backup.drive.DriveUploader; -import javinator9889.securepass.backup.drive.IDriveDownloader; -import javinator9889.securepass.backup.drive.IDriveUploader; - -/** - * Class for managing backups - * Created by Javinator9889 on 06/04/2018. - */ -public class BackupManager implements IBackup { - private IDriveUploader mUploader; - private IDriveDownloader mDownloader; - - /** - * Public constructor for managing backups - * - * @param backupContext Context when instantiating this class - * @param sourceActivity Activity when instantiating this class - * @see Activity - * @see Context - * @see DriveUploader - * @see DriveDownloader - */ - public BackupManager(@NonNull Context backupContext, @NonNull Activity sourceActivity) { - this.mUploader = new DriveUploader(backupContext, sourceActivity); - this.mDownloader = new DriveDownloader(backupContext, sourceActivity); - } - - /** - * Does the backup by using - * {@link javinator9889.securepass.backup.drive.DriveUploader DriveUploader} class - * - * @see javinator9889.securepass.backup.drive.IDriveUploader - */ - @Override - public void doBackup() { - this.mUploader.uploadDatabase(); - } - - /** - * Restores the backup by using - * {@link javinator9889.securepass.backup.drive.DriveDownloader DriveDownloader} class - * - * @see javinator9889.securepass.backup.drive.IDriveDownloader - */ - @Override - public void restoreBackup() { - - } -} +package javinator9889.securepass.backup; + +import android.app.Activity; +import android.content.Context; + +import androidx.annotation.NonNull; +import javinator9889.securepass.backup.drive.DriveDownloader; +import javinator9889.securepass.backup.drive.DriveUploader; +import javinator9889.securepass.backup.drive.IDriveDownloader; +import javinator9889.securepass.backup.drive.IDriveUploader; + +/** + * Class for managing backups + * Created by Javinator9889 on 06/04/2018. + */ +public class BackupManager implements IBackup { + private IDriveUploader mUploader; + private IDriveDownloader mDownloader; + + /** + * Public constructor for managing backups + * + * @param backupContext Context when instantiating this class + * @param sourceActivity Activity when instantiating this class + * @see Activity + * @see Context + * @see DriveUploader + * @see DriveDownloader + */ + public BackupManager(@NonNull Context backupContext, @NonNull Activity sourceActivity) { + this.mUploader = new DriveUploader(backupContext, sourceActivity); + this.mDownloader = new DriveDownloader(backupContext, sourceActivity); + } + + /** + * Does the backup by using + * {@link javinator9889.securepass.backup.drive.DriveUploader DriveUploader} class + * + * @see javinator9889.securepass.backup.drive.IDriveUploader + */ + @Override + public void doBackup() { + this.mUploader.uploadDatabase(); + } + + /** + * Restores the backup by using + * {@link javinator9889.securepass.backup.drive.DriveDownloader DriveDownloader} class + * + * @see javinator9889.securepass.backup.drive.IDriveDownloader + */ + @Override + public void restoreBackup() { + + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/backup/IBackup.java b/SecurePass/app/src/main/java/javinator9889/securepass/backup/IBackup.java similarity index 96% rename from APP/app/src/main/java/javinator9889/securepass/backup/IBackup.java rename to SecurePass/app/src/main/java/javinator9889/securepass/backup/IBackup.java index 10464a6..e6c8981 100644 --- a/APP/app/src/main/java/javinator9889/securepass/backup/IBackup.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/backup/IBackup.java @@ -1,23 +1,23 @@ -package javinator9889.securepass.backup; - -/** - * Interface for accessing {@link BackupManager BackupManager class} - * Created by Javinator9889 on 20/09/2018. - */ -public interface IBackup { - /** - * Does the backup by using - * {@link javinator9889.securepass.backup.drive.DriveUploader DriveUploader} class - * - * @see javinator9889.securepass.backup.drive.IDriveUploader - */ - void doBackup(); - - /** - * Restores the backup by using - * {@link javinator9889.securepass.backup.drive.DriveDownloader DriveDownloader} class - * - * @see javinator9889.securepass.backup.drive.IDriveDownloader - */ - void restoreBackup(); -} +package javinator9889.securepass.backup; + +/** + * Interface for accessing {@link BackupManager BackupManager class} + * Created by Javinator9889 on 20/09/2018. + */ +public interface IBackup { + /** + * Does the backup by using + * {@link javinator9889.securepass.backup.drive.DriveUploader DriveUploader} class + * + * @see javinator9889.securepass.backup.drive.IDriveUploader + */ + void doBackup(); + + /** + * Restores the backup by using + * {@link javinator9889.securepass.backup.drive.DriveDownloader DriveDownloader} class + * + * @see javinator9889.securepass.backup.drive.IDriveDownloader + */ + void restoreBackup(); +} diff --git a/APP/app/src/main/java/javinator9889/securepass/backup/drive/DriveDownloader.java b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/DriveDownloader.java similarity index 97% rename from APP/app/src/main/java/javinator9889/securepass/backup/drive/DriveDownloader.java rename to SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/DriveDownloader.java index 88c8664..58bf6bb 100644 --- a/APP/app/src/main/java/javinator9889/securepass/backup/drive/DriveDownloader.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/DriveDownloader.java @@ -1,196 +1,196 @@ -package javinator9889.securepass.backup.drive; - -import android.app.Activity; -import android.content.Context; -import android.text.InputType; -import android.util.Log; - -import com.afollestad.materialdialogs.MaterialDialog; -import com.google.android.gms.drive.DriveContents; -import com.google.android.gms.drive.DriveFile; -import com.google.android.gms.drive.DriveResourceClient; -import com.google.android.gms.drive.Metadata; -import com.google.android.gms.drive.events.OpenFileCallback; -import com.google.android.gms.drive.widget.DataBufferAdapter; -import com.google.android.gms.tasks.Task; -import com.google.common.hash.Hashing; -import com.google.common.io.ByteStreams; -import com.google.common.io.Files; - -import net.sqlcipher.database.SQLiteDatabase; -import net.sqlcipher.database.SQLiteException; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; - -import androidx.annotation.NonNull; -import javinator9889.securepass.R; -import javinator9889.securepass.backup.drive.base.GoogleDriveBase; -import javinator9889.securepass.io.IOManager; -import javinator9889.securepass.objects.ByteArrayKeeper; -import javinator9889.securepass.util.cipher.FileCipher; -import javinator9889.securepass.util.cipher.ICipher; - -/** - * Class for downloading files into the device - * Created by Javinator9889 on 03/09/2018. - * - * @see GoogleDriveBase - * @see IDriveDownloader - */ -public class DriveDownloader extends GoogleDriveBase implements IDriveDownloader { - private static final String TAG = "DriveDownloader"; - private MaterialDialog mProgressBar; - - /** - * Public constructor for starting the download activity - * - * @param driveContext Context when instantiating this class - * @param mainActivity Activity when instantiating this class - * @see Context - * @see Activity - * @see GoogleDriveBase - * @see MaterialDialog - */ - public DriveDownloader(@NonNull Context driveContext, @NonNull Activity mainActivity) { - super(driveContext, mainActivity); - super.signIn(); - mProgressBar = new MaterialDialog.Builder(driveContext) - .title(R.string.retrieving_data) - .content(R.string.wait) - .cancelable(false) - .progress(false, 100) - .build(); - } - - /** - * Restores the data and saves it into a ResultsAdapter - * - * @see DataBufferAdapter - * @see DriveFile - * @see Task - */ - @Override - public void restoreData() { - IOManager ioManager = IOManager.newInstance(getDriveContext()); - final ByteArrayKeeper ivVector = new ByteArrayKeeper(); - if (!ioManager.isAnyIVVectorStored()) { - DataBufferAdapter vectorData = new ResultsAdapter(getDriveContext()); - getIVVector(vectorData); - DriveFile vectorFile = null; - for (int i = 0; i < vectorData.getCount(); ++i) - vectorFile = vectorData.getItem(i).getDriveId().asDriveFile(); - Task ivFileTask = getDriveResourceClient() - .openFile(vectorFile, DriveFile.MODE_READ_ONLY); - ivFileTask.continueWith(task -> { - DriveContents contents = task.getResult(); - try (InputStream stream = contents.getInputStream()) { - ivVector.storeArray(ByteStreams.toByteArray(stream)); - return getDriveResourceClient().discardContents(contents); - } - }); - try { - ioManager.saveIVVector(ivVector.getArray()); - } catch (IOException e) { - e.printStackTrace(); - } - } - DataBufferAdapter databaseBackup = new ResultsAdapter(getDriveContext()); - super.queryFiles(databaseBackup); - DriveFile databaseFile = null; - for (int i = 0; i < databaseBackup.getCount(); ++i) - databaseFile = databaseBackup.getItem(i).getDriveId().asDriveFile(); - retrieveContents(databaseFile); - } - - /** - * Retrieves contents by using supper methods for querying and saving files - * - * @param contents a DriveFile which has the databaseFile - * @see #restoreData() - */ - private void retrieveContents(@NonNull DriveFile contents) { - mProgressBar.show(); - final DriveResourceClient resourceClient = super.getDriveResourceClient(); - final Context driveContext = super.getDriveContext(); - resourceClient.openFile(contents, DriveFile.MODE_READ_ONLY, - new OpenFileCallback() { - @Override - public void onProgress(long bytesDownloaded, long bytesExpected) { - int progress = (int) ((bytesDownloaded * 100) / bytesExpected); - Log.d(TAG, String.format("Download progress: %d percent", progress)); - mProgressBar.setProgress(progress); - } - - @Override - public void onContents(@NonNull DriveContents driveContents) { - mProgressBar.setProgress(100); - try { - try (InputStream obtainedFile = driveContents.getInputStream()) { - ICipher cipher = new FileCipher(driveContext); - IOManager io = IOManager.newInstance(driveContext); - File destination = new File(io.downloadedDatabaseBackupPath()); - cipher.decryptFile(obtainedFile, destination); - mProgressBar.dismiss(); - completeDownload(); - } - } catch (Exception e) { - Log.e(TAG, "Exception while copying/retrieving database", e); - } - } - - @Override - public void onError(@NonNull Exception e) { - Log.e(TAG, "Exception while downloading/retrieving contents", e); - } - }); - } - - /** - * As the database is encrypted, we must check if the user knows the password which used for - * doing the encryption - * - * @see SQLiteDatabase - * @see IOManager - */ - private void completeDownload() { - final Context driveContext = super.getDriveContext(); - SQLiteDatabase.loadLibs(driveContext); - IOManager io = IOManager.newInstance(driveContext); - String databaseDownloadedBackupPath = io.downloadedDatabaseBackupPath(); - final StringBuilder passwordBuilder = new StringBuilder(); - MaterialDialog passwordInputDialog = new MaterialDialog.Builder(driveContext) - .title(R.string.put_pass) - .content(R.string.pass_need) - .inputType(InputType.TYPE_TEXT_VARIATION_PASSWORD) - .input(null, null, false, - ((dialog, input) -> passwordBuilder.append(input))) - .onAny(((dialog, which) -> { - final String password = Hashing.sha256() - .hashString(passwordBuilder.toString(), StandardCharsets.UTF_8) - .toString(); - try { - SQLiteDatabase openedDatabase = SQLiteDatabase - .openDatabase(databaseDownloadedBackupPath, password, null, - SQLiteDatabase.OPEN_READONLY); - openedDatabase.close(); - File databaseBackup = new File(databaseDownloadedBackupPath); - File databasePath = io.getDatabasePath(); - try { - Files.move(databaseBackup, databasePath); - showMessage("Backup restore completed"); - } catch (IOException e) { - showMessage("Error while recovering your backup"); - } - } catch (SQLiteException e) { - showMessage("Password not correct"); - completeDownload(); - } - })) - .cancelable(false) - .build(); - passwordInputDialog.show(); - } -} +package javinator9889.securepass.backup.drive; + +import android.app.Activity; +import android.content.Context; +import android.text.InputType; +import android.util.Log; + +import com.afollestad.materialdialogs.MaterialDialog; +import com.google.android.gms.drive.DriveContents; +import com.google.android.gms.drive.DriveFile; +import com.google.android.gms.drive.DriveResourceClient; +import com.google.android.gms.drive.Metadata; +import com.google.android.gms.drive.events.OpenFileCallback; +import com.google.android.gms.drive.widget.DataBufferAdapter; +import com.google.android.gms.tasks.Task; +import com.google.common.hash.Hashing; +import com.google.common.io.ByteStreams; +import com.google.common.io.Files; + +import net.sqlcipher.database.SQLiteDatabase; +import net.sqlcipher.database.SQLiteException; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; + +import androidx.annotation.NonNull; +import javinator9889.securepass.R; +import javinator9889.securepass.backup.drive.base.GoogleDriveBase; +import javinator9889.securepass.io.IOManager; +import javinator9889.securepass.objects.ByteArrayKeeper; +import javinator9889.securepass.util.cipher.FileCipher; +import javinator9889.securepass.util.cipher.ICipher; + +/** + * Class for downloading files into the device + * Created by Javinator9889 on 03/09/2018. + * + * @see GoogleDriveBase + * @see IDriveDownloader + */ +public class DriveDownloader extends GoogleDriveBase implements IDriveDownloader { + private static final String TAG = "DriveDownloader"; + private MaterialDialog mProgressBar; + + /** + * Public constructor for starting the download activity + * + * @param driveContext Context when instantiating this class + * @param mainActivity Activity when instantiating this class + * @see Context + * @see Activity + * @see GoogleDriveBase + * @see MaterialDialog + */ + public DriveDownloader(@NonNull Context driveContext, @NonNull Activity mainActivity) { + super(driveContext, mainActivity); + super.signIn(); + mProgressBar = new MaterialDialog.Builder(driveContext) + .title(R.string.retrieving_data) + .content(R.string.wait) + .cancelable(false) + .progress(false, 100) + .build(); + } + + /** + * Restores the data and saves it into a ResultsAdapter + * + * @see DataBufferAdapter + * @see DriveFile + * @see Task + */ + @Override + public void restoreData() { + IOManager ioManager = IOManager.newInstance(getDriveContext()); + final ByteArrayKeeper ivVector = new ByteArrayKeeper(); + if (!ioManager.isAnyIVVectorStored()) { + DataBufferAdapter vectorData = new ResultsAdapter(getDriveContext()); + getIVVector(vectorData); + DriveFile vectorFile = null; + for (int i = 0; i < vectorData.getCount(); ++i) + vectorFile = vectorData.getItem(i).getDriveId().asDriveFile(); + Task ivFileTask = getDriveResourceClient() + .openFile(vectorFile, DriveFile.MODE_READ_ONLY); + ivFileTask.continueWith(task -> { + DriveContents contents = task.getResult(); + try (InputStream stream = contents.getInputStream()) { + ivVector.storeArray(ByteStreams.toByteArray(stream)); + return getDriveResourceClient().discardContents(contents); + } + }); + try { + ioManager.saveIVVector(ivVector.getArray()); + } catch (IOException e) { + e.printStackTrace(); + } + } + DataBufferAdapter databaseBackup = new ResultsAdapter(getDriveContext()); + super.queryFiles(databaseBackup); + DriveFile databaseFile = null; + for (int i = 0; i < databaseBackup.getCount(); ++i) + databaseFile = databaseBackup.getItem(i).getDriveId().asDriveFile(); + retrieveContents(databaseFile); + } + + /** + * Retrieves contents by using supper methods for querying and saving files + * + * @param contents a DriveFile which has the databaseFile + * @see #restoreData() + */ + private void retrieveContents(@NonNull DriveFile contents) { + mProgressBar.show(); + final DriveResourceClient resourceClient = super.getDriveResourceClient(); + final Context driveContext = super.getDriveContext(); + resourceClient.openFile(contents, DriveFile.MODE_READ_ONLY, + new OpenFileCallback() { + @Override + public void onProgress(long bytesDownloaded, long bytesExpected) { + int progress = (int) ((bytesDownloaded * 100) / bytesExpected); + Log.d(TAG, String.format("Download progress: %d percent", progress)); + mProgressBar.setProgress(progress); + } + + @Override + public void onContents(@NonNull DriveContents driveContents) { + mProgressBar.setProgress(100); + try { + try (InputStream obtainedFile = driveContents.getInputStream()) { + ICipher cipher = new FileCipher(driveContext); + IOManager io = IOManager.newInstance(driveContext); + File destination = new File(io.downloadedDatabaseBackupPath()); + cipher.decryptFile(obtainedFile, destination); + mProgressBar.dismiss(); + completeDownload(); + } + } catch (Exception e) { + Log.e(TAG, "Exception while copying/retrieving database", e); + } + } + + @Override + public void onError(@NonNull Exception e) { + Log.e(TAG, "Exception while downloading/retrieving contents", e); + } + }); + } + + /** + * As the database is encrypted, we must check if the user knows the password which used for + * doing the encryption + * + * @see SQLiteDatabase + * @see IOManager + */ + private void completeDownload() { + final Context driveContext = super.getDriveContext(); + SQLiteDatabase.loadLibs(driveContext); + IOManager io = IOManager.newInstance(driveContext); + String databaseDownloadedBackupPath = io.downloadedDatabaseBackupPath(); + final StringBuilder passwordBuilder = new StringBuilder(); + MaterialDialog passwordInputDialog = new MaterialDialog.Builder(driveContext) + .title(R.string.put_pass) + .content(R.string.pass_need) + .inputType(InputType.TYPE_TEXT_VARIATION_PASSWORD) + .input(null, null, false, + ((dialog, input) -> passwordBuilder.append(input))) + .onAny(((dialog, which) -> { + final String password = Hashing.sha256() + .hashString(passwordBuilder.toString(), StandardCharsets.UTF_8) + .toString(); + try { + SQLiteDatabase openedDatabase = SQLiteDatabase + .openDatabase(databaseDownloadedBackupPath, password, null, + SQLiteDatabase.OPEN_READONLY); + openedDatabase.close(); + File databaseBackup = new File(databaseDownloadedBackupPath); + File databasePath = io.getDatabasePath(); + try { + Files.move(databaseBackup, databasePath); + showMessage("Backup restore completed"); + } catch (IOException e) { + showMessage("Error while recovering your backup"); + } + } catch (SQLiteException e) { + showMessage("Password not correct"); + completeDownload(); + } + })) + .cancelable(false) + .build(); + passwordInputDialog.show(); + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/backup/drive/DriveUploader.java b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/DriveUploader.java similarity index 97% rename from APP/app/src/main/java/javinator9889/securepass/backup/drive/DriveUploader.java rename to SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/DriveUploader.java index 87fac4f..c1886fa 100644 --- a/APP/app/src/main/java/javinator9889/securepass/backup/drive/DriveUploader.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/DriveUploader.java @@ -1,224 +1,224 @@ -package javinator9889.securepass.backup.drive; - -import android.app.Activity; -import android.content.Context; -import android.util.Log; - -import com.google.android.gms.drive.DriveContents; -import com.google.android.gms.drive.DriveFolder; -import com.google.android.gms.drive.DriveResource; -import com.google.android.gms.drive.DriveResourceClient; -import com.google.android.gms.drive.Metadata; -import com.google.android.gms.drive.MetadataChangeSet; -import com.google.android.gms.drive.widget.DataBufferAdapter; -import com.google.android.gms.tasks.Task; -import com.google.android.gms.tasks.Tasks; -import com.google.common.io.Files; - -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; - -import javax.crypto.BadPaddingException; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; - -import androidx.annotation.NonNull; -import javinator9889.securepass.backup.drive.base.GoogleDriveBase; -import javinator9889.securepass.io.IOManager; -import javinator9889.securepass.objects.GeneralObjectContainer; -import javinator9889.securepass.objects.ObjectContainer; -import javinator9889.securepass.util.cipher.FileCipher; -import javinator9889.securepass.util.cipher.ICipher; -import javinator9889.securepass.util.values.Constants; - -/** - * Class for uploading files to app folder at Google Drive - * - * @see GoogleDriveBase - * @see IDriveUploader - * Created by Javinator9889 on 24/08/2018. - */ -public class DriveUploader extends GoogleDriveBase implements IDriveUploader { - private static final String TAG = "DriveUploader"; - private ICipher mFileCipher; - private IOManager mIOManager; - - /** - * Public constructor for starting the upload activity - * - * @param driveContext Context when instantiating this class - * @param mainActivity Activity when instantiating this class - * @see Activity - * @see Context - * @see GoogleDriveBase - * @see FileCipher - */ - public DriveUploader(@NonNull Context driveContext, @NonNull Activity mainActivity) { - super(driveContext, mainActivity); - super.signIn(); - this.mFileCipher = new FileCipher(driveContext); - this.mIOManager = IOManager.newInstance(driveContext); - } - - /** - * Creates a file inside the app folder at Google Drive - *

- * First, it ciphers the object (database) to upload.
- * Then, it tries to upload that such file (stored temporally at cache dir) by - * setting the {@link Constants.SQL} DB_FILENAME and the - * {@link Constants.DRIVE} MIME_TYPE
- * - * Also it uploads the necessary IV Vector for encrypting/decrypting the file - *

- * - * @see DriveResourceClient - * @see FileCipher#encryptFile(File, File) - * @see Tasks - * @see Files#copy(File, OutputStream) - * @see MetadataChangeSet - */ - private void createFileInAppFolder() { - final DriveResourceClient resourceClient = super.getDriveResourceClient(); - final Context driveContext = super.getDriveContext(); - final Activity driveActivity = super.getMainActivity(); - final Task appFolderTask = resourceClient.getAppFolder(); - final Task driveContentTask = resourceClient.createContents(); - final GeneralObjectContainer fileContainer = new ObjectContainer<>(1); - try { - fileContainer.storeObject(new File(driveContext.getCacheDir().getAbsolutePath() + - "/SecurePass.crypt.db")); - mFileCipher.encryptFile(mIOManager.getDatabasePath(), - fileContainer.getLatestStoredObject()); - } catch (NoSuchPaddingException | NoSuchAlgorithmException | - InvalidAlgorithmParameterException | InvalidKeyException | BadPaddingException | - IllegalBlockSizeException | IOException e) { - Log.e(TAG, "Error while encrypting file - working at insecure mode | More info: " - + e.getMessage()); - fileContainer.storeObject(mIOManager.getDatabasePath()); - } finally { - Tasks.whenAll(appFolderTask, driveContentTask) - .continueWith(task -> { - DriveFolder appFolder = appFolderTask.getResult(); - DriveContents folderContents = driveContentTask.getResult(); - try (OutputStream streamToGoogleDrive = folderContents.getOutputStream()) { - Files.copy(fileContainer.getLatestStoredObject(), streamToGoogleDrive); - } - MetadataChangeSet changeSet = new MetadataChangeSet.Builder() - .setTitle(Constants.SQL.DB_FILENAME) - .setMimeType(Constants.DRIVE.MIME_TYPE) - .setPinned(true) - .build(); - return resourceClient.createFile(appFolder, changeSet, folderContents); - }) - .addOnSuccessListener(driveActivity, driveFileTask -> { - int uploadIVVectorStatus = uploadIVVector(); - if (uploadIVVectorStatus == 0) - showMessage("DB file uploaded"); - else - showMessage("Error uploading file"); - }) - .addOnFailureListener(driveActivity, e -> { - Log.e(TAG, Constants.DRIVE.GOOGLE_DRIVE_FILE_NOT_CREATED, e); - showMessage("Error while uploading"); - }); - finalizeUpload(fileContainer.getLatestStoredObject()); - } - } - - /** - * After uploading the database, it must destroy the cached version - * - * @param sourceFile path for the file to be deleted if possible - * @see File#equals(Object) - * @see File#delete() - */ - private void finalizeUpload(@NonNull File sourceFile) { - if (!sourceFile.equals(mIOManager.getDatabasePath())) { - sourceFile.delete(); - } - } - - /** - * Uploads the IV Vector to the app folder at Google Drive. It must be uploaded once - * - * @return int value which represents the status of the stored object: '0' if everything has - * gone well, else '-1' - * @see Tasks - * @see ObjectContainer#getLatestStoredObject() - */ - private int uploadIVVector() { - final DriveResourceClient resourceClient = super.getDriveResourceClient(); - final Activity driveActivity = super.getMainActivity(); - final Task appFolderTask = resourceClient.getAppFolder(); - final Task driveContentTask = resourceClient.createContents(); - final GeneralObjectContainer status = new ObjectContainer<>(1); - Tasks.whenAll(appFolderTask, driveContentTask) - .continueWith(task -> { - DriveFolder appFolder = appFolderTask.getResult(); - DriveContents folderContents = driveContentTask.getResult(); - try (OutputStream streamToGoogleDrive = folderContents.getOutputStream()) { - Files.copy(mIOManager.getIVVector(), streamToGoogleDrive); - } - MetadataChangeSet changeSet = new MetadataChangeSet.Builder() - .setTitle(Constants.DRIVE.IV_FILE) - .setMimeType(Constants.DRIVE.IV_MIME_TYPE) - .build(); - return resourceClient.createFile(appFolder, changeSet, folderContents); - }) - .addOnSuccessListener(driveActivity, driveFileTask -> status.storeObject(0)) - .addOnFailureListener(driveActivity, e -> { - Log.e(TAG, Constants.DRIVE.GOOGLE_DRIVE_FILE_NOT_CREATED, e); - status.storeObject(-1); - }); - return status.getLatestStoredObject(); - } - - /** - * Deletes old files if found at the Google Drive app folder, in order to only store and save - * the latest one - * - * @param resultsAdapter container with all the found objects that can be deleted - */ - private void deleteOldFiles(DataBufferAdapter resultsAdapter) { - int resultsFound = resultsAdapter.getCount(); - for (int i = 0; i < resultsFound; ++i) { - DriveResource fileToDelete = resultsAdapter.getItem(i).getDriveId().asDriveResource(); - getDriveResourceClient().delete(fileToDelete); - } - } - - /** - * General public method which invokes in order the following ones: - *
    - *
  • - * {@link #isAbleToSignIn()} - *
  • - *
  • - * {@link #queryFiles(DataBufferAdapter)} - *
  • - *
  • - * {@link #createFileInAppFolder()} - *
  • - *
  • - * {@link #deleteOldFiles(DataBufferAdapter)} - *
  • - *
- * - * @see DataBufferAdapter - * @see ResultsAdapter - * @see GoogleDriveBase - */ - @Override - public void uploadDatabase() { - DataBufferAdapter resultsAdapter = new ResultsAdapter(getDriveContext()); - if (super.isAbleToSignIn()) { - queryFiles(resultsAdapter); - createFileInAppFolder(); - deleteOldFiles(resultsAdapter); - } - } -} +package javinator9889.securepass.backup.drive; + +import android.app.Activity; +import android.content.Context; +import android.util.Log; + +import com.google.android.gms.drive.DriveContents; +import com.google.android.gms.drive.DriveFolder; +import com.google.android.gms.drive.DriveResource; +import com.google.android.gms.drive.DriveResourceClient; +import com.google.android.gms.drive.Metadata; +import com.google.android.gms.drive.MetadataChangeSet; +import com.google.android.gms.drive.widget.DataBufferAdapter; +import com.google.android.gms.tasks.Task; +import com.google.android.gms.tasks.Tasks; +import com.google.common.io.Files; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +import androidx.annotation.NonNull; +import javinator9889.securepass.backup.drive.base.GoogleDriveBase; +import javinator9889.securepass.io.IOManager; +import javinator9889.securepass.objects.GeneralObjectContainer; +import javinator9889.securepass.objects.ObjectContainer; +import javinator9889.securepass.util.cipher.FileCipher; +import javinator9889.securepass.util.cipher.ICipher; +import javinator9889.securepass.util.values.Constants; + +/** + * Class for uploading files to app folder at Google Drive + * + * @see GoogleDriveBase + * @see IDriveUploader + * Created by Javinator9889 on 24/08/2018. + */ +public class DriveUploader extends GoogleDriveBase implements IDriveUploader { + private static final String TAG = "DriveUploader"; + private ICipher mFileCipher; + private IOManager mIOManager; + + /** + * Public constructor for starting the upload activity + * + * @param driveContext Context when instantiating this class + * @param mainActivity Activity when instantiating this class + * @see Activity + * @see Context + * @see GoogleDriveBase + * @see FileCipher + */ + public DriveUploader(@NonNull Context driveContext, @NonNull Activity mainActivity) { + super(driveContext, mainActivity); + super.signIn(); + this.mFileCipher = new FileCipher(driveContext); + this.mIOManager = IOManager.newInstance(driveContext); + } + + /** + * Creates a file inside the app folder at Google Drive + *

+ * First, it ciphers the object (database) to upload.
+ * Then, it tries to upload that such file (stored temporally at cache dir) by + * setting the {@link Constants.SQL} DB_FILENAME and the + * {@link Constants.DRIVE} MIME_TYPE
+ * + * Also it uploads the necessary IV Vector for encrypting/decrypting the file + *

+ * + * @see DriveResourceClient + * @see FileCipher#encryptFile(File, File) + * @see Tasks + * @see Files#copy(File, OutputStream) + * @see MetadataChangeSet + */ + private void createFileInAppFolder() { + final DriveResourceClient resourceClient = super.getDriveResourceClient(); + final Context driveContext = super.getDriveContext(); + final Activity driveActivity = super.getMainActivity(); + final Task appFolderTask = resourceClient.getAppFolder(); + final Task driveContentTask = resourceClient.createContents(); + final GeneralObjectContainer fileContainer = new ObjectContainer<>(1); + try { + fileContainer.storeObject(new File(driveContext.getCacheDir().getAbsolutePath() + + "/SecurePass.crypt.db")); + mFileCipher.encryptFile(mIOManager.getDatabasePath(), + fileContainer.getLatestStoredObject()); + } catch (NoSuchPaddingException | NoSuchAlgorithmException | + InvalidAlgorithmParameterException | InvalidKeyException | BadPaddingException | + IllegalBlockSizeException | IOException e) { + Log.e(TAG, "Error while encrypting file - working at insecure mode | More info: " + + e.getMessage()); + fileContainer.storeObject(mIOManager.getDatabasePath()); + } finally { + Tasks.whenAll(appFolderTask, driveContentTask) + .continueWith(task -> { + DriveFolder appFolder = appFolderTask.getResult(); + DriveContents folderContents = driveContentTask.getResult(); + try (OutputStream streamToGoogleDrive = folderContents.getOutputStream()) { + Files.copy(fileContainer.getLatestStoredObject(), streamToGoogleDrive); + } + MetadataChangeSet changeSet = new MetadataChangeSet.Builder() + .setTitle(Constants.SQL.DB_FILENAME) + .setMimeType(Constants.DRIVE.MIME_TYPE) + .setPinned(true) + .build(); + return resourceClient.createFile(appFolder, changeSet, folderContents); + }) + .addOnSuccessListener(driveActivity, driveFileTask -> { + int uploadIVVectorStatus = uploadIVVector(); + if (uploadIVVectorStatus == 0) + showMessage("DB file uploaded"); + else + showMessage("Error uploading file"); + }) + .addOnFailureListener(driveActivity, e -> { + Log.e(TAG, Constants.DRIVE.GOOGLE_DRIVE_FILE_NOT_CREATED, e); + showMessage("Error while uploading"); + }); + finalizeUpload(fileContainer.getLatestStoredObject()); + } + } + + /** + * After uploading the database, it must destroy the cached version + * + * @param sourceFile path for the file to be deleted if possible + * @see File#equals(Object) + * @see File#delete() + */ + private void finalizeUpload(@NonNull File sourceFile) { + if (!sourceFile.equals(mIOManager.getDatabasePath())) { + sourceFile.delete(); + } + } + + /** + * Uploads the IV Vector to the app folder at Google Drive. It must be uploaded once + * + * @return int value which represents the status of the stored object: '0' if everything has + * gone well, else '-1' + * @see Tasks + * @see ObjectContainer#getLatestStoredObject() + */ + private int uploadIVVector() { + final DriveResourceClient resourceClient = super.getDriveResourceClient(); + final Activity driveActivity = super.getMainActivity(); + final Task appFolderTask = resourceClient.getAppFolder(); + final Task driveContentTask = resourceClient.createContents(); + final GeneralObjectContainer status = new ObjectContainer<>(1); + Tasks.whenAll(appFolderTask, driveContentTask) + .continueWith(task -> { + DriveFolder appFolder = appFolderTask.getResult(); + DriveContents folderContents = driveContentTask.getResult(); + try (OutputStream streamToGoogleDrive = folderContents.getOutputStream()) { + Files.copy(mIOManager.getIVVector(), streamToGoogleDrive); + } + MetadataChangeSet changeSet = new MetadataChangeSet.Builder() + .setTitle(Constants.DRIVE.IV_FILE) + .setMimeType(Constants.DRIVE.IV_MIME_TYPE) + .build(); + return resourceClient.createFile(appFolder, changeSet, folderContents); + }) + .addOnSuccessListener(driveActivity, driveFileTask -> status.storeObject(0)) + .addOnFailureListener(driveActivity, e -> { + Log.e(TAG, Constants.DRIVE.GOOGLE_DRIVE_FILE_NOT_CREATED, e); + status.storeObject(-1); + }); + return status.getLatestStoredObject(); + } + + /** + * Deletes old files if found at the Google Drive app folder, in order to only store and save + * the latest one + * + * @param resultsAdapter container with all the found objects that can be deleted + */ + private void deleteOldFiles(DataBufferAdapter resultsAdapter) { + int resultsFound = resultsAdapter.getCount(); + for (int i = 0; i < resultsFound; ++i) { + DriveResource fileToDelete = resultsAdapter.getItem(i).getDriveId().asDriveResource(); + getDriveResourceClient().delete(fileToDelete); + } + } + + /** + * General public method which invokes in order the following ones: + *
    + *
  • + * {@link #isAbleToSignIn()} + *
  • + *
  • + * {@link #queryFiles(DataBufferAdapter)} + *
  • + *
  • + * {@link #createFileInAppFolder()} + *
  • + *
  • + * {@link #deleteOldFiles(DataBufferAdapter)} + *
  • + *
+ * + * @see DataBufferAdapter + * @see ResultsAdapter + * @see GoogleDriveBase + */ + @Override + public void uploadDatabase() { + DataBufferAdapter resultsAdapter = new ResultsAdapter(getDriveContext()); + if (super.isAbleToSignIn()) { + queryFiles(resultsAdapter); + createFileInAppFolder(); + deleteOldFiles(resultsAdapter); + } + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/backup/drive/IDriveDownloader.java b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/IDriveDownloader.java similarity index 96% rename from APP/app/src/main/java/javinator9889/securepass/backup/drive/IDriveDownloader.java rename to SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/IDriveDownloader.java index da93d29..6b8428d 100644 --- a/APP/app/src/main/java/javinator9889/securepass/backup/drive/IDriveDownloader.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/IDriveDownloader.java @@ -1,20 +1,20 @@ -package javinator9889.securepass.backup.drive; - -import com.google.android.gms.drive.DriveFile; -import com.google.android.gms.drive.widget.DataBufferAdapter; -import com.google.android.gms.tasks.Task; - -/** - * Interface for accessing {@link DriveDownloader} - * Created by Javinator9889 on 03/09/2018. - */ -public interface IDriveDownloader { - /** - * Restores the data and saves it into a ResultsAdapter - * - * @see DataBufferAdapter - * @see DriveFile - * @see Task - */ - void restoreData(); -} +package javinator9889.securepass.backup.drive; + +import com.google.android.gms.drive.DriveFile; +import com.google.android.gms.drive.widget.DataBufferAdapter; +import com.google.android.gms.tasks.Task; + +/** + * Interface for accessing {@link DriveDownloader} + * Created by Javinator9889 on 03/09/2018. + */ +public interface IDriveDownloader { + /** + * Restores the data and saves it into a ResultsAdapter + * + * @see DataBufferAdapter + * @see DriveFile + * @see Task + */ + void restoreData(); +} diff --git a/APP/app/src/main/java/javinator9889/securepass/backup/drive/IDriveUploader.java b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/IDriveUploader.java similarity index 96% rename from APP/app/src/main/java/javinator9889/securepass/backup/drive/IDriveUploader.java rename to SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/IDriveUploader.java index 8b54d20..e23d798 100644 --- a/APP/app/src/main/java/javinator9889/securepass/backup/drive/IDriveUploader.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/IDriveUploader.java @@ -1,34 +1,34 @@ -package javinator9889.securepass.backup.drive; - -import com.google.android.gms.drive.widget.DataBufferAdapter; - -import javinator9889.securepass.backup.drive.base.GoogleDriveBase; - -/** - * Interface for accessing {@link DriveUploader} - * Created by Javinator9889 on 24/08/2018. - */ -public interface IDriveUploader { - /** - * General public method which invokes in order the following ones: - *
    - *
  • - * {@link DriveUploader#isAbleToSignIn()} ()} - *
  • - *
  • - * {@link DriveUploader#queryFiles(DataBufferAdapter)} - *
  • - *
  • - * {@link DriveUploader#createFileInAppFolder()} - *
  • - *
  • - * {@link DriveUploader#deleteOldFiles(DataBufferAdapter)} - *
  • - *
- * - * @see DataBufferAdapter - * @see ResultsAdapter - * @see GoogleDriveBase - */ - void uploadDatabase(); -} +package javinator9889.securepass.backup.drive; + +import com.google.android.gms.drive.widget.DataBufferAdapter; + +import javinator9889.securepass.backup.drive.base.GoogleDriveBase; + +/** + * Interface for accessing {@link DriveUploader} + * Created by Javinator9889 on 24/08/2018. + */ +public interface IDriveUploader { + /** + * General public method which invokes in order the following ones: + *
    + *
  • + * {@link DriveUploader#isAbleToSignIn()} ()} + *
  • + *
  • + * {@link DriveUploader#queryFiles(DataBufferAdapter)} + *
  • + *
  • + * {@link DriveUploader#createFileInAppFolder()} + *
  • + *
  • + * {@link DriveUploader#deleteOldFiles(DataBufferAdapter)} + *
  • + *
+ * + * @see DataBufferAdapter + * @see ResultsAdapter + * @see GoogleDriveBase + */ + void uploadDatabase(); +} diff --git a/APP/app/src/main/java/javinator9889/securepass/backup/drive/ResultsAdapter.java b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/ResultsAdapter.java similarity index 96% rename from APP/app/src/main/java/javinator9889/securepass/backup/drive/ResultsAdapter.java rename to SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/ResultsAdapter.java index 0edb9ec..dc5cac1 100644 --- a/APP/app/src/main/java/javinator9889/securepass/backup/drive/ResultsAdapter.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/ResultsAdapter.java @@ -1,28 +1,28 @@ -package javinator9889.securepass.backup.drive; - -import android.content.Context; - -import com.google.android.gms.drive.Metadata; -import com.google.android.gms.drive.widget.DataBufferAdapter; - -import androidx.annotation.NonNull; - -/** - * Store and save recovered documents from Google Drive - * - * @see DataBufferAdapter - * @see Metadata - * Created by Javinator9889 on 07/04/2018. - */ -public class ResultsAdapter extends DataBufferAdapter { - /** - * Required public constructor that invokes - * {@link DataBufferAdapter#DataBufferAdapter(Context, int) super method} super ones with a - * {@link android.R.layout#simple_list_item_1 simple list item} by default - * - * @param context Context when instantiating this class - */ - public ResultsAdapter(@NonNull Context context) { - super(context, android.R.layout.simple_list_item_1); - } -} +package javinator9889.securepass.backup.drive; + +import android.content.Context; + +import com.google.android.gms.drive.Metadata; +import com.google.android.gms.drive.widget.DataBufferAdapter; + +import androidx.annotation.NonNull; + +/** + * Store and save recovered documents from Google Drive + * + * @see DataBufferAdapter + * @see Metadata + * Created by Javinator9889 on 07/04/2018. + */ +public class ResultsAdapter extends DataBufferAdapter { + /** + * Required public constructor that invokes + * {@link DataBufferAdapter#DataBufferAdapter(Context, int) super method} super ones with a + * {@link android.R.layout#simple_list_item_1 simple list item} by default + * + * @param context Context when instantiating this class + */ + public ResultsAdapter(@NonNull Context context) { + super(context, android.R.layout.simple_list_item_1); + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/backup/drive/base/GoogleDriveBase.java b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/base/GoogleDriveBase.java similarity index 97% rename from APP/app/src/main/java/javinator9889/securepass/backup/drive/base/GoogleDriveBase.java rename to SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/base/GoogleDriveBase.java index d3b1def..e67bc4f 100644 --- a/APP/app/src/main/java/javinator9889/securepass/backup/drive/base/GoogleDriveBase.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/base/GoogleDriveBase.java @@ -1,246 +1,246 @@ -package javinator9889.securepass.backup.drive.base; - -import android.app.Activity; -import android.content.Context; -import android.widget.Toast; - -import com.google.android.gms.auth.api.signin.GoogleSignIn; -import com.google.android.gms.auth.api.signin.GoogleSignInAccount; -import com.google.android.gms.drive.Drive; -import com.google.android.gms.drive.DriveFolder; -import com.google.android.gms.drive.DriveResourceClient; -import com.google.android.gms.drive.Metadata; -import com.google.android.gms.drive.MetadataBuffer; -import com.google.android.gms.drive.query.Filters; -import com.google.android.gms.drive.query.Query; -import com.google.android.gms.drive.query.SearchableField; -import com.google.android.gms.drive.query.SortOrder; -import com.google.android.gms.drive.query.SortableField; -import com.google.android.gms.drive.widget.DataBufferAdapter; -import com.google.android.gms.tasks.Task; - -import java.security.Key; -import java.security.spec.AlgorithmParameterSpec; - -import androidx.annotation.NonNull; -import androidx.annotation.StringRes; -import javinator9889.securepass.R; -import javinator9889.securepass.backup.drive.ResultsAdapter; -import javinator9889.securepass.util.values.Constants; -import javinator9889.securepass.util.values.Constants.DRIVE; - -/** - * Created by Javinator9889 on 24/04/2018. - * Base class for managing Google Drive connections - */ -public class GoogleDriveBase implements IDriveBase { - private static final String TAG = "drive-base"; - private Context mDriveContext; - private Activity mMainActivity; - private DriveResourceClient mDriveResourceClient; - private DataBufferAdapter mResultsAdapter; - private SignIn mSignInClient; - - /** - * Public constructor for base class - * - * @param driveContext Context when initializing this class - * @param mainActivity Activity when initializing this class - * @see Context - * @see Activity - */ - public GoogleDriveBase(@NonNull Context driveContext, @NonNull Activity mainActivity) { - this.mDriveContext = driveContext; - this.mMainActivity = mainActivity; - mSignInClient = SignIn.getInstance(mainActivity, driveContext); - mResultsAdapter = new ResultsAdapter(driveContext); - } - - /** - * Obtains Context - * - * @return Context object - * @see Context - */ - public Context getDriveContext() { - return mDriveContext; - } - - /** - * Obtains Activity - * - * @return Activity object - * @see Activity - */ - public Activity getMainActivity() { - return mMainActivity; - } - - /** - * Obtains the ResultsAdapter - * - * @return DataBufferAdapter of Metadata object - * @see DataBufferAdapter - * @see Metadata - */ - public DataBufferAdapter getResultsAdapter() { - return mResultsAdapter; - } - - /** - * Obtains the DriveResourceClient - * - * @return DriveResourceClient object - * @see DriveResourceClient - */ - public DriveResourceClient getDriveResourceClient() { - return mDriveResourceClient; - } - - /** - * Obtains the SignInClient - * - * @return SignIn object - * @see SignIn - */ - public SignIn getSignInClient() { - return mSignInClient; - } - - /** - * Signs-in into Google Drive by using the SignIn class - * - * @see SignIn - */ - @Override - public void signIn() { - mSignInClient.signIn(); - } - - /** - * Determines whether is able to sign-in - * - * @return boolean: 'true' if is user is signed-in, else 'false' - */ - protected boolean isAbleToSignIn() { - if (!mSignInClient.isSignedIn()) { - GoogleSignInAccount latestSignedInAccount = GoogleSignIn - .getLastSignedInAccount(mDriveContext); - if (latestSignedInAccount != null) { - mDriveResourceClient = Drive - .getDriveResourceClient(mDriveContext, latestSignedInAccount); - return true; - } else { - showMessage(R.string.sign_in_first); - return false; - } - } else - return true; - } - - /** - * Sets the DriveResourceClient for classes that inherit from this - * - * @param resourceClient DriveResourceClient when the user has signed-in - * @see DriveResourceClient - */ - @Override - public void setDriveResourceClient(DriveResourceClient resourceClient) { - this.mDriveResourceClient = resourceClient; - } - - /** - * Sets whether the user is or not logged in - * - * @param isLoggedIn boolean, 'true' if signed-in, else 'false' - */ - @Override - public void setLoggedIn(boolean isLoggedIn) { - mSignInClient.setSignedIn(isLoggedIn); - } - - /** - * Method for not repeating code when showing a Toast - * - * @param message String which contains the message to be shown - * @see #showMessage(int) - * @deprecated use {@link #showMessage(int)} instead - */ - @Override - @Deprecated - public void showMessage(@NonNull String message) { - Toast.makeText(mDriveContext, message, Toast.LENGTH_LONG).show(); - } - - /** - * Method for not repeating code when showing a Toast - * - * @param message @StringRes int which contains the resource id (R.string - * .string_name) - * @see StringRes - * @see R.string - */ - @Override - public void showMessage(@StringRes int message) { - Toast.makeText(mDriveContext, message, Toast.LENGTH_LONG).show(); - } - - /** - * Query the files that applies to some filters, saving them to a DataBufferAdapter object - * - * @param resultsAdapter DataBufferAdapter of Metadata which will store the results - * @see Constants.DRIVE - * @see Constants.SQL - * @see DataBufferAdapter - * @see Metadata - */ - protected void queryFiles(DataBufferAdapter resultsAdapter) { - SortOrder sortOrder = new SortOrder.Builder().addSortAscending(SortableField.CREATED_DATE) - .build(); - Query query = new Query.Builder() - .addFilter(Filters.and(Filters.eq(SearchableField.TITLE, Constants.SQL.DB_FILENAME), - Filters.eq(SearchableField.MIME_TYPE, Constants.DRIVE.MIME_TYPE))) - .setSortOrder(sortOrder) - .build(); - retrieveContents(query, resultsAdapter); - } - - /** - * Query only the files that are an IV Vector (for encryption), saving them to a - * DataBufferAdapter object - * - * @param resultsAdapter DataBufferAdapter of Metadata which will store the results - * @see Constants.SQL - * @see Constants.DRIVE - * @see javax.crypto.Cipher#init(int, Key, AlgorithmParameterSpec) - * @see java.security.SecureRandom#nextBytes(byte[]) - */ - protected void getIVVector(DataBufferAdapter resultsAdapter) { - SortOrder sortOrder = new SortOrder.Builder().addSortAscending(SortableField.CREATED_DATE) - .build(); - Query query = new Query.Builder() - .addFilter(Filters.and(Filters.eq(SearchableField.TITLE, DRIVE.IV_FILE), - Filters.eq(SearchableField.MIME_TYPE, DRIVE.IV_MIME_TYPE))) - .setSortOrder(sortOrder) - .build(); - retrieveContents(query, resultsAdapter); - } - - /** - * By providing a query, retrieve the correspondent Google Drive files into an adapter - * - * @param query determines which files will be downloaded - * @param resultsAdapter stores files inside a BufferAdapter - * @see Query - * @see DataBufferAdapter - * @see Metadata - */ - private void retrieveContents(@NonNull Query query, DataBufferAdapter resultsAdapter) { - Task appFolderTask = getDriveResourceClient().getAppFolder(); - appFolderTask.addOnSuccessListener(getMainActivity(), driveFolder -> { - Task queryTask = getDriveResourceClient() - .queryChildren(driveFolder, query); - queryTask.addOnSuccessListener(getMainActivity(), resultsAdapter::append); - }); - } -} +package javinator9889.securepass.backup.drive.base; + +import android.app.Activity; +import android.content.Context; +import android.widget.Toast; + +import com.google.android.gms.auth.api.signin.GoogleSignIn; +import com.google.android.gms.auth.api.signin.GoogleSignInAccount; +import com.google.android.gms.drive.Drive; +import com.google.android.gms.drive.DriveFolder; +import com.google.android.gms.drive.DriveResourceClient; +import com.google.android.gms.drive.Metadata; +import com.google.android.gms.drive.MetadataBuffer; +import com.google.android.gms.drive.query.Filters; +import com.google.android.gms.drive.query.Query; +import com.google.android.gms.drive.query.SearchableField; +import com.google.android.gms.drive.query.SortOrder; +import com.google.android.gms.drive.query.SortableField; +import com.google.android.gms.drive.widget.DataBufferAdapter; +import com.google.android.gms.tasks.Task; + +import java.security.Key; +import java.security.spec.AlgorithmParameterSpec; + +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; +import javinator9889.securepass.R; +import javinator9889.securepass.backup.drive.ResultsAdapter; +import javinator9889.securepass.util.values.Constants; +import javinator9889.securepass.util.values.Constants.DRIVE; + +/** + * Created by Javinator9889 on 24/04/2018. + * Base class for managing Google Drive connections + */ +public class GoogleDriveBase implements IDriveBase { + private static final String TAG = "drive-base"; + private Context mDriveContext; + private Activity mMainActivity; + private DriveResourceClient mDriveResourceClient; + private DataBufferAdapter mResultsAdapter; + private SignIn mSignInClient; + + /** + * Public constructor for base class + * + * @param driveContext Context when initializing this class + * @param mainActivity Activity when initializing this class + * @see Context + * @see Activity + */ + public GoogleDriveBase(@NonNull Context driveContext, @NonNull Activity mainActivity) { + this.mDriveContext = driveContext; + this.mMainActivity = mainActivity; + mSignInClient = SignIn.getInstance(mainActivity, driveContext); + mResultsAdapter = new ResultsAdapter(driveContext); + } + + /** + * Obtains Context + * + * @return Context object + * @see Context + */ + public Context getDriveContext() { + return mDriveContext; + } + + /** + * Obtains Activity + * + * @return Activity object + * @see Activity + */ + public Activity getMainActivity() { + return mMainActivity; + } + + /** + * Obtains the ResultsAdapter + * + * @return DataBufferAdapter of Metadata object + * @see DataBufferAdapter + * @see Metadata + */ + public DataBufferAdapter getResultsAdapter() { + return mResultsAdapter; + } + + /** + * Obtains the DriveResourceClient + * + * @return DriveResourceClient object + * @see DriveResourceClient + */ + public DriveResourceClient getDriveResourceClient() { + return mDriveResourceClient; + } + + /** + * Obtains the SignInClient + * + * @return SignIn object + * @see SignIn + */ + public SignIn getSignInClient() { + return mSignInClient; + } + + /** + * Signs-in into Google Drive by using the SignIn class + * + * @see SignIn + */ + @Override + public void signIn() { + mSignInClient.signIn(); + } + + /** + * Determines whether is able to sign-in + * + * @return boolean: 'true' if is user is signed-in, else 'false' + */ + protected boolean isAbleToSignIn() { + if (!mSignInClient.isSignedIn()) { + GoogleSignInAccount latestSignedInAccount = GoogleSignIn + .getLastSignedInAccount(mDriveContext); + if (latestSignedInAccount != null) { + mDriveResourceClient = Drive + .getDriveResourceClient(mDriveContext, latestSignedInAccount); + return true; + } else { + showMessage(R.string.sign_in_first); + return false; + } + } else + return true; + } + + /** + * Sets the DriveResourceClient for classes that inherit from this + * + * @param resourceClient DriveResourceClient when the user has signed-in + * @see DriveResourceClient + */ + @Override + public void setDriveResourceClient(DriveResourceClient resourceClient) { + this.mDriveResourceClient = resourceClient; + } + + /** + * Sets whether the user is or not logged in + * + * @param isLoggedIn boolean, 'true' if signed-in, else 'false' + */ + @Override + public void setLoggedIn(boolean isLoggedIn) { + mSignInClient.setSignedIn(isLoggedIn); + } + + /** + * Method for not repeating code when showing a Toast + * + * @param message String which contains the message to be shown + * @see #showMessage(int) + * @deprecated use {@link #showMessage(int)} instead + */ + @Override + @Deprecated + public void showMessage(@NonNull String message) { + Toast.makeText(mDriveContext, message, Toast.LENGTH_LONG).show(); + } + + /** + * Method for not repeating code when showing a Toast + * + * @param message @StringRes int which contains the resource id (R.string + * .string_name) + * @see StringRes + * @see R.string + */ + @Override + public void showMessage(@StringRes int message) { + Toast.makeText(mDriveContext, message, Toast.LENGTH_LONG).show(); + } + + /** + * Query the files that applies to some filters, saving them to a DataBufferAdapter object + * + * @param resultsAdapter DataBufferAdapter of Metadata which will store the results + * @see Constants.DRIVE + * @see Constants.SQL + * @see DataBufferAdapter + * @see Metadata + */ + protected void queryFiles(DataBufferAdapter resultsAdapter) { + SortOrder sortOrder = new SortOrder.Builder().addSortAscending(SortableField.CREATED_DATE) + .build(); + Query query = new Query.Builder() + .addFilter(Filters.and(Filters.eq(SearchableField.TITLE, Constants.SQL.DB_FILENAME), + Filters.eq(SearchableField.MIME_TYPE, Constants.DRIVE.MIME_TYPE))) + .setSortOrder(sortOrder) + .build(); + retrieveContents(query, resultsAdapter); + } + + /** + * Query only the files that are an IV Vector (for encryption), saving them to a + * DataBufferAdapter object + * + * @param resultsAdapter DataBufferAdapter of Metadata which will store the results + * @see Constants.SQL + * @see Constants.DRIVE + * @see javax.crypto.Cipher#init(int, Key, AlgorithmParameterSpec) + * @see java.security.SecureRandom#nextBytes(byte[]) + */ + protected void getIVVector(DataBufferAdapter resultsAdapter) { + SortOrder sortOrder = new SortOrder.Builder().addSortAscending(SortableField.CREATED_DATE) + .build(); + Query query = new Query.Builder() + .addFilter(Filters.and(Filters.eq(SearchableField.TITLE, DRIVE.IV_FILE), + Filters.eq(SearchableField.MIME_TYPE, DRIVE.IV_MIME_TYPE))) + .setSortOrder(sortOrder) + .build(); + retrieveContents(query, resultsAdapter); + } + + /** + * By providing a query, retrieve the correspondent Google Drive files into an adapter + * + * @param query determines which files will be downloaded + * @param resultsAdapter stores files inside a BufferAdapter + * @see Query + * @see DataBufferAdapter + * @see Metadata + */ + private void retrieveContents(@NonNull Query query, DataBufferAdapter resultsAdapter) { + Task appFolderTask = getDriveResourceClient().getAppFolder(); + appFolderTask.addOnSuccessListener(getMainActivity(), driveFolder -> { + Task queryTask = getDriveResourceClient() + .queryChildren(driveFolder, query); + queryTask.addOnSuccessListener(getMainActivity(), resultsAdapter::append); + }); + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/backup/drive/base/IDriveBase.java b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/base/IDriveBase.java similarity index 96% rename from APP/app/src/main/java/javinator9889/securepass/backup/drive/base/IDriveBase.java rename to SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/base/IDriveBase.java index c18024b..9d11802 100644 --- a/APP/app/src/main/java/javinator9889/securepass/backup/drive/base/IDriveBase.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/base/IDriveBase.java @@ -1,59 +1,59 @@ -package javinator9889.securepass.backup.drive.base; - -import com.google.android.gms.drive.DriveResourceClient; - -import androidx.annotation.NonNull; -import androidx.annotation.StringRes; -import javinator9889.securepass.R; - -/** - * Interface for accessing the GoogleDriveBase class - * Created by Javinator9889 on 24/04/2018. - */ -public interface IDriveBase { - int REQUEST_CODE_SIGN_IN = 0; - - int REQUEST_CODE_OPEN_ITEM = 1; - - /** - * Signs-in into Google Drive by using the SignIn class - * - * @see SignIn - */ - void signIn(); - - /** - * Sets the DriveResourceClient for classes that inherit from this - * - * @param resourceClient DriveResourceClient when the user has signed-in - * @see DriveResourceClient - */ - void setDriveResourceClient(DriveResourceClient resourceClient); - - /** - * Sets whether the user is or not logged in - * - * @param isLoggedIn boolean, 'true' if signed-in, else 'false' - */ - void setLoggedIn(boolean isLoggedIn); - - /** - * Method for not repeating code when showing a Toast - * - * @param message String which contains the message to be shown - * @see #showMessage(int) - * @deprecated use {@link #showMessage(int)} instead - */ - @Deprecated - void showMessage(@NonNull String message); - - /** - * Method for not repeating code when showing a Toast - * - * @param message @StringRes int which contains the resource id (R.string - * .string_name) - * @see StringRes - * @see R.string - */ - void showMessage(@StringRes int message); -} +package javinator9889.securepass.backup.drive.base; + +import com.google.android.gms.drive.DriveResourceClient; + +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; +import javinator9889.securepass.R; + +/** + * Interface for accessing the GoogleDriveBase class + * Created by Javinator9889 on 24/04/2018. + */ +public interface IDriveBase { + int REQUEST_CODE_SIGN_IN = 0; + + int REQUEST_CODE_OPEN_ITEM = 1; + + /** + * Signs-in into Google Drive by using the SignIn class + * + * @see SignIn + */ + void signIn(); + + /** + * Sets the DriveResourceClient for classes that inherit from this + * + * @param resourceClient DriveResourceClient when the user has signed-in + * @see DriveResourceClient + */ + void setDriveResourceClient(DriveResourceClient resourceClient); + + /** + * Sets whether the user is or not logged in + * + * @param isLoggedIn boolean, 'true' if signed-in, else 'false' + */ + void setLoggedIn(boolean isLoggedIn); + + /** + * Method for not repeating code when showing a Toast + * + * @param message String which contains the message to be shown + * @see #showMessage(int) + * @deprecated use {@link #showMessage(int)} instead + */ + @Deprecated + void showMessage(@NonNull String message); + + /** + * Method for not repeating code when showing a Toast + * + * @param message @StringRes int which contains the resource id (R.string + * .string_name) + * @see StringRes + * @see R.string + */ + void showMessage(@StringRes int message); +} diff --git a/APP/app/src/main/java/javinator9889/securepass/backup/drive/base/SignIn.java b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/base/SignIn.java similarity index 97% rename from APP/app/src/main/java/javinator9889/securepass/backup/drive/base/SignIn.java rename to SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/base/SignIn.java index 3388b3e..9ee6f7c 100644 --- a/APP/app/src/main/java/javinator9889/securepass/backup/drive/base/SignIn.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/base/SignIn.java @@ -1,134 +1,134 @@ -package javinator9889.securepass.backup.drive.base; - -import android.app.Activity; -import android.content.Context; - -import com.google.android.gms.auth.api.signin.GoogleSignIn; -import com.google.android.gms.auth.api.signin.GoogleSignInClient; -import com.google.android.gms.auth.api.signin.GoogleSignInOptions; -import com.google.android.gms.drive.Drive; - -import androidx.annotation.NonNull; -import javinator9889.securepass.objects.GeneralObjectContainer; -import javinator9889.securepass.objects.ObjectContainer; - -/** - * Singleton class for singing-in into Google Drive - * Created by Javinator9889 on 25/04/2018. - */ -public class SignIn { - private static final int REQUEST_CODE_SIGN_IN = 0; - private static SignIn INSTANCE = null; - private GeneralObjectContainer mActivityContainer; - private GeneralObjectContainer mContextContainer; - private boolean mIsSignedIn; - private boolean mIsSignInClientBuilt; - private GoogleSignInClient mGoogleSignInClient; - - /** - * Generates the SignIn instance the first time it is executed - *

- * Stores Activity and Context into - * ObjectContainer for avoiding memory leaks - *

- * - * @param mainActivity Activity when the class was launched - * @param driveContext Context when the class was launched - * @see Activity - * @see Context - * @see ObjectContainer - * @see GeneralObjectContainer - */ - private SignIn(@NonNull Activity mainActivity, @NonNull Context driveContext) { - INSTANCE = this; - this.mActivityContainer = new ObjectContainer<>(mainActivity); - this.mContextContainer = new ObjectContainer<>(driveContext); - this.mIsSignedIn = false; - this.mIsSignInClientBuilt = false; - } - - /** - * Accessible method for obtaining a SignIn class instance - *

- * Stores Activity and Context into - * ObjectContainer for avoiding memory leaks - *

- * - * @param mainActivity Activity when the class was launched - * @param driveContext Context when the class was launched - * @return SignIn instance if available, else new instance - * @see Activity - * @see Context - * @see ObjectContainer - * @see GeneralObjectContainer - */ - public static SignIn getInstance(@NonNull Activity mainActivity, - @NonNull Context driveContext) { - return INSTANCE != null ? INSTANCE : new SignIn(mainActivity, driveContext); - } - - /** - * Signs-in into Google Drive by requesting the user some credentials - * - * @see GoogleSignInClient - * @see #buildGoogleSignInClient() - */ - public void signIn() { - Activity mainActivity = mActivityContainer.getLatestStoredObject(); - if (mIsSignInClientBuilt) - mainActivity.startActivityForResult(mGoogleSignInClient.getSignInIntent(), - REQUEST_CODE_SIGN_IN); - else { - buildGoogleSignInClient(); - mainActivity.startActivityForResult(mGoogleSignInClient.getSignInIntent(), - REQUEST_CODE_SIGN_IN); - } - } - - /** - * Generates the Google Drive sign in client, necessary for accessing to the Google Drive API - * at the app folder with the chosen account - * - * @see GoogleSignIn - * @see GoogleSignInOptions - */ - private void buildGoogleSignInClient() { - Context driveContext = mContextContainer.getLatestStoredObject(); - GoogleSignInOptions signInOptions = - new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) - .requestScopes(Drive.SCOPE_FILE, Drive.SCOPE_APPFOLDER) - .build(); - this.mGoogleSignInClient = GoogleSignIn.getClient(driveContext, signInOptions); - mIsSignInClientBuilt = true; - } - - /** - * Sets whether the user is or not signed in - * - * @param isSignedIn boolean 'true' if already signed-in, else 'false' - */ - public void setSignedIn(boolean isSignedIn) { - this.mIsSignedIn = isSignedIn; - } - - /** - * Checks if user is already signed-in - * - * @return boolean 'true' when signed-in, else 'false' - */ - public boolean isSignedIn() { - return mIsSignedIn; - } - - /** - * Finish this class when a new instance is required for some reason - */ - public void finish() { - mIsSignedIn = false; - mIsSignInClientBuilt = false; - mContextContainer.removeAllObjects(); - mActivityContainer.removeAllObjects(); - mGoogleSignInClient = null; - INSTANCE = null; - } -} +package javinator9889.securepass.backup.drive.base; + +import android.app.Activity; +import android.content.Context; + +import com.google.android.gms.auth.api.signin.GoogleSignIn; +import com.google.android.gms.auth.api.signin.GoogleSignInClient; +import com.google.android.gms.auth.api.signin.GoogleSignInOptions; +import com.google.android.gms.drive.Drive; + +import androidx.annotation.NonNull; +import javinator9889.securepass.objects.GeneralObjectContainer; +import javinator9889.securepass.objects.ObjectContainer; + +/** + * Singleton class for singing-in into Google Drive + * Created by Javinator9889 on 25/04/2018. + */ +public class SignIn { + private static final int REQUEST_CODE_SIGN_IN = 0; + private static SignIn INSTANCE = null; + private GeneralObjectContainer mActivityContainer; + private GeneralObjectContainer mContextContainer; + private boolean mIsSignedIn; + private boolean mIsSignInClientBuilt; + private GoogleSignInClient mGoogleSignInClient; + + /** + * Generates the SignIn instance the first time it is executed + *

+ * Stores Activity and Context into + * ObjectContainer for avoiding memory leaks + *

+ * + * @param mainActivity Activity when the class was launched + * @param driveContext Context when the class was launched + * @see Activity + * @see Context + * @see ObjectContainer + * @see GeneralObjectContainer + */ + private SignIn(@NonNull Activity mainActivity, @NonNull Context driveContext) { + INSTANCE = this; + this.mActivityContainer = new ObjectContainer<>(mainActivity); + this.mContextContainer = new ObjectContainer<>(driveContext); + this.mIsSignedIn = false; + this.mIsSignInClientBuilt = false; + } + + /** + * Accessible method for obtaining a SignIn class instance + *

+ * Stores Activity and Context into + * ObjectContainer for avoiding memory leaks + *

+ * + * @param mainActivity Activity when the class was launched + * @param driveContext Context when the class was launched + * @return SignIn instance if available, else new instance + * @see Activity + * @see Context + * @see ObjectContainer + * @see GeneralObjectContainer + */ + public static SignIn getInstance(@NonNull Activity mainActivity, + @NonNull Context driveContext) { + return INSTANCE != null ? INSTANCE : new SignIn(mainActivity, driveContext); + } + + /** + * Signs-in into Google Drive by requesting the user some credentials + * + * @see GoogleSignInClient + * @see #buildGoogleSignInClient() + */ + public void signIn() { + Activity mainActivity = mActivityContainer.getLatestStoredObject(); + if (mIsSignInClientBuilt) + mainActivity.startActivityForResult(mGoogleSignInClient.getSignInIntent(), + REQUEST_CODE_SIGN_IN); + else { + buildGoogleSignInClient(); + mainActivity.startActivityForResult(mGoogleSignInClient.getSignInIntent(), + REQUEST_CODE_SIGN_IN); + } + } + + /** + * Generates the Google Drive sign in client, necessary for accessing to the Google Drive API + * at the app folder with the chosen account + * + * @see GoogleSignIn + * @see GoogleSignInOptions + */ + private void buildGoogleSignInClient() { + Context driveContext = mContextContainer.getLatestStoredObject(); + GoogleSignInOptions signInOptions = + new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) + .requestScopes(Drive.SCOPE_FILE, Drive.SCOPE_APPFOLDER) + .build(); + this.mGoogleSignInClient = GoogleSignIn.getClient(driveContext, signInOptions); + mIsSignInClientBuilt = true; + } + + /** + * Sets whether the user is or not signed in + * + * @param isSignedIn boolean 'true' if already signed-in, else 'false' + */ + public void setSignedIn(boolean isSignedIn) { + this.mIsSignedIn = isSignedIn; + } + + /** + * Checks if user is already signed-in + * + * @return boolean 'true' when signed-in, else 'false' + */ + public boolean isSignedIn() { + return mIsSignedIn; + } + + /** + * Finish this class when a new instance is required for some reason + */ + public void finish() { + mIsSignedIn = false; + mIsSignInClientBuilt = false; + mContextContainer.removeAllObjects(); + mActivityContainer.removeAllObjects(); + mGoogleSignInClient = null; + INSTANCE = null; + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/data/configuration/ConfigFields.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/ConfigFields.java similarity index 77% rename from APP/app/src/main/java/javinator9889/securepass/data/configuration/ConfigFields.java rename to SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/ConfigFields.java index b5baaae..a0657dd 100644 --- a/APP/app/src/main/java/javinator9889/securepass/data/configuration/ConfigFields.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/ConfigFields.java @@ -1,152 +1,191 @@ -package javinator9889.securepass.data.configuration; - -import java.io.Serializable; - -import androidx.annotation.Nullable; -import javinator9889.securepass.util.values.DatabaseTables; - -/** - * Copyright © 2018 - present | APP by Javinator9889 - * - * This program 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. - * - * This program 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 this program. If not, see https://www.gnu.org/licenses/. - * - * Created by Javinator9889 on 17/10/2018 - APP. - */ -public abstract class ConfigFields implements IConfigFields, Serializable { - private long mId; - private String mDescription; - private int mSortOrder; - private long mConfigId; - - /** - * Abstract constructor only visible for inheriting classes - * - * @param id config field id - * @param description optional description - * @param sortOrder fields sort order - * @param configId configuration id - * @see ImagesConfig - * @see PassConfig - * @see LongTextConfig - * @see SmallTextConfig - */ - ConfigFields(long id, @Nullable String description, int sortOrder, - long configId) { - mId = id; - mDescription = description; - mSortOrder = sortOrder; - mConfigId = configId; - } - - /** - * Obtains current configuration ID (the same as in the database) - * - * @return long corresponding the ID - */ - @Override - public long getConfigId() { - return mConfigId; - } - - /** - * Obtains current description (the same as in the database) - * - * @return String corresponding the description (may be null) - */ - @Override - @Nullable - public String getDescription() { - return mDescription; - } - - /** - * Obtains current sort order (the same as in the database) - * - * @return int corresponding the sort order - */ - @Override - public int getSortOrder() { - return mSortOrder; - } - - /** - * Sets current configuration ID (the same as in the database) - * - * @param id long which must exists at configurations IDs - */ - @Override - public void setConfigId(long id) { - this.mConfigId = id; - } - - /** - * Sets current description (the same as in the database) - * - * @param description nullable String which contains the description - */ - @Override - public void setDescription(@Nullable String description) { - this.mDescription = description; - } - - /** - * Sets current sort order (the same as in the database) - * - * @param index int which correspondents the order inside the fields objects - */ - @Override - public void setSortOrder(int index) { - this.mSortOrder = index; - } - - /** - * Gets current field ID (the same as in the database) - cannot be changed - * - * @return long corresponding the ID - */ - @Override - public long getFieldId() { - return mId; - } - - /** - * Changes field ID if there is any reason for - * - * @param id long corresponding the new ID - */ - @Override - public void setFieldId(long id) { - this.mId = id; - } - - /** - * Gets the proper table name - names available at - * {@link javinator9889.securepass.util.values.Constants.SQL SQL names} attributes - * - * @return String which is the table name - * @see javinator9889.securepass.util.values.Constants.SQL - */ - @Override - public abstract String getTableName(); - - /** - * Gets the proper database type - types available at - * {@link DatabaseTables DatabaseTables enum} types - * - * @return DatabaseTables object with the correspondent type - * @see DatabaseTables - */ - @Override - public abstract DatabaseTables getTableType(); -} +package javinator9889.securepass.data.configuration; + +import java.io.Serializable; +import java.util.Objects; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import javinator9889.securepass.util.values.DatabaseTables; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 17/10/2018 - APP. + */ +public abstract class ConfigFields implements IConfigFields, Serializable { + private long mId; + private String mDescription; + private int mSortOrder; + private long mConfigId; + + /** + * Abstract constructor only visible for inheriting classes + * + * @param id config field id + * @param description optional description + * @param sortOrder fields sort order + * @param configId configuration id + * @see ImagesConfig + * @see PassConfig + * @see LongTextConfig + * @see SmallTextConfig + */ + ConfigFields(long id, @Nullable String description, int sortOrder, + long configId) { + mId = id; + mDescription = description; + mSortOrder = sortOrder; + mConfigId = configId; + } + + /** + * Obtains current configuration ID (the same as in the database) + * + * @return long corresponding the ID + */ + @Override + public long getConfigId() { + return mConfigId; + } + + /** + * Obtains current description (the same as in the database) + * + * @return String corresponding the description (may be null) + */ + @Override + @Nullable + public String getDescription() { + return mDescription; + } + + /** + * Obtains current sort order (the same as in the database) + * + * @return int corresponding the sort order + */ + @Override + public int getSortOrder() { + return mSortOrder; + } + + /** + * Sets current configuration ID (the same as in the database) + * + * @param id long which must exists at configurations IDs + */ + @Override + public void setConfigId(long id) { + this.mConfigId = id; + } + + /** + * Sets current description (the same as in the database) + * + * @param description nullable String which contains the description + */ + @Override + public void setDescription(@Nullable String description) { + this.mDescription = description; + } + + /** + * Sets current sort order (the same as in the database) + * + * @param index int which correspondents the order inside the fields objects + */ + @Override + public void setSortOrder(int index) { + this.mSortOrder = index; + } + + /** + * Gets current field ID (the same as in the database) - cannot be changed + * + * @return long corresponding the ID + */ + @Override + public long getFieldId() { + return mId; + } + + /** + * Changes field ID if there is any reason for + * + * @param id long corresponding the new ID + */ + @Override + public void setFieldId(long id) { + this.mId = id; + } + + + /** + * Gets the proper table name - names available at + * {@link javinator9889.securepass.util.values.Constants.SQL SQL names} attributes + * + * @return String which is the table name + * @see javinator9889.securepass.util.values.Constants.SQL + */ + @Override + public abstract String getTableName(); + + /** + * Gets the proper database type - types available at + * {@link DatabaseTables DatabaseTables enum} types + * + * @return DatabaseTables object with the correspondent type + * @see DatabaseTables + */ + @Override + public abstract DatabaseTables getTableType(); + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ConfigFields that = (ConfigFields) o; + return mId == that.mId && + mSortOrder == that.mSortOrder && + mConfigId == that.mConfigId && + Objects.equals(mDescription, that.mDescription); + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + + return Objects.hash(mId, mDescription, mSortOrder, mConfigId); + } + + /** + * {@inheritDoc} + */ + @NonNull + @Override + public String toString() { + return getTableName() + ":\n" + + "{ ID: " + getFieldId() + ",\n" + + " Description: " + getDescription() + ",\n" + + " Sort order: " + getSortOrder() + ",\n" + + " Configuration ID: " + getConfigId() + "}\n"; + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/data/configuration/Configuration.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/Configuration.java similarity index 80% rename from APP/app/src/main/java/javinator9889/securepass/data/configuration/Configuration.java rename to SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/Configuration.java index 60559bc..60dfb2e 100644 --- a/APP/app/src/main/java/javinator9889/securepass/data/configuration/Configuration.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/Configuration.java @@ -1,100 +1,123 @@ -package javinator9889.securepass.data.configuration; - -import java.io.Serializable; - -import androidx.annotation.Nullable; -import javinator9889.securepass.objects.GeneralObjectContainer; -import javinator9889.securepass.objects.ObjectContainer; - -/** - * Class that contains configurations available at class level - * Created by Javinator9889 on 21/08/2018. - */ -public class Configuration implements IConfiguration, Serializable { - private long mId; - private String mConfigurationName; - private GeneralObjectContainer mContainer; - - /** - * Public available constructor - * - * @param id configuration ID (same as in database) - * @param configurationName nullable String which has a configuration name - * @param container nullable container for storing {@link IConfigFields} - */ - public Configuration(long id, - @Nullable String configurationName, - @Nullable GeneralObjectContainer - container) { - this.mId = id; - this.mConfigurationName = configurationName; - this.mContainer = (container == null) ? - new ObjectContainer<>() : - container; - } - - /** - * Obtains current configuration ID (same as in database) - * - * @return long corresponding the current ID - */ - @Override - public long getConfigurationId() { - return mId; - } - - /** - * Obtains current configuration name (same as in database) - can be null - * - * @return String with the name - */ - @Override - @Nullable - public String getConfigurationName() { - return mConfigurationName; - } - - /** - * Obtains current configuration fields (same as in database) - * - * @return {@link GeneralObjectContainer} of {@link IConfigFields} - * @see ObjectContainer - */ - @Override - public GeneralObjectContainer getConfigFields() { - return mContainer; - } - - /** - * Changes configuration ID if needed (it should not be changed) - * - * @param id long with the new configuration ID - */ - @Override - public void setConfigurationId(long id) { - this.mId = id; - } - - /** - * Changes current configuration name (can be null) - * - * @param name the new name (or null for no one) - */ - @Override - public void setConfigurationName(@Nullable String name) { - this.mConfigurationName = name; - } - - /** - * Adds a new {@link IConfigFields configuration} by using the - * {@link IConfigFields#getSortOrder() field sort order} - * - * @param field new configuration to store - * @see ConfigFields - */ - @Override - public void addConfigurationField(IConfigFields field) { - int position = field.getSortOrder(); - mContainer.storeObject(field, position); - } -} +package javinator9889.securepass.data.configuration; + +import java.io.Serializable; +import java.util.Objects; + +import androidx.annotation.Nullable; +import javinator9889.securepass.objects.GeneralObjectContainer; +import javinator9889.securepass.objects.ObjectContainer; + +/** + * Class that contains configurations available at class level + * Created by Javinator9889 on 21/08/2018. + */ +public class Configuration implements IConfiguration, Serializable { + private long mId; + private String mConfigurationName; + private GeneralObjectContainer mContainer; + + /** + * Public available constructor + * + * @param id configuration ID (same as in database) + * @param configurationName nullable String which has a configuration name + * @param container nullable container for storing {@link IConfigFields} + */ + public Configuration(long id, + @Nullable String configurationName, + @Nullable GeneralObjectContainer + container) { + this.mId = id; + this.mConfigurationName = configurationName; + this.mContainer = (container == null) ? + new ObjectContainer<>() : + container; + } + + /** + * Obtains current configuration ID (same as in database) + * + * @return long corresponding the current ID + */ + @Override + public long getConfigurationId() { + return mId; + } + + /** + * Obtains current configuration name (same as in database) - can be null + * + * @return String with the name + */ + @Override + @Nullable + public String getConfigurationName() { + return mConfigurationName; + } + + /** + * Obtains current configuration fields (same as in database) + * + * @return {@link GeneralObjectContainer} of {@link IConfigFields} + * @see ObjectContainer + */ + @Override + public GeneralObjectContainer getConfigFields() { + return mContainer; + } + + /** + * Changes configuration ID if needed (it should not be changed) + * + * @param id long with the new configuration ID + */ + @Override + public void setConfigurationId(long id) { + this.mId = id; + } + + /** + * Changes current configuration name (can be null) + * + * @param name the new name (or null for no one) + */ + @Override + public void setConfigurationName(@Nullable String name) { + this.mConfigurationName = name; + } + + /** + * Adds a new {@link IConfigFields configuration} by using the + * {@link IConfigFields#getSortOrder() field sort order} + * + * @param field new configuration to store + * @see ConfigFields + */ + @Override + public void addConfigurationField(IConfigFields field) { + int position = field.getSortOrder(); + mContainer.storeObject(field, position); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Configuration that = (Configuration) o; + return mId == that.mId && + Objects.equals(mConfigurationName, that.mConfigurationName) && + Objects.equals(mContainer, that.mContainer); + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + + return Objects.hash(mId, mConfigurationName, mContainer); + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/data/configuration/IConfigFields.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/IConfigFields.java similarity index 96% rename from APP/app/src/main/java/javinator9889/securepass/data/configuration/IConfigFields.java rename to SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/IConfigFields.java index 475b3fc..c95eaa7 100644 --- a/APP/app/src/main/java/javinator9889/securepass/data/configuration/IConfigFields.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/IConfigFields.java @@ -1,83 +1,83 @@ -package javinator9889.securepass.data.configuration; - -import javinator9889.securepass.util.values.DatabaseTables; - -/** - * Interface for accessing {@link ConfigFields} methods - * Created by Javinator9889 on 21/08/2018. - */ -public interface IConfigFields { - /** - * Obtains current configuration ID (the same as in the database) - * - * @return long corresponding the ID - */ - long getConfigId(); - - /** - * Obtains current description (the same as in the database) - * - * @return String corresponding the description (may be null) - */ - String getDescription(); - - /** - * Obtains current sort order (the same as in the database) - * - * @return int corresponding the sort order - */ - int getSortOrder(); - - /** - * Gets the proper table name - names available at - * {@link javinator9889.securepass.util.values.Constants.SQL SQL names} attributes - * - * @return String which is the table name - * @see javinator9889.securepass.util.values.Constants.SQL - */ - String getTableName(); - - /** - * Sets current configuration ID (the same as in the database) - * - * @param id long which must exists at configurations IDs - */ - void setConfigId(long id); - - /** - * Sets current description (the same as in the database) - * - * @param description nullable String which contains the description - */ - void setDescription(String description); - - /** - * Sets current sort order (the same as in the database) - * - * @param index int which correspondents the order inside the fields objects - */ - void setSortOrder(int index); - - /** - * Gets the proper database type - types available at - * {@link DatabaseTables DatabaseTables enum} types - * - * @return DatabaseTables object with the correspondent type - * @see DatabaseTables - */ - DatabaseTables getTableType(); - - /** - * Gets current field ID (the same as in the database) - cannot be changed - * - * @return long corresponding the ID - */ - long getFieldId(); - - /** - * Changes field ID if there is any reason for - * - * @param id long corresponding the new ID - */ - void setFieldId(long id); -} +package javinator9889.securepass.data.configuration; + +import javinator9889.securepass.util.values.DatabaseTables; + +/** + * Interface for accessing {@link ConfigFields} methods + * Created by Javinator9889 on 21/08/2018. + */ +public interface IConfigFields { + /** + * Obtains current configuration ID (the same as in the database) + * + * @return long corresponding the ID + */ + long getConfigId(); + + /** + * Obtains current description (the same as in the database) + * + * @return String corresponding the description (may be null) + */ + String getDescription(); + + /** + * Obtains current sort order (the same as in the database) + * + * @return int corresponding the sort order + */ + int getSortOrder(); + + /** + * Gets the proper table name - names available at + * {@link javinator9889.securepass.util.values.Constants.SQL SQL names} attributes + * + * @return String which is the table name + * @see javinator9889.securepass.util.values.Constants.SQL + */ + String getTableName(); + + /** + * Sets current configuration ID (the same as in the database) + * + * @param id long which must exists at configurations IDs + */ + void setConfigId(long id); + + /** + * Sets current description (the same as in the database) + * + * @param description nullable String which contains the description + */ + void setDescription(String description); + + /** + * Sets current sort order (the same as in the database) + * + * @param index int which correspondents the order inside the fields objects + */ + void setSortOrder(int index); + + /** + * Gets the proper database type - types available at + * {@link DatabaseTables DatabaseTables enum} types + * + * @return DatabaseTables object with the correspondent type + * @see DatabaseTables + */ + DatabaseTables getTableType(); + + /** + * Gets current field ID (the same as in the database) - cannot be changed + * + * @return long corresponding the ID + */ + long getFieldId(); + + /** + * Changes field ID if there is any reason for + * + * @param id long corresponding the new ID + */ + void setFieldId(long id); +} diff --git a/APP/app/src/main/java/javinator9889/securepass/data/configuration/IConfiguration.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/IConfiguration.java similarity index 96% rename from APP/app/src/main/java/javinator9889/securepass/data/configuration/IConfiguration.java rename to SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/IConfiguration.java index 7b1dccb..ee621cf 100644 --- a/APP/app/src/main/java/javinator9889/securepass/data/configuration/IConfiguration.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/IConfiguration.java @@ -1,56 +1,56 @@ -package javinator9889.securepass.data.configuration; - -import androidx.annotation.Nullable; -import javinator9889.securepass.objects.GeneralObjectContainer; -import javinator9889.securepass.objects.ObjectContainer; - -/** - * Created by Javinator9889 on 21/08/2018. - */ -public interface IConfiguration { - /** - * Obtains current configuration ID (same as in database) - * - * @return long corresponding the current ID - */ - long getConfigurationId(); - - /** - * Obtains current configuration name (same as in database) - can be null - * - * @return String with the name - */ - @Nullable - String getConfigurationName(); - - /** - * Obtains current configuration fields (same as in database) - * - * @return {@link GeneralObjectContainer} of {@link IConfigFields} - * @see ObjectContainer - */ - GeneralObjectContainer getConfigFields(); - - /** - * Changes configuration ID if needed (it should not be changed) - * - * @param id long with the new configuration ID - */ - void setConfigurationId(long id); - - /** - * Changes current configuration name (can be null) - * - * @param name the new name (or null for no one) - */ - void setConfigurationName(String name); - - /** - * Adds a new {@link IConfigFields configuration} by using the - * {@link IConfigFields#getSortOrder() field sort order} - * - * @param field new configuration to store - * @see ConfigFields - */ - void addConfigurationField(IConfigFields field); -} +package javinator9889.securepass.data.configuration; + +import androidx.annotation.Nullable; +import javinator9889.securepass.objects.GeneralObjectContainer; +import javinator9889.securepass.objects.ObjectContainer; + +/** + * Created by Javinator9889 on 21/08/2018. + */ +public interface IConfiguration { + /** + * Obtains current configuration ID (same as in database) + * + * @return long corresponding the current ID + */ + long getConfigurationId(); + + /** + * Obtains current configuration name (same as in database) - can be null + * + * @return String with the name + */ + @Nullable + String getConfigurationName(); + + /** + * Obtains current configuration fields (same as in database) + * + * @return {@link GeneralObjectContainer} of {@link IConfigFields} + * @see ObjectContainer + */ + GeneralObjectContainer getConfigFields(); + + /** + * Changes configuration ID if needed (it should not be changed) + * + * @param id long with the new configuration ID + */ + void setConfigurationId(long id); + + /** + * Changes current configuration name (can be null) + * + * @param name the new name (or null for no one) + */ + void setConfigurationName(String name); + + /** + * Adds a new {@link IConfigFields configuration} by using the + * {@link IConfigFields#getSortOrder() field sort order} + * + * @param field new configuration to store + * @see ConfigFields + */ + void addConfigurationField(IConfigFields field); +} diff --git a/APP/app/src/main/java/javinator9889/securepass/data/configuration/ImagesConfig.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/ImagesConfig.java similarity index 97% rename from APP/app/src/main/java/javinator9889/securepass/data/configuration/ImagesConfig.java rename to SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/ImagesConfig.java index 57c91ff..6bb3228 100644 --- a/APP/app/src/main/java/javinator9889/securepass/data/configuration/ImagesConfig.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/ImagesConfig.java @@ -1,58 +1,58 @@ -package javinator9889.securepass.data.configuration; - -import androidx.annotation.Nullable; -import javinator9889.securepass.util.values.Constants.SQL.IMAGES_CONFIG; -import javinator9889.securepass.util.values.DatabaseTables; - -/** - * Contains available images configurations - uses {@link ConfigFields} methods - * @see ConfigFields - * @see IConfigFields - * Created by Javinator9889 on 21/08/2018. - */ -public class ImagesConfig extends ConfigFields { - private static final String TABLE_NAME = IMAGES_CONFIG.NAME; - private static final DatabaseTables TABLE_TYPE = - DatabaseTables.IMAGES_CONFIG; - - /** - * Constructor that uses - * {@link ConfigFields#ConfigFields(long, String, int, long) ConfigFileds constructor} (only - * visible for this classes) - generates ImagesConfig instance - * - * @param id config field id - * @param description optional description - * @param sortOrder fields sort order - * @param configId configuration id - * @see ConfigFields - * @see IConfigFields - */ - public ImagesConfig(long id, @Nullable String description, int sortOrder, - long configId) { - super(id, description, sortOrder, configId); - } - - /** - * Gets the proper table name - names available at - * {@link javinator9889.securepass.util.values.Constants.SQL SQL names} attributes - * - * @return String which is the table name - * @see javinator9889.securepass.util.values.Constants.SQL - */ - @Override - public String getTableName() { - return TABLE_NAME; - } - - /** - * Gets the proper database type - types available at - * {@link DatabaseTables DatabaseTables enum} types - * - * @return DatabaseTables object with the correspondent type - * @see DatabaseTables - */ - @Override - public DatabaseTables getTableType() { - return TABLE_TYPE; - } -} +package javinator9889.securepass.data.configuration; + +import androidx.annotation.Nullable; +import javinator9889.securepass.util.values.Constants.SQL.IMAGES_CONFIG; +import javinator9889.securepass.util.values.DatabaseTables; + +/** + * Contains available images configurations - uses {@link ConfigFields} methods + * @see ConfigFields + * @see IConfigFields + * Created by Javinator9889 on 21/08/2018. + */ +public class ImagesConfig extends ConfigFields { + private static final String TABLE_NAME = IMAGES_CONFIG.NAME; + private static final DatabaseTables TABLE_TYPE = + DatabaseTables.IMAGES_CONFIG; + + /** + * Constructor that uses + * {@link ConfigFields#ConfigFields(long, String, int, long) ConfigFileds constructor} (only + * visible for this classes) - generates ImagesConfig instance + * + * @param id config field id + * @param description optional description + * @param sortOrder fields sort order + * @param configId configuration id + * @see ConfigFields + * @see IConfigFields + */ + public ImagesConfig(long id, @Nullable String description, int sortOrder, + long configId) { + super(id, description, sortOrder, configId); + } + + /** + * Gets the proper table name - names available at + * {@link javinator9889.securepass.util.values.Constants.SQL SQL names} attributes + * + * @return String which is the table name + * @see javinator9889.securepass.util.values.Constants.SQL + */ + @Override + public String getTableName() { + return TABLE_NAME; + } + + /** + * Gets the proper database type - types available at + * {@link DatabaseTables DatabaseTables enum} types + * + * @return DatabaseTables object with the correspondent type + * @see DatabaseTables + */ + @Override + public DatabaseTables getTableType() { + return TABLE_TYPE; + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/data/configuration/LongTextConfig.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/LongTextConfig.java similarity index 96% rename from APP/app/src/main/java/javinator9889/securepass/data/configuration/LongTextConfig.java rename to SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/LongTextConfig.java index 3b663b3..7edb3d1 100644 --- a/APP/app/src/main/java/javinator9889/securepass/data/configuration/LongTextConfig.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/LongTextConfig.java @@ -1,56 +1,56 @@ -package javinator9889.securepass.data.configuration; - -import androidx.annotation.Nullable; - -import javinator9889.securepass.util.values.Constants.SQL.LONG_TEXT_CONFIG; -import javinator9889.securepass.util.values.DatabaseTables; - -/** - * Created by Javinator9889 on 21/08/2018. - */ -public class LongTextConfig extends ConfigFields { - private static final String TABLE_NAME = LONG_TEXT_CONFIG.NAME; - private static final DatabaseTables TABLE_TYPE = - DatabaseTables.LONG_TEXT_CONFIG; - - /** - * Constructor that uses - * {@link ConfigFields#ConfigFields(long, String, int, long) ConfigFileds constructor} (only - * visible for this classes) - generates LongTextConfig instance - * - * @param id config field id - * @param description optional description - * @param sortOrder fields sort order - * @param configId configuration id - * @see ConfigFields - * @see IConfigFields - */ - public LongTextConfig(long id, @Nullable String description, int sortOrder, - long configId) { - super(id, description, sortOrder, configId); - } - - /** - * Gets the proper table name - names available at - * {@link javinator9889.securepass.util.values.Constants.SQL SQL names} attributes - * - * @return String which is the table name - * @see javinator9889.securepass.util.values.Constants.SQL - */ - @Override - public String getTableName() { - return TABLE_NAME; - } - - /** - * Gets the proper database type - types available at - * {@link DatabaseTables DatabaseTables enum} types - * - * @return DatabaseTables object with the correspondent type - * @see DatabaseTables - */ - @Override - public DatabaseTables getTableType() { - return TABLE_TYPE; - } -} +package javinator9889.securepass.data.configuration; + +import androidx.annotation.Nullable; + +import javinator9889.securepass.util.values.Constants.SQL.LONG_TEXT_CONFIG; +import javinator9889.securepass.util.values.DatabaseTables; + +/** + * Created by Javinator9889 on 21/08/2018. + */ +public class LongTextConfig extends ConfigFields { + private static final String TABLE_NAME = LONG_TEXT_CONFIG.NAME; + private static final DatabaseTables TABLE_TYPE = + DatabaseTables.LONG_TEXT_CONFIG; + + /** + * Constructor that uses + * {@link ConfigFields#ConfigFields(long, String, int, long) ConfigFileds constructor} (only + * visible for this classes) - generates LongTextConfig instance + * + * @param id config field id + * @param description optional description + * @param sortOrder fields sort order + * @param configId configuration id + * @see ConfigFields + * @see IConfigFields + */ + public LongTextConfig(long id, @Nullable String description, int sortOrder, + long configId) { + super(id, description, sortOrder, configId); + } + + /** + * Gets the proper table name - names available at + * {@link javinator9889.securepass.util.values.Constants.SQL SQL names} attributes + * + * @return String which is the table name + * @see javinator9889.securepass.util.values.Constants.SQL + */ + @Override + public String getTableName() { + return TABLE_NAME; + } + + /** + * Gets the proper database type - types available at + * {@link DatabaseTables DatabaseTables enum} types + * + * @return DatabaseTables object with the correspondent type + * @see DatabaseTables + */ + @Override + public DatabaseTables getTableType() { + return TABLE_TYPE; + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/data/configuration/PassConfig.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/PassConfig.java similarity index 96% rename from APP/app/src/main/java/javinator9889/securepass/data/configuration/PassConfig.java rename to SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/PassConfig.java index 7bf39da..4083235 100644 --- a/APP/app/src/main/java/javinator9889/securepass/data/configuration/PassConfig.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/PassConfig.java @@ -1,56 +1,56 @@ -package javinator9889.securepass.data.configuration; - -import androidx.annotation.Nullable; - -import javinator9889.securepass.util.values.Constants.SQL.PASS_CONFIG; -import javinator9889.securepass.util.values.DatabaseTables; - -/** - * Created by Javinator9889 on 21/08/2018. - */ -public class PassConfig extends ConfigFields { - private static final String TABLE_NAME = PASS_CONFIG.NAME; - private static final DatabaseTables TABLE_TYPE = - DatabaseTables.PASS_CONFIG; - - /** - * Constructor that uses - * {@link ConfigFields#ConfigFields(long, String, int, long) ConfigFileds constructor} (only - * visible for this classes) - generates PassConfig instance - * - * @param id config field id - * @param description optional description - * @param sortOrder fields sort order - * @param configId configuration id - * @see ConfigFields - * @see IConfigFields - */ - public PassConfig(long id, @Nullable String description, int sortOrder, - long configId) { - super(id, description, sortOrder, configId); - } - - /** - * Gets the proper table name - names available at - * {@link javinator9889.securepass.util.values.Constants.SQL SQL names} attributes - * - * @return String which is the table name - * @see javinator9889.securepass.util.values.Constants.SQL - */ - @Override - public String getTableName() { - return TABLE_NAME; - } - - /** - * Gets the proper database type - types available at - * {@link DatabaseTables DatabaseTables enum} types - * - * @return DatabaseTables object with the correspondent type - * @see DatabaseTables - */ - @Override - public DatabaseTables getTableType() { - return TABLE_TYPE; - } -} +package javinator9889.securepass.data.configuration; + +import androidx.annotation.Nullable; + +import javinator9889.securepass.util.values.Constants.SQL.PASS_CONFIG; +import javinator9889.securepass.util.values.DatabaseTables; + +/** + * Created by Javinator9889 on 21/08/2018. + */ +public class PassConfig extends ConfigFields { + private static final String TABLE_NAME = PASS_CONFIG.NAME; + private static final DatabaseTables TABLE_TYPE = + DatabaseTables.PASS_CONFIG; + + /** + * Constructor that uses + * {@link ConfigFields#ConfigFields(long, String, int, long) ConfigFileds constructor} (only + * visible for this classes) - generates PassConfig instance + * + * @param id config field id + * @param description optional description + * @param sortOrder fields sort order + * @param configId configuration id + * @see ConfigFields + * @see IConfigFields + */ + public PassConfig(long id, @Nullable String description, int sortOrder, + long configId) { + super(id, description, sortOrder, configId); + } + + /** + * Gets the proper table name - names available at + * {@link javinator9889.securepass.util.values.Constants.SQL SQL names} attributes + * + * @return String which is the table name + * @see javinator9889.securepass.util.values.Constants.SQL + */ + @Override + public String getTableName() { + return TABLE_NAME; + } + + /** + * Gets the proper database type - types available at + * {@link DatabaseTables DatabaseTables enum} types + * + * @return DatabaseTables object with the correspondent type + * @see DatabaseTables + */ + @Override + public DatabaseTables getTableType() { + return TABLE_TYPE; + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/data/configuration/SmallTextConfig.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/SmallTextConfig.java similarity index 97% rename from APP/app/src/main/java/javinator9889/securepass/data/configuration/SmallTextConfig.java rename to SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/SmallTextConfig.java index 16c1b49..bf074a7 100644 --- a/APP/app/src/main/java/javinator9889/securepass/data/configuration/SmallTextConfig.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/SmallTextConfig.java @@ -1,55 +1,55 @@ -package javinator9889.securepass.data.configuration; - -import androidx.annotation.Nullable; - -import javinator9889.securepass.util.values.Constants.SQL.SMALL_TEXT_CONFIG; -import javinator9889.securepass.util.values.DatabaseTables; - -/** - * Created by Javinator9889 on 21/08/2018. - */ -public class SmallTextConfig extends ConfigFields { - private static final String TABLE_NAME = SMALL_TEXT_CONFIG.NAME; - private static final DatabaseTables TABLE_TYPE = DatabaseTables.SMALL_TEXT; - - /** - * Constructor that uses - * {@link ConfigFields#ConfigFields(long, String, int, long) ConfigFileds constructor} (only - * visible for this classes) - generates SmallTextConfig instance - * - * @param id config field id - * @param description optional description - * @param sortOrder fields sort order - * @param configId configuration id - * @see ConfigFields - * @see IConfigFields - */ - public SmallTextConfig(long id, @Nullable String description, int sortOrder, - long configId) { - super(id, description, sortOrder, configId); - } - - /** - * Gets the proper table name - names available at - * {@link javinator9889.securepass.util.values.Constants.SQL SQL names} attributes - * - * @return String which is the table name - * @see javinator9889.securepass.util.values.Constants.SQL - */ - @Override - public String getTableName() { - return TABLE_NAME; - } - - /** - * Gets the proper database type - types available at - * {@link DatabaseTables DatabaseTables enum} types - * - * @return DatabaseTables object with the correspondent type - * @see DatabaseTables - */ - @Override - public DatabaseTables getTableType() { - return TABLE_TYPE; - } -} +package javinator9889.securepass.data.configuration; + +import androidx.annotation.Nullable; + +import javinator9889.securepass.util.values.Constants.SQL.SMALL_TEXT_CONFIG; +import javinator9889.securepass.util.values.DatabaseTables; + +/** + * Created by Javinator9889 on 21/08/2018. + */ +public class SmallTextConfig extends ConfigFields { + private static final String TABLE_NAME = SMALL_TEXT_CONFIG.NAME; + private static final DatabaseTables TABLE_TYPE = DatabaseTables.SMALL_TEXT; + + /** + * Constructor that uses + * {@link ConfigFields#ConfigFields(long, String, int, long) ConfigFileds constructor} (only + * visible for this classes) - generates SmallTextConfig instance + * + * @param id config field id + * @param description optional description + * @param sortOrder fields sort order + * @param configId configuration id + * @see ConfigFields + * @see IConfigFields + */ + public SmallTextConfig(long id, @Nullable String description, int sortOrder, + long configId) { + super(id, description, sortOrder, configId); + } + + /** + * Gets the proper table name - names available at + * {@link javinator9889.securepass.util.values.Constants.SQL SQL names} attributes + * + * @return String which is the table name + * @see javinator9889.securepass.util.values.Constants.SQL + */ + @Override + public String getTableName() { + return TABLE_NAME; + } + + /** + * Gets the proper database type - types available at + * {@link DatabaseTables DatabaseTables enum} types + * + * @return DatabaseTables object with the correspondent type + * @see DatabaseTables + */ + @Override + public DatabaseTables getTableType() { + return TABLE_TYPE; + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/data/container/ClassContainer.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/container/ClassContainer.java similarity index 93% rename from APP/app/src/main/java/javinator9889/securepass/data/container/ClassContainer.java rename to SecurePass/app/src/main/java/javinator9889/securepass/data/container/ClassContainer.java index 808282e..5fd4d12 100644 --- a/APP/app/src/main/java/javinator9889/securepass/data/container/ClassContainer.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/container/ClassContainer.java @@ -1,135 +1,135 @@ -package javinator9889.securepass.data.container; - -import java.io.Serializable; -import java.util.List; -import java.util.Map; - -import androidx.annotation.NonNull; -import javinator9889.securepass.data.entry.Category; -import javinator9889.securepass.data.entry.Entry; -import javinator9889.securepass.data.entry.QRCode; -import javinator9889.securepass.data.secret.Field; -import javinator9889.securepass.data.secret.SecurityCode; - -/** - * Created by Javinator9889 on 06/04/2018. - * CLASS FOR TESTINGS - */ -public class ClassContainer implements Serializable { - private List categories; - private List entries; - private List qrCodes; - private List fields; - private List securityCodes; - private Map userSharedPreferences; - - public ClassContainer(@NonNull List categories, - @NonNull List entries, - @NonNull List qrCodes, - @NonNull List fields, - @NonNull List securityCodes, - @NonNull Map userSharedPreferences) { - this.categories = categories; - this.entries = entries; - this.qrCodes = qrCodes; - this.fields = fields; - this.securityCodes = securityCodes; - this.userSharedPreferences = userSharedPreferences; - } - - public ClassContainer(){} - - public void setCategories(List categories) { - this.categories = categories; - } - - public void setEntries(List entries) { - this.entries = entries; - } - - public void setQrCodes(List qrCodes) { - this.qrCodes = qrCodes; - } - - public void setFields(List fields) { - this.fields = fields; - } - - public void setSecurityCodes(List securityCodes) { - this.securityCodes = securityCodes; - } - - public void setUserSharedPreferences(Map userSharedPreferences) { - this.userSharedPreferences = userSharedPreferences; - } - -// public void storeDataInDB() { -// Context appContext = SecurePass.getApplicationInstance().getApplicationContext(); -// String password = IOManager.newInstance(appContext).readPassword(); -// DatabaseManager manager = DatabaseManager.newInstance(appContext, password); -// CommonOperations operations = CommonOperations.newInstance(manager); -// for (Category actualCategory : categories) -// operations.registerNewCategory(actualCategory.getName()); -// for (Entry entry : entries) -// operations.registerNewAccount( -// entry.getAccountName(), -// entry.getAccountPassword(), -// entry.getIcon(), -// entry.getDescription(), -// entry.getCategory().getId()); -// for (QRCode qrCode : qrCodes) -// operations.registerQRCode( -// qrCode.getEntry().getId(), -// qrCode.getName(), -// qrCode.getDescription(), -// qrCode.getQrData()); -// for (SecurityCode code : securityCodes) -// operations.registerNewSecurityCodeSource(code.getAccountName()); -// for (Field field : fields) -// operations.registerNewFieldForSecurityCodeSource(field.getCode(), field.isCodeUsed(), -// field.getSecurityCodeID()); -// operations.finishConnection(); -// } - - public List getCategories() { - return categories; - } - - public List getEntries() { - return entries; - } - - public List getQrCodes() { - return qrCodes; - } - - public List getFields() { - return fields; - } - - public List getSecurityCodes() { - return securityCodes; - } - - public Map getUserSharedPreferences() { - return userSharedPreferences; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - for (Category category : categories) - builder.append(category.toString()); - for (Entry entry : entries) - builder.append(entry.toString()); - for (QRCode qrCode : qrCodes) - builder.append(qrCode.toString()); - for (Field field : fields) - builder.append(field.toString()); - for (SecurityCode securityCode : securityCodes) - builder.append(securityCode.toString()); - builder.append(userSharedPreferences.toString()); - return builder.toString(); - //return super.toString(); - } -} +package javinator9889.securepass.data.container; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +import androidx.annotation.NonNull; +import javinator9889.securepass.data.entry.Category; +import javinator9889.securepass.data.entry.Entry; +import javinator9889.securepass.data.entry.QRCode; +import javinator9889.securepass.data.secret.Field; +import javinator9889.securepass.data.secret.SecurityCode; + +/** + * Created by Javinator9889 on 06/04/2018. + * CLASS FOR TESTINGS + */ +public class ClassContainer implements Serializable { + private List categories; + private List entries; + private List qrCodes; + private List fields; + private List securityCodes; + private Map userSharedPreferences; + + public ClassContainer(@NonNull List categories, + @NonNull List entries, + @NonNull List qrCodes, + @NonNull List fields, + @NonNull List securityCodes, + @NonNull Map userSharedPreferences) { + this.categories = categories; + this.entries = entries; + this.qrCodes = qrCodes; + this.fields = fields; + this.securityCodes = securityCodes; + this.userSharedPreferences = userSharedPreferences; + } + + public ClassContainer(){} + + public void setCategories(List categories) { + this.categories = categories; + } + + public void setEntries(List entries) { + this.entries = entries; + } + + public void setQrCodes(List qrCodes) { + this.qrCodes = qrCodes; + } + + public void setFields(List fields) { + this.fields = fields; + } + + public void setSecurityCodes(List securityCodes) { + this.securityCodes = securityCodes; + } + + public void setUserSharedPreferences(Map userSharedPreferences) { + this.userSharedPreferences = userSharedPreferences; + } + +// public void storeDataInDB() { +// Context appContext = SecurePass.getApplicationInstance().getApplicationContext(); +// String password = IOManager.newInstance(appContext).readPassword(); +// DatabaseManager manager = DatabaseManager.getInstance(appContext, password); +// CommonOperations operations = CommonOperations.newInstance(manager); +// for (Category actualCategory : categories) +// operations.registerNewCategory(actualCategory.getName()); +// for (Entry entry : entries) +// operations.registerNewAccount( +// entry.getAccountName(), +// entry.getAccountPassword(), +// entry.getIcon(), +// entry.getDescription(), +// entry.getCategoryId().getId()); +// for (QRCode qrCode : qrCodes) +// operations.registerQRCode( +// qrCode.getEntryId().getId(), +// qrCode.getName(), +// qrCode.getDescription(), +// qrCode.getQrData()); +// for (SecurityCode code : securityCodes) +// operations.registerNewSecurityCodeSource(code.getAccountName()); +// for (Field field : fields) +// operations.registerNewFieldForSecurityCodeSource(field.getCode(), field.isCodeUsed(), +// field.getSecurityCodeID()); +// operations.finishConnection(); +// } + + public List getCategories() { + return categories; + } + + public List getEntries() { + return entries; + } + + public List getQrCodes() { + return qrCodes; + } + + public List getFields() { + return fields; + } + + public List getSecurityCodes() { + return securityCodes; + } + + public Map getUserSharedPreferences() { + return userSharedPreferences; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + for (Category category : categories) + builder.append(category.toString()); + for (Entry entry : entries) + builder.append(entry.toString()); + for (QRCode qrCode : qrCodes) + builder.append(qrCode.toString()); + for (Field field : fields) + builder.append(field.toString()); + for (SecurityCode securityCode : securityCodes) + builder.append(securityCode.toString()); + builder.append(userSharedPreferences.toString()); + return builder.toString(); + //return super.toString(); + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/data/entry/Category.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/Category.java similarity index 61% rename from APP/app/src/main/java/javinator9889/securepass/data/entry/Category.java rename to SecurePass/app/src/main/java/javinator9889/securepass/data/entry/Category.java index dd207be..41dde83 100644 --- a/APP/app/src/main/java/javinator9889/securepass/data/entry/Category.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/Category.java @@ -1,65 +1,91 @@ -package javinator9889.securepass.data.entry; - -import java.io.Serializable; - -/** - * Class for containing categories - * Created by Javinator9889 on 29/03/2018. - */ -public class Category implements Serializable { - private int mId; - private String mName; - - /** - * Public available constructor for generating Category - * - * @param id category ID - * @param name category name - */ - public Category(int id, String name) { - this.mId = id; - this.mName = name; - } - - /** - * @deprecated Default constructor - deprecated. Use {@link #Category(int, String)} instead - */ - @Deprecated - public Category() { - this.mId = 0; - this.mName = "Global"; - } - - /** - * Obtains current category ID - * - * @return long with the ID - */ - public int getId() { - return mId; - } - - /** - * Obtains current category name - * - * @return String with the name - */ - public String getName() { - return mName; - } - - /** - * Updates current category name - * - * @param name new name - */ - public void setName(String name) { - this.mName = name; - } - - @Override - public String toString() { - return "Category ID: " + mId + "\n" + - "Category name: " + mName + "\n"; - } -} +package javinator9889.securepass.data.entry; + +import java.io.Serializable; +import java.util.Objects; + +/** + * Class for containing categories + * Created by Javinator9889 on 29/03/2018. + */ +public class Category implements Serializable { + private long mId; + private String mName; + + /** + * Public available constructor for generating Category + * + * @param id category ID + * @param name category name + */ + public Category(long id, String name) { + this.mId = id; + this.mName = name; + } + + /** + * @deprecated Default constructor - deprecated. Use {@link #Category(long, String)} instead + */ + @Deprecated + public Category() { + this.mId = 0; + this.mName = "Global"; + } + + /** + * Obtains current category ID + * + * @return long with the ID + */ + public long getId() { + return mId; + } + + /** + * Obtains current category name + * + * @return String with the name + */ + public String getName() { + return mName; + } + + /** + * Updates current category name + * + * @param name new name + */ + public void setName(String name) { + this.mName = name; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return "Category ID: " + mId + "\n" + + "Category name: " + mName + "\n"; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Category category = (Category) o; + return mId == category.mId && + Objects.equals(mName, category.mName); + } + + /** + * {@inheritDoc} + * + * @see Objects#hash(Object...) + */ + @Override + public int hashCode() { + return Objects.hash(mId, mName); + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/Entry.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/Entry.java new file mode 100644 index 0000000..cb5e51b --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/Entry.java @@ -0,0 +1,132 @@ +package javinator9889.securepass.data.entry; + +import java.io.Serializable; +import java.util.Objects; + +import androidx.annotation.NonNull; + +/** + * Created by Javinator9889 on 29/03/2018. + */ +public class Entry implements Serializable { + private long mId; + private long mCategoryId; + private long mConfigId; + private String mName; + private String mIcon; + + /** + * Public constructor declaring only the needed entry params + * + * @param id entry ID + * @param name entry name + * @param icon entry icon + * @param categoryId entry parent category ID + * @param configurationId entry parent configuration ID + */ + public Entry(long id, + @NonNull String name, + @NonNull String icon, + long categoryId, + long configurationId) { + mId = id; + mName = name; + mIcon = icon; + mCategoryId = categoryId; + mConfigId = configurationId; + } + + /** + * Obtains current entry ID + * + * @return long with the ID + */ + public long getId() { + return mId; + } + + /** + * Obtains current entry name + * + * @return String with the name + */ + public String getName() { + return mName; + } + + /** + * Updates entry name + * + * @param name new name + */ + public void setName(String name) { + this.mName = name; + } + + /** + * Obtains current entry icon + * + * @return String with the icon + */ + public String getIcon() { + return mIcon; + } + + /** + * Sets a new icon for the entry + * + * @param icon new icon + */ + public void setIcon(String icon) { + this.mIcon = icon; + } + + /** + * Gets current entry category + * + * @return {@code long} with the category ID + */ + public long getCategoryId() { + return mCategoryId; + } + + /** + * Updates current entry categoryId + * + * @param categoryId new categoryId + */ + public void setCategoryId(long categoryId) { + this.mCategoryId = categoryId; + } + + @Override + public String toString() { + return "Entry ID: " + mId + + "\nEntry icon: " + mIcon + + "\nEntry name: " + mName + + "\nEntry categoryId: " + mCategoryId; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Entry entry = (Entry) o; + return mId == entry.mId && + mCategoryId == entry.mCategoryId && + mConfigId == entry.mConfigId && + Objects.equals(mName, entry.mName) && + Objects.equals(mIcon, entry.mIcon); + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + return Objects.hash(mId, mCategoryId, mConfigId, mName, mIcon); + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/data/entry/QRCode.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/QRCode.java similarity index 60% rename from APP/app/src/main/java/javinator9889/securepass/data/entry/QRCode.java rename to SecurePass/app/src/main/java/javinator9889/securepass/data/entry/QRCode.java index 97cc026..34479fd 100644 --- a/APP/app/src/main/java/javinator9889/securepass/data/entry/QRCode.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/QRCode.java @@ -1,138 +1,166 @@ -package javinator9889.securepass.data.entry; - -import java.io.Serializable; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -/** - * Class containing QRCodes - * Created by Javinator9889 on 29/03/2018. - */ -public class QRCode implements Serializable { - private long mId; - private String mName; - private String description; - private String mQrData; - private Entry mParentEntry; - - /** - * Public constructor available for generating a new QRCode - * - * @param id QRCode ID - * @param name QRCode name - * @param description QRCode description - * @param qrData QRCode data - * @param parentEntry QRCode parent entry - */ - public QRCode(long id, - @NonNull String name, - @Nullable String description, - @NonNull String qrData, - @NonNull Entry parentEntry) { - this.mId = id; - this.mName = name; - this.description = description; - this.mQrData = qrData; - this.mParentEntry = parentEntry; - } - - /** - * Obtains current QRCode ID - * - * @return long with the ID - */ - public long getId() { - return mId; - } - - /** - * Updates current QRCode ID - this method should not be used - * - * @param id new ID - */ - public void setId(long id) { - this.mId = id; - } - - /** - * Obtains current QRCode name - * - * @return String with the name - */ - public String getName() { - return mName; - } - - /** - * Updates current QRCode name - * - * @param name new name - */ - public void setName(String name) { - this.mName = name; - } - - /** - * Obtains current QRCode description - * - * @return String with the description - */ - public String getDescription() { - return description; - } - - /** - * Updates current QRCode description - * - * @param description new description - */ - public void setDescription(String description) { - this.description = description; - } - - /** - * Obtains QRCode data - * - * @return String with data - */ - public String getQrData() { - return mQrData; - } - - /** - * Updates QRCode data - * - * @param qrData new data - */ - public void setQrData(String qrData) { - this.mQrData = qrData; - } - - /** - * Obtains QRCode parent entry - * - * @return parent Entry - */ - public Entry getEntry() { - return mParentEntry; - } - - /** - * Updates QRCode parent entry - * - * @param entry new entry - */ - public void setEntry(@NonNull Entry entry) { - this.mParentEntry = entry; - } - - @Override - public String toString() { - return "QRCode ID: " + mId + - "\nQRCode mName: " + mName + - "\nQRCode description: " + description + - "\nQRCode data: " + mQrData + - "\nQRCode entry: " + mParentEntry.toString(); - } -} +package javinator9889.securepass.data.entry; + +import java.io.Serializable; +import java.util.Objects; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +/** + * Class containing QRCodes + * Created by Javinator9889 on 29/03/2018. + */ +public class QRCode implements Serializable { + private long mId; + private String mName; + private String description; + private String mQrData; + private long mParentEntryId; + + /** + * Public constructor available for generating a new QRCode + * + * @param id QRCode ID + * @param name QRCode name + * @param description QRCode description + * @param qrData QRCode data + * @param parentEntryId QRCode parent entry ID + */ + public QRCode(long id, + @NonNull String name, + @Nullable String description, + @NonNull String qrData, + long parentEntryId) { + this.mId = id; + this.mName = name; + this.description = description; + this.mQrData = qrData; + this.mParentEntryId = parentEntryId; + } + + /** + * Obtains current QRCode ID + * + * @return long with the ID + */ + public long getId() { + return mId; + } + + /** + * Updates current QRCode ID - this method should not be used + * + * @param id new ID + */ + public void setId(long id) { + this.mId = id; + } + + /** + * Obtains current QRCode name + * + * @return String with the name + */ + public String getName() { + return mName; + } + + /** + * Updates current QRCode name + * + * @param name new name + */ + public void setName(String name) { + this.mName = name; + } + + /** + * Obtains current QRCode description + * + * @return String with the description + */ + public String getDescription() { + return description; + } + + /** + * Updates current QRCode description + * + * @param description new description + */ + public void setDescription(String description) { + this.description = description; + } + + /** + * Obtains QRCode data + * + * @return String with data + */ + public String getQrData() { + return mQrData; + } + + /** + * Updates QRCode data + * + * @param qrData new data + */ + public void setQrData(String qrData) { + this.mQrData = qrData; + } + + /** + * Obtains QRCode parent entry + * + * @return parent entry ID + */ + public long getEntryId() { + return mParentEntryId; + } + + /** + * Updates QRCode parent entryId + * + * @param entryId new entryId + */ + public void setEntryId(@NonNull long entryId) { + this.mParentEntryId = entryId; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return "QRCode ID: " + mId + + "\nQRCode name: " + mName + + "\nQRCode description: " + description + + "\nQRCode data: " + mQrData + + "\nQRCode entry ID: " + mParentEntryId; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + QRCode qrCode = (QRCode) o; + return mId == qrCode.mId && + mParentEntryId == qrCode.mParentEntryId && + Objects.equals(mName, qrCode.mName) && + Objects.equals(description, qrCode.description) && + Objects.equals(mQrData, qrCode.mQrData); + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + + return Objects.hash(mId, mName, description, mQrData, mParentEntryId); + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/ICommonMethods.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/ICommonMethods.java similarity index 67% rename from APP/app/src/main/java/javinator9889/securepass/data/entry/fields/ICommonMethods.java rename to SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/ICommonMethods.java index 1c33026..be2beef 100644 --- a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/ICommonMethods.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/ICommonMethods.java @@ -1,24 +1,38 @@ -package javinator9889.securepass.data.entry.fields; - -import androidx.annotation.NonNull; - -/** - * Interface with common methods to {@link Image}, {@link Password}, {@link LongText} and - * {@link SmallText} - * Created by Javinator9889 on 16/08/2018. - */ -public interface ICommonMethods { - /** - * Updates the field description by te given one - * - * @param fieldDescription new description - */ - void setFieldDescription(@NonNull String fieldDescription); - - /** - * Obtains the current field description - * - * @return String with the description - */ - String getFieldDescription(); -} +package javinator9889.securepass.data.entry.fields; + +import androidx.annotation.NonNull; + +/** + * Interface with common methods to {@link Image}, {@link Password}, {@link LongText} and + * {@link SmallText} + * Created by Javinator9889 on 16/08/2018. + */ +public interface ICommonMethods { + /** + * Updates the field description by te given one + * + * @param fieldDescription new description + */ + void setFieldDescription(@NonNull String fieldDescription); + + /** + * Obtains the current field description + * + * @return String with the description + */ + String getFieldDescription(); + + /** + * Gets the parent entry ID for this image + * + * @return {@code long} with the ID + */ + long getEntryId(); + + /** + * Sets a new image parent entry ID + * + * @param id new parent entry ID + */ + void setEntryId(long id); +} diff --git a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/IImage.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/IImage.java similarity index 96% rename from APP/app/src/main/java/javinator9889/securepass/data/entry/fields/IImage.java rename to SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/IImage.java index d3072d0..5647ae1 100644 --- a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/IImage.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/IImage.java @@ -1,39 +1,39 @@ -package javinator9889.securepass.data.entry.fields; - -import androidx.annotation.NonNull; - -/** - * Interface for accessing {@link Image} methods - * Created by Javinator9889 on 16/08/2018. - */ -public interface IImage extends ICommonMethods { - /** - * Saves the image source - * - * @param imageSource non null String containing the Base64 source - * @see android.util.Base64 - */ - void setImageSource(@NonNull String imageSource); - - /** - * Obtains the image source - * - * @return String containing the Base64 image - * @see android.util.Base64 - */ - String getImageSource(); - - /** - * Obtains the current image ID - * - * @return long corresponding the ID - */ - long getImageID(); - - /** - * Sets a new image ID for any reason - should not be called - * - * @param imageID the new ID - */ - void setImageID(long imageID); -} +package javinator9889.securepass.data.entry.fields; + +import androidx.annotation.NonNull; + +/** + * Interface for accessing {@link Image} methods + * Created by Javinator9889 on 16/08/2018. + */ +public interface IImage extends ICommonMethods { + /** + * Saves the image source + * + * @param imageSource non null String containing the Base64 source + * @see android.util.Base64 + */ + void setImageSource(@NonNull String imageSource); + + /** + * Obtains the image source + * + * @return String containing the Base64 image + * @see android.util.Base64 + */ + String getImageSource(); + + /** + * Obtains the current image ID + * + * @return long corresponding the ID + */ + long getImageID(); + + /** + * Sets a new image ID for any reason - should not be called + * + * @param imageID the new ID + */ + void setImageID(long imageID); +} diff --git a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/IPassword.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/IPassword.java similarity index 95% rename from APP/app/src/main/java/javinator9889/securepass/data/entry/fields/IPassword.java rename to SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/IPassword.java index d8e1e5e..89806f4 100644 --- a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/IPassword.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/IPassword.java @@ -1,37 +1,37 @@ -package javinator9889.securepass.data.entry.fields; - -import androidx.annotation.NonNull; - -/** - * Interface for accessing the {@link Password} methods - * Created by Javinator9889 on 16/08/2018. - */ -public interface IPassword extends ICommonMethods { - /** - * Sets a new password - * - * @param password non null String with the password - */ - void setPassword(@NonNull String password); - - /** - * Obtains the current stored password - * - * @return String with the password - */ - String getPassword(); - - /** - * Gets the current password ID - * - * @return long with the ID - */ - long getPasswordID(); - - /** - * Sets a new ID - this method should not be called - * - * @param passwordID new ID - */ - void setPasswordID(long passwordID); -} +package javinator9889.securepass.data.entry.fields; + +import androidx.annotation.NonNull; + +/** + * Interface for accessing the {@link Password} methods + * Created by Javinator9889 on 16/08/2018. + */ +public interface IPassword extends ICommonMethods { + /** + * Sets a new password + * + * @param password non null String with the password + */ + void setPassword(@NonNull String password); + + /** + * Obtains the current stored password + * + * @return String with the password + */ + String getPassword(); + + /** + * Gets the current password ID + * + * @return long with the ID + */ + long getPasswordID(); + + /** + * Sets a new ID - this method should not be called + * + * @param passwordID new ID + */ + void setPasswordID(long passwordID); +} diff --git a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/IText.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/IText.java similarity index 81% rename from APP/app/src/main/java/javinator9889/securepass/data/entry/fields/IText.java rename to SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/IText.java index 8eb9f0a..1e99ada 100644 --- a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/IText.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/IText.java @@ -1,51 +1,65 @@ -package javinator9889.securepass.data.entry.fields; - -import androidx.annotation.NonNull; - -/** - * Copyright © 2018 - present | APP by Javinator9889 - * - * This program 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. - * - * This program 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 this program. If not, see https://www.gnu.org/licenses/. - * - * Created by Javinator9889 on 26/10/2018 - APP. - */ -public interface IText extends ICommonMethods { - /** - * Sets the new text - * - * @param text non null text - */ - void setText(@NonNull String text); - - /** - * Obtains the current text - * - * @return String with the text - */ - String getText(); - - /** - * Gets the current text ID - * - * @return long with the text - */ - long getTextID(); - - /** - * Sets a new text ID for any reason - this method should not be called - * - * @param id the new ID - */ - void setTextID(long id); -} +package javinator9889.securepass.data.entry.fields; + +import androidx.annotation.NonNull; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 26/10/2018 - APP. + */ +public interface IText extends ICommonMethods { + /** + * Sets the new text + * + * @param text non null text + */ + void setText(@NonNull String text); + + /** + * Obtains the current text + * + * @return String with the text + */ + String getText(); + + /** + * Gets the current text ID + * + * @return long with the text + */ + long getTextID(); + + /** + * Sets a new text ID for any reason - this method should not be called + * + * @param id the new ID + */ + void setTextID(long id); + + /** + * Gets the order of the text. + * + * @return {@code int} with the sort order. + */ + int getOrder(); + + /** + * Sets a new order of the text. + * + * @param order new text order. + */ + void setOrder(int order); +} diff --git a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/Image.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/Image.java similarity index 56% rename from APP/app/src/main/java/javinator9889/securepass/data/entry/fields/Image.java rename to SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/Image.java index 7856756..2af896b 100644 --- a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/Image.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/Image.java @@ -1,100 +1,157 @@ -package javinator9889.securepass.data.entry.fields; - - -import java.io.Serializable; - -import androidx.annotation.NonNull; - -/** - * Stores Image fields - * Created by Javinator9889 on 16/08/2018. - */ -public class Image implements IImage, Serializable { - private String mSource; - private long mId; - private String mFieldDescription; - - /** - * Public available constructor for generating a new instance - * - * @param id current image ID - * @param source Base64 image information - * @param fieldDescription description - * @see android.util.Base64 - */ - public Image(long id, @NonNull String source, @NonNull String fieldDescription) { - this.mId = id; - this.mSource = source; - this.mFieldDescription = fieldDescription; - } - - /** - * Saves the image source - * - * @param imageSource non null String containing the Base64 source - * @see android.util.Base64 - */ - @Override - public void setImageSource(@NonNull String imageSource) { - this.mSource = imageSource; - } - - /** - * Obtains the image source - * - * @return String containing the Base64 image - * @see android.util.Base64 - */ - @Override - public String getImageSource() { - return mSource; - } - - /** - * Obtains the current image ID - * - * @return long corresponding the ID - */ - @Override - public long getImageID() { - return mId; - } - - /** - * Sets a new image ID for any reason - should not be called - * - * @param imageID the new ID - */ - @Override - public void setImageID(long imageID) { - this.mId = imageID; - } - - /** - * Updates the field description by te given one - * - * @param fieldDescription new description - * @see ICommonMethods - */ - @Override - public void setFieldDescription(@NonNull String fieldDescription) { - this.mFieldDescription = fieldDescription; - } - - /** - * Obtains the current field description - * - * @return String with the description - * @see ICommonMethods - */ - @Override - public String getFieldDescription() { - return mFieldDescription; - } - - @Override - public String toString() { - return "Source: " + getImageSource() + "\nmId: " + getImageID() + "\nField description: " - + getFieldDescription(); - } -} +package javinator9889.securepass.data.entry.fields; + + +import org.jetbrains.annotations.NotNull; + +import java.io.Serializable; +import java.util.Objects; + +import androidx.annotation.NonNull; + +/** + * Stores Image fields + * Created by Javinator9889 on 16/08/2018. + */ +public class Image implements IImage, Serializable { + private long mId; + private long mParentEntryId; + private String mSource; + private String mFieldDescription; + + /** + * Public available constructor for generating a new instance + * + * @param id current image ID + * @param source Base64 image information + * @param fieldDescription description + * @see android.util.Base64 + */ + public Image(long id, + long parentEntryId, + @NonNull String source, + @NonNull String fieldDescription) { + this.mId = id; + this.mParentEntryId = parentEntryId; + this.mSource = source; + this.mFieldDescription = fieldDescription; + } + + /** + * Saves the image source + * + * @param imageSource non null String containing the Base64 source + * @see android.util.Base64 + */ + @Override + public void setImageSource(@NonNull String imageSource) { + this.mSource = imageSource; + } + + /** + * Obtains the image source + * + * @return String containing the Base64 image + * @see android.util.Base64 + */ + @Override + public String getImageSource() { + return mSource; + } + + /** + * Obtains the current image ID + * + * @return long corresponding the ID + */ + @Override + public long getImageID() { + return mId; + } + + /** + * Sets a new image ID for any reason - should not be called + * + * @param imageID the new ID + */ + @Override + public void setImageID(long imageID) { + this.mId = imageID; + } + + /** + * Gets the parent entry ID for this image + * + * @return {@code long} with the ID + */ + @Override + public long getEntryId() { + return mParentEntryId; + } + + /** + * Sets a new image parent entry ID + * + * @param id new parent entry ID + */ + @Override + public void setEntryId(long id) { + mParentEntryId = id; + } + + /** + * Updates the field description by te given one + * + * @param fieldDescription new description + * @see ICommonMethods + */ + @Override + public void setFieldDescription(@NonNull String fieldDescription) { + this.mFieldDescription = fieldDescription; + } + + /** + * Obtains the current field description + * + * @return String with the description + * @see ICommonMethods + */ + @Override + public String getFieldDescription() { + return mFieldDescription; + } + + /** + * {@inheritDoc} + */ + @NotNull + @Override + public String toString() { + return "Source: " + getImageSource() + + "\nId: " + getImageID() + + "\nEntry ID: " + getEntryId() + + "\nField description: " + getFieldDescription(); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Image image = (Image) o; + return mId == image.mId && + mParentEntryId == image.mParentEntryId && + Objects.equals(mSource, image.mSource) && + Objects.equals(mFieldDescription, image.mFieldDescription); + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + + return Objects.hash(mId, mParentEntryId, mSource, mFieldDescription); + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/LongText.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/LongText.java new file mode 100644 index 0000000..684b2bf --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/LongText.java @@ -0,0 +1,43 @@ +package javinator9889.securepass.data.entry.fields; + +import org.jetbrains.annotations.NotNull; + +import java.io.Serializable; + +import androidx.annotation.NonNull; + +/** + * Created by Javinator9889 on 16/08/2018. + */ +public class LongText extends Text implements Serializable { + /** + * Public available constructor that uses + * {@link Text#Text(long, long, String, String, int) super} + * constructor + * + * @param id long text ID + * @param parentEntryId long parent entry ID + * @param text long text text + * @param fieldDescription description + */ + public LongText(long id, + long parentEntryId, + @NonNull String text, + @NonNull String fieldDescription, + int order) { + super(id, parentEntryId, text, fieldDescription, order); + } + + /** + * {@inheritDoc} + */ + @NotNull + @Override + public String toString() { + return "Text: " + getText() + + "\nID: " + getTextID() + + "\nField description: " + getFieldDescription() + + "\nEntry ID: " + getEntryId() + + "\nSort order: " + getOrder(); + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/Password.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/Password.java similarity index 55% rename from APP/app/src/main/java/javinator9889/securepass/data/entry/fields/Password.java rename to SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/Password.java index b66f30e..64e6bc0 100644 --- a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/Password.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/Password.java @@ -1,96 +1,152 @@ -package javinator9889.securepass.data.entry.fields; - -import java.io.Serializable; - -import androidx.annotation.NonNull; - -/** - * Stores Password fields - * Created by Javinator9889 on 16/08/2018. - */ -public class Password implements IPassword, Serializable { - private long mId; - private String mPassword; - private String mFieldDescription; - - /** - * Public available constructor fon generating a new instance - * - * @param id password ID - * @param password current password - cannot be null - * @param fieldDescription description for this field - cannot be null - */ - public Password(long id, @NonNull String password, @NonNull String fieldDescription) { - this.mId = id; - this.mPassword = password; - this.mFieldDescription = fieldDescription; - } - - /** - * Sets a new password - * - * @param password non null String with the password - */ - @Override - public void setPassword(@NonNull String password) { - this.mPassword = password; - } - - /** - * Obtains the current stored password - * - * @return String with the password - */ - @Override - public String getPassword() { - return mPassword; - } - - /** - * Gets the current password ID - * - * @return long with the ID - */ - @Override - public long getPasswordID() { - return mId; - } - - /** - * Sets a new ID - this method should not be called - * - * @param passwordID new ID - */ - @Override - public void setPasswordID(long passwordID) { - this.mId = passwordID; - } - - /** - * Updates the field description by te given one - * - * @param fieldDescription new description - * @see ICommonMethods - */ - @Override - public void setFieldDescription(@NonNull String fieldDescription) { - this.mFieldDescription = fieldDescription; - } - - /** - * Obtains the current field description - * - * @return String with the description - * @see ICommonMethods - */ - @Override - public String getFieldDescription() { - return mFieldDescription; - } - - @Override - public String toString() { - return "Password: " + getPassword() + "\nID: " + getPasswordID() + "\nField description: " + - getFieldDescription(); - } -} +package javinator9889.securepass.data.entry.fields; + +import org.jetbrains.annotations.NotNull; + +import java.io.Serializable; +import java.util.Objects; + +import androidx.annotation.NonNull; + +/** + * Stores Password fields + * Created by Javinator9889 on 16/08/2018. + */ +public class Password implements IPassword, Serializable { + private long mId; + private long mParentEntryId; + private String mPassword; + private String mFieldDescription; + + /** + * Public available constructor fon generating a new instance + * + * @param id password ID + * @param password current password - cannot be null + * @param fieldDescription description for this field - cannot be null + */ + public Password(long id, + long parentEntryId, + @NonNull String password, + @NonNull String fieldDescription) { + this.mId = id; + this.mParentEntryId = parentEntryId; + this.mPassword = password; + this.mFieldDescription = fieldDescription; + } + + /** + * Sets a new password + * + * @param password non null String with the password + */ + @Override + public void setPassword(@NonNull String password) { + this.mPassword = password; + } + + /** + * Obtains the current stored password + * + * @return String with the password + */ + @Override + public String getPassword() { + return mPassword; + } + + /** + * Gets the current password ID + * + * @return long with the ID + */ + @Override + public long getPasswordID() { + return mId; + } + + /** + * Sets a new ID - this method should not be called + * + * @param passwordID new ID + */ + @Override + public void setPasswordID(long passwordID) { + this.mId = passwordID; + } + + /** + * Updates the field description by te given one + * + * @param fieldDescription new description + * @see ICommonMethods + */ + @Override + public void setFieldDescription(@NonNull String fieldDescription) { + this.mFieldDescription = fieldDescription; + } + + /** + * Obtains the current field description + * + * @return String with the description + * @see ICommonMethods + */ + @Override + public String getFieldDescription() { + return mFieldDescription; + } + + /** + * Gets the parent entry ID for this image + * + * @return {@code long} with the ID + */ + @Override + public long getEntryId() { + return mParentEntryId; + } + + /** + * Sets a new image parent entry ID + * + * @param id new parent entry ID + */ + @Override + public void setEntryId(long id) { + mParentEntryId = id; + } + + /** + * {@inheritDoc} + */ + @NotNull + @Override + public String toString() { + return "Password: " + getPassword() + + "\nID: " + getPasswordID() + + "\nField description: " + getFieldDescription(); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Password password = (Password) o; + return mId == password.mId && + mParentEntryId == password.mParentEntryId && + Objects.equals(mPassword, password.mPassword) && + Objects.equals(mFieldDescription, password.mFieldDescription); + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + + return Objects.hash(mId, mParentEntryId, mPassword, mFieldDescription); + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/SmallText.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/SmallText.java new file mode 100644 index 0000000..a9ca41c --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/SmallText.java @@ -0,0 +1,43 @@ +package javinator9889.securepass.data.entry.fields; + +import org.jetbrains.annotations.NotNull; + +import java.io.Serializable; + +import androidx.annotation.NonNull; + +/** + * Created by Javinator9889 on 16/08/2018. + */ +public class SmallText extends Text implements Serializable { + /** + * Public available constructor that uses + * {@link Text#Text(long, long, String, String, int) super} + * constructor + * + * @param id long text ID + * @param parentEntryId long parent entry ID + * @param text long text text + * @param fieldDescription description + */ + public SmallText(long id, + long parentEntryId, + @NonNull String text, + @NonNull String fieldDescription, + int order) { + super(id, parentEntryId, text, fieldDescription, order); + } + + /** + * {@inheritDoc} + */ + @NotNull + @Override + public String toString() { + return "Text: " + getText() + + "\nID: " + getTextID() + + "\nField description: " + getFieldDescription() + + "\nEntry ID: " + getEntryId() + + "\nSort order: " + getOrder(); + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/Text.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/Text.java similarity index 55% rename from APP/app/src/main/java/javinator9889/securepass/data/entry/fields/Text.java rename to SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/Text.java index 7bf3479..9eadea9 100644 --- a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/Text.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/Text.java @@ -1,96 +1,171 @@ -package javinator9889.securepass.data.entry.fields; - -import androidx.annotation.NonNull; - -/** - * Copyright © 2018 - present | APP by Javinator9889 - * - * This program 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. - * - * This program 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 this program. If not, see https://www.gnu.org/licenses/. - * - * Created by Javinator9889 on 26/10/2018 - APP. - */ -public abstract class Text implements IText { - private long mId; - private String mText; - private String mFieldDescription; - - /** - * Constructor only available for inheritance classes - * - * @param id the text ID - * @param text the current text - * @param fieldDescription description - */ - Text(long id, @NonNull String text, @NonNull String fieldDescription) { - mId = id; - mText = text; - mFieldDescription = fieldDescription; - } - - /** - * Sets the new text - * - * @param text non null text - */ - public void setText(@NonNull String text) { - mText = text; - } - - /** - * Obtains the current text - * - * @return String with the text - */ - public String getText() { - return mText; - } - - /** - * Gets the current text ID - * - * @return long with the text - */ - public long getTextID() { - return mId; - } - - /** - * Sets a new text ID for any reason - this method should not be called - * - * @param id the new ID - */ - public void setTextID(long id) { - mId = id; - } - - /** - * Updates the field description by te given one - * - * @param fieldDescription new description - * @see ICommonMethods - */ - public void setFieldDescription(@NonNull String fieldDescription) { - mFieldDescription = fieldDescription; - } - - /** - * Obtains the current field description - * - * @return String with the description - * @see ICommonMethods - */ - public String getFieldDescription() { - return mFieldDescription; - } -} +package javinator9889.securepass.data.entry.fields; + +import java.util.Objects; + +import androidx.annotation.NonNull; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + *

+ * This program 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. + *

+ * This program 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 this program. If not, see https://www.gnu.org/licenses/. + *

+ * Created by Javinator9889 on 26/10/2018 - APP. + */ +public abstract class Text implements IText { + private long mId; + private long mParentEntryId; + private String mText; + private String mFieldDescription; + private int mOrder; + + /** + * Constructor only available for inheritance classes + * + * @param id the text ID + * @param text the current text + * @param fieldDescription description + * @param parentEntryId the parent entry ID + * @param order the sort order + */ + Text(long id, + long parentEntryId, + @NonNull String text, + @NonNull String fieldDescription, + int order) { + mId = id; + mParentEntryId = parentEntryId; + mText = text; + + mFieldDescription = fieldDescription; + mOrder = order; + } + + /** + * Sets the new text + * + * @param text non null text + */ + public void setText(@NonNull String text) { + mText = text; + } + + /** + * Obtains the current text + * + * @return String with the text + */ + public String getText() { + return mText; + } + + /** + * Gets the current text ID + * + * @return long with the text + */ + public long getTextID() { + return mId; + } + + /** + * Sets a new text ID for any reason - this method should not be called + * + * @param id the new ID + */ + public void setTextID(long id) { + mId = id; + } + + /** + * Updates the field description by te given one + * + * @param fieldDescription new description + * @see ICommonMethods + */ + public void setFieldDescription(@NonNull String fieldDescription) { + mFieldDescription = fieldDescription; + } + + /** + * Obtains the current field description + * + * @return String with the description + * @see ICommonMethods + */ + public String getFieldDescription() { + return mFieldDescription; + } + + /** + * Gets the parent entry ID for this image + * + * @return {@code long} with the ID + */ + @Override + public long getEntryId() { + return mParentEntryId; + } + + /** + * Sets a new image parent entry ID + * + * @param id new parent entry ID + */ + @Override + public void setEntryId(long id) { + mParentEntryId = id; + } + + /** + * Gets the order of the text. + * + * @return {@code int} with the sort order. + */ + @Override + public int getOrder() { + return mOrder; + } + + /** + * Sets a new order of the text. + * + * @param order new text order. + */ + @Override + public void setOrder(int order) { + mOrder = order; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Text text = (Text) o; + return mId == text.mId && + mParentEntryId == text.mParentEntryId && + Objects.equals(mText, text.mText) && + Objects.equals(mFieldDescription, text.mFieldDescription); + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + return Objects.hash(mId, mParentEntryId, mText, mFieldDescription); + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/data/secret/Field.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/secret/Field.java similarity index 56% rename from APP/app/src/main/java/javinator9889/securepass/data/secret/Field.java rename to SecurePass/app/src/main/java/javinator9889/securepass/data/secret/Field.java index b2dcd98..040423e 100644 --- a/APP/app/src/main/java/javinator9889/securepass/data/secret/Field.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/secret/Field.java @@ -1,74 +1,103 @@ -package javinator9889.securepass.data.secret; - -import java.io.Serializable; - -import androidx.annotation.NonNull; - -/** - * Contains Fields of the {@link SecurityCode} class - * Created by Javinator9889 on 29/03/2018. - */ -public class Field implements Serializable { - private long mId; - private String mCode; - private boolean mIsCodeUsed; - private SecurityCode mFieldOf; - - /** - * Public available constructor for Field - * - * @param id field ID - * @param code field code - * @param isCodeUsed whether the code has been used or not - * @param fieldOf {@link SecurityCode} parent - * @see SecurityCode - */ - public Field(long id, @NonNull String code, boolean isCodeUsed, @NonNull SecurityCode fieldOf) { - this.mId = id; - this.mCode = code; - this.mIsCodeUsed = isCodeUsed; - this.mFieldOf = fieldOf; - } - - /** - * Obtains parent ID - * - * @return long with the parent ID - */ - public long getSecurityCodeID() { - return mFieldOf.getId(); - } - - /** - * Obtains field code - * - * @return String with the code - */ - public String getCode() { - return mCode; - } - - /** - * Determine whether the current code has been used - * - * @return boolean, 'true' if used, else 'false' - */ - public boolean isCodeUsed() { - return mIsCodeUsed; - } - - /** - * Gets current field ID - * - * @return long with the ID - */ - public long getId() { - return mId; - } - - @Override - public String toString() { - return "Field mCode: " + mCode + "\nField is used: " + mIsCodeUsed + "\nField field of: " + - mFieldOf.toString(); - } -} +package javinator9889.securepass.data.secret; + +import java.io.Serializable; +import java.util.Objects; + +import androidx.annotation.NonNull; + +/** + * Contains Fields of the {@link SecurityCode} class + * Created by Javinator9889 on 29/03/2018. + */ +public class Field implements Serializable { + private long mId; + private String mCode; + private boolean mIsCodeUsed; + private long mSecurityCodeId; + + /** + * Public available constructor for Field + * + * @param id field ID + * @param code field code + * @param isCodeUsed whether the code has been used or not + * @param securityCodeId security code parent ID + * @see SecurityCode + */ + public Field(long id, @NonNull String code, boolean isCodeUsed, long securityCodeId) { + this.mId = id; + this.mCode = code; + this.mIsCodeUsed = isCodeUsed; + this.mSecurityCodeId = securityCodeId; + } + + /** + * Obtains parent ID + * + * @return long with the parent ID + */ + public long getSecurityCodeID() { + return mSecurityCodeId; + } + + /** + * Obtains field code + * + * @return String with the code + */ + public String getCode() { + return mCode; + } + + /** + * Determine whether the current code has been used + * + * @return boolean, 'true' if used, else 'false' + */ + public boolean isCodeUsed() { + return mIsCodeUsed; + } + + /** + * Gets current field ID + * + * @return long with the ID + */ + public long getId() { + return mId; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return "Field Code: " + mCode + + "\nField ID: " + mId + + "\nField is used: " + mIsCodeUsed + + "\nField of: " + mSecurityCodeId + "\n"; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Field field = (Field) o; + return mId == field.mId && + mIsCodeUsed == field.mIsCodeUsed && + mSecurityCodeId == field.mSecurityCodeId && + Objects.equals(mCode, field.mCode); + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + + return Objects.hash(mId, mCode, mIsCodeUsed, mSecurityCodeId); + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/data/secret/SecurityCode.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/secret/SecurityCode.java similarity index 64% rename from APP/app/src/main/java/javinator9889/securepass/data/secret/SecurityCode.java rename to SecurePass/app/src/main/java/javinator9889/securepass/data/secret/SecurityCode.java index 1eac8a6..6abba23 100644 --- a/APP/app/src/main/java/javinator9889/securepass/data/secret/SecurityCode.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/secret/SecurityCode.java @@ -1,49 +1,74 @@ -package javinator9889.securepass.data.secret; - -import java.io.Serializable; - -import androidx.annotation.NonNull; - -/** - * Class that contains Fields with SecurityCodes - * Created by Javinator9889 on 29/03/2018. - */ -public class SecurityCode implements Serializable { - private long mId; - private String mAccountName; - - /** - * Public available constructor for SecurityCodes - * - * @param id SecurityCode ID - * @param accountName SecurityCode name - */ - public SecurityCode(long id, @NonNull String accountName) { - this.mId = id; - this.mAccountName = accountName; - } - - /** - * Obtains current ID - * - * @return long with the ID - */ - public long getId() { - return mId; - } - - /** - * Obtains current SecurityCode account name - * - * @return String with the name - */ - public String getAccountName() { - return mAccountName; - } - - @Override - public String toString() { - return "SecurityCode ID: " + mId + - "\nSecurityCode account name: " + mAccountName + "\n"; - } -} +package javinator9889.securepass.data.secret; + +import java.io.Serializable; +import java.util.Objects; + +import androidx.annotation.NonNull; + +/** + * Class that contains Fields with SecurityCodes + * Created by Javinator9889 on 29/03/2018. + */ +public class SecurityCode implements Serializable { + private long mId; + private String mAccountName; + + /** + * Public available constructor for SecurityCodes + * + * @param id SecurityCode ID + * @param accountName SecurityCode name + */ + public SecurityCode(long id, @NonNull String accountName) { + this.mId = id; + this.mAccountName = accountName; + } + + /** + * Obtains current ID + * + * @return long with the ID + */ + public long getId() { + return mId; + } + + /** + * Obtains current SecurityCode account name + * + * @return String with the name + */ + public String getAccountName() { + return mAccountName; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return "SecurityCode ID: " + mId + + "\nSecurityCode account name: " + mAccountName + "\n"; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + SecurityCode that = (SecurityCode) o; + return mId == that.mId && + Objects.equals(mAccountName, that.mAccountName); + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + + return Objects.hash(mId, mAccountName); + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/errors/cipher/NoPrivateKeyException.java b/SecurePass/app/src/main/java/javinator9889/securepass/errors/cipher/NoPrivateKeyException.java new file mode 100644 index 0000000..283a8e5 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/errors/cipher/NoPrivateKeyException.java @@ -0,0 +1,30 @@ +package javinator9889.securepass.errors.cipher; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + *

+ * This program 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. + *

+ * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + *

+ * Created by Javinator9889 on 11/11/2018 - APP. + */ +public class NoPrivateKeyException extends RuntimeException { + /** + * Constructs a new runtime exception with the specified detail message. The cause is not + * initialized, and may subsequently be initialized by a call to {@link #initCause}. + * + * @param message the detail message. The detail message is saved for later retrieval by the + * {@link #getMessage()} method. + */ + public NoPrivateKeyException(String message) { + super(message); + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/errors/database/ExecutorNonDefinedException.java b/SecurePass/app/src/main/java/javinator9889/securepass/errors/database/ExecutorNonDefinedException.java new file mode 100644 index 0000000..7e0d086 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/errors/database/ExecutorNonDefinedException.java @@ -0,0 +1,33 @@ +package javinator9889.securepass.errors.database; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 01/11/2018 - APP. + */ +public class ExecutorNonDefinedException extends RuntimeException { + /** + * Constructs a new runtime exception with the specified detail message. + * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. + */ + public ExecutorNonDefinedException(String message) { + super(message); + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/errors/database/NoJobsEnqueuedError.java b/SecurePass/app/src/main/java/javinator9889/securepass/errors/database/NoJobsEnqueuedError.java new file mode 100644 index 0000000..3bd2eb5 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/errors/database/NoJobsEnqueuedError.java @@ -0,0 +1,33 @@ +package javinator9889.securepass.errors.database; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 02/11/2018 - APP. + */ +public class NoJobsEnqueuedError extends RuntimeException { + /** + * Constructs a new runtime exception with the specified detail message. + * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. + */ + public NoJobsEnqueuedError(String message) { + super(message); + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/errors/database/OverriddenMethodsNotDefinedError.java b/SecurePass/app/src/main/java/javinator9889/securepass/errors/database/OverriddenMethodsNotDefinedError.java new file mode 100644 index 0000000..593bff0 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/errors/database/OverriddenMethodsNotDefinedError.java @@ -0,0 +1,33 @@ +package javinator9889.securepass.errors.database; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 01/11/2018 - APP. + */ +public class OverriddenMethodsNotDefinedError extends RuntimeException { + /** + * Constructs a new runtime exception with the specified detail message. + * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. + */ + public OverriddenMethodsNotDefinedError(String message) { + super(message); + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/errors/GoogleDriveNotAvailableException.java b/SecurePass/app/src/main/java/javinator9889/securepass/errors/drive/GoogleDriveNotAvailableException.java similarity index 81% rename from APP/app/src/main/java/javinator9889/securepass/errors/GoogleDriveNotAvailableException.java rename to SecurePass/app/src/main/java/javinator9889/securepass/errors/drive/GoogleDriveNotAvailableException.java index 0e8dcea..42ba358 100644 --- a/APP/app/src/main/java/javinator9889/securepass/errors/GoogleDriveNotAvailableException.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/errors/drive/GoogleDriveNotAvailableException.java @@ -1,13 +1,13 @@ -package javinator9889.securepass.errors; - -/** - * Created by Javinator9889 on 06/04/2018. - */ -public class GoogleDriveNotAvailableException extends RuntimeException { - /** - * {@inheritDoc} - */ - public GoogleDriveNotAvailableException(String message) { - super(message); - } -} +package javinator9889.securepass.errors.drive; + +/** + * Created by Javinator9889 on 06/04/2018. + */ +public class GoogleDriveNotAvailableException extends RuntimeException { + /** + * {@inheritDoc} + */ + public GoogleDriveNotAvailableException(String message) { + super(message); + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/errors/GoogleDriveUnableToOpenFileException.java b/SecurePass/app/src/main/java/javinator9889/securepass/errors/drive/GoogleDriveUnableToOpenFileException.java similarity index 81% rename from APP/app/src/main/java/javinator9889/securepass/errors/GoogleDriveUnableToOpenFileException.java rename to SecurePass/app/src/main/java/javinator9889/securepass/errors/drive/GoogleDriveUnableToOpenFileException.java index e945bc6..eee3caf 100644 --- a/APP/app/src/main/java/javinator9889/securepass/errors/GoogleDriveUnableToOpenFileException.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/errors/drive/GoogleDriveUnableToOpenFileException.java @@ -1,13 +1,13 @@ -package javinator9889.securepass.errors; - -/** - * Created by Javinator9889 on 07/04/2018. - */ -public class GoogleDriveUnableToOpenFileException extends RuntimeException { - /** - * {@inheritDoc} - */ - public GoogleDriveUnableToOpenFileException(String message) { - super(message); - } -} +package javinator9889.securepass.errors.drive; + +/** + * Created by Javinator9889 on 07/04/2018. + */ +public class GoogleDriveUnableToOpenFileException extends RuntimeException { + /** + * {@inheritDoc} + */ + public GoogleDriveUnableToOpenFileException(String message) { + super(message); + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/io/IOManager.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/IOManager.java similarity index 59% rename from APP/app/src/main/java/javinator9889/securepass/io/IOManager.java rename to SecurePass/app/src/main/java/javinator9889/securepass/io/IOManager.java index ede026d..28d029e 100644 --- a/APP/app/src/main/java/javinator9889/securepass/io/IOManager.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/IOManager.java @@ -1,263 +1,380 @@ -package javinator9889.securepass.io; - -import android.content.Context; -import android.util.Log; - -import com.google.android.gms.common.util.IOUtils; -import com.google.common.io.Files; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import javinator9889.securepass.R; -import javinator9889.securepass.util.cipher.PasswordCipher; -import javinator9889.securepass.util.cipher.PasswordSaver; -import javinator9889.securepass.util.values.Constants; - -/** - * Created by Javinator9889 on 26/03/2018. - * Manage inputs-outputs from application - */ - -public class IOManager { - private Context mActivityContext; - private File mFilesCache; - private File mDatabasePath; - private File mDataDir; - - /** - * Private constructor used by {@link #newInstance(Context)} method - * - * @param activityContext Context when instantiated the class - * @see Context - * @see File - */ - private IOManager(@NonNull Context activityContext) { - this.mActivityContext = activityContext; - this.mFilesCache = activityContext.getCacheDir(); - this.mDatabasePath = activityContext.getDatabasePath(Constants.SQL.DB_FILENAME); - this.mDataDir = activityContext.getFilesDir(); - } - - /** - * Public static available constructor for getting IOManager instances. Uses internally - * {@link #IOManager(Context)} - * - * @param activityContext Context when instantiated the class - * @return IOManager generated instance - * @see Context - */ - @NonNull - public static IOManager newInstance(Context activityContext) { - return new IOManager(activityContext); - } - - /** - * Checks if there is any IV Vector stored (for encryption/decryption) at cache or data dir - * - * @return boolean 'true' if there is any vector, else 'false' - * @see Context#getCacheDir() - * @see Context#getDataDir() - */ - public boolean isAnyIVVectorStored() { - File cacheFile = new File(mFilesCache.getAbsolutePath() + "/iv_vector.dat"); - File dataFile = new File(mDataDir.getAbsolutePath() + "/iv_vector.dat"); - return cacheFile.exists() || dataFile.exists(); - } - - /** - * Gets IV Vector file description inside the {@link File} object - * - * @return File with IV Vector file data - * @see Context#getCacheDir() - * @see Context#getDataDir() - */ - public File getIVVector() { - File cacheFile = new File(mFilesCache.getAbsolutePath() + "/iv_vector.dat"); - File dataFile = new File(mDataDir.getAbsolutePath() + "/iv_vector.dat"); - return dataFile.exists() ? - mDataDir.listFiles((dir, name) -> name.toLowerCase().equals("iv_vector.dat"))[0] : - cacheFile.listFiles(((dir, name) -> name.toLowerCase().equals("iv_vector.dat")))[0]; - } - - /** - * Stores the IV Vector at the {@link Context#getDataDir() data dir path} - * - * @param ivVector the vector (in bytes) which will be stored - * @throws IOException if it is not possible to write to the file - * @see Context#getDataDir() - * @see Files#write(byte[], File) - */ - public void saveIVVector(byte[] ivVector) throws IOException { - String filename = mDataDir.getAbsolutePath() + "/iv_vector.dat"; - File outputFile = new File(filename); - Files.write(ivVector, outputFile); - } - - /** - * Loads from {@link R.raw raw resources} all the SQL scripts - * - * @return a List of String with the correspondent scripts - * @throws IOException when there is no file available - * @see R.raw - */ - public List loadSQLScript() throws IOException { - List result = new ArrayList<>(5); - int[] sqlScripts = new int[]{R.raw.create_category, R.raw.create_entry, R.raw.create_qrcode, - R.raw.create_security_code, R.raw.create_field}; - for (int sqlScript : sqlScripts) { - InputStream sqlScriptInputFile = this.mActivityContext.getResources() - .openRawResource(sqlScript); - StringBuilder builder = new StringBuilder(); - BufferedReader sqlStringsInFile = new BufferedReader( - new InputStreamReader(sqlScriptInputFile)); - String currentLine; - while ((currentLine = sqlStringsInFile.readLine()) != null) - builder.append(currentLine).append("\n"); - result.add(builder.toString()); - } - return result; - } - - /** - * Loads from {@link R.raw raw resources} the privacy text saved as Markdown file - * - * @return String with the hole text - * @throws IOException when there is no file available - */ - public String loadPrivacyTextMD() throws IOException { - InputStream privacyPolicyInputStream = this.mActivityContext.getResources() - .openRawResource(R.raw.privacy); - StringBuilder builder = new StringBuilder(); - BufferedReader reader = new BufferedReader(new InputStreamReader(privacyPolicyInputStream)); - String currentLine; - while ((currentLine = reader.readLine()) != null) - builder.append(currentLine).append("\n"); - return builder.toString(); - } - - /** - * Loads from {@link R.raw raw resources} the terms and conditions text saved as - * Markdown - * file - * - * @return String with the hole text - * @throws IOException when there is no file available - */ - public String loadTermsConditionsTextMD() throws IOException { - InputStream termsConditionsStream = this.mActivityContext.getResources() - .openRawResource(R.raw.terms_conditions); - StringBuilder builder = new StringBuilder(); - BufferedReader reader = new BufferedReader(new InputStreamReader(termsConditionsStream)); - String currentLine; - while ((currentLine = reader.readLine()) != null) - builder.append(currentLine).append("\n"); - return builder.toString(); - } - - /** - * Stores a password in {@link com.chamber.java.library.SharedChamber} - * - * @param userPassword password to save - * @deprecated method as the password is no longer saved in a file - */ - @Deprecated - public void storePassword(@NonNull String userPassword) { - PasswordCipher passwordSaver = PasswordSaver.instantiate(mActivityContext); - passwordSaver.putPassword(userPassword); - } - - /** - * Reads password from {@link com.chamber.java.library.SharedChamber} - * - * @return String with the password - * @deprecated method as the password is no longer saved in a file - */ - @Deprecated - @Nullable - public String readPassword() { - PasswordCipher passwordReader = PasswordSaver.instantiate(mActivityContext); - return passwordReader.getPassword(); - } - - /** - * Writes an InputStream with a database backup to an OutputStream - * - * @param from source - * @deprecated everything is now done at - * {@link javinator9889.securepass.backup.drive.DriveDownloader DriveDownloader} class - */ - @Deprecated - public void writeDownloadedDatabaseBackup(@NonNull InputStream from) { - String filename = mFilesCache.getAbsolutePath() + "/SecurePass.db"; - try { - OutputStream to = new FileOutputStream(filename); - IOUtils.copyStream(from, to); - } catch (IOException e) { - Log.e("Copy IO", "There was an error while trying to copy the InputStream" + - " to an OutputStream. Full trace: ", e); - } - } - - /** - * Reads a downloaded database backup from FilesCache - * - * @return InputStream when file is available - * @deprecated everything is now done at - * {@link javinator9889.securepass.backup.drive.DriveDownloader DriveDownloader} class - */ - @Deprecated - public InputStream readDownloadedDatabaseBackup() { - String filename = mFilesCache.getAbsolutePath() + "/SecurePass.db"; - try { - return new FileInputStream(filename); - } catch (FileNotFoundException e) { - Log.e("Read class", "File not found when trying to recover. Full trace: ", e); - return null; - } - } - - /** - * Obtains the path where databases backups are saved temporally - * - * @return String with the path - */ - public String downloadedDatabaseBackupPath() { - return mFilesCache.getAbsolutePath() + "/SecurePass.db"; - } - - /** - * Removes downloaded database backup - * - * @deprecated everything is now done at - * {@link javinator9889.securepass.backup.drive.DriveDownloader DriveDownloader} class - */ - @Deprecated - public void deleteDownloadedDatabaseBackup() { - String filename = mFilesCache.getAbsolutePath() + "/class.bck"; - - File fileToDelete = new File(filename); - if (!fileToDelete.delete()) - Log.e("Delete IO", "There was an error while trying to delete class.bck"); - } - - /** - * Obtains the path where database is stored - * - * @return File with the path - */ - public File getDatabasePath() { - return mDatabasePath; - } -} +package javinator9889.securepass.io; + +import android.content.Context; +import android.util.Base64; +import android.util.Log; + +import com.github.javinator9889.exporter.FileToBytesExporter; +import com.google.android.gms.common.util.IOUtils; +import com.google.common.io.Files; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.KeyStoreException; +import java.security.UnrecoverableEntryException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import javinator9889.securepass.R; +import javinator9889.securepass.util.cipher.PasswordSaver; +import javinator9889.securepass.util.cipher.keystore.IPasswordCipher; +import javinator9889.securepass.util.cipher.keystore.PasswordCipher; +import javinator9889.securepass.util.values.Constants; + +/** + * Created by Javinator9889 on 26/03/2018. Manage inputs-outputs from application + */ + +public class IOManager { + private Context mActivityContext; + private File mFilesCache; + private File mDatabasePath; + private File mDataDir; + + /** + * Private constructor used by {@link #newInstance(Context)} method + * + * @param activityContext Context when instantiated the class + * + * @see Context + * @see File + */ + private IOManager(@NonNull Context activityContext) { + this.mActivityContext = activityContext; + this.mFilesCache = activityContext.getCacheDir(); + this.mDatabasePath = activityContext.getDatabasePath(Constants.SQL.DB_FILENAME); + this.mDataDir = activityContext.getFilesDir(); + } + + /** + * Public static available constructor for getting IOManager instances. Uses internally {@link + * #IOManager(Context)} + * + * @param activityContext Context when instantiated the class + * + * @return IOManager generated instance + * + * @see Context + */ + @NonNull + public static IOManager newInstance(@NonNull Context activityContext) { + return new IOManager(activityContext); + } + + /** + * Checks if there is any IV Vector stored (for encryption/decryption) at cache or data dir + * + * @return boolean 'true' if there is any vector, else 'false' + * + * @see Context#getCacheDir() + * @see Context#getDataDir() + */ + public boolean isAnyIVVectorStored() { + File cacheFile = new File(mFilesCache.getAbsolutePath() + "/iv_vector.dat"); + File dataFile = new File(mDataDir.getAbsolutePath() + "/iv_vector.dat"); + return cacheFile.exists() || dataFile.exists(); + } + + /** + * Gets IV Vector file description inside the {@link File} object + * + * @return File with IV Vector file data + * + * @see Context#getCacheDir() + * @see Context#getDataDir() + */ + public File getIVVector() { + File cacheFile = new File(mFilesCache.getAbsolutePath() + "/iv_vector.dat"); + File dataFile = new File(mDataDir.getAbsolutePath() + "/iv_vector.dat"); + return dataFile.exists() ? + mDataDir.listFiles((dir, name) -> name.toLowerCase().equals("iv_vector.dat"))[0] : + cacheFile.listFiles(((dir, name) -> name.toLowerCase().equals("iv_vector.dat")))[0]; + } + + /** + * Stores the IV Vector at the {@link Context#getDataDir() data dir path} + * + * @param ivVector the vector (in bytes) which will be stored + * + * @throws IOException if it is not possible to write to the file + * @see Context#getDataDir() + * @see Files#write(byte[], File) + */ + public void saveIVVector(byte[] ivVector) throws IOException { + String filename = mDataDir.getAbsolutePath() + "/iv_vector.dat"; + File outputFile = new File(filename); + Files.write(ivVector, outputFile); + } + + /** + * Loads from {@link R.raw raw resources} all the SQL scripts + * + * @return a List of String with the correspondent scripts + * + * @throws IOException when there is no file available + * @see R.raw + * @deprecated this method is no longer valid - use {@link #obtainSQLScript()} instead + */ + @Deprecated + public List loadSQLScript() throws IOException { +// FileToBytesExporter exporter = new FileToBytesExporter(); + List result = new ArrayList<>(5); + int[] sqlScripts = new int[]{R.raw.create_category, R.raw.create_entry, R.raw.create_qrcode, + R.raw.create_security_code, R.raw.create_field}; + for (int sqlScript : sqlScripts) { + InputStream sqlScriptInputFile = this.mActivityContext.getResources() + .openRawResource(sqlScript); + StringBuilder builder = new StringBuilder(); + BufferedReader sqlStringsInFile = new BufferedReader( + new InputStreamReader(sqlScriptInputFile)); + String currentLine; + while ((currentLine = sqlStringsInFile.readLine()) != null) + builder.append(currentLine).append("\n"); + result.add(builder.toString()); + } + return result; + } + + /** + * Loads from {@link R.raw raw resources} the binary SQL script, using {@link + * FileToBytesExporter} for recovering data + * + * @return {@code ArrayList} with the different SQL parts. + * + * @throws IOException if something happens while recovering the data from the source file. + * @see FileToBytesExporter#readObject(File) + */ + public List obtainSQLScript() throws IOException { + InputStream sourceFile = mActivityContext + .getResources() + .openRawResource(R.raw.database_script); +// FileToBytesExporter reader = new FileToBytesExporter(); +// reader.readObject(sourceFile); +// String obtainedData = reader.getReadData(); + StringBuilder data = new StringBuilder(); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(sourceFile))) { + String line; + while ((line = reader.readLine()) != null) + data.append(line).append("\n"); + } + String[] separateScripts = data.toString().split("(\\r?\\n){2}"); + return new ArrayList<>(Arrays.asList(separateScripts)); + } + + /** + * Loads from {@link R.raw raw resources} the privacy text saved as Markdown file + * + * @return String with the hole text + * + * @throws IOException when there is no file available + */ + public String loadPrivacyTextMD() throws IOException { + InputStream privacyPolicyInputStream = this.mActivityContext.getResources() + .openRawResource(R.raw.privacy); + StringBuilder builder = new StringBuilder(); + BufferedReader reader = new BufferedReader(new InputStreamReader(privacyPolicyInputStream)); + String currentLine; + while ((currentLine = reader.readLine()) != null) + builder.append(currentLine).append("\n"); + return builder.toString(); + } + + /** + * Loads from {@link R.raw raw resources} the terms and conditions text saved as Markdown + * file + * + * @return String with the hole text + * + * @throws IOException when there is no file available + */ + public String loadTermsConditionsTextMD() throws IOException { + InputStream termsConditionsStream = this.mActivityContext.getResources() + .openRawResource(R.raw.terms_conditions); + StringBuilder builder = new StringBuilder(); + BufferedReader reader = new BufferedReader(new InputStreamReader(termsConditionsStream)); + String currentLine; + while ((currentLine = reader.readLine()) != null) + builder.append(currentLine).append("\n"); + return builder.toString(); + } + + /** + * Obtains the {@code byte[]} value of the user hashed password by applying an encryption + * algorithm using RSA - see {@link PasswordCipher} for more information. + * + * @param userHashedPassword password to encrypt - it must be about 256 bits. + * + * @return {@code true} when there was no error, {@code false} if something happened. + */ + public boolean savePassword(@NonNull String userHashedPassword) { + String alias = Constants.CIPHER.PASSWORD.ALIAS; + String filename = Constants.CIPHER.PASSWORD.FILENAME; + try { + IPasswordCipher cipher = new PasswordCipher(mActivityContext, alias); + cipher.createNewKeys(); + byte[] password = cipher + .encryptPassword(userHashedPassword.getBytes(StandardCharsets.UTF_8)); + File passwordFile = new File(mDataDir.getAbsolutePath() + "/" + filename); + if (!passwordFile.exists()) + passwordFile.createNewFile(); + try (OutputStream outputStream = new FileOutputStream(passwordFile)) { + outputStream.write(Base64.encode(password, Base64.DEFAULT)); + } + return true; + } catch (KeyStoreException | InvalidAlgorithmParameterException | InvalidKeyException | + UnrecoverableEntryException | IOException ignored) { + return false; + } + } + + /** + * Reads, decodes and decrypts a password stored inside the {@linkplain + * Constants.CIPHER.PASSWORD password file}. + * + * @return a {@code byte[]} with the password if the file exists or {@code null} if there was + * any error. + */ + public byte[] recoverPassword() { + String alias = Constants.CIPHER.PASSWORD.ALIAS; + String filename = Constants.CIPHER.PASSWORD.FILENAME; + try { + IPasswordCipher cipher = new PasswordCipher(mActivityContext, alias); + File passwordFile = new File(mDataDir.getAbsolutePath() + "/" + filename); + if (!passwordFile.exists()) + return null; + byte[] recoveredPassword = Files.toByteArray(passwordFile); + byte[] decodedPassword = Base64.decode(recoveredPassword, Base64.DEFAULT); + return cipher.decryptPassword(decodedPassword).getBytes(StandardCharsets.UTF_8); + } catch (KeyStoreException | IOException | InvalidKeyException | + UnrecoverableEntryException exception) { + exception.printStackTrace(); + return null; + } + } + + /** + * Opens and reads the database file that is used by SQLCipher. + * + * @return {@code byte[]} with the database data, or {@code null} if there is any error. + */ + public byte[] readDatabaseFileAsBytes() { + try { + return Files.toByteArray(mDatabasePath); + } catch (IOException exception) { + exception.printStackTrace(); + return null; + } + } + + /** + * Stores a password in {@link com.chamber.java.library.SharedChamber} + * + * @param userPassword password to save + * + * @deprecated method as the password is no longer saved in a file + */ + @Deprecated + public void storePassword(@NonNull String userPassword) { + PasswordSaver passwordSaver = PasswordSaver.instantiate(mActivityContext); + passwordSaver.putPassword(userPassword); + } + + /** + * Reads password from {@link com.chamber.java.library.SharedChamber} + * + * @return String with the password + * + * @deprecated method as the password is no longer saved in a file + */ + @Deprecated + @Nullable + public String readPassword() { + PasswordSaver passwordReader = PasswordSaver.instantiate(mActivityContext); + return passwordReader.getPassword(); + } + + /** + * Writes an InputStream with a database backup to an OutputStream + * + * @param from source + * + * @deprecated everything is now done at {@link javinator9889.securepass.backup.drive.DriveDownloader + * DriveDownloader} class + */ + @Deprecated + public void writeDownloadedDatabaseBackup(@NonNull InputStream from) { + String filename = mFilesCache.getAbsolutePath() + "/SecurePass.db"; + try { + OutputStream to = new FileOutputStream(filename); + IOUtils.copyStream(from, to); + } catch (IOException e) { + Log.e("Copy IO", "There was an error while trying to copy the InputStream" + + " to an OutputStream. Full trace: ", e); + } + } + + /** + * Reads a downloaded database backup from FilesCache + * + * @return InputStream when file is available + * + * @deprecated everything is now done at {@link javinator9889.securepass.backup.drive.DriveDownloader + * DriveDownloader} class + */ + @Deprecated + public InputStream readDownloadedDatabaseBackup() { + String filename = mFilesCache.getAbsolutePath() + "/SecurePass.db"; + try { + return new FileInputStream(filename); + } catch (FileNotFoundException e) { + Log.e("Read class", "File not found when trying to recover. Full trace: ", e); + return null; + } + } + + /** + * Obtains the path where databases backups are saved temporally + * + * @return String with the path + */ + public String downloadedDatabaseBackupPath() { + return mFilesCache.getAbsolutePath() + "/SecurePass.db"; + } + + /** + * Removes downloaded database backup + * + * @deprecated everything is now done at {@link javinator9889.securepass.backup.drive.DriveDownloader + * DriveDownloader} class + */ + @Deprecated + public void deleteDownloadedDatabaseBackup() { + String filename = mFilesCache.getAbsolutePath() + "/class.bck"; + + File fileToDelete = new File(filename); + if (!fileToDelete.delete()) + Log.e("Delete IO", "There was an error while trying to delete class.bck"); + } + + /** + * Obtains the path where database is stored + * + * @return File with the path + */ + public File getDatabasePath() { + return mDatabasePath; + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/io/database/DatabaseManager.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/DatabaseManager.java similarity index 78% rename from APP/app/src/main/java/javinator9889/securepass/io/database/DatabaseManager.java rename to SecurePass/app/src/main/java/javinator9889/securepass/io/database/DatabaseManager.java index 1af75c4..799d15a 100644 --- a/APP/app/src/main/java/javinator9889/securepass/io/database/DatabaseManager.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/DatabaseManager.java @@ -1,162 +1,179 @@ -package javinator9889.securepass.io.database; - -import android.content.Context; -import android.util.Log; - -import net.sqlcipher.database.SQLiteDatabase; - -import java.io.File; -import java.io.IOException; -import java.util.List; - -import androidx.annotation.NonNull; -import javinator9889.securepass.io.IOManager; -import javinator9889.securepass.io.database.operations.CommonOperations; -import javinator9889.securepass.util.resources.ISharedPreferencesManager; -import javinator9889.securepass.util.resources.PreferencesManager; -import javinator9889.securepass.util.values.Constants; - -/** - * Created by Javinator9889 on 26/03/2018. - * Based on SQLCipher documentation - */ - -public class DatabaseManager { - private Context mActivityContext; - private File mDatabaseFile; - private String mUserHashedPassword; - private Thread mDatabaseInitializer; - - /** - * Generates a new instance and also initializes the database with {@link #initDB()} method - * - * @param activityContext Context when instantiating the class - * @param userHashedPassword password for encrypting/decrypting the database - * @see Context - * @see #initDB() - */ - private DatabaseManager(Context activityContext, @NonNull String userHashedPassword) { - this.mActivityContext = activityContext; - this.mUserHashedPassword = userHashedPassword; - initDB(); - } - - /** - * Generates a DatabaseManager instance - * - * @param activityContext Context when instantiating the class - * @param userHashedPassword password for encrypting/decrypting the database - * @return DatabaseManager instance - * @see Context - */ - @NonNull - public static DatabaseManager newInstance(Context activityContext, - @NonNull String userHashedPassword) { - return new DatabaseManager(activityContext, userHashedPassword); - } - - /** - * Initializes de database with the required script on a separate thread. - *

- * It reads from {@link ISharedPreferencesManager} if the - * {@link ISharedPreferencesManager#isApplicationInitialized() application is initialized - * } for creating the correspondent files.
- * If the - * {@link ISharedPreferencesManager#isDatabaseInitialized() database is initialized} it - * will not load again the scripts. Else, by using {@link IOManager} it will create the - * tables inside SQLite - *

- * - * @see SQLiteDatabase - * @see PreferencesManager - * @see IOManager#loadSQLScript() - */ - private void initDB() { - mDatabaseInitializer = new Thread(new Runnable() { - private final Context databaseContext = DatabaseManager.this.mActivityContext; - private final String databasePassword = DatabaseManager.this.mUserHashedPassword; - - @Override - public void run() { - SQLiteDatabase.loadLibs(databaseContext); - ISharedPreferencesManager preferencesManager = PreferencesManager.getInstance(); - mDatabaseFile = databaseContext - .getDatabasePath(Constants.SQL.DB_FILENAME); - if (!preferencesManager.isApplicationInitialized()) { - try { - mDatabaseFile.delete(); - mDatabaseFile.createNewFile(); - } catch (IOException e) { - e.printStackTrace(); - } - } - SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase( - mDatabaseFile, - databasePassword, - null); - List databaseScripts; - try { - if (!preferencesManager.isDatabaseInitialized()) { - databaseScripts = IOManager.newInstance(databaseContext).loadSQLScript(); - for (String script : databaseScripts) { - database.execSQL(script); - } - DatabaseManager.this.createDefaultCategory(); - } - } catch (IOException e) { - throw new RuntimeException(e.getCause()); - } finally { - database.close(); - } - } - }); - mDatabaseInitializer.setName(Constants.SQL.DB_INIT_THREAD_NAME); - mDatabaseInitializer.setUncaughtExceptionHandler(new ThreadExceptionHandler()); - mDatabaseInitializer.run(); - } - - /** - * Gets the database instance from SQLite - * - * @return SQLiteDatabase instance - */ - public SQLiteDatabase getDatabaseInstance() { - SQLiteDatabase.loadLibs(mActivityContext); - return SQLiteDatabase.openOrCreateDatabase(mDatabaseFile, mUserHashedPassword, null); - } - - /** - * Gets the thread when running for joining the database initializer with current thread - * - * @return Thread with the init process - * @see Thread - * @see Thread#join() - */ - public Thread getDatabaseInitializer() { - return mDatabaseInitializer; - } - - /** - * Creates the default category necessary in order to allow the hole application work - */ - private void createDefaultCategory() { - CommonOperations operations = CommonOperations.newInstance(this); - operations.registerDefaultCategory(); - operations.finishConnection(); - } - - /** - * Class for handling Threading exceptions - */ - private class ThreadExceptionHandler implements Thread.UncaughtExceptionHandler { - /** - * {@inheritDoc} - */ - @Override - public void uncaughtException(Thread t, Throwable e) { - Log.e(t.getName(), "Exception in thread \"" + t.getName() + "\" with " + - "exception thrown -> " + e.getMessage() + "\nFull trace: "); - e.printStackTrace(); - } - } -} +package javinator9889.securepass.io.database; + +import android.content.Context; +import android.util.Log; + +import com.github.javinator9889.exporter.FileToBytesExporter; + +import net.sqlcipher.database.SQLiteDatabase; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +import androidx.annotation.NonNull; +import javinator9889.securepass.io.IOManager; +import javinator9889.securepass.io.database.operations.CommonOperations; +import javinator9889.securepass.util.resources.ISharedPreferencesManager; +import javinator9889.securepass.util.resources.PreferencesManager; +import javinator9889.securepass.util.values.Constants; + +/** + * Created by Javinator9889 on 26/03/2018. + * Based on SQLCipher documentation + */ + +public class DatabaseManager { + private static DatabaseManager INSTANCE = null; + // private Context mActivityContext; + private File mDatabaseFile; + private String mUserHashedPassword; + private Thread mDatabaseInitializer; + + /** + * Generates a new instance and also initializes the database with {@link #initDB(Context)} method + * + * @param activityContext Context when instantiating the class + * @param userHashedPassword password for encrypting/decrypting the database + * @see Context + * @see #initDB(Context) + */ + private DatabaseManager(Context activityContext, @NonNull String userHashedPassword) { +// this.mActivityContext = activityContext; + this.mUserHashedPassword = userHashedPassword; + initDB(activityContext); + INSTANCE = this; + } + + /** + * Generates a DatabaseManager instance. If the libraries are loaded + * + * @param activityContext Context when instantiating the class + * @param userHashedPassword password for encrypting/decrypting the database + * @return DatabaseManager instance + * @see Context + */ + @NonNull + public static DatabaseManager getInstance(Context activityContext, + @NonNull String userHashedPassword) { + return INSTANCE == null ? + new DatabaseManager(activityContext, userHashedPassword) : + INSTANCE; + } + + /** + * Initializes de database with the required script on a separate thread. + *

+ * It reads from {@link ISharedPreferencesManager} if the + * {@link ISharedPreferencesManager#isApplicationInitialized() application is initialized + * } for creating the correspondent files.
+ * If the + * {@link ISharedPreferencesManager#isDatabaseInitialized() database is initialized} it + * will not load again the scripts. Else, by using {@link IOManager} it will create the + * tables inside SQLite + *

+ * + * @param databaseContext Context when instantiating the class + * @see SQLiteDatabase + * @see PreferencesManager + * @see IOManager#loadSQLScript() + */ + private void initDB(@NonNull final Context databaseContext) { + mDatabaseInitializer = new Thread(new Runnable() { + // private final Context databaseContext = DatabaseManager.this.mActivityContext; + private final String databasePassword = DatabaseManager.this.mUserHashedPassword; + + @Override + public void run() { + SQLiteDatabase.loadLibs(databaseContext); + ISharedPreferencesManager preferencesManager = PreferencesManager.getInstance(); + mDatabaseFile = databaseContext + .getDatabasePath(Constants.SQL.DB_FILENAME); + if (!preferencesManager.isApplicationInitialized()) { + try { + mDatabaseFile.delete(); + mDatabaseFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase( + mDatabaseFile, + databasePassword, + null); + List databaseScripts; + try { + if (!preferencesManager.isDatabaseInitialized()) { + databaseScripts = IOManager.newInstance(databaseContext).obtainSQLScript(); + for (String script : databaseScripts) { + database.execSQL(script); + } + DatabaseManager.this.createDefaultCategory(); + } + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException(e.getCause()); + } finally { + database.close(); + } + } + }); + mDatabaseInitializer.setName(Constants.SQL.DB_INIT_THREAD_NAME); + mDatabaseInitializer.setUncaughtExceptionHandler(new ThreadExceptionHandler()); + mDatabaseInitializer.run(); + } + + /** + * Gets the database instance from SQLite + * + * @return SQLiteDatabase instance + */ + public SQLiteDatabase getDatabaseInstance() { +// SQLiteDatabase.loadLibs(context); + return SQLiteDatabase.openOrCreateDatabase(mDatabaseFile, mUserHashedPassword, null); + } + + /** + * Gets the thread when running for joining the database initializer with current thread + * + * @return Thread with the init process + * @see Thread + * @see Thread#join() + */ + public Thread getDatabaseInitializer() { + return mDatabaseInitializer; + } + + /** + * Finalizes this instance (e.g.: the ongoing database operations are finished) - method should + * be called whether is going to use a new instance. + */ + public static void finish() { + INSTANCE = null; + } + + /** + * Creates the default category necessary in order to allow the hole application work + */ + private void createDefaultCategory() { + CommonOperations operations = new CommonOperations(this); + operations.registerDefaultCategory(); + operations.finishConnection(); + } + + /** + * Class for handling Threading exceptions + */ + private class ThreadExceptionHandler implements Thread.UncaughtExceptionHandler { + /** + * {@inheritDoc} + */ + @Override + public void uncaughtException(Thread t, Throwable e) { + Log.e(t.getName(), "Exception in thread \"" + t.getName() + "\" with " + + "exception thrown -> " + e.getMessage() + "\nFull trace: "); + e.printStackTrace(); + } + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/CommonOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/CommonOperations.java new file mode 100644 index 0000000..2280834 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/CommonOperations.java @@ -0,0 +1,491 @@ +package javinator9889.securepass.io.database.operations; + +import android.content.ContentValues; +import android.util.Log; + +import com.github.javinator9889.exporter.FileToBytesExporter; +import com.github.javinator9889.threading.pools.ThreadsPooling; +import com.github.javinator9889.threading.threads.notifyingthread.NotifyingThread; +import com.github.javinator9889.threading.threads.notifyingthread.OnThreadCompletedListener; + +import net.sqlcipher.Cursor; +import net.sqlcipher.database.SQLiteDatabase; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.BlockingQueue; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import java8.util.J8Arrays; +import javinator9889.securepass.errors.database.ExecutorNonDefinedException; +import javinator9889.securepass.errors.database.NoJobsEnqueuedError; +import javinator9889.securepass.errors.database.OverriddenMethodsNotDefinedError; +import javinator9889.securepass.io.database.DatabaseManager; +import javinator9889.securepass.objects.ObjectContainer; +import javinator9889.securepass.util.values.Constants.SQL; + +/** + * Created by Javinator9889 on 29/03/2018. + */ +public class CommonOperations implements OnThreadCompletedListener { + private static final String TAG = "Database Operations"; + private static final String WHERE_ID = null; + private static final String TABLE_NAME = null; + private SQLiteDatabase mDatabase; + private ThreadsPooling mExecutor; + private ObjectContainer mWaitingThreads; + + /** + * Public constructor for creating this class - use this instead of {@link + * #newInstance(DatabaseManager)}. + * + * @param databaseInstance instance of the {@link DatabaseManager} object. + * @see DatabaseManager + */ + public CommonOperations(@NonNull DatabaseManager databaseInstance) { + try { + if (databaseInstance.getDatabaseInitializer().isAlive()) + databaseInstance.getDatabaseInitializer().join(); + mDatabase = databaseInstance.getDatabaseInstance(); + mExecutor = ThreadsPooling.builder().build(); + mWaitingThreads = new ObjectContainer<>(); + } catch (InterruptedException e) { + Log.e(getTag(), "Error while trying to join thread \"" + + SQL.DB_INIT_THREAD_NAME + "\". Interrupted exception. Full trace:", e); + } + } + + /** + * Public class loader - uses {@link #CommonOperations(DatabaseManager) private constructor} + * + * @param databaseManagerInstance instance of the {@link DatabaseManager} object + * @return CommonOperations + * @deprecated use {@link #CommonOperations(DatabaseManager)} instead + */ + @Deprecated + public static CommonOperations newInstance(DatabaseManager databaseManagerInstance) { + return new CommonOperations(databaseManagerInstance); + } + + /** + * Whenever {@link SQLiteDatabase#needUpgrade(int)} is called (and the result is {@code + * true}), this method should be called as it will upgrade the database. + * + * @param source the new database version that will be updated. + * @throws IOException whenever the source does not exists or there is any error while + * reading (for example, it has been closed). + */ + public void onDatabaseUpdate(@NonNull InputStream source) throws IOException { + FileToBytesExporter opener = new FileToBytesExporter(); + opener.readObject(source); + String[] newDatabaseVersion = opener.getReadData().split("(\\r?\\n){2}"); + for (String query : newDatabaseVersion) + mDatabase.execSQL(query); + } + + /** + * Method for changing the database password + * + * @param newDatabasePassword new password + * @see SQLiteDatabase#changePassword(String) + */ + public void changeDatabasePassword(@NonNull String newDatabasePassword) { + this.mDatabase.changePassword(newDatabasePassword); + } + + /** + * Registers the default ("Global") category + * + * @return long with the category ID (should be '1') + * @see SQLiteDatabase#insertWithOnConflict(String, String, ContentValues, int) + */ + public long registerDefaultCategory() { + ContentValues params = new ContentValues(); + params.put(SQL.CATEGORY.C_ID, 0); + params.put(SQL.CATEGORY.C_NAME, "Global"); + return mDatabase.insertWithOnConflict(SQL.CATEGORY.NAME, null, params, + SQLiteDatabase.CONFLICT_IGNORE); + } + + /** + * Gets the tag for {@link android.util.Log} output - should be overridden + * + * @return String with the tag name + */ + public String getTag() { + return TAG; + } + + /** + * Gets the WHERE ID clause for using {@link #scheduleUpdateExecutor(long, ContentValues)} - + * should be overridden + * + * @return {@code String} with the WHERE clause - null if not defined + */ + @Nullable + public String getWhereId() { + return WHERE_ID; + } + + /** + * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - should + * be overridden + * + * @return {@code String} with the TABLE NAME - null if not defined + */ + @Nullable + public String getTableName() { + return TABLE_NAME; + } + + /** + * Tries to insert the data at the specified table + * + * @param tableName the table to insert the row + * @param params map containing the initial values + * @return the row ID or -1 if any error occurred + * @see SQLiteDatabase#insert(String, String, ContentValues) + * @see ContentValues + */ + protected long insert(@NonNull String tableName, @NonNull ContentValues params) { + mDatabase.beginTransaction(); + long insertResult = mDatabase.insert(tableName, null, params); + if (insertResult != -1) + mDatabase.setTransactionSuccessful(); + mDatabase.endTransaction(); + return insertResult; + } + + /** + * Tries to insert the data at the specified table ignoring conflicts + * + * @param tableName the table to insert the row + * @param params map containing the initial values + * @return the row ID or -1 if any error occurred + * @see SQLiteDatabase#insertWithOnConflict(String, String, ContentValues, int) + * @see SQLiteDatabase#CONFLICT_IGNORE + * @see ContentValues + */ + protected long insertIgnoreOnConflict(@NonNull String tableName, + @NonNull ContentValues params) { + mDatabase.beginTransaction(); + long insertResult = mDatabase.insertWithOnConflict(tableName, null, params, SQLiteDatabase + .CONFLICT_IGNORE); + if (insertResult != -1) + mDatabase.setTransactionSuccessful(); + mDatabase.endTransaction(); + return insertResult; + } + + /** + * Tries to insert the data at the specified table aborting when conflicts occur + * + * @param tableName the table to insert the row + * @param params map containing the initial values + * @return the row ID or -1 if any error occurred + * @see SQLiteDatabase#insertWithOnConflict(String, String, ContentValues, int) + * @see SQLiteDatabase#CONFLICT_ABORT + * @see ContentValues + */ + protected long insertAbortOnConflict(@NonNull String tableName, @NonNull ContentValues params) { + mDatabase.beginTransaction(); + long insertResult = mDatabase.insertWithOnConflict(tableName, null, params, SQLiteDatabase + .CONFLICT_ABORT); + if (insertResult != -1) + mDatabase.setTransactionSuccessful(); + mDatabase.endTransaction(); + return insertResult; + } + + /** + * Tries to insert the data at the specified table doing nothing with conflicts + * + * @param tableName the table to insert the row + * @param params map containing the initial values + * @return the row ID or -1 if any error ocurred + * @see SQLiteDatabase#insertWithOnConflict(String, String, ContentValues, int) + * @see SQLiteDatabase#CONFLICT_NONE + * @see ContentValues + */ + protected long insertNoneOnConflit(@NonNull String tableName, @NonNull ContentValues params) { + mDatabase.beginTransaction(); + long insertResult = mDatabase.insertWithOnConflict(tableName, null, params, SQLiteDatabase + .CONFLICT_NONE); + if (insertResult != -1) + mDatabase.setTransactionSuccessful(); + mDatabase.endTransaction(); + return insertResult; + } + + /** + * Tries to insert the data at the specified table failing with conflicts + * + * @param tableName the table to insert the row + * @param params map containing the initial values + * @return the row ID or -1 if any error occurred + * @see SQLiteDatabase#insertWithOnConflict(String, String, ContentValues, int) + * @see SQLiteDatabase#CONFLICT_FAIL + * @see ContentValues + */ + protected long insertFailOnConflict(@NonNull String tableName, @NonNull ContentValues params) { + mDatabase.beginTransaction(); + long insertResult = mDatabase.insertWithOnConflict(tableName, null, params, SQLiteDatabase + .CONFLICT_FAIL); + if (insertResult != -1) + mDatabase.setTransactionSuccessful(); + else + throw new RuntimeException("Error occurred while inserting data"); + mDatabase.endTransaction(); + return insertResult; + } + + /** + * Tries to insert the data at the specified table replacing conflicts + * + * @param tableName the table to insert the row + * @param params map containing the initial values + * @return the row ID or -1 if any error occurred + * @see SQLiteDatabase#insertWithOnConflict(String, String, ContentValues, int) + * @see SQLiteDatabase#CONFLICT_REPLACE + * @see ContentValues + */ + protected long insertReplaceOnConflict(@NonNull String tableName, + @NonNull ContentValues params) { + mDatabase.beginTransaction(); + long insertResult = mDatabase.insertWithOnConflict(tableName, null, params, SQLiteDatabase + .CONFLICT_REPLACE); + if (insertResult != -1) + mDatabase.setTransactionSuccessful(); + mDatabase.endTransaction(); + return insertResult; + } + + /** + * Tries to insert the data at the specified table rolling back on conflicts + * + * @param tableName the table to insert the row + * @param params map containing the initial values + * @return the row ID or -1 if any error occurred + * @see SQLiteDatabase#insertWithOnConflict(String, String, ContentValues, int) + * @see SQLiteDatabase#CONFLICT_ROLLBACK + * @see ContentValues + */ + protected long insertRollbackOnConflict(@NonNull String tableName, + @NonNull ContentValues params) { + mDatabase.beginTransaction(); + long insertResult = mDatabase.insertWithOnConflict(tableName, null, params, SQLiteDatabase + .CONFLICT_ROLLBACK); + if (insertResult != -1) + mDatabase.setTransactionSuccessful(); + mDatabase.endTransaction(); + return insertResult; + } + + /** + * Updates table information if exists + * + * @param tableName table name to modify + * @param values new values to insert + * @param whereClause SQL where clause + * @param whereArgs SQL where args (probably it is an ID) + * @return the affected rows + * @throws net.sqlcipher.SQLException If the SQL string is invalid for some reason + * @throws IllegalStateException if the database is not open + */ + protected int update(@NonNull String tableName, + @NonNull ContentValues values, + @NonNull String whereClause, + @NonNull String[] whereArgs) { + return mDatabase.update(tableName, values, whereClause, whereArgs); + } + + /** + * Obtains the specified table information and saves it inside a {@link Cursor} + * + * @param tableName where to obtain the values. + * @param columnsToGet which columns to get - passing null will return all columns. + * @param whereClause where to obtain data - passing null will return all rows. + * @param args args for modifying the whereClause statement. + * @param groupBy a filter declaring how to group rows - passing null will cause the rows + * to not to be grouped. + * @param having a filter declaring which row groups to include in the cursor, if groupBy + * is being used + * @param orderBy how to order the rows - passing null will use the default sort order + * @return a {@link Cursor} object positioned before the first entry + * @throws net.sqlcipher.SQLException if there is an issue executing the SQL + * @throws IllegalStateException if the database is not open + * @see Cursor + */ + protected Cursor get(@NonNull String tableName, + @Nullable String[] columnsToGet, + @Nullable String whereClause, + @Nullable String[] args, + @Nullable String groupBy, + @Nullable String having, + @Nullable String orderBy) { + return mDatabase + .query(tableName, columnsToGet, whereClause, args, groupBy, having, orderBy); + } + + /** + * Gets all fields for the given table name + * + * @param tableName where to obtain the values + * @return a {@link Cursor} object positioned before the first entry + * @throws net.sqlcipher.SQLException if there is an issue executing the SQL + * @throws IllegalStateException if the database is not open + * @see Cursor + */ + protected Cursor getAll(@NonNull String tableName, @Nullable String orderBy) { + return get(tableName, null, null, null, null, null, orderBy); + } + + /** + * Generates a {@link Map} of the values obtained by the cursor, assigning the {@code column + * name} to its index - useful for retrieving values from {@code SELECT} clause. + * + * @param cursor the source cursor from which the values will be obtained. + * @return {@code Map} with the relation between column name and column index. + * @see HashMap + */ + @NonNull + protected Map constructMapFromCursor(@NonNull Cursor cursor) { + String[] columnNames = cursor.getColumnNames(); + Map result = new HashMap<>(cursor.getColumnCount(), 1.0f); + for (String columnName : columnNames) { + int index = cursor.getColumnIndex(columnName); + result.put(columnName, index); + } + return result; + } + + /** + * Deletes all columns for a given ID of a table + * + * @param tableName table to delete values + * @param idFieldName table column name which contains the ID + * @param id ID of the row to delete + * @return the number of rows affected + * @throws net.sqlcipher.SQLException If the SQL string is invalid for some reason + * @throws IllegalStateException if the database is not open + */ + protected int delete(@NonNull String tableName, @NonNull String idFieldName, long id) { + String whereClause = idFieldName + "=?"; + return mDatabase.delete(tableName, whereClause, setSelectionArgs(id)); + } + + /** + * Closes database connection. + * + * @see SQLiteDatabase#close() + */ + public void finishConnection() { + try { + mExecutor.shutdownWaitTermination(); + } catch (InterruptedException e) { + Log.w(TAG, "Task executor was interrupted while waiting threads to finish", e); + } finally { + mDatabase.close(); + DatabaseManager.finish(); + } + } + + /** + * Casts {@code long} to a {@code String[]} array + * + * @param id ID to cast + * @return {@code String[]} with the ID value + */ + private String[] setSelectionArgs(long id) { + return new String[]{String.valueOf(id)}; + } + + /** + * Converts an array of {@code Object} varargs into a {@code String} array + * + * @param args amount of elements to store in a {@code String} array + * @return {@code String[]} containing the args + */ + protected String[] whereArgs(@NonNull Object... args) { + return J8Arrays.stream(args).map(Object::toString).toArray(String[]::new); +// return Arrays.copyOf(args, args.length, String[].class); + } + + /** + * Schedules an update operation by using the given ID and new values + * + * @param id ID where changing values + * @param params new values + * @throws OverriddenMethodsNotDefinedError when {@link #getTableName()} or {@link + * #getWhereId()} are not overridden. + * @throws ExecutorNonDefinedException if, for any reason, executor is {@code null}. + * @see ThreadsPooling#add(Runnable) + * @see ThreadsPooling#start() + */ + protected void scheduleUpdateExecutor(long id, @NonNull ContentValues params) { + if (getTableName() == null || getWhereId() == null) { + StringBuilder nonDefinedAttributes = new StringBuilder(3); + boolean isFirstDefined = false; + if (getTableName() == null) { + nonDefinedAttributes.append("getTableName()"); + isFirstDefined = true; + } + if (getWhereId() == null) + if (isFirstDefined) + nonDefinedAttributes.append(", "); + nonDefinedAttributes.append("getWhereId()"); + throw new OverriddenMethodsNotDefinedError("Following methods not overridden: " + + nonDefinedAttributes.toString()); + } + if (mExecutor == null) + throw new ExecutorNonDefinedException("You must define the \"ThreadsPooling\" by " + + "using \"CommonOperations(DatabaseManager)\" constructor"); + BlockingQueue queue = mExecutor.getWorkingThreadsQueue(); + if (queue.remainingCapacity() == 0) + mWaitingThreads.storeObject(() -> update(getTableName(), params, getWhereId(), + whereArgs(id))); + else + mExecutor.add(new NotifyingThread(() -> update(getTableName(), params, getWhereId(), + whereArgs(id)), this)); + } + + /** + * Runs the {@link ThreadsPooling} - only necessary when doing UPDATE operations + * + * @throws NoJobsEnqueuedError when there is no job added to the queue + */ + public void apply() { + int startedThreads = mExecutor.start(); + if (startedThreads == 0) + throw new NoJobsEnqueuedError("There is no pending thread waiting to be executed"); + } + + /** + * When a thread finish its execution, if using a {@link NotifyingThread} and the class is + * subscribed, this method is called, with the {@code Runnable} which corresponds the just + * finished thread, and the {@code Throwable} containing the exception (if any exception has + * benn thrown). + *

+ * Refer to {@link NotifyingThread#addOnThreadCompletedListener(OnThreadCompletedListener)} for + * getting more information about subscribing classes. + * + * @param thread the thread that has just finished its execution. + * @param exception the exception if happened, else {@code null}. + */ + @Override + public void onThreadCompletedListener(@NotNull Thread thread, + @org.jetbrains.annotations.Nullable Throwable exception) { + if (mWaitingThreads.isAnyObjectStored()) { + Runnable firstObject = mWaitingThreads.getStoredObjectAtIndex(0); + if (firstObject != null) { + mExecutor.add(firstObject); + mWaitingThreads.removeObjectAtIndex(0); + } + } + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/category/CategoryOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/category/CategoryOperations.java new file mode 100644 index 0000000..ceefc69 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/category/CategoryOperations.java @@ -0,0 +1,180 @@ +package javinator9889.securepass.io.database.operations.category; + +import android.content.ContentValues; +import android.util.Log; + +import net.sqlcipher.Cursor; + +import java.util.Map; + +import androidx.annotation.NonNull; +import javinator9889.securepass.data.entry.Category; +import javinator9889.securepass.io.database.DatabaseManager; +import javinator9889.securepass.io.database.operations.CommonOperations; +import javinator9889.securepass.objects.GeneralObjectContainer; +import javinator9889.securepass.objects.ObjectContainer; +import javinator9889.securepass.util.values.Constants.SQL.CATEGORY; +import javinator9889.securepass.util.values.database.CategoryFields; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + *

+ * This program 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. + *

+ * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + *

+ * Created by Javinator9889 on 31/10/2018 - APP. + */ +public class CategoryOperations extends CommonOperations implements ICategorySetOperations, + ICategoryGetOperations { + private static final String TAG = "Category Operations"; + private static final String TABLE_NAME = CATEGORY.NAME; + private static final CategoryFields ID = CategoryFields.ID; + private static final CategoryFields NAME = CategoryFields.NAME; + private static final String CATEGORY_WHERE_ID = ID.getFieldName() + "=?"; + + /** + * Available constructor, matching {@link CommonOperations#CommonOperations(DatabaseManager) + * super} one + * + * @param databaseManager instance of the {@link DatabaseManager} object + * + * @see DatabaseManager + */ + public CategoryOperations(@NonNull DatabaseManager databaseManager) { + super(databaseManager); + } + + /** + * Gets the tag for {@link Log} output - should be overridden + * + * @return String with the tag name + */ + @Override + public String getTag() { + return TAG; + } + + /** + * Gets the WHERE ID clause for using {@link #scheduleUpdateExecutor(long, ContentValues)} - + * should be overridden + * + * @return {@code String} with the WHERE clause - null if not defined + */ + @NonNull + @Override + public String getWhereId() { + return CATEGORY_WHERE_ID; + } + + /** + * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - should + * be overridden + * + * @return {@code String} with the TABLE NAME - null if not defined + */ + @NonNull + @Override + public String getTableName() { + return TABLE_NAME; + } + + /** + * Obtains the category name by using the given ID + * + * @param categoryId the category ID where obtaining the name + * + * @return {@code String} with the name + */ + @Override + public String getCategoryName(long categoryId) { + String name = null; + try (Cursor categoryCursor = get(TABLE_NAME, whereArgs(NAME.getFieldName()), + CATEGORY_WHERE_ID, whereArgs(categoryId), null, null, ID.getFieldName() + " ASC")) { + Map categoriesColumns = constructMapFromCursor(categoryCursor); + if (categoryCursor.moveToNext()) + name = categoryCursor.getString(categoriesColumns.get(NAME.getFieldName())); + } + return name; + } + + /** + * Obtains all categories' data and saves it inside a {@link GeneralObjectContainer} of {@link + * Category} + * + * @return {@code GeneralObjectContainer} of categories + * + * @see ObjectContainer + * @see Category + */ + @Override + public GeneralObjectContainer getAllCategories() { + GeneralObjectContainer categories = new ObjectContainer<>(); + try (Cursor categoriesCursor = getAll(TABLE_NAME, ID.getFieldName() + " ASC")) { + Map categoriesColumns = constructMapFromCursor(categoriesCursor); + while (categoriesCursor.moveToNext()) { + long id = categoriesCursor.getLong(categoriesColumns.get(ID.getFieldName())); + String name = categoriesCursor.getString(categoriesColumns.get(NAME.getFieldName())); + Category currentCategory = new Category(id, name); + categories.storeObject(currentCategory); + } + } + return categories; + } + + /** + * Registers a new simple category + * + * @param categoryName the name of the new category + * + * @return {@code long} with the new category ID + */ + @Override + public long registerNewCategory(@NonNull String categoryName) { + ContentValues params = setParams(categoryName); + return insertFailOnConflict(TABLE_NAME, params); + } + + /** + * Updates the category name by using the given ID + * + * @param categoryId id of the category to update + * @param categoryName new name + */ + @Override + public void updateCategoryName(long categoryId, @NonNull String categoryName) { + ContentValues params = setParams(categoryName); + scheduleUpdateExecutor(categoryId, params); + } + + /** + * Removes the hole category by the given ID + * + * @param categoryId category ID to remove + */ + @Override + public void removeCategory(long categoryId) { + int i = delete(TABLE_NAME, ID.getFieldName(), categoryId); + Log.d(TAG, "Number of rows deleted: " + i); + } + + /** + * Generates a map with the provided params + * + * @param categoryName category name + * + * @return {@code ContentValues} with the params + */ + private ContentValues setParams(@NonNull String categoryName) { + ContentValues params = new ContentValues(1); + params.put(NAME.getFieldName(), categoryName); + return params; + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/category/ICategoryGetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/category/ICategoryGetOperations.java new file mode 100644 index 0000000..48c82ca --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/category/ICategoryGetOperations.java @@ -0,0 +1,42 @@ +package javinator9889.securepass.io.database.operations.category; + +import javinator9889.securepass.data.entry.Category; +import javinator9889.securepass.objects.GeneralObjectContainer; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 31/10/2018 - APP. + */ +public interface ICategoryGetOperations { + /** + * Obtains the category name by using the given ID + * + * @param categoryId the category ID where obtaining the name + * @return {@code String} with the name + */ + String getCategoryName(long categoryId); + + /** + * Obtains all categories' data and saves it inside a {@link GeneralObjectContainer} of + * {@link Category} + * + * @return {@code GeneralObjectContainer} of categories + * @see javinator9889.securepass.objects.ObjectContainer + * @see Category + */ + GeneralObjectContainer getAllCategories(); +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/category/ICategorySetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/category/ICategorySetOperations.java new file mode 100644 index 0000000..10b73c0 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/category/ICategorySetOperations.java @@ -0,0 +1,51 @@ +package javinator9889.securepass.io.database.operations.category; + +import androidx.annotation.NonNull; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 31/10/2018 - APP. + */ +public interface ICategorySetOperations { + /** + * Registers a new simple category + * + * @param categoryName the name of the new category + * @return {@code long} with the new category ID + */ + long registerNewCategory(@NonNull String categoryName); + + /** + * Updates the category name by using the given ID + * + * @param categoryId id of the category to update + * @param categoryName new name + */ + void updateCategoryName(long categoryId, @NonNull String categoryName); + + /** + * Removes the hole category by the given ID + * + * @param categoryId category ID to remove + */ + void removeCategory(long categoryId); + + /** + * Applies pending changes to the database - only necessary when doing UPDATE operations + */ + void apply(); +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/ConfigurationOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/ConfigurationOperations.java new file mode 100644 index 0000000..776dae1 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/ConfigurationOperations.java @@ -0,0 +1,183 @@ +package javinator9889.securepass.io.database.operations.configuration; + +import android.content.ContentValues; +import android.util.Log; + +import net.sqlcipher.Cursor; + +import java.util.Map; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import javinator9889.securepass.data.configuration.Configuration; +import javinator9889.securepass.data.configuration.IConfiguration; +import javinator9889.securepass.io.database.DatabaseManager; +import javinator9889.securepass.io.database.operations.CommonOperations; +import javinator9889.securepass.objects.GeneralObjectContainer; +import javinator9889.securepass.objects.ObjectContainer; +import javinator9889.securepass.util.values.Constants; +import javinator9889.securepass.util.values.database.ConfigurationFields; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + *

+ * This program 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. + *

+ * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + *

+ * Created by Javinator9889 on 02/11/2018 - APP. + */ +public class ConfigurationOperations extends CommonOperations + implements IConfigurationSetOperations, IConfigurationGetOperations { + private static final String TAG = "Configuration Operations"; + private static final String TABLE_NAME = Constants.SQL.CONFIGURATION.NAME; + private static final ConfigurationFields ID = ConfigurationFields.ID; + private static final ConfigurationFields NAME = ConfigurationFields.NAME; + private static final String WHERE_ID = ID.getFieldName() + "=?"; + + /** + * Available constructor, matching {@link CommonOperations#CommonOperations(DatabaseManager) + * super} one + * + * @param databaseInstance instance of the {@link DatabaseManager} object + * + * @see DatabaseManager + */ + public ConfigurationOperations(@NonNull DatabaseManager databaseInstance) { + super(databaseInstance); + } + + /** + * Gets the tag for {@link Log} output - should be overridden + * + * @return String with the tag name + */ + @Override + public String getTag() { + return TAG; + } + + /** + * Gets the WHERE ID clause for using {@link #scheduleUpdateExecutor(long, ContentValues)} - + * should be overridden + * + * @return {@code String} with the WHERE clause - null if not defined + */ + @Nullable + @Override + public String getWhereId() { + return WHERE_ID; + } + + /** + * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - should + * be overridden + * + * @return {@code String} with the TABLE NAME - null if not defined + */ + @Nullable + @Override + public String getTableName() { + return TABLE_NAME; + } + + /** + * Obtains the configuration's name by using its ID + * + * @param configurationId ID of the configuration + * + * @return {@code String} with the configuration name + */ + @Override + public String getConfigurationName(long configurationId) { + String name = null; + try (Cursor configurationCursor = get(TABLE_NAME, whereArgs(NAME.getFieldName()), + WHERE_ID, whereArgs(configurationId), null, null, ID.getFieldName() + " ASC")) { + Map configurationsColumns = constructMapFromCursor(configurationCursor); + if (configurationCursor.moveToNext()) + name = configurationCursor.getString(configurationsColumns.get(NAME.getFieldName())); + } + return name; + } + + /** + * Obtains all configurations' data and saves it inside a {@link GeneralObjectContainer} of + * {@link IConfiguration} + * + * @return {@code GeneralObjectContainer} of entries + * + * @see ObjectContainer + * @see Configuration + */ + @Override + public GeneralObjectContainer getAllConfigurations() { + GeneralObjectContainer configurations = new ObjectContainer<>(); + try (Cursor configurationsCursor = getAll(TABLE_NAME, ID.getFieldName() + " ASC")) { + Map configColumns = constructMapFromCursor(configurationsCursor); + while (configurationsCursor.moveToNext()) { + long id = configurationsCursor.getLong(configColumns.get(ID.getFieldName())); + String name = configurationsCursor.getString(configColumns.get(NAME.getFieldName())); + IConfiguration currentConfiguration = new Configuration(id, name, null); + configurations.storeObject(currentConfiguration); + } + } + return configurations; + } + + /** + * Registers a new simple configuration + * + * @param configurationName new custom configuration name + * + * @return {@code long} with the new configuration ID + */ + @Override + public long registerNewConfiguration(@NonNull String configurationName) { + ContentValues params = setParams(configurationName); + return insertReplaceOnConflict(TABLE_NAME, params); + } + + /** + * Updates the configuration's name by using its ID + * + * @param configurationId ID of the configuration + * @param configurationName new configuration name + */ + @Override + public void updateConfigurationName(long configurationId, @NonNull String configurationName) { + ContentValues params = setParams(configurationName); + scheduleUpdateExecutor(configurationId, params); + } + + /** + * Removes the configuration from the DB + * + * @param configurationId ID of the configuration to delete + */ + @Override + public void removeConfiguration(long configurationId) { + delete(TABLE_NAME, ID.getFieldName(), configurationId); + } + + /** + * Generates a map with the provided params + * + * @param name configuration name + * + * @return {@code ContentValues} with the params + * + * @see ContentValues + */ + private ContentValues setParams(@NonNull String name) { + ContentValues params = new ContentValues(1); + params.put(NAME.getFieldName(), name); + return params; + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/IConfigurationGetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/IConfigurationGetOperations.java new file mode 100644 index 0000000..843bcc8 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/IConfigurationGetOperations.java @@ -0,0 +1,44 @@ +package javinator9889.securepass.io.database.operations.configuration; + +import javinator9889.securepass.data.configuration.Configuration; +import javinator9889.securepass.data.configuration.IConfiguration; +import javinator9889.securepass.objects.GeneralObjectContainer; +import javinator9889.securepass.objects.ObjectContainer; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 02/11/2018 - APP. + */ +public interface IConfigurationGetOperations { + /** + * Obtains the configuration's name by using its ID + * + * @param configurationId ID of the configuration + * @return {@code String} with the configuration name + */ + String getConfigurationName(long configurationId); + + /** + * Obtains all configurations' data and saves it inside a {@link GeneralObjectContainer} of + * {@link javinator9889.securepass.data.configuration.IConfiguration} + * + * @return {@code GeneralObjectContainer} of entries + * @see ObjectContainer + * @see Configuration + */ + GeneralObjectContainer getAllConfigurations(); +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/IConfigurationSetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/IConfigurationSetOperations.java new file mode 100644 index 0000000..fe0128a --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/IConfigurationSetOperations.java @@ -0,0 +1,54 @@ +package javinator9889.securepass.io.database.operations.configuration; + +import androidx.annotation.NonNull; +import javinator9889.securepass.errors.database.NoJobsEnqueuedError; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + *

+ * This program 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. + *

+ * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + *

+ * Created by Javinator9889 on 02/11/2018 - APP. + */ +public interface IConfigurationSetOperations { + /** + * Registers a new simple configuration + * + * @param configurationName new custom configuration name + * + * @return {@code long} with the new configuration ID + */ + long registerNewConfiguration(@NonNull String configurationName); + + /** + * Updates the configuration's name by using its ID + * + * @param configurationId ID of the configuration + * @param configurationName new configuration name + */ + void updateConfigurationName(long configurationId, @NonNull String configurationName); + + /** + * Removes the configuration from the DB + * + * @param configurationId ID of the configuration to delete + */ + void removeConfiguration(long configurationId); + + /** + * Runs the {@link com.github.javinator9889.threading.pools.ThreadsPooling} - only necessary + * when doing UPDATE operations + * + * @throws NoJobsEnqueuedError when there is no job added to the queue + */ + void apply(); +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/ConfigFieldsOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/ConfigFieldsOperations.java new file mode 100644 index 0000000..60ad91c --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/ConfigFieldsOperations.java @@ -0,0 +1,221 @@ +package javinator9889.securepass.io.database.operations.configuration.configurationfields; + +import android.content.ContentValues; +import android.util.Log; + +import net.sqlcipher.Cursor; + +import java.util.Map; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import javinator9889.securepass.data.configuration.ConfigFields; +import javinator9889.securepass.data.configuration.IConfigFields; +import javinator9889.securepass.io.database.DatabaseManager; +import javinator9889.securepass.io.database.operations.CommonOperations; +import javinator9889.securepass.objects.GeneralObjectContainer; +import javinator9889.securepass.objects.ObjectContainer; +import javinator9889.securepass.util.values.database.ConfigFieldsFields; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + *

+ * This program 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. + *

+ * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + *

+ * Created by Javinator9889 on 02/11/2018 - APP. + */ +public abstract class ConfigFieldsOperations extends CommonOperations + implements IConfigFieldsSetOperations, IConfigFieldsGetOperations { + protected static final ConfigFieldsFields ID = ConfigFieldsFields.ID; + protected static final ConfigFieldsFields DESCRIPTION = ConfigFieldsFields.DESCRIPTION; + protected static final ConfigFieldsFields ORDER = ConfigFieldsFields.ORDER; + protected static final ConfigFieldsFields CONFIGURATION = ConfigFieldsFields.CONFIGURATION; + protected static final String ORDER_BY = ID.getFieldName() + " ASC"; + private static final String WHERE_ID = ID.getFieldName() + "=?"; + + /** + * Available constructor, matching {@link CommonOperations#CommonOperations(DatabaseManager) + * super} one + * + * @param databaseInstance instance of the {@link DatabaseManager} object + * + * @see DatabaseManager + */ + protected ConfigFieldsOperations(@NonNull DatabaseManager databaseInstance) { + super(databaseInstance); + } + + /** + * Obtains the current description for the field + * + * @param id ID of the field where obtaining the data + * + * @return {@code String} with the name + */ + @Override + public String getConfigFieldDescription(long id) { + String description = null; + try (Cursor configFieldsCursor = get(getTableName(), whereArgs(DESCRIPTION.getFieldName()), + getWhereId(), whereArgs(id), null, null, ORDER_BY)) { + Map configurationsColumns = constructMapFromCursor(configFieldsCursor); + if (configFieldsCursor.moveToNext()) + description = configFieldsCursor.getString(configurationsColumns.get(DESCRIPTION.getFieldName())); + } + return description; + } + + /** + * Obtains the current field's order + * + * @param id ID of the field where obtaining the data + * + * @return {@code int} with the ordinal order + */ + @Override + public int getConfigFieldOrder(long id) { + int order = -1; + try (Cursor configFieldsCursor = get(getTableName(), whereArgs(ORDER.getFieldName()), + getWhereId(), whereArgs(id), null, null, ORDER_BY)) { + Map configurationsColumns = constructMapFromCursor(configFieldsCursor); + if (configFieldsCursor.moveToNext()) + order = configFieldsCursor.getInt(configurationsColumns.get(ORDER.getFieldName())); + } + return order; + } + + /** + * Obtains the current field's parent ID + * + * @param id ID of the field where obtaining the data + * + * @return {@code long} with the ID + */ + @Override + public long getConfigFieldConfigurationId(long id) { + long configurationId = -1; + try (Cursor configFieldsCursor = get(getTableName(), whereArgs(CONFIGURATION.getFieldName()), + getWhereId(), whereArgs(id), null, null, ORDER_BY)) { + Map configurationsColumns = constructMapFromCursor(configFieldsCursor); + if (configFieldsCursor.moveToNext()) + configurationId = configFieldsCursor.getLong(configurationsColumns.get + (CONFIGURATION.getFieldName())); + } + return configurationId; + } + + + /** + * Registers a new simple configuration field + * + * @param description field description + * @param order field order for displaying at UI + * @param configurationId parent configuration ID + * + * @return {@code long} with the new ID + */ + @Override + public long registerNewConfigField(@NonNull String description, + int order, + long configurationId) { + ContentValues params = setParams(description, order, configurationId); + return insertIgnoreOnConflict(getTableName(), params); + } + + /** + * Updates the field's description + * + * @param id ID of the field to change + * @param description new description + */ + @Override + public void updateConfigFieldDescription(long id, @NonNull String description) { + ContentValues params = new ContentValues(1); + params.put(DESCRIPTION.getFieldName(), description); + scheduleUpdateExecutor(id, params); + } + + /** + * Updates the field's order + * + * @param id ID of the field to change + * @param order new order + */ + @Override + public void updateConfigurationOrder(long id, int order) { + ContentValues params = new ContentValues(1); + params.put(ORDER.getFieldName(), order); + scheduleUpdateExecutor(id, params); + } + + /** + * Generates a map with the provided params + * + * @param description config field description + * @param order config field order + * @param configurationId config field parent configuration ID + * + * @return {@code ContentValues} with the params + * + * @see ContentValues + */ + protected ContentValues setParams(@NonNull String description, + int order, + long configurationId) { + ContentValues params = new ContentValues(3); + params.put(DESCRIPTION.getFieldName(), description); + params.put(ORDER.getFieldName(), order); + params.put(CONFIGURATION.getFieldName(), configurationId); + return params; + } + + /** + * Gets the WHERE ID clause for using {@link #scheduleUpdateExecutor(long, ContentValues)} - + * should be overridden + * + * @return {@code String} with the WHERE clause - null if not defined + */ + @Nullable + @Override + public String getWhereId() { + return WHERE_ID; + } + + /** + * Gets the tag for {@link Log} output - should be overridden + * + * @return String with the tag name + */ + @Override + public abstract String getTag(); + + /** + * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - should + * be overridden + * + * @return {@code String} with the TABLE NAME - null if not defined + */ + @Nullable + @Override + public abstract String getTableName(); + + /** + * Obtains all config fields' data and saves it inside a {@link GeneralObjectContainer} of + * {@link IConfigFields} + * + * @return {@code GeneralObjectContainer} of entries + * + * @see ObjectContainer + * @see ConfigFields + */ + @Override + public abstract GeneralObjectContainer getAllConfigFields(); +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/IConfigFieldsGetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/IConfigFieldsGetOperations.java new file mode 100644 index 0000000..3d6c0ca --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/IConfigFieldsGetOperations.java @@ -0,0 +1,59 @@ +package javinator9889.securepass.io.database.operations.configuration.configurationfields; + +import javinator9889.securepass.data.configuration.IConfigFields; +import javinator9889.securepass.objects.GeneralObjectContainer; +import javinator9889.securepass.objects.ObjectContainer; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 02/11/2018 - APP. + */ +public interface IConfigFieldsGetOperations { + /** + * Obtains the current description for the field + * + * @param id ID of the field where obtaining the data + * @return {@code String} with the name + */ + String getConfigFieldDescription(long id); + + /** + * Obtains the current field's order + * + * @param id ID of the field where obtaining the data + * @return {@code int} with the ordinal order + */ + int getConfigFieldOrder(long id); + + /** + * Obtains the current field's parent ID + * + * @param id ID of the field where obtaining the data + * @return {@code long} with the ID + */ + long getConfigFieldConfigurationId(long id); + + /** + * Obtains all config fields' data and saves it inside a {@link GeneralObjectContainer} of + * {@link IConfigFields} + * + * @return {@code GeneralObjectContainer} of entries + * @see ObjectContainer + * @see javinator9889.securepass.data.configuration.ConfigFields + */ + GeneralObjectContainer getAllConfigFields(); +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/IConfigFieldsSetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/IConfigFieldsSetOperations.java new file mode 100644 index 0000000..3772105 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/IConfigFieldsSetOperations.java @@ -0,0 +1,57 @@ +package javinator9889.securepass.io.database.operations.configuration.configurationfields; + +import androidx.annotation.NonNull; +import javinator9889.securepass.errors.database.NoJobsEnqueuedError; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + *

+ * This program 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. + *

+ * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + *

+ * Created by Javinator9889 on 02/11/2018 - APP. + */ +public interface IConfigFieldsSetOperations { + /** + * Registers a new simple configuration field + * + * @param description field description + * @param order field order for displaying at UI + * @param configurationId parent configuration ID + * + * @return {@code long} with the new ID + */ + long registerNewConfigField(@NonNull String description, int order, long configurationId); + + /** + * Updates the field's description + * + * @param id ID of the field to change + * @param description new description + */ + void updateConfigFieldDescription(long id, @NonNull String description); + + /** + * Updates the field's order + * + * @param id ID of the field to change + * @param order new order + */ + void updateConfigurationOrder(long id, int order); + + /** + * Runs the {@link com.github.javinator9889.threading.pools.ThreadsPooling} - only necessary + * when doing UPDATE operations + * + * @throws NoJobsEnqueuedError when there is no job added to the queue + */ + void apply(); +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/imagesconfig/ImagesConfigOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/imagesconfig/ImagesConfigOperations.java new file mode 100644 index 0000000..223ad10 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/imagesconfig/ImagesConfigOperations.java @@ -0,0 +1,103 @@ +package javinator9889.securepass.io.database.operations.configuration.configurationfields.imagesconfig; + +import android.content.ContentValues; +import android.util.Log; + +import net.sqlcipher.Cursor; + +import java.util.Map; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import javinator9889.securepass.data.configuration.IConfigFields; +import javinator9889.securepass.data.configuration.ImagesConfig; +import javinator9889.securepass.io.database.DatabaseManager; +import javinator9889.securepass.io.database.operations.CommonOperations; +import javinator9889.securepass.io.database.operations.configuration.configurationfields.ConfigFieldsOperations; +import javinator9889.securepass.objects.GeneralObjectContainer; +import javinator9889.securepass.objects.ObjectContainer; +import javinator9889.securepass.util.values.Constants; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + *

+ * This program 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. + *

+ * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + *

+ * Created by Javinator9889 on 02/11/2018 - APP. + */ +public class ImagesConfigOperations extends ConfigFieldsOperations { + private static final String TAG = "ImagesConfig Operations"; + private static final String TABLE_NAME = Constants.SQL.IMAGES_CONFIG.NAME; + + /** + * Available constructor, matching {@link CommonOperations#CommonOperations(DatabaseManager) + * super} one + * + * @param databaseInstance instance of the {@link DatabaseManager} object + * + * @see DatabaseManager + */ + public ImagesConfigOperations(@NonNull DatabaseManager databaseInstance) { + super(databaseInstance); + } + + /** + * Gets the tag for {@link Log} output - should be overridden + * + * @return String with the tag name + */ + @Override + public String getTag() { + return TAG; + } + + /** + * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - should + * be overridden + * + * @return {@code String} with the TABLE NAME - null if not defined + */ + @Nullable + @Override + public String getTableName() { + return TABLE_NAME; + } + + /** + * Obtains all config fields' data and saves it inside a {@link GeneralObjectContainer} of + * {@link IConfigFields} + * + * @return {@code GeneralObjectContainer} of entries + * + * @see ObjectContainer + * @see javinator9889.securepass.data.configuration.ImagesConfig + */ + @Override + public GeneralObjectContainer getAllConfigFields() { + GeneralObjectContainer configFields = new ObjectContainer<>(); + try (Cursor imagesConfigCursor = getAll(TABLE_NAME, ORDER_BY)) { + Map imagesConfigColumns = constructMapFromCursor(imagesConfigCursor); + while (imagesConfigCursor.moveToNext()) { + long id = imagesConfigCursor.getLong(imagesConfigColumns.get(ID.getFieldName())); + String description = imagesConfigCursor.getString( + imagesConfigColumns.get(DESCRIPTION.getFieldName())); + int sortOrder = + imagesConfigCursor.getInt(imagesConfigColumns.get(ORDER.getFieldName())); + long configId = imagesConfigCursor.getLong( + imagesConfigColumns.get(CONFIGURATION.getFieldName())); + IConfigFields currentField = new ImagesConfig(id, description, sortOrder, configId); + configFields.storeObject(currentField); + } + } + return configFields; + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/longtextconfig/LongTextConfigOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/longtextconfig/LongTextConfigOperations.java new file mode 100644 index 0000000..5bd9520 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/longtextconfig/LongTextConfigOperations.java @@ -0,0 +1,104 @@ +package javinator9889.securepass.io.database.operations.configuration.configurationfields.longtextconfig; + +import android.content.ContentValues; +import android.util.Log; + +import net.sqlcipher.Cursor; + +import java.util.Map; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import javinator9889.securepass.data.configuration.IConfigFields; +import javinator9889.securepass.data.configuration.LongTextConfig; +import javinator9889.securepass.io.database.DatabaseManager; +import javinator9889.securepass.io.database.operations.CommonOperations; +import javinator9889.securepass.io.database.operations.configuration.configurationfields.ConfigFieldsOperations; +import javinator9889.securepass.objects.GeneralObjectContainer; +import javinator9889.securepass.objects.ObjectContainer; +import javinator9889.securepass.util.values.Constants; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + *

+ * This program 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. + *

+ * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + *

+ * Created by Javinator9889 on 02/11/2018 - APP. + */ +public class LongTextConfigOperations extends ConfigFieldsOperations { + private static final String TAG = "LongTextConfig Operations"; + private static final String TABLE_NAME = Constants.SQL.LONG_TEXT_CONFIG.NAME; + + /** + * Available constructor, matching {@link CommonOperations#CommonOperations(DatabaseManager) + * super} one + * + * @param databaseInstance instance of the {@link DatabaseManager} object + * + * @see DatabaseManager + */ + public LongTextConfigOperations(@NonNull DatabaseManager databaseInstance) { + super(databaseInstance); + } + + /** + * Gets the tag for {@link Log} output - should be overridden + * + * @return String with the tag name + */ + @Override + public String getTag() { + return TAG; + } + + /** + * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - should + * be overridden + * + * @return {@code String} with the TABLE NAME - null if not defined + */ + @Nullable + @Override + public String getTableName() { + return TABLE_NAME; + } + + /** + * Obtains all config fields' data and saves it inside a {@link GeneralObjectContainer} of + * {@link IConfigFields} + * + * @return {@code GeneralObjectContainer} of entries + * + * @see ObjectContainer + * @see javinator9889.securepass.data.configuration.LongTextConfig + */ + @Override + public GeneralObjectContainer getAllConfigFields() { + GeneralObjectContainer configFields = new ObjectContainer<>(); + try (Cursor longTextConfigCursor = getAll(TABLE_NAME, ORDER_BY)) { + Map longTextColumns = constructMapFromCursor(longTextConfigCursor); + while (longTextConfigCursor.moveToNext()) { + long id = longTextConfigCursor.getLong(longTextColumns.get(ID.getFieldName())); + String description = longTextConfigCursor.getString( + longTextColumns.get(DESCRIPTION.getFieldName())); + int sortOrder = + longTextConfigCursor.getInt(longTextColumns.get(ORDER.getFieldName())); + long configId = longTextConfigCursor.getLong( + longTextColumns.get(CONFIGURATION.getFieldName())); + IConfigFields currentField = + new LongTextConfig(id, description, sortOrder, configId); + configFields.storeObject(currentField); + } + } + return configFields; + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/passconfig/PassConfigOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/passconfig/PassConfigOperations.java new file mode 100644 index 0000000..19b0452 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/passconfig/PassConfigOperations.java @@ -0,0 +1,103 @@ +package javinator9889.securepass.io.database.operations.configuration.configurationfields.passconfig; + +import android.content.ContentValues; +import android.util.Log; + +import net.sqlcipher.Cursor; + +import java.util.Map; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import javinator9889.securepass.data.configuration.IConfigFields; +import javinator9889.securepass.data.configuration.PassConfig; +import javinator9889.securepass.io.database.DatabaseManager; +import javinator9889.securepass.io.database.operations.CommonOperations; +import javinator9889.securepass.io.database.operations.configuration.configurationfields.ConfigFieldsOperations; +import javinator9889.securepass.objects.GeneralObjectContainer; +import javinator9889.securepass.objects.ObjectContainer; +import javinator9889.securepass.util.values.Constants; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + *

+ * This program 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. + *

+ * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + *

+ * Created by Javinator9889 on 02/11/2018 - APP. + */ +public class PassConfigOperations extends ConfigFieldsOperations { + private static final String TAG = "PassConfig Operations"; + private static final String TABLE_NAME = Constants.SQL.PASS_CONFIG.NAME; + + /** + * Available constructor, matching {@link CommonOperations#CommonOperations(DatabaseManager) + * super} one + * + * @param databaseInstance instance of the {@link DatabaseManager} object + * + * @see DatabaseManager + */ + public PassConfigOperations(@NonNull DatabaseManager databaseInstance) { + super(databaseInstance); + } + + /** + * Gets the tag for {@link Log} output - should be overridden + * + * @return String with the tag name + */ + @Override + public String getTag() { + return TAG; + } + + /** + * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - should + * be overridden + * + * @return {@code String} with the TABLE NAME - null if not defined + */ + @Nullable + @Override + public String getTableName() { + return TABLE_NAME; + } + + /** + * Obtains all config fields' data and saves it inside a {@link GeneralObjectContainer} of + * {@link IConfigFields} + * + * @return {@code GeneralObjectContainer} of entries + * + * @see ObjectContainer + * @see javinator9889.securepass.data.configuration.PassConfig + */ + @Override + public GeneralObjectContainer getAllConfigFields() { + GeneralObjectContainer configFields = new ObjectContainer<>(); + try (Cursor passConfigsCursor = getAll(TABLE_NAME, ORDER_BY)) { + Map passConfigColumns = constructMapFromCursor(passConfigsCursor); + while (passConfigsCursor.moveToNext()) { + long id = passConfigsCursor.getLong(passConfigColumns.get(ID.getFieldName())); + String description = passConfigsCursor.getString( + passConfigColumns.get(DESCRIPTION.getFieldName())); + int order = passConfigsCursor.getInt(passConfigColumns.get(ORDER.getFieldName())); + long configurationId = passConfigsCursor.getLong( + passConfigColumns.get(CONFIGURATION.getFieldName())); + IConfigFields currentConfigField = + new PassConfig(id, description, order, configurationId); + configFields.storeObject(currentConfigField); + } + } + return configFields; + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/smalltextconfig/SmallTextConfigOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/smalltextconfig/SmallTextConfigOperations.java new file mode 100644 index 0000000..6a95456 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/smalltextconfig/SmallTextConfigOperations.java @@ -0,0 +1,105 @@ +package javinator9889.securepass.io.database.operations.configuration.configurationfields.smalltextconfig; + +import android.content.ContentValues; +import android.util.Log; + +import net.sqlcipher.Cursor; + +import java.util.Map; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import javinator9889.securepass.data.configuration.IConfigFields; +import javinator9889.securepass.data.configuration.SmallTextConfig; +import javinator9889.securepass.io.database.DatabaseManager; +import javinator9889.securepass.io.database.operations.CommonOperations; +import javinator9889.securepass.io.database.operations.configuration.configurationfields.ConfigFieldsOperations; +import javinator9889.securepass.objects.GeneralObjectContainer; +import javinator9889.securepass.objects.ObjectContainer; +import javinator9889.securepass.util.values.Constants; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + *

+ * This program 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. + *

+ * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + *

+ * Created by Javinator9889 on 02/11/2018 - APP. + */ +public class SmallTextConfigOperations extends ConfigFieldsOperations { + private static final String TAG = "SmallTextConfig Operations"; + private static final String TABLE_NAME = Constants.SQL.IMAGES_CONFIG.NAME; + + /** + * Available constructor, matching {@link CommonOperations#CommonOperations(DatabaseManager) + * super} one + * + * @param databaseInstance instance of the {@link DatabaseManager} object + * + * @see DatabaseManager + */ + public SmallTextConfigOperations(@NonNull DatabaseManager databaseInstance) { + super(databaseInstance); + } + + /** + * Gets the tag for {@link Log} output - should be overridden + * + * @return String with the tag name + */ + @Override + public String getTag() { + return TAG; + } + + /** + * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - should + * be overridden + * + * @return {@code String} with the TABLE NAME - null if not defined + */ + @Nullable + @Override + public String getTableName() { + return TABLE_NAME; + } + + /** + * Obtains all config fields' data and saves it inside a {@link GeneralObjectContainer} of + * {@link IConfigFields} + * + * @return {@code GeneralObjectContainer} of entries + * + * @see ObjectContainer + * @see javinator9889.securepass.data.configuration.SmallTextConfig + */ + @Override + public GeneralObjectContainer getAllConfigFields() { + GeneralObjectContainer configFields = new ObjectContainer<>(); + try (Cursor smallTextConfigCursor = getAll(TABLE_NAME, ORDER_BY)) { + Map smallTextColumns = constructMapFromCursor(smallTextConfigCursor); + while (smallTextConfigCursor.moveToNext()) { + long id = smallTextConfigCursor.getLong(smallTextColumns.get(ID.getFieldName())); + String description = + smallTextConfigCursor.getString( + smallTextColumns.get(DESCRIPTION.getFieldName())); + int sortOrder = + smallTextConfigCursor.getInt(smallTextColumns.get(ORDER.getFieldName())); + long configId = smallTextConfigCursor.getLong( + smallTextColumns.get(CONFIGURATION.getFieldName())); + IConfigFields currentField = + new SmallTextConfig(id, description, sortOrder, configId); + configFields.storeObject(currentField); + } + } + return configFields; + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/EntryOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/EntryOperations.java new file mode 100644 index 0000000..33daddf --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/EntryOperations.java @@ -0,0 +1,315 @@ +package javinator9889.securepass.io.database.operations.entry; + +import android.content.ContentValues; + +import net.sqlcipher.Cursor; + +import java.util.Map; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import javinator9889.securepass.data.configuration.Configuration; +import javinator9889.securepass.data.entry.Category; +import javinator9889.securepass.data.entry.Entry; +import javinator9889.securepass.io.database.DatabaseManager; +import javinator9889.securepass.io.database.operations.CommonOperations; +import javinator9889.securepass.objects.GeneralObjectContainer; +import javinator9889.securepass.objects.ObjectContainer; +import javinator9889.securepass.util.values.Constants.SQL.ENTRY; +import javinator9889.securepass.util.values.database.EntryFields; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + *

+ * This program 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. + *

+ * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + *

+ * Created by Javinator9889 on 28/10/2018 - APP. + */ +public class EntryOperations extends CommonOperations implements + IEntrySetOperations, IEntryGetOperations { + private static final String TAG = "Entry Operations"; + private static final String TABLE_NAME = ENTRY.NAME; + private static final EntryFields NAME = EntryFields.NAME; + private static final EntryFields ID = EntryFields.ID; + private static final EntryFields ICON = EntryFields.ICON; + private static final EntryFields CATEGORY = EntryFields.CATEGORY; + private static final EntryFields CONFIGURATION = EntryFields.CONFIGURATION; + private static final String ENTRY_WHERE_ID = ID.getFieldName() + "=?"; + + /** + * Available constructor, matching {@link CommonOperations#CommonOperations(DatabaseManager) + * super} one + * + * @param databaseManager instance of the {@link DatabaseManager} object + * + * @see DatabaseManager + */ + public EntryOperations(@NonNull DatabaseManager databaseManager) { + super(databaseManager); + } + + /** + * {@inheritDoc} + */ + @Override + public String getTag() { + return TAG; + } + + /** + * Gets the WHERE ID clause for using {@link #scheduleUpdateExecutor(long, ContentValues)} - + * should be overridden + * + * @return {@code String} with the WHERE clause - null if not defined + */ + @NonNull + @Override + public String getWhereId() { + return ENTRY_WHERE_ID; + } + + /** + * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - should + * be overridden + * + * @return {@code String} with the TABLE NAME - null if not defined + */ + @NonNull + @Override + public String getTableName() { + return TABLE_NAME; + } + + /** + * Registers a new simple entry + * + * @param parentCategoryId category ID + * @param configId configuration ID + * @param entryName entry name + * @param icon entry icon + * + * @return long with the new entry ID + * + * @see Category + * @see Configuration + */ + @Override + public long registerNewEntry(long parentCategoryId, + long configId, + @NonNull String entryName, + @NonNull String icon) { + ContentValues params = setParams(entryName, icon, parentCategoryId, configId); + return insertReplaceOnConflict(TABLE_NAME, params); + } + + /** + * Updates entry name + * + * @param entryId entry ID + * @param name new name + */ + @Override + public void updateName(long entryId, + @NonNull String name) { + ContentValues params = new ContentValues(1); + params.put(NAME.getFieldName(), name); + scheduleUpdateExecutor(entryId, params); + } + + /** + * Updates entry icon + * + * @param entryId entry ID + * @param icon new icon + */ + @Override + public void updateIcon(long entryId, + @NonNull String icon) { + ContentValues params = new ContentValues(1); + params.put(ICON.getFieldName(), icon); + scheduleUpdateExecutor(entryId, params); + } + + /** + * Updates entry category + * + * @param entryId entry ID + * @param categoryId new category ID + */ + @Override + public void updateCategory(long entryId, + long categoryId) { + ContentValues params = new ContentValues(1); + params.put(CATEGORY.getFieldName(), categoryId); + scheduleUpdateExecutor(entryId, params); + } + + /** + * Updates entry configuration + * + * @param entryId entry ID + * @param configurationId new configuration ID + */ + @Override + public void updateConfiguration(long entryId, + long configurationId) { + ContentValues params = new ContentValues(1); + params.put(CONFIGURATION.getFieldName(), configurationId); + scheduleUpdateExecutor(entryId, params); + } + + /** + * Removes the hole entry by the given ID + * + * @param entryId entry ID + */ + @Override + public void removeEntry(long entryId) { + delete(TABLE_NAME, ID.getFieldName(), entryId); + } + + /** + * Generates a map with the provided params + * + * @param entryName entry name + * @param entryIcon entry icon + * @param categoryId category ID + * @param configurationId configuration ID + * + * @return {@code ContentValues} with the params + * + * @see ContentValues + */ + private ContentValues setParams(@NonNull String entryName, + @NonNull String entryIcon, + long categoryId, + long configurationId) { + ContentValues params = new ContentValues(4); + params.put(NAME.getFieldName(), entryName); + params.put(ICON.getFieldName(), entryIcon); + params.put(CATEGORY.getFieldName(), categoryId); + params.put(CONFIGURATION.getFieldName(), configurationId); + return params; + } + + /** + * Obtains the entry name by using the given ID + * + * @param entryId entry ID + * + * @return {@code String} with the entry name - null if ID does not exist + */ + @Override + @Nullable + public String getEntryName(long entryId) { + String name = null; + try (Cursor entryCursor = get(TABLE_NAME, whereArgs(NAME.getFieldName()), ENTRY_WHERE_ID, + whereArgs(entryId), null, null, ID.getFieldName() + " ASC")) { + Map entryColumns = constructMapFromCursor(entryCursor); + if (entryCursor.moveToNext()) + name = entryCursor.getString(entryColumns.get(NAME.getFieldName())); + } + return name; + } + + /** + * Obtains the entry icon by using the given ID + * + * @param entryId entry ID + * + * @return {@code String} with the entry icon - null if ID does not exist + */ + @Override + @Nullable + public String getEntryIcon(long entryId) { + String icon = null; + try (Cursor iconCursor = get(TABLE_NAME, whereArgs(ICON.getFieldName()), ENTRY_WHERE_ID, + whereArgs(entryId), null, null, ID.getFieldName() + " ASC")) { + Map iconColumns = constructMapFromCursor(iconCursor); + if (iconCursor.moveToNext()) + icon = iconCursor.getString(iconColumns.get(ICON.getFieldName())); + } + return icon; + } + + /** + * Obtains the entry parent category by using the given ID + * + * @param entryId entry ID + * + * @return {@code long} with the category ID - 0 if ID does not exist + * + * @see Category + */ + @Override + public long getEntryCategory(long entryId) { + long id = 0; + try (Cursor categoryCursor = get(TABLE_NAME, whereArgs(CATEGORY.getFieldName()), + ENTRY_WHERE_ID, whereArgs(entryId), null, null, + ID.getFieldName() + " ASC")) { + Map categoryColumns = constructMapFromCursor(categoryCursor); + if (categoryCursor.moveToNext()) + id = categoryCursor.getLong(categoryColumns.get(CATEGORY.getFieldName())); + } + return id; + } + + /** + * Obtains the entry configuration by using the given ID + * + * @param entryId entry ID + * + * @return {@code long} with the configuration ID - 0 if ID does not exist + * + * @see Configuration + */ + @Override + public long getEntryConfiguration(long entryId) { + long id = 0; + try (Cursor configCursor = get(TABLE_NAME, whereArgs(CONFIGURATION.getFieldName()), + ENTRY_WHERE_ID, whereArgs(entryId), null, null, + ID.getFieldName() + " ASC")) { + Map configColumns = constructMapFromCursor(configCursor); + if (configCursor.moveToNext()) + id = configCursor.getLong(configColumns.get(CONFIGURATION.getFieldName())); + } + return id; + } + + /** + * Obtains all entries' data and saves it inside a {@link GeneralObjectContainer} of {@link + * Entry} + * + * @return {@code GeneralObjectContainer} of entries + * + * @see ObjectContainer + * @see Entry + */ + @Override + public GeneralObjectContainer getAllEntries() { + GeneralObjectContainer entries = new ObjectContainer<>(); + try (Cursor entriesCursor = getAll(TABLE_NAME, ID.getFieldName() + " ASC")) { + Map entriesColumns = constructMapFromCursor(entriesCursor); + while (entriesCursor.moveToNext()) { + long id = entriesCursor.getLong(entriesColumns.get(ID.getFieldName())); + String name = entriesCursor.getString(entriesColumns.get(NAME.getFieldName())); + String icon = entriesCursor.getString(entriesColumns.get(ICON.getFieldName())); + long categoryId = entriesCursor.getLong(entriesColumns.get(CATEGORY.getFieldName())); + long configurationId = + entriesCursor.getLong(entriesColumns.get(CONFIGURATION.getFieldName())); + Entry currentEntry = new Entry(id, name, icon, categoryId, configurationId); + entries.storeObject(currentEntry); + } + } + return entries; + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/IEntryGetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/IEntryGetOperations.java new file mode 100644 index 0000000..76e981a --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/IEntryGetOperations.java @@ -0,0 +1,68 @@ +package javinator9889.securepass.io.database.operations.entry; + +import javinator9889.securepass.data.entry.Entry; +import javinator9889.securepass.objects.GeneralObjectContainer; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 28/10/2018 - APP. + */ +public interface IEntryGetOperations { + /** + * Obtains the entry name by using the given ID + * + * @param entryId entry ID + * @return {@code String} with the entry name + */ + String getEntryName(long entryId); + + /** + * Obtains the entry icon by using the given ID + * + * @param entryId entry ID + * @return {@code String} with the entry icon + */ + String getEntryIcon(long entryId); + + /** + * Obtains the entry parent category by using the given ID + * + * @param entryId entry ID + * @return {@code long} with the category ID + * @see javinator9889.securepass.data.entry.Category + */ + long getEntryCategory(long entryId); + + /** + * Obtains the entry configuration by using the given ID + * + * @param entryId entry ID + * @return {@code long} with the configuration ID + * @see javinator9889.securepass.data.configuration.Configuration + */ + long getEntryConfiguration(long entryId); + + /** + * Obtains all entries' data and saves it inside a {@link GeneralObjectContainer} of + * {@link Entry} + * + * @return {@code GeneralObjectContainer} of entries + * @see javinator9889.securepass.objects.ObjectContainer + * @see Entry + */ + GeneralObjectContainer getAllEntries(); +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/IEntrySetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/IEntrySetOperations.java new file mode 100644 index 0000000..65799ca --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/IEntrySetOperations.java @@ -0,0 +1,81 @@ +package javinator9889.securepass.io.database.operations.entry; + +import androidx.annotation.NonNull; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 28/10/2018 - APP. + */ +public interface IEntrySetOperations { + /** + * Registers a new simple entry + * + * @param parentCategoryId category ID + * @param configId configuration ID + * @param entryName entry name + * @param icon entry icon + * @return long with the new entry ID + * @see javinator9889.securepass.data.entry.Category + * @see javinator9889.securepass.data.configuration.Configuration + */ + long registerNewEntry(long parentCategoryId, long configId, @NonNull String entryName, + @NonNull String icon); + + /** + * Updates entry name + * + * @param entryId entry ID + * @param name new name + */ + void updateName(long entryId, @NonNull String name); + + /** + * Updates entry icon + * + * @param entryId entry ID + * @param icon new icon + */ + void updateIcon(long entryId, @NonNull String icon); + + /** + * Updates entry category + * + * @param entryId entry ID + * @param categoryId new category ID + */ + void updateCategory(long entryId, long categoryId); + + /** + * Updates entry configuration + * + * @param entryId entry ID + * @param configurationId new configuration ID + */ + void updateConfiguration(long entryId, long configurationId); + + /** + * Removes the hole entry by the given ID + * + * @param entryId entry ID + */ + void removeEntry(long entryId); + + /** + * Applies pending changes to the database - only necessary when doing UPDATE operations + */ + void apply(); +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/image/IImageGetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/image/IImageGetOperations.java new file mode 100644 index 0000000..3f46bbb --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/image/IImageGetOperations.java @@ -0,0 +1,66 @@ +package javinator9889.securepass.io.database.operations.entry.image; + +import javinator9889.securepass.data.entry.fields.Image; +import javinator9889.securepass.objects.GeneralObjectContainer; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 02/11/2018 - APP. + */ +public interface IImageGetOperations { + /** + * Obtains the image source by its ID + * + * @param imageId ID of the image to get the source + * @return {@code String} with the source + */ + String getImageSource(long imageId); + + /** + * Obtains the image description by its ID + * + * @param imageId ID of the image to get the description + * @return {@code String} with the description + */ + String getImageDescription(long imageId); + + /** + * Obtains the image order by its ID + * + * @param imageId ID of the image to get the order + * @return {@code int} with the ordinal order + */ + int getImageOrder(long imageId); + + /** + * Obtains the image parent entry ID + * + * @param imageId ID of the image to get the parent entry ID + * @return {@code long} with the entry ID + */ + long getImageEntryId(long imageId); + + /** + * Obtains all images' data and saves it inside a {@link GeneralObjectContainer} of + * {@link Image} + * + * @return {@code GeneralObjectContainer} of entries + * @see javinator9889.securepass.objects.ObjectContainer + * @see Image + */ + GeneralObjectContainer getAllImages(); +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/image/IImageSetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/image/IImageSetOperations.java new file mode 100644 index 0000000..171c70f --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/image/IImageSetOperations.java @@ -0,0 +1,74 @@ +package javinator9889.securepass.io.database.operations.entry.image; + +import androidx.annotation.NonNull; +import javinator9889.securepass.errors.database.NoJobsEnqueuedError; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + *

+ * This program 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. + *

+ * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + *

+ * Created by Javinator9889 on 02/11/2018 - APP. + */ +public interface IImageSetOperations { + /** + * Registers a new simple image + * + * @param source image source + * @param description image description + * @param order ordinal order when showing on UI + * @param entryId parent entry ID + * + * @return {@code long} with the new image ID + */ + long registerNewImage(@NonNull String source, @NonNull String description, int order, + long entryId); + + /** + * Updates the image source of the provided ID + * + * @param imageId ID of the image to change source + * @param newSource new source + */ + void updateImageSource(long imageId, @NonNull String newSource); + + /** + * Updates the image description of the provided ID + * + * @param imageId ID of the image to change description + * @param newDescription new description + */ + void updateImageDescription(long imageId, @NonNull String newDescription); + + /** + * Updates the image order of the provided ID + * + * @param imageId ID of the image to change order + * @param newOrder new ordinal order + */ + void updateImageOrder(long imageId, int newOrder); + + /** + * Removes the image by its ID + * + * @param imageId ID of the image to delete + */ + void removeImage(long imageId); + + /** + * Runs the {@link com.github.javinator9889.threading.pools.ThreadsPooling} - only necessary + * when doing UPDATE operations + * + * @throws NoJobsEnqueuedError when there is no job added to the queue + */ + void apply(); +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/image/ImageOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/image/ImageOperations.java new file mode 100644 index 0000000..b268b40 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/image/ImageOperations.java @@ -0,0 +1,286 @@ +package javinator9889.securepass.io.database.operations.entry.image; + +import android.content.ContentValues; +import android.util.Log; + +import net.sqlcipher.Cursor; + +import java.util.Map; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import javinator9889.securepass.data.entry.fields.Image; +import javinator9889.securepass.io.database.DatabaseManager; +import javinator9889.securepass.io.database.operations.CommonOperations; +import javinator9889.securepass.objects.GeneralObjectContainer; +import javinator9889.securepass.objects.ObjectContainer; +import javinator9889.securepass.util.values.Constants; +import javinator9889.securepass.util.values.database.ImageFields; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + *

+ * This program 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. + *

+ * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + *

+ * Created by Javinator9889 on 02/11/2018 - APP. + */ +public class ImageOperations extends CommonOperations implements IImageSetOperations, + IImageGetOperations { + private static final String TAG = "Image Operations"; + private static final String TABLE_NAME = Constants.SQL.IMAGE.NAME; + private static final ImageFields ID = ImageFields.ID; + private static final ImageFields SOURCE = ImageFields.SOURCE; + private static final ImageFields DESCRIPTION = ImageFields.DESCRIPTION; + private static final ImageFields ORDER = ImageFields.ORDER; + private static final ImageFields ENTRY = ImageFields.ENTRY; + private static final String WHERE_ID = ID.getFieldName() + "=?"; + + /** + * Available constructor, matching {@link CommonOperations#CommonOperations(DatabaseManager) + * super} one + * + * @param databaseInstance instance of the {@link DatabaseManager} object + * + * @see DatabaseManager + */ + public ImageOperations(@NonNull DatabaseManager databaseInstance) { + super(databaseInstance); + } + + /** + * Gets the tag for {@link Log} output - should be overridden + * + * @return String with the tag name + */ + @Override + public String getTag() { + return TAG; + } + + /** + * Gets the WHERE ID clause for using {@link #scheduleUpdateExecutor(long, ContentValues)} - + * should be overridden + * + * @return {@code String} with the WHERE clause - null if not defined + */ + @Nullable + @Override + public String getWhereId() { + return WHERE_ID; + } + + /** + * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - should + * be overridden + * + * @return {@code String} with the TABLE NAME - null if not defined + */ + @Nullable + @Override + public String getTableName() { + return TABLE_NAME; + } + + /** + * Obtains the image source by its ID + * + * @param imageId ID of the image to get the source + * + * @return {@code String} with the source + */ + @Override + public String getImageSource(long imageId) { + String source = null; + try (Cursor imagesCursor = get(TABLE_NAME, whereArgs(SOURCE.getFieldName()), WHERE_ID, + whereArgs(imageId), null, null, ID.getFieldName() + " ASC")) { + Map imagesColumns = constructMapFromCursor(imagesCursor); + if (imagesCursor.moveToNext()) + source = imagesCursor.getString(imagesColumns.get(SOURCE.getFieldName())); + } + return source; + } + + /** + * Obtains the image description by its ID + * + * @param imageId ID of the image to get the description + * + * @return {@code String} with the description + */ + @Override + public String getImageDescription(long imageId) { + String description = null; + try (Cursor imagesCursor = get(TABLE_NAME, whereArgs(DESCRIPTION.getFieldName()), WHERE_ID, + whereArgs(imageId), null, null, ID.getFieldName() + " ASC")) { + Map imagesColumns = constructMapFromCursor(imagesCursor); + if (imagesCursor.moveToNext()) + description = imagesCursor.getString(imagesColumns.get(DESCRIPTION.getFieldName())); + } + return description; + } + + /** + * Obtains the image order by its ID + * + * @param imageId ID of the image to get the order + * + * @return {@code int} with the ordinal order + */ + @Override + public int getImageOrder(long imageId) { + int order = -1; + try (Cursor imagesCursor = get(TABLE_NAME, whereArgs(ORDER.getFieldName()), WHERE_ID, + whereArgs(imageId), null, null, ID.getFieldName() + " ASC")) { + Map imagesColumns = constructMapFromCursor(imagesCursor); + if (imagesCursor.moveToNext()) + order = imagesCursor.getInt(imagesColumns.get(ORDER.getFieldName())); + } + return order; + } + + /** + * Obtains the image parent entry ID + * + * @param imageId ID of the image to get the parent entry ID + * + * @return {@code long} with the entry ID + */ + @Override + public long getImageEntryId(long imageId) { + long entryId = -1; + try (Cursor imagesCursor = get(TABLE_NAME, whereArgs(ENTRY.getFieldName()), WHERE_ID, + whereArgs(imageId), null, null, ID.getFieldName() + " ASC")) { + Map imagesColumns = constructMapFromCursor(imagesCursor); + if (imagesCursor.moveToNext()) + entryId = imagesCursor.getLong(imagesColumns.get(ENTRY.getFieldName())); + } + return entryId; + } + + /** + * Obtains all images' data and saves it inside a {@link GeneralObjectContainer} of {@link + * Image} + * + * @return {@code GeneralObjectContainer} of entries + * + * @see ObjectContainer + * @see Image + */ + @Override + public GeneralObjectContainer getAllImages() { + GeneralObjectContainer images = new ObjectContainer<>(); + try (Cursor imagesCursor = getAll(TABLE_NAME, ID.getFieldName() + " ASC")) { + Map imagesColumns = constructMapFromCursor(imagesCursor); + while (imagesCursor.moveToNext()) { + long id = imagesCursor.getLong(imagesColumns.get(ID.getFieldName())); + long entryId = imagesCursor.getLong(imagesColumns.get(ENTRY.getFieldName())); + String source = imagesCursor.getString(imagesColumns.get(SOURCE.getFieldName())); + String description = imagesCursor.getString(imagesColumns.get(DESCRIPTION.getFieldName())); + Image currentImage = new Image(id, entryId, source, description); + images.storeObject(currentImage); + } + } + return images; + } + + /** + * Registers a new simple image + * + * @param source image source + * @param description image description + * @param order ordinal order when showing on UI + * @param entryId parent entry ID + * + * @return {@code long} with the new image ID + */ + @Override + public long registerNewImage(@NonNull String source, + @NonNull String description, + int order, + long entryId) { + ContentValues params = setParams(source, description, order, entryId); + return insertReplaceOnConflict(TABLE_NAME, params); + } + + /** + * Updates the image source of the provided ID + * + * @param imageId ID of the image to change source + * @param newSource new source + */ + @Override + public void updateImageSource(long imageId, @NonNull String newSource) { + ContentValues params = new ContentValues(1); + params.put(SOURCE.getFieldName(), newSource); + scheduleUpdateExecutor(imageId, params); + } + + /** + * Updates the image description of the provided ID + * + * @param imageId ID of the image to change description + * @param newDescription new description + */ + @Override + public void updateImageDescription(long imageId, @NonNull String newDescription) { + ContentValues params = new ContentValues(1); + params.put(DESCRIPTION.getFieldName(), newDescription); + scheduleUpdateExecutor(imageId, params); + } + + /** + * Updates the image order of the provided ID + * + * @param imageId ID of the image to change order + * @param newOrder new ordinal order + */ + @Override + public void updateImageOrder(long imageId, int newOrder) { + ContentValues params = new ContentValues(1); + params.put(ORDER.getFieldName(), newOrder); + scheduleUpdateExecutor(imageId, params); + } + + /** + * Removes the image by its ID + * + * @param imageId ID of the image to delete + */ + @Override + public void removeImage(long imageId) { + delete(TABLE_NAME, ID.getFieldName(), imageId); + } + + /** + * Generates a map with the provided params + * + * @param source image source + * @param description image description + * @param order ordinal order + * @param entryId entry ID + * + * @return {@code ContentValues} with the params + * + * @see ContentValues + */ + private ContentValues setParams(@NonNull String source, + @NonNull String description, + int order, + long entryId) { + ContentValues params = new ContentValues(4); + params.put(SOURCE.getFieldName(), source); + params.put(DESCRIPTION.getFieldName(), description); + params.put(ORDER.getFieldName(), order); + params.put(ENTRY.getFieldName(), entryId); + return params; + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/password/IPasswordGetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/password/IPasswordGetOperations.java new file mode 100644 index 0000000..7c10e2f --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/password/IPasswordGetOperations.java @@ -0,0 +1,66 @@ +package javinator9889.securepass.io.database.operations.entry.password; + +import javinator9889.securepass.data.entry.fields.Password; +import javinator9889.securepass.objects.GeneralObjectContainer; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 01/11/2018 - APP. + */ +public interface IPasswordGetOperations { + /** + * Obtains the stored password + * + * @param passwordId ID of the password in the DB + * @return {@code String} with the password + */ + String getPasswordPassword(long passwordId); + + /** + * Obtains the password description + * + * @param passwordId ID of the password in DB + * @return {@code String} with the description + */ + String getPasswordDescription(long passwordId); + + /** + * Obtains the password ordinal order + * + * @param passwordId ID of the password in DB + * @return {@code int} with the order + */ + int getPasswordOrder(long passwordId); + + /** + * Obtains the password parent entry ID + * + * @param passwordId ID of the password in DB + * @return {@code long} with the entry ID + */ + long getPasswordEntryId(long passwordId); + + /** + * Obtains all passwords' data and saves it inside a {@link GeneralObjectContainer} of + * {@link Password} + * + * @return {@code GeneralObjectContainer} of entries + * @see javinator9889.securepass.objects.ObjectContainer + * @see Password + */ + GeneralObjectContainer getAllPasswords(); +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/password/IPasswordSetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/password/IPasswordSetOperations.java new file mode 100644 index 0000000..f9af135 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/password/IPasswordSetOperations.java @@ -0,0 +1,71 @@ +package javinator9889.securepass.io.database.operations.entry.password; + +import androidx.annotation.NonNull; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 01/11/2018 - APP. + */ +public interface IPasswordSetOperations { + /** + * Registers a new simple password entry + * + * @param password password to save + * @param description current entry description + * @param order ordinal order when showing it on UI + * @param entryId parent entry ID + * @return {@code long} with the new password ID + */ + long registerNewPassword(@NonNull String password, @NonNull String description, int order, + long entryId); + + /** + * Updates the saved password by using the given ID + * + * @param passwordId ID of the entry to change + * @param password new password to save + */ + void updatePassword(long passwordId, @NonNull String password); + + /** + * Updates the password description by using the given ID + * + * @param passwordId ID of the entry to change + * @param description new description + */ + void updateDescription(long passwordId, @NonNull String description); + + /** + * Updates the password order inside the entry + * + * @param passwordId ID of the password to change + * @param order new order + */ + void updateSortOrder(long passwordId, int order); + + /** + * Removes the hole password by using the given ID + * + * @param passwordId password ID to remove + */ + void removePassword(long passwordId); + + /** + * Applies pending changes to the database - only necessary when doing UPDATE operations + */ + void apply(); +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/password/PasswordOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/password/PasswordOperations.java new file mode 100644 index 0000000..1831faf --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/password/PasswordOperations.java @@ -0,0 +1,281 @@ +package javinator9889.securepass.io.database.operations.entry.password; + +import android.content.ContentValues; +import android.util.Log; + +import net.sqlcipher.Cursor; + +import java.util.Map; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import javinator9889.securepass.data.entry.fields.Password; +import javinator9889.securepass.io.database.DatabaseManager; +import javinator9889.securepass.io.database.operations.CommonOperations; +import javinator9889.securepass.objects.GeneralObjectContainer; +import javinator9889.securepass.objects.ObjectContainer; +import javinator9889.securepass.util.values.Constants; +import javinator9889.securepass.util.values.database.PasswordFields; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 01/11/2018 - APP. + */ +public class PasswordOperations extends CommonOperations implements IPasswordSetOperations, + IPasswordGetOperations { + private static final String TAG = "Password Operations"; + private static final String TABLE_NAME = Constants.SQL.PASSWORD.NAME; + private static final PasswordFields ID = PasswordFields.ID; + private static final PasswordFields PASSWORD = PasswordFields.PASSWORD; + private static final PasswordFields DESCRIPTION = PasswordFields.DESCRIPTION; + private static final PasswordFields ORDER = PasswordFields.ORDER; + private static final PasswordFields ENTRY = PasswordFields.ENTRY; + private static final String WHERE_ID = ID.getFieldName() + "=?"; + + /** + * Available constructor, matching + * {@link CommonOperations#CommonOperations(DatabaseManager) super} one + * + * @param databaseInstance instance of the {@link DatabaseManager} object + * @see DatabaseManager + */ + public PasswordOperations(@NonNull DatabaseManager databaseInstance) { + super(databaseInstance); + } + + /** + * Gets the tag for {@link Log} output - should be overridden + * + * @return String with the tag name + */ + @Override + public String getTag() { + return TAG; + } + + /** + * Gets the WHERE ID clause for using {@link #scheduleUpdateExecutor(long, ContentValues)} - + * should be overridden + * + * @return {@code String} with the WHERE clause - null if not defined + */ + @Nullable + @Override + public String getWhereId() { + return WHERE_ID; + } + + /** + * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - + * should be overridden + * + * @return {@code String} with the TABLE NAME - null if not defined + */ + @Nullable + @Override + public String getTableName() { + return TABLE_NAME; + } + + /** + * Obtains the stored password + * + * @param passwordId ID of the password in the DB + * @return {@code String} with the password + */ + @Override + public String getPasswordPassword(long passwordId) { + String password = null; + try (Cursor passwordCursor = get(TABLE_NAME, whereArgs(PASSWORD.getFieldName()), WHERE_ID, + whereArgs(passwordId), null, null, ID.getFieldName() + " ASC")) { + Map passwordColumns = constructMapFromCursor(passwordCursor); + if (passwordCursor.moveToNext()) + password = passwordCursor.getString(passwordColumns.get(PASSWORD.getFieldName())); + } + return password; + } + + /** + * Obtains the password description + * + * @param passwordId ID of the password in DB + * @return {@code String} with the description + */ + @Override + public String getPasswordDescription(long passwordId) { + String description = null; + try (Cursor passwordCursor = get(TABLE_NAME, whereArgs(DESCRIPTION.getFieldName()), WHERE_ID, + whereArgs(passwordId), null, null, ID.getFieldName() + " ASC")) { + Map passwordColumns = constructMapFromCursor(passwordCursor); + if (passwordCursor.moveToNext()) + description = passwordCursor.getString(passwordColumns.get(DESCRIPTION.getFieldName())); + } + return description; + } + + /** + * Obtains the password ordinal order + * + * @param passwordId ID of the password in DB + * @return {@code int} with the order + */ + @Override + public int getPasswordOrder(long passwordId) { + int order = -1; + try (Cursor passwordCursor = get(TABLE_NAME, whereArgs(ORDER.getFieldName()), WHERE_ID, + whereArgs(passwordId), null, null, ID.getFieldName() + " ASC")) { + Map passwordColumns = constructMapFromCursor(passwordCursor); + if (passwordCursor.moveToNext()) + order = passwordCursor.getInt(passwordColumns.get(ORDER.getFieldName())); + } + return order; + } + + /** + * Obtains the password parent entry ID + * + * @param passwordId ID of the password in DB + * @return {@code long} with the entry ID + */ + @Override + public long getPasswordEntryId(long passwordId) { + long entryId = -1; + try (Cursor passwordCursor = get(TABLE_NAME, whereArgs(ENTRY.getFieldName()), WHERE_ID, + whereArgs(passwordId), null, null, ID.getFieldName() + " ASC")) { + Map passwordColumns = constructMapFromCursor(passwordCursor); + if (passwordCursor.moveToNext()) + entryId = passwordCursor.getLong(passwordColumns.get(ENTRY.getFieldName())); + } + return entryId; + } + + /** + * Obtains all entries' data and saves it inside a {@link GeneralObjectContainer} of + * {@link Password} + * + * @return {@code GeneralObjectContainer} of entries + * @see ObjectContainer + * @see Password + */ + @Override + public GeneralObjectContainer getAllPasswords() { + GeneralObjectContainer passwords = new ObjectContainer<>(); + try (Cursor passwordCursor = getAll(TABLE_NAME, ID.getFieldName() + " ASC")) { + Map passwordColumns = constructMapFromCursor(passwordCursor); + while (passwordCursor.moveToNext()) { + long id = passwordCursor.getLong(passwordColumns.get(ID.getFieldName())); + long entryId = passwordCursor.getLong(passwordColumns.get(ENTRY.getFieldName())); + String password = + passwordCursor.getString(passwordColumns.get(PASSWORD.getFieldName())); + String description = + passwordCursor.getString(passwordColumns.get(DESCRIPTION.getFieldName())); + Password currentPassword = new Password(id, entryId, password, description); + passwords.storeObject(currentPassword); + } + } + return passwords; + } + + /** + * Registers a new simple password entry + * + * @param password password to save + * @param description current entry description + * @param order ordinal order when showing it on UI + * @param entryId parent entry ID + * @return {@code long} with the new password ID + */ + @Override + public long registerNewPassword(@NonNull String password, + @NonNull String description, + int order, + long entryId) { + ContentValues params = setParams(password, description, order, entryId); + return insertReplaceOnConflict(TABLE_NAME, params); + } + + /** + * Updates the saved password by using the given ID + * + * @param passwordId ID of the entry to change + * @param password new password to save + */ + @Override + public void updatePassword(long passwordId, @NonNull String password) { + ContentValues params = new ContentValues(1); + params.put(PASSWORD.getFieldName(), password); + scheduleUpdateExecutor(passwordId, params); + } + + /** + * Updates the password description by using the given ID + * + * @param passwordId ID of the entry to change + * @param description new description + */ + @Override + public void updateDescription(long passwordId, @NonNull String description) { + ContentValues params = new ContentValues(1); + params.put(DESCRIPTION.getFieldName(), description); + scheduleUpdateExecutor(passwordId, params); + } + + /** + * Updates the password order inside the entry + * + * @param passwordId ID of the password to change + * @param order new order + */ + @Override + public void updateSortOrder(long passwordId, int order) { + ContentValues params = new ContentValues(1); + params.put(ORDER.getFieldName(), order); + scheduleUpdateExecutor(passwordId, params); + } + + /** + * Removes the hole password by using the given ID + * + * @param passwordId password ID to remove + */ + @Override + public void removePassword(long passwordId) { + delete(TABLE_NAME, ID.getFieldName(), passwordId); + } + + /** + * Generates a map with the provided params + * + * @param password password + * @param description password description + * @param order ordinal order + * @param entryId entry ID + * @return {@code ContentValues} with the params + * @see ContentValues + */ + private ContentValues setParams(@NonNull String password, + @NonNull String description, + int order, + long entryId) { + ContentValues params = new ContentValues(4); + params.put(PASSWORD.getFieldName(), password); + params.put(DESCRIPTION.getFieldName(), description); + params.put(ORDER.getFieldName(), order); + params.put(ENTRY.getFieldName(), entryId); + return params; + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/qrcode/IQRCodeGetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/qrcode/IQRCodeGetOperations.java new file mode 100644 index 0000000..6931db6 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/qrcode/IQRCodeGetOperations.java @@ -0,0 +1,62 @@ +/* + * Copyright © 2019 - present | SecurePass by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 02/02/2019 - SecurePass. + */ +package javinator9889.securepass.io.database.operations.entry.qrcode; + +import androidx.annotation.Nullable; +import javinator9889.securepass.data.entry.QRCode; +import javinator9889.securepass.objects.GeneralObjectContainer; + +public interface IQRCodeGetOperations { + /** + * Obtains the QRCode name by using the given ID. + * @param id the QRCode ID. + * @return {@code String} with the name. + */ + String getQRCodeName(long id); + + /** + * Obtains the QRCode description by using the given ID - can be {@code null}. + * @param id the QRCode ID. + * @return {@code String} with the description. + */ + @Nullable + String getQRCodeDescription(long id); + + /** + * Obtains the QRCode data by using the given ID. + * @param id the QRCode ID. + * @return {@code String} with the data. + */ + String getQRCodeData(long id); + + /** + * Obtains the QRCode entry ID by using the QRCode ID. + * @param id the QRCode ID. + * @return {@code long} with the entry ID. + */ + long getQRCodeEntryID(long id); + + /** + * Obtains all entries' data and saves it inside a {@link GeneralObjectContainer} of + * {@link QRCode} + * + * @return {@code GeneralObjectContainer} of entries + * @see javinator9889.securepass.objects.ObjectContainer + * @see QRCode + */ + GeneralObjectContainer getAllQRCodes(); +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/qrcode/IQRCodeSetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/qrcode/IQRCodeSetOperations.java new file mode 100644 index 0000000..7232ff7 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/qrcode/IQRCodeSetOperations.java @@ -0,0 +1,68 @@ +/* + * Copyright © 2019 - present | SecurePass by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 02/02/2019 - SecurePass. + */ +package javinator9889.securepass.io.database.operations.entry.qrcode; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +public interface IQRCodeSetOperations { + /** + * Registers a new QRCode on the database. + * @param entryId parent entry ID. + * @param name the name for the QRCode. + * @param description the optional description for the QRCode - can be {@code null}. + * @param qrCodeData the data of the QR. + * @return {@code long} with the created row ID. + */ + long registerNewQRCode(long entryId, + @NonNull String name, + @Nullable String description, + @NonNull String qrCodeData); + + /** + * Updates the QRCode name by using the given ID. + * @param id the QRCode ID. + * @param name the new name. + */ + void updateName(long id, @NonNull String name); + + /** + * Updates the QRCode description by using the given ID. + * @param id the QRCode ID. + * @param description the new description - can be {@code null}. + */ + void updateDescription(long id, @Nullable String description); + + /** + * Updates the QRCode data by using the given ID. + * @param id the QRCode ID. + * @param qrCodeData the new QRCode data. + */ + void updateQrCodeData(long id, @NonNull String qrCodeData); + + /** + * Removes the QRCode by using the given ID. + * @param id the QRCode row to delete. + */ + void removeQRCode(long id); + + /** + * Applies pending changes to the database - only necessary when doing UPDATE + * operations. + */ + void apply(); +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/qrcode/QRCodeOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/qrcode/QRCodeOperations.java new file mode 100644 index 0000000..52aa142 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/qrcode/QRCodeOperations.java @@ -0,0 +1,288 @@ +/* + * Copyright © 2019 - present | SecurePass by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 02/02/2019 - SecurePass. + */ +package javinator9889.securepass.io.database.operations.entry.qrcode; + +import android.content.ContentValues; +import android.util.Log; + +import net.sqlcipher.Cursor; + +import java.util.Map; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import javinator9889.securepass.data.entry.QRCode; +import javinator9889.securepass.io.database.DatabaseManager; +import javinator9889.securepass.io.database.operations.CommonOperations; +import javinator9889.securepass.objects.GeneralObjectContainer; +import javinator9889.securepass.objects.ObjectContainer; +import javinator9889.securepass.util.values.Constants; +import javinator9889.securepass.util.values.database.QRCodeFields; + +public class QRCodeOperations extends CommonOperations implements + IQRCodeSetOperations, IQRCodeGetOperations { + private static final String TAG = "Entry Operations"; + private static final String TABLE_NAME = Constants.SQL.QR_CODE.NAME; + private static final QRCodeFields NAME = QRCodeFields.NAME; + private static final QRCodeFields ID = QRCodeFields.ID; + private static final QRCodeFields DESCRIPTION = QRCodeFields.DESCRIPTION; + private static final QRCodeFields DATA = QRCodeFields.DATA; + private static final QRCodeFields ENTRY = QRCodeFields.ENTRY; + private static final String QRCODE_WHERE_ID = ID.getFieldName() + "=?"; + + /** + * Public constructor for creating this class - use this instead of {@link + * #newInstance(DatabaseManager)}. + * + * @param databaseInstance instance of the {@link DatabaseManager} object. + * @see DatabaseManager + */ + public QRCodeOperations(@NonNull DatabaseManager databaseInstance) { + super(databaseInstance); + } + + /** + * Gets the tag for {@link Log} output - should be overridden + * + * @return String with the tag name + */ + @Override + public String getTag() { + return TAG; + } + + /** + * Gets the WHERE ID clause for using {@link #scheduleUpdateExecutor(long, ContentValues)} - + * should be overridden + * + * @return {@code String} with the WHERE clause - null if not defined + */ + @Nullable + @Override + public String getWhereId() { + return QRCODE_WHERE_ID; + } + + /** + * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - should + * be overridden + * + * @return {@code String} with the TABLE NAME - null if not defined + */ + @Nullable + @Override + public String getTableName() { + return TABLE_NAME; + } + + /** + * Obtains the QRCode name by using the given ID. + * + * @param id the QRCode ID. + * @return {@code String} with the name. + */ + @Override + public String getQRCodeName(long id) { + String name = null; + try (Cursor qrCodeCursor = get(TABLE_NAME, whereArgs(NAME.getFieldName()), + QRCODE_WHERE_ID, whereArgs(id), null, null, ID.getFieldName() + " ASC")) { + Map qrCodeColumns = constructMapFromCursor(qrCodeCursor); + if (qrCodeCursor.moveToNext()) { + name = qrCodeCursor.getString(qrCodeColumns.get(NAME.getFieldName())); + } + } + return name; + } + + /** + * Obtains the QRCode description by using the given ID - can be {@code null}. + * + * @param id the QRCode ID. + * @return {@code String} with the description. + */ + @Nullable + @Override + public String getQRCodeDescription(long id) { + String description = null; + try (Cursor qrCodeCursor = get(TABLE_NAME, whereArgs(DESCRIPTION.getFieldName()), + QRCODE_WHERE_ID, whereArgs(id), null, null, ID.getFieldName() + " ASC")) { + Map qrCodeColumns = constructMapFromCursor(qrCodeCursor); + if (qrCodeCursor.moveToNext()) { + description = qrCodeCursor + .getString(qrCodeColumns.get(DESCRIPTION.getFieldName())); + } + } + return description; + } + + /** + * Obtains the QRCode data by using the given ID. + * + * @param id the QRCode ID. + * @return {@code String} with the data. + */ + @Override + public String getQRCodeData(long id) { + String qrCodeData = null; + try (Cursor qrCodeCursor = get(TABLE_NAME, whereArgs(DATA.getFieldName()), + QRCODE_WHERE_ID, whereArgs(id), null, null, ID.getFieldName() + " ASC")) { + Map qrCodeColumns = constructMapFromCursor(qrCodeCursor); + if (qrCodeCursor.moveToNext()) { + qrCodeData = qrCodeCursor + .getString(qrCodeColumns.get(DATA.getFieldName())); + } + } + return qrCodeData; + } + + /** + * Obtains the QRCode entry ID by using the QRCode ID. + * + * @param id the QRCode ID. + * @return {@code long} with the entry ID. + */ + @Override + public long getQRCodeEntryID(long id) { + long entryId = -1; + try (Cursor qrCodeCursor = get(TABLE_NAME, whereArgs(ENTRY.getFieldName()), + QRCODE_WHERE_ID, whereArgs(id), null, null, ID.getFieldName() + " ASC")) { + Map qrCodeColumns = constructMapFromCursor(qrCodeCursor); + if (qrCodeCursor.moveToNext()) { + entryId = qrCodeCursor.getLong(qrCodeColumns.get(ENTRY.getFieldName())); + } + } + return entryId; + } + + /** + * Obtains all entries' data and saves it inside a {@link GeneralObjectContainer} of + * {@link QRCode} + * + * @return {@code GeneralObjectContainer} of entries + * @see ObjectContainer + * @see QRCode + */ + @Override + public GeneralObjectContainer getAllQRCodes() { + GeneralObjectContainer results = new ObjectContainer<>(); + try (Cursor qrCodes = getAll(TABLE_NAME, ID.getFieldName() + " ASC")) { + Map qrCodesColumns = constructMapFromCursor(qrCodes); + while (qrCodes.moveToNext()) { + long id = qrCodes.getLong(qrCodesColumns.get(ID.getFieldName())); + String name = qrCodes.getString(qrCodesColumns.get(NAME.getFieldName())); + String description = qrCodes + .getString(qrCodesColumns.get(DESCRIPTION.getFieldName())); + String data = qrCodes.getString(qrCodesColumns.get(DATA.getFieldName())); + long entryId = qrCodes.getLong(qrCodesColumns.get(ENTRY.getFieldName())); + QRCode currentCode = new QRCode(id, name, description, data, entryId); + results.storeObject(currentCode); + } + } + return results; + } + + /** + * Registers a new QRCode on the database. + * + * @param entryId parent entry ID. + * @param name the name for the QRCode. + * @param description the optional description for the QRCode - can be {@code null}. + * @param qrCodeData the data of the QR. + * @return {@code long} with the created row ID. + */ + @Override + public long registerNewQRCode(long entryId, + @NonNull String name, + @Nullable String description, + @NonNull String qrCodeData) { + ContentValues params = setParams(entryId, name, description, qrCodeData); + return insertReplaceOnConflict(TABLE_NAME, params); + } + + /** + * Updates the QRCode name by using the given ID. + * + * @param id the QRCode ID. + * @param name the new name. + */ + @Override + public void updateName(long id, @NonNull String name) { + ContentValues params = new ContentValues(1); + params.put(NAME.getFieldName(), name); + scheduleUpdateExecutor(id, params); + } + + /** + * Updates the QRCode description by using the given ID. + * + * @param id the QRCode ID. + * @param description the new description - can be {@code null}. + */ + @Override + public void updateDescription(long id, @Nullable String description) { + ContentValues params = new ContentValues(1); + params.put(DESCRIPTION.getFieldName(), description); + scheduleUpdateExecutor(id, params); + } + + /** + * Updates the QRCode data by using the given ID. + * + * @param id the QRCode ID. + * @param qrCodeData the new QRCode data. + */ + @Override + public void updateQrCodeData(long id, @NonNull String qrCodeData) { + ContentValues params = new ContentValues(1); + params.put(DATA.getFieldName(), qrCodeData); + scheduleUpdateExecutor(id, params); + } + + /** + * Removes the QRCode by using the given ID. + * + * @param id the QRCode row to delete. + */ + @Override + public void removeQRCode(long id) { + delete(TABLE_NAME, ID.getFieldName(), id); + } + + /** + * Generates a map with the provided params. + * + * @param entryId entry ID. + * @param name QRCode name. + * @param description QRCode description - can be {@code null}. + * @param data QRCode data. + * + * @return {@code ContentValues} with the params + * + * @see ContentValues + */ + private ContentValues setParams(long entryId, + @NonNull String name, + @Nullable String description, + @NonNull String data) { + ContentValues params = new ContentValues(4); + params.put(ENTRY.getFieldName(), entryId); + params.put(NAME.getFieldName(), name); + params.put(DESCRIPTION.getFieldName(), description); + params.put(DATA.getFieldName(), data); + return params; + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/ITextGetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/ITextGetOperations.java new file mode 100644 index 0000000..8d7eae6 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/ITextGetOperations.java @@ -0,0 +1,53 @@ +package javinator9889.securepass.io.database.operations.entry.text; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 02/11/2018 - APP. + */ +public interface ITextGetOperations { + /** + * Obtains the text's field text + * + * @param textId ID of the text to obtain its data + * @return {@code String} with the text + */ + String getTextText(long textId); + + /** + * Obtains the text's description + * + * @param textId ID of the text to obtain its data + * @return {@code String} with the description + */ + String getTextDescription(long textId); + + /** + * Obtains the text's order + * + * @param textId ID of the text to obtain its data + * @return {@code int} with the ordinal order + */ + int getTextOrder(long textId); + + /** + * Obtains the text's entry ID + * + * @param textId ID of the text to obtain its data + * @return {@code long} with the entry ID + */ + long getTextEntryId(long textId); +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/ITextSetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/ITextSetOperations.java new file mode 100644 index 0000000..8eb0d27 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/ITextSetOperations.java @@ -0,0 +1,74 @@ +package javinator9889.securepass.io.database.operations.entry.text; + +import androidx.annotation.NonNull; +import javinator9889.securepass.errors.database.NoJobsEnqueuedError; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + *

+ * This program 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. + *

+ * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + *

+ * Created by Javinator9889 on 02/11/2018 - APP. + */ +public interface ITextSetOperations { + /** + * Updates the current text by the provided one + * + * @param textId ID of the text field to change + * @param text new text + */ + void updateTextText(long textId, @NonNull String text); + + /** + * Updates the current text description + * + * @param textId ID of the text to change + * @param description new description + */ + void updateTextDescription(long textId, @NonNull String description); + + /** + * Updates the current text order + * + * @param textId ID of the text to change + * @param order new order + */ + void updateTextOrder(long textId, int order); + + /** + * Removes the text by using its ID + * + * @param textId ID of the text to remove + */ + void removeText(long textId); + + /** + * Registers a new simple small text + * + * @param text text to store in the DB + * @param description small text description + * @param order ordinal order + * @param entryId parent entry ID + * + * @return {@code long} with the new small text ID + */ + long registerNewText(@NonNull String text, @NonNull String description, int order, + long entryId); + + /** + * Runs the {@link com.github.javinator9889.threading.pools.ThreadsPooling} - only necessary + * when doing UPDATE operations + * + * @throws NoJobsEnqueuedError when there is no job added to the queue + */ + void apply(); +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/longtext/ILongTextGetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/longtext/ILongTextGetOperations.java new file mode 100644 index 0000000..f019bef --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/longtext/ILongTextGetOperations.java @@ -0,0 +1,35 @@ +package javinator9889.securepass.io.database.operations.entry.text.longtext; + +import javinator9889.securepass.data.entry.fields.LongText; +import javinator9889.securepass.io.database.operations.entry.text.ITextGetOperations; +import javinator9889.securepass.objects.GeneralObjectContainer; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 02/11/2018 - APP. + */ +public interface ILongTextGetOperations extends ITextGetOperations { + /** + * Obtains all long texts' data and saves it inside a {@link GeneralObjectContainer} of + * {@link LongText} + * + * @return {@code GeneralObjectContainer} of entries + * @see javinator9889.securepass.objects.ObjectContainer + * @see LongText + */ + GeneralObjectContainer getAllLongTexts(); +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/longtext/LongTextOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/longtext/LongTextOperations.java new file mode 100644 index 0000000..7b5aeff --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/longtext/LongTextOperations.java @@ -0,0 +1,289 @@ +package javinator9889.securepass.io.database.operations.entry.text.longtext; + +import android.content.ContentValues; +import android.util.Log; + +import net.sqlcipher.Cursor; + +import java.util.Map; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import javinator9889.securepass.data.entry.fields.LongText; +import javinator9889.securepass.io.database.DatabaseManager; +import javinator9889.securepass.io.database.operations.CommonOperations; +import javinator9889.securepass.io.database.operations.entry.text.ITextSetOperations; +import javinator9889.securepass.objects.GeneralObjectContainer; +import javinator9889.securepass.objects.ObjectContainer; +import javinator9889.securepass.util.values.Constants; +import javinator9889.securepass.util.values.database.LongTextFields; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + *

+ * This program 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. + *

+ * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + *

+ * Created by Javinator9889 on 02/11/2018 - APP. + */ +public class LongTextOperations extends CommonOperations implements ITextSetOperations, + ILongTextGetOperations { + private static final String TAG = "LongText Operations"; + private static final String TABLE_NAME = Constants.SQL.LONG_TEXT.NAME; + private static final LongTextFields ID = LongTextFields.ID; + private static final LongTextFields TEXT = LongTextFields.TEXT; + private static final LongTextFields DESCRIPTION = LongTextFields.DESCRIPTION; + private static final LongTextFields ORDER = LongTextFields.ORDER; + private static final LongTextFields ENTRY = LongTextFields.ENTRY; + private static final String WHERE_ID = ID.getFieldName() + "=?"; + + /** + * Available constructor, matching {@link CommonOperations#CommonOperations(DatabaseManager) + * super} one + * + * @param databaseInstance instance of the {@link DatabaseManager} object + * + * @see DatabaseManager + */ + public LongTextOperations(@NonNull DatabaseManager databaseInstance) { + super(databaseInstance); + } + + /** + * Gets the tag for {@link Log} output - should be overridden + * + * @return String with the tag name + */ + @Override + public String getTag() { + return TAG; + } + + /** + * Gets the WHERE ID clause for using {@link #scheduleUpdateExecutor(long, ContentValues)} - + * should be overridden + * + * @return {@code String} with the WHERE clause - null if not defined + */ + @Nullable + @Override + public String getWhereId() { + return WHERE_ID; + } + + /** + * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - should + * be overridden + * + * @return {@code String} with the TABLE NAME - null if not defined + */ + @Nullable + @Override + public String getTableName() { + return TABLE_NAME; + } + + /** + * Obtains the text's field text + * + * @param textId ID of the text to obtain its data + * + * @return {@code String} with the text + */ + @Override + public String getTextText(long textId) { + String text = null; + try (Cursor longTextsCursor = get(TABLE_NAME, whereArgs(ID.getFieldName()), WHERE_ID, + whereArgs(textId), null, null, ID.getFieldName() + " ASC")) { + Map longTextColumns = constructMapFromCursor(longTextsCursor); + if (longTextsCursor.moveToNext()) + text = longTextsCursor.getString(longTextColumns.get(TEXT.getFieldName())); + } + return text; + } + + /** + * Obtains the text's description + * + * @param textId ID of the text to obtain its data + * + * @return {@code String} with the description + */ + @Override + public String getTextDescription(long textId) { + String description = null; + try (Cursor longTextsCursor = get(TABLE_NAME, whereArgs(DESCRIPTION.getFieldName()), + WHERE_ID, whereArgs(textId), null, null, ID.getFieldName() + " ASC")) { + Map longTextColumns = constructMapFromCursor(longTextsCursor); + if (longTextsCursor.moveToNext()) + description = longTextsCursor.getString(longTextColumns.get(DESCRIPTION)); + } + return description; + } + + /** + * Obtains the text's order + * + * @param textId ID of the text to obtain its data + * + * @return {@code int} with the ordinal order + */ + @Override + public int getTextOrder(long textId) { + int order = -1; + try (Cursor longTextsCursor = get(TABLE_NAME, whereArgs(ORDER.getFieldName()), WHERE_ID, + whereArgs(textId), null, null, ID.getFieldName() + " ASC")) { + Map longTextColumns = constructMapFromCursor(longTextsCursor); + if (longTextsCursor.moveToNext()) + order = longTextsCursor.getInt(longTextColumns.get(ORDER.getFieldName())); + } + return order; + } + + /** + * Obtains the text's entry ID + * + * @param textId ID of the text to obtain its data + * + * @return {@code long} with the entry ID + */ + @Override + public long getTextEntryId(long textId) { + long entryId = -1; + try (Cursor longTextsCursor = get(TABLE_NAME, whereArgs(ENTRY.getFieldName()), WHERE_ID, + whereArgs(textId), null, null, ID.getFieldName() + " ASC")) { + Map longTextColumns = constructMapFromCursor(longTextsCursor); + if (longTextsCursor.moveToNext()) + entryId = longTextsCursor.getLong(longTextColumns.get(ENTRY.getFieldName())); + } + return entryId; + } + + /** + * Registers a new simple long text + * + * @param text text to store in the DB + * @param description long text description + * @param order ordinal order + * @param entryId parent entry ID + * + * @return {@code long} with the new long text ID + */ + @Override + public long registerNewText(@NonNull String text, + @NonNull String description, + int order, + long entryId) { + ContentValues params = setParams(text, description, order, entryId); + return insertReplaceOnConflict(TABLE_NAME, params); + } + + /** + * Updates the current text by the provided one + * + * @param textId ID of the text field to change + * @param text new text + */ + @Override + public void updateTextText(long textId, @NonNull String text) { + ContentValues params = new ContentValues(1); + params.put(TEXT.getFieldName(), text); + scheduleUpdateExecutor(textId, params); + } + + /** + * Updates the current text description + * + * @param textId ID of the text to change + * @param description new description + */ + @Override + public void updateTextDescription(long textId, @NonNull String description) { + ContentValues params = new ContentValues(1); + params.put(DESCRIPTION.getFieldName(), description); + scheduleUpdateExecutor(textId, params); + } + + /** + * Updates the current text order + * + * @param textId ID of the text to change + * @param order new order + */ + @Override + public void updateTextOrder(long textId, int order) { + ContentValues params = new ContentValues(1); + params.put(ORDER.getFieldName(), order); + scheduleUpdateExecutor(textId, params); + } + + /** + * Removes the text by using its ID + * + * @param textId ID of the text to remove + */ + @Override + public void removeText(long textId) { + delete(TABLE_NAME, ID.getFieldName(), textId); + } + + /** + * Obtains all long texts' data and saves it inside a {@link GeneralObjectContainer} of {@link + * LongText} + * + * @return {@code GeneralObjectContainer} of entries + * + * @see ObjectContainer + * @see LongText + */ + @Override + public GeneralObjectContainer getAllLongTexts() { + GeneralObjectContainer longTexts = new ObjectContainer<>(); + try (Cursor longTextsCursor = getAll(TABLE_NAME, ID.getFieldName() + " ASC")) { + Map longTextColumns = constructMapFromCursor(longTextsCursor); + while (longTextsCursor.moveToNext()) { + long id = longTextsCursor.getLong(longTextColumns.get(ID.getFieldName())); + String text = longTextsCursor.getString(longTextColumns.get(TEXT.getFieldName())); + String description = + longTextsCursor.getString(longTextColumns.get(DESCRIPTION.getFieldName())); + int order = longTextsCursor.getInt(longTextColumns.get(ORDER.getFieldName())); + long entryId = longTextsCursor.getLong(longTextColumns.get(ENTRY.getFieldName())); + LongText currentLongText = new LongText(id, entryId, text, description, order); + longTexts.storeObject(currentLongText); + } + } + return longTexts; + } + + /** + * Generates a map with the provided params + * + * @param text text source + * @param description text description + * @param order ordinal order + * @param entryId entry ID + * + * @return {@code ContentValues} with the params + * + * @see ContentValues + */ + private ContentValues setParams(@NonNull String text, + @NonNull String description, + int order, + long entryId) { + ContentValues params = new ContentValues(4); + params.put(TEXT.getFieldName(), text); + params.put(DESCRIPTION.getFieldName(), description); + params.put(ORDER.getFieldName(), order); + params.put(ENTRY.getFieldName(), entryId); + return params; + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/smalltext/ISmallTextGetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/smalltext/ISmallTextGetOperations.java new file mode 100644 index 0000000..8bc69a4 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/smalltext/ISmallTextGetOperations.java @@ -0,0 +1,35 @@ +package javinator9889.securepass.io.database.operations.entry.text.smalltext; + +import javinator9889.securepass.data.entry.fields.SmallText; +import javinator9889.securepass.io.database.operations.entry.text.ITextGetOperations; +import javinator9889.securepass.objects.GeneralObjectContainer; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 02/11/2018 - APP. + */ +public interface ISmallTextGetOperations extends ITextGetOperations { + /** + * Obtains all small texts' data and saves it inside a {@link GeneralObjectContainer} of + * {@link SmallText} + * + * @return {@code GeneralObjectContainer} of entries + * @see javinator9889.securepass.objects.ObjectContainer + * @see SmallText + */ + GeneralObjectContainer getAllSmallTexts(); +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/smalltext/SmallTextOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/smalltext/SmallTextOperations.java new file mode 100644 index 0000000..378b5b7 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/smalltext/SmallTextOperations.java @@ -0,0 +1,289 @@ +package javinator9889.securepass.io.database.operations.entry.text.smalltext; + +import android.content.ContentValues; +import android.util.Log; + +import net.sqlcipher.Cursor; + +import java.util.Map; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import javinator9889.securepass.data.entry.fields.SmallText; +import javinator9889.securepass.io.database.DatabaseManager; +import javinator9889.securepass.io.database.operations.CommonOperations; +import javinator9889.securepass.io.database.operations.entry.text.ITextSetOperations; +import javinator9889.securepass.objects.GeneralObjectContainer; +import javinator9889.securepass.objects.ObjectContainer; +import javinator9889.securepass.util.values.Constants; +import javinator9889.securepass.util.values.database.SmallTextFields; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + *

+ * This program 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. + *

+ * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + *

+ * Created by Javinator9889 on 02/11/2018 - APP. + */ +public class SmallTextOperations extends CommonOperations implements ITextSetOperations, + ISmallTextGetOperations { + private static final String TAG = "SmallText Operations"; + private static final String TABLE_NAME = Constants.SQL.SMALL_TEXT.NAME; + private static final SmallTextFields ID = SmallTextFields.ID; + private static final SmallTextFields TEXT = SmallTextFields.TEXT; + private static final SmallTextFields DESCRIPTION = SmallTextFields.DESCRIPTION; + private static final SmallTextFields ORDER = SmallTextFields.ORDER; + private static final SmallTextFields ENTRY = SmallTextFields.ENTRY; + private static final String WHERE_ID = ID.getFieldName() + "=?"; + + /** + * Available constructor, matching {@link CommonOperations#CommonOperations(DatabaseManager) + * super} one + * + * @param databaseInstance instance of the {@link DatabaseManager} object + * + * @see DatabaseManager + */ + public SmallTextOperations(@NonNull DatabaseManager databaseInstance) { + super(databaseInstance); + } + + /** + * Gets the tag for {@link Log} output - should be overridden + * + * @return String with the tag name + */ + @Override + public String getTag() { + return TAG; + } + + /** + * Gets the WHERE ID clause for using {@link #scheduleUpdateExecutor(long, ContentValues)} - + * should be overridden + * + * @return {@code String} with the WHERE clause - null if not defined + */ + @Nullable + @Override + public String getWhereId() { + return WHERE_ID; + } + + /** + * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - should + * be overridden + * + * @return {@code String} with the TABLE NAME - null if not defined + */ + @Nullable + @Override + public String getTableName() { + return TABLE_NAME; + } + + /** + * Obtains the text's field text + * + * @param textId ID of the text to obtain its data + * + * @return {@code String} with the text + */ + @Override + public String getTextText(long textId) { + String text = null; + try (Cursor smallTextsCursor = get(TABLE_NAME, whereArgs(TEXT.getFieldName()), WHERE_ID, + whereArgs(textId), null, null, ID.getFieldName() + " ASC")) { + Map smallTextColumns = constructMapFromCursor(smallTextsCursor); + if (smallTextsCursor.moveToNext()) + text = smallTextsCursor.getString(smallTextColumns.get(TEXT.getFieldName())); + } + return text; + } + + /** + * Obtains the text's description + * + * @param textId ID of the text to obtain its data + * + * @return {@code String} with the description + */ + @Override + public String getTextDescription(long textId) { + String description = null; + try (Cursor smallTextsCursor = get(TABLE_NAME, whereArgs(DESCRIPTION.getFieldName()), WHERE_ID, + whereArgs(textId), null, null, ID.getFieldName() + " ASC")) { + Map smallTextColumns = constructMapFromCursor(smallTextsCursor); + if (smallTextsCursor.moveToNext()) + description = smallTextsCursor.getString(smallTextColumns.get(DESCRIPTION.getFieldName())); + } + return description; + } + + /** + * Obtains the text's order + * + * @param textId ID of the text to obtain its data + * + * @return {@code int} with the ordinal order + */ + @Override + public int getTextOrder(long textId) { + int order = -1; + try (Cursor smallTextsCursor = get(TABLE_NAME, whereArgs(ORDER.getFieldName()), WHERE_ID, + whereArgs(textId), null, null, ID.getFieldName() + " ASC")) { + Map smallTextColumns = constructMapFromCursor(smallTextsCursor); + if (smallTextsCursor.moveToNext()) + order = smallTextsCursor.getInt(smallTextColumns.get(ORDER.getFieldName())); + } + return order; + } + + /** + * Obtains the text's entry ID + * + * @param textId ID of the text to obtain its data + * + * @return {@code long} with the entry ID + */ + @Override + public long getTextEntryId(long textId) { + long entryId = -1; + try (Cursor smallTextsCursor = get(TABLE_NAME, whereArgs(ENTRY.getFieldName()), WHERE_ID, + whereArgs(textId), null, null, ID.getFieldName() + " ASC")) { + Map smallTextColumns = constructMapFromCursor(smallTextsCursor); + if (smallTextsCursor.moveToNext()) + entryId = smallTextsCursor.getLong(smallTextColumns.get(ENTRY.getFieldName())); + } + return entryId; + } + + /** + * Registers a new simple small text + * + * @param text text to store in the DB + * @param description small text description + * @param order ordinal order + * @param entryId parent entry ID + * + * @return {@code long} with the new small text ID + */ + @Override + public long registerNewText(@NonNull String text, + @NonNull String description, + int order, + long entryId) { + ContentValues params = setParams(text, description, order, entryId); + return insertReplaceOnConflict(TABLE_NAME, params); + } + + /** + * Updates the current text by the provided one + * + * @param textId ID of the text field to change + * @param text new text + */ + @Override + public void updateTextText(long textId, @NonNull String text) { + ContentValues params = new ContentValues(1); + params.put(TEXT.getFieldName(), text); + scheduleUpdateExecutor(textId, params); + } + + /** + * Updates the current text description + * + * @param textId ID of the text to change + * @param description new description + */ + @Override + public void updateTextDescription(long textId, @NonNull String description) { + ContentValues params = new ContentValues(1); + params.put(DESCRIPTION.getFieldName(), description); + scheduleUpdateExecutor(textId, params); + } + + /** + * Updates the current text order + * + * @param textId ID of the text to change + * @param order new order + */ + @Override + public void updateTextOrder(long textId, int order) { + ContentValues params = new ContentValues(1); + params.put(ORDER.getFieldName(), order); + scheduleUpdateExecutor(textId, params); + } + + /** + * Removes the text by using its ID + * + * @param textId ID of the text to remove + */ + @Override + public void removeText(long textId) { + delete(TABLE_NAME, ID.getFieldName(), textId); + } + + /** + * Obtains all small texts' data and saves it inside a {@link GeneralObjectContainer} of {@link + * SmallText} + * + * @return {@code GeneralObjectContainer} of entries + * + * @see ObjectContainer + * @see SmallText + */ + @Override + public GeneralObjectContainer getAllSmallTexts() { + GeneralObjectContainer smallTexts = new ObjectContainer<>(); + try (Cursor smallTextsCursor = getAll(TABLE_NAME, ID.getFieldName() + " ASC")) { + Map smallTextColumns = constructMapFromCursor(smallTextsCursor); + while (smallTextsCursor.moveToNext()) { + long id = smallTextsCursor.getLong(smallTextColumns.get(ID.getFieldName())); + String text = smallTextsCursor.getString(smallTextColumns.get(TEXT.getFieldName())); + String description = + smallTextsCursor.getString(smallTextColumns.get(DESCRIPTION.getFieldName())); + int order = smallTextsCursor.getInt(smallTextColumns.get(ORDER.getFieldName())); + long entryId = smallTextsCursor.getLong(smallTextColumns.get(ENTRY.getFieldName())); + SmallText currentSmallText = new SmallText(id, entryId, text, description, order); + smallTexts.storeObject(currentSmallText); + } + } + return smallTexts; + } + + /** + * Generates a map with the provided params + * + * @param text text source + * @param description text description + * @param order ordinal order + * @param entryId entry ID + * + * @return {@code ContentValues} with the params + * + * @see ContentValues + */ + private ContentValues setParams(@NonNull String text, + @NonNull String description, + int order, + long entryId) { + ContentValues params = new ContentValues(4); + params.put(TEXT.getFieldName(), text); + params.put(DESCRIPTION.getFieldName(), description); + params.put(ORDER.getFieldName(), order); + params.put(ENTRY.getFieldName(), entryId); + return params; + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/securitycode/ISecurityCodeGetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/securitycode/ISecurityCodeGetOperations.java new file mode 100644 index 0000000..6fe5ed2 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/securitycode/ISecurityCodeGetOperations.java @@ -0,0 +1,42 @@ +package javinator9889.securepass.io.database.operations.securitycode; + +import javinator9889.securepass.data.secret.SecurityCode; +import javinator9889.securepass.objects.GeneralObjectContainer; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 01/11/2018 - APP. + */ +public interface ISecurityCodeGetOperations { + /** + * Obtains the security code name by using the given ID + * + * @param securityCodeId ID where obtaining the name + * @return {@code String} with the name + */ + String getSecurityCodeName(long securityCodeId); + + /** + * Obtains all security codes' data and saves it inside a {@link GeneralObjectContainer} of + * {@link SecurityCode} + * + * @return {@code GeneralObjectContainer} of security codes + * @see javinator9889.securepass.objects.ObjectContainer + * @see SecurityCode + */ + GeneralObjectContainer getAllSecurityCodes(); +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/securitycode/ISecurityCodeSetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/securitycode/ISecurityCodeSetOperations.java new file mode 100644 index 0000000..6bfbe67 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/securitycode/ISecurityCodeSetOperations.java @@ -0,0 +1,51 @@ +package javinator9889.securepass.io.database.operations.securitycode; + +import androidx.annotation.NonNull; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 01/11/2018 - APP. + */ +public interface ISecurityCodeSetOperations { + /** + * Registers a new simple security code + * + * @param securityCodeName security code name + * @return {@code long} with the ID + */ + long registerNewSecurityCode(@NonNull String securityCodeName); + + /** + * Updates security code name + * + * @param securityCodeId security code ID where changing name + * @param newName new name + */ + void updateName(long securityCodeId, @NonNull String newName); + + /** + * Removes the security code with its fields by using the provided ID + * + * @param securityCodeId ID to remove + */ + void removeSecurityCode(long securityCodeId); + + /** + * Applies pending changes to the database - only necessary when doing UPDATE operations + */ + void apply(); +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/securitycode/SecurityCodeOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/securitycode/SecurityCodeOperations.java new file mode 100644 index 0000000..2aeef65 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/securitycode/SecurityCodeOperations.java @@ -0,0 +1,177 @@ +package javinator9889.securepass.io.database.operations.securitycode; + +import android.content.ContentValues; + +import net.sqlcipher.Cursor; + +import java.util.Map; + +import androidx.annotation.NonNull; +import javinator9889.securepass.data.secret.SecurityCode; +import javinator9889.securepass.io.database.DatabaseManager; +import javinator9889.securepass.io.database.operations.CommonOperations; +import javinator9889.securepass.objects.GeneralObjectContainer; +import javinator9889.securepass.objects.ObjectContainer; +import javinator9889.securepass.util.values.Constants; +import javinator9889.securepass.util.values.database.SecurityCodesFields; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + *

+ * This program 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. + *

+ * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + *

+ * Created by Javinator9889 on 01/11/2018 - APP. + */ +public class SecurityCodeOperations extends CommonOperations implements + ISecurityCodeSetOperations, ISecurityCodeGetOperations { + private static final String TAG = "Security Codes Operations"; + private static final String TABLE_NAME = Constants.SQL.SECURITY_CODE.NAME; + private static final SecurityCodesFields ID = SecurityCodesFields.ID; + private static final SecurityCodesFields NAME = SecurityCodesFields.NAME; + private static final String WHERE_ID = ID.getFieldName() + "=?"; + + /** + * Available constructor, matching {@link CommonOperations#CommonOperations(DatabaseManager) + * super} one + * + * @param databaseManager instance of the {@link DatabaseManager} object + * + * @see DatabaseManager + */ + public SecurityCodeOperations(@NonNull DatabaseManager databaseManager) { + super(databaseManager); + } + + /** + * {@inheritDoc} + */ + @Override + public String getTag() { + return TAG; + } + + /** + * Gets the WHERE ID clause for using {@link #scheduleUpdateExecutor(long, ContentValues)} - + * should be overridden + * + * @return {@code String} with the WHERE clause - null if not defined + */ + @NonNull + @Override + public String getWhereId() { + return WHERE_ID; + } + + /** + * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - should + * be overridden + * + * @return {@code String} with the TABLE NAME - null if not defined + */ + @NonNull + @Override + public String getTableName() { + return TABLE_NAME; + } + + /** + * Obtains the security code name by using the given ID + * + * @param securityCodeId ID where obtaining the name + * + * @return {@code String} with the name + */ + @Override + public String getSecurityCodeName(long securityCodeId) { + String name = null; + try (Cursor securityCodesCursor = get(TABLE_NAME, whereArgs(NAME.getFieldName()), + WHERE_ID, whereArgs(securityCodeId), null, null, ID.getFieldName() + " ASC")) { + Map securityCodeColums = constructMapFromCursor(securityCodesCursor); + if (securityCodesCursor.moveToNext()) + name = securityCodesCursor.getString(securityCodeColums.get(NAME.getFieldName())); + } + return name; + } + + /** + * Obtains all security codes' data and saves it inside a {@link GeneralObjectContainer} of + * {@link SecurityCode} + * + * @return {@code GeneralObjectContainer} of security codes + * + * @see ObjectContainer + * @see SecurityCode + */ + @Override + public GeneralObjectContainer getAllSecurityCodes() { + GeneralObjectContainer securityCodes = new ObjectContainer<>(); + try (Cursor securityCodesCursor = getAll(TABLE_NAME, ID.getFieldName() + " ASC")) { + Map securityCodeColumns = constructMapFromCursor(securityCodesCursor); + while (securityCodesCursor.moveToNext()) { + long id = securityCodesCursor.getLong(securityCodeColumns.get(ID.getFieldName())); + String name = + securityCodesCursor.getString(securityCodeColumns.get(NAME.getFieldName())); + SecurityCode currentSecurityCode = new SecurityCode(id, name); + securityCodes.storeObject(currentSecurityCode); + } + } + return securityCodes; + } + + /** + * Registers a new simple security code + * + * @param securityCodeName security code name + * + * @return {@code long} with the ID + */ + @Override + public long registerNewSecurityCode(@NonNull String securityCodeName) { + ContentValues params = setParams(securityCodeName); + return insertReplaceOnConflict(TABLE_NAME, params); + } + + /** + * Updates security code name + * + * @param securityCodeId security code ID where changing name + * @param newName new name + */ + @Override + public void updateName(long securityCodeId, @NonNull String newName) { + ContentValues params = setParams(newName); + scheduleUpdateExecutor(securityCodeId, params); + } + + /** + * Removes the security code with its fields by using the provided ID + * + * @param securityCodeId ID to remove + */ + @Override + public void removeSecurityCode(long securityCodeId) { + delete(TABLE_NAME, ID.getFieldName(), securityCodeId); + } + + /** + * Generates a map with the provided params + * + * @param securityCodeName category name + * + * @return {@code ContentValues} with the params + */ + private ContentValues setParams(@NonNull String securityCodeName) { + ContentValues params = new ContentValues(1); + params.put(NAME.getFieldName(), securityCodeName); + return params; + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/securitycode/field/FieldOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/securitycode/field/FieldOperations.java new file mode 100644 index 0000000..d6daee4 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/securitycode/field/FieldOperations.java @@ -0,0 +1,225 @@ +package javinator9889.securepass.io.database.operations.securitycode.field; + +import android.content.ContentValues; +import android.util.Log; + +import net.sqlcipher.Cursor; + +import java.util.Map; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import javinator9889.securepass.data.secret.Field; +import javinator9889.securepass.data.secret.SecurityCode; +import javinator9889.securepass.io.database.DatabaseManager; +import javinator9889.securepass.io.database.operations.CommonOperations; +import javinator9889.securepass.objects.GeneralObjectContainer; +import javinator9889.securepass.objects.ObjectContainer; +import javinator9889.securepass.util.values.Constants; +import javinator9889.securepass.util.values.database.FieldsFields; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + *

+ * This program 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. + *

+ * This program 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 this program. If not, see https://www.gnu.org/licenses/. + *

+ * Created by Javinator9889 on 01/11/2018 - APP. + */ +public class FieldOperations extends CommonOperations implements IFieldSetOperations, + IFieldGetOperations { + private static final String TAG = "Fields Operations"; + private static final String TABLE_NAME = Constants.SQL.FIELD.NAME; + private static final FieldsFields ID = FieldsFields.ID; + private static final FieldsFields CODE = FieldsFields.CODE; + private static final FieldsFields USED = FieldsFields.USED; + private static final FieldsFields SECURITY_CODE = FieldsFields.SECURITY_CODES; + private static final String WHERE_ID = ID.getFieldName() + "=?"; + + /** + * Available constructor, matching + * {@link CommonOperations#CommonOperations(DatabaseManager) super} one + * + * @param databaseManager instance of the {@link DatabaseManager} object + * @see DatabaseManager + */ + public FieldOperations(@NonNull DatabaseManager databaseManager) { + super(databaseManager); + } + + /** + * Gets the tag for {@link Log} output - should be overridden + * + * @return String with the tag name + */ + @Override + public String getTag() { + return TAG; + } + + /** + * Gets the WHERE ID clause for using {@link #scheduleUpdateExecutor(long, ContentValues)} - + * should be overridden + * + * @return {@code String} with the WHERE clause - null if not defined + */ + @Nullable + @Override + public String getWhereId() { + return WHERE_ID; + } + + /** + * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - + * should be overridden + * + * @return {@code String} with the TABLE NAME - null if not defined + */ + @Nullable + @Override + public String getTableName() { + return TABLE_NAME; + } + + + /** + * Obtains the field's code by using the provided ID + * + * @param fieldId ID of the field where obtaining the code + * @return {@code String} with the code + */ + @Override + public String getFieldCode(long fieldId) { + String code = null; + try (Cursor fieldsCursor = get(TABLE_NAME, whereArgs(CODE.getFieldName()), WHERE_ID, + whereArgs(fieldId), null, null, ID.getFieldName() + " ASC")) { + Map fieldsColumns = constructMapFromCursor(fieldsCursor); + if (fieldsCursor.moveToNext()) + code = fieldsCursor.getString(fieldsColumns.get(CODE.getFieldName())); + } + return code; + } + + /** + * Obtains if the field's code has been used + * + * @param fieldId ID of the field where obtaining the code + * @return {@code boolean} with the value + */ + @Override + public boolean getFieldCodeBeenUsed(long fieldId) { + boolean isCodeUsed = false; + try (Cursor fieldsCursor = get(TABLE_NAME, whereArgs(USED.getFieldName()), WHERE_ID, + whereArgs(fieldId), null, null, ID.getFieldName() + " ASC")) { + Map fieldsColums = constructMapFromCursor(fieldsCursor); + if (fieldsCursor.moveToNext()) + isCodeUsed = fieldsCursor.getInt(fieldsColums.get(USED.getFieldName())) != 0; + } + return isCodeUsed; + } + + /** + * Obtains all the fields' data and stores it inside a {@link GeneralObjectContainer} of + * {@link Field} + * + * @return {@code GeneralObjectContainer} with the fields + * @see ObjectContainer + * @see Field + */ + @Override + public GeneralObjectContainer getAllFields() { + GeneralObjectContainer fields = new ObjectContainer<>(); + try (Cursor fieldsCursor = getAll(TABLE_NAME, ID.getFieldName() + " ASC")) { + Map fieldColumns = constructMapFromCursor(fieldsCursor); + while (fieldsCursor.moveToNext()) { + long id = fieldsCursor.getLong(fieldColumns.get(ID.getFieldName())); + long securityCodeId = + fieldsCursor.getLong(fieldColumns.get(SECURITY_CODE.getFieldName())); + String code = fieldsCursor.getString(fieldColumns.get(CODE.getFieldName())); + boolean isCodeUsed = + fieldsCursor.getInt(fieldColumns.get(USED.getFieldName())) != 0; + Field currentField = new Field(id, code, isCodeUsed, securityCodeId); + fields.storeObject(currentField); + } + } + return fields; + } + + /** + * Registers a new simple field + * + * @param securityCodeId parent {@link SecurityCode} ID + * @param code code contained by field + * @param isCodeUsed whether the code has been used or not + * @return {@code long} with the new field ID + */ + @Override + public long registerNewField(long securityCodeId, @NonNull String code, boolean isCodeUsed) { + ContentValues params = setParams(securityCodeId, code, isCodeUsed); + return insertReplaceOnConflict(TABLE_NAME, params); + } + + /** + * Updates the field's code + * + * @param fieldId ID where changing the code + * @param newCode new code + */ + @Override + public void updateFieldCode(long fieldId, @NonNull String newCode) { + ContentValues params = new ContentValues(1); + params.put(CODE.getFieldName(), newCode); + scheduleUpdateExecutor(fieldId, params); + } + + /** + * Updates the field's code been used + * + * @param fieldId ID where changing the code + * @param isCodeUsed whether the code has been used or not + */ + @Override + public void updateFieldCodeBeenUsed(long fieldId, boolean isCodeUsed) { + ContentValues params = new ContentValues(1); + params.put(USED.getFieldName(), isCodeUsed); + scheduleUpdateExecutor(fieldId, params); + } + + /** + * Removes field by using the given ID + * + * @param fieldId ID of the field to delete + */ + @Override + public void removeField(long fieldId) { + delete(TABLE_NAME, ID.getFieldName(), fieldId); + } + + /** + * Generates a map with the provided params + * + * @param securityCodeId security code ID + * @param code field's code + * @param isCodeUsed whether the code has been used or not + * @return {@code ContentValues} with the params + */ + private ContentValues setParams(long securityCodeId, + @NonNull String code, + boolean isCodeUsed) { + ContentValues params = new ContentValues(3); + params.put(SECURITY_CODE.getFieldName(), securityCodeId); + params.put(CODE.getFieldName(), code); + params.put(USED.getFieldName(), isCodeUsed); + return params; + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/securitycode/field/IFieldGetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/securitycode/field/IFieldGetOperations.java new file mode 100644 index 0000000..cb7da5c --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/securitycode/field/IFieldGetOperations.java @@ -0,0 +1,50 @@ +package javinator9889.securepass.io.database.operations.securitycode.field; + +import javinator9889.securepass.data.secret.Field; +import javinator9889.securepass.objects.GeneralObjectContainer; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 01/11/2018 - APP. + */ +public interface IFieldGetOperations { + /** + * Obtains the field's code by using the provided ID + * + * @param fieldId ID of the field where obtaining the code + * @return {@code String} with the code + */ + String getFieldCode(long fieldId); + + /** + * Obtains if the field's code has been used + * + * @param fieldId ID of the field where obtaining the code + * @return {@code boolean} with the value + */ + boolean getFieldCodeBeenUsed(long fieldId); + + /** + * Obtains all the fields' data and stores it inside a {@link GeneralObjectContainer} of + * {@link Field} + * + * @return {@code GeneralObjectContainer} with the fields + * @see javinator9889.securepass.objects.ObjectContainer + * @see Field + */ + GeneralObjectContainer getAllFields(); +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/securitycode/field/IFieldSetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/securitycode/field/IFieldSetOperations.java new file mode 100644 index 0000000..42a30a9 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/securitycode/field/IFieldSetOperations.java @@ -0,0 +1,61 @@ +package javinator9889.securepass.io.database.operations.securitycode.field; + +import androidx.annotation.NonNull; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 01/11/2018 - APP. + */ +public interface IFieldSetOperations { + /** + * Registers a new simple field + * + * @param securityCodeId parent {@link javinator9889.securepass.data.secret.SecurityCode} ID + * @param code code contained by field + * @param isCodeUsed whether the code has been used or not + * @return {@code long} with the new field ID + */ + long registerNewField(long securityCodeId, @NonNull String code, boolean isCodeUsed); + + /** + * Updates the field's code + * + * @param fieldId ID where changing the code + * @param newCode new code + */ + void updateFieldCode(long fieldId, @NonNull String newCode); + + /** + * Updates the field's code been used + * + * @param fieldId ID where changing the code + * @param isCodeUsed whether the code has been used or not + */ + void updateFieldCodeBeenUsed(long fieldId, boolean isCodeUsed); + + /** + * Removes field by using the given ID + * + * @param fieldId ID of the field to delete + */ + void removeField(long fieldId); + + /** + * Applies pending changes to the database - only necessary when doing UPDATE operations + */ + void apply(); +} diff --git a/APP/app/src/main/java/javinator9889/securepass/objects/ByteArrayKeeper.java b/SecurePass/app/src/main/java/javinator9889/securepass/objects/ByteArrayKeeper.java similarity index 95% rename from APP/app/src/main/java/javinator9889/securepass/objects/ByteArrayKeeper.java rename to SecurePass/app/src/main/java/javinator9889/securepass/objects/ByteArrayKeeper.java index 64d5ddf..18f2b89 100644 --- a/APP/app/src/main/java/javinator9889/securepass/objects/ByteArrayKeeper.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/objects/ByteArrayKeeper.java @@ -1,58 +1,58 @@ -package javinator9889.securepass.objects; - -/** - * Class for containing a ByteArray - * Created by Javinator9889 on 21/09/2018. - */ -public class ByteArrayKeeper { - private byte[] mArray; - private boolean mIsAnyArrayStored; - - /** - * Default constructor creates an empty array - * - * @see #ByteArrayKeeper(byte[]) - */ - public ByteArrayKeeper() { - this(new byte[]{}); - } - - /** - * Stores the given array in the class - * - * @param array object to store - */ - public ByteArrayKeeper(byte[] array) { - this.mArray = array; - this.mIsAnyArrayStored = array.length > 0; - } - - /** - * Checks if there is any array stored - * - * @return boolean 'true' if there is anyone stored, else 'false' - */ - public boolean isAnyArrayStored() { - return mIsAnyArrayStored; - } - - /** - * Stores an array in class - * - * @param source the array to store - */ - public void storeArray(byte[] source) { - this.mArray = source; - mIsAnyArrayStored = source.length > 0; - } - - /** - * Gets the stored array in class - * - * @return byte[] array if anyone stored, else {@code null} - * @see #isAnyArrayStored() - */ - public byte[] getArray() { - return isAnyArrayStored() ? mArray : null; - } -} +package javinator9889.securepass.objects; + +/** + * Class for containing a ByteArray + * Created by Javinator9889 on 21/09/2018. + */ +public class ByteArrayKeeper { + private byte[] mArray; + private boolean mIsAnyArrayStored; + + /** + * Default constructor creates an empty array + * + * @see #ByteArrayKeeper(byte[]) + */ + public ByteArrayKeeper() { + this(new byte[]{}); + } + + /** + * Stores the given array in the class + * + * @param array object to store + */ + public ByteArrayKeeper(byte[] array) { + this.mArray = array; + this.mIsAnyArrayStored = array.length > 0; + } + + /** + * Checks if there is any array stored + * + * @return boolean 'true' if there is anyone stored, else 'false' + */ + public boolean isAnyArrayStored() { + return mIsAnyArrayStored; + } + + /** + * Stores an array in class + * + * @param source the array to store + */ + public void storeArray(byte[] source) { + this.mArray = source; + mIsAnyArrayStored = source.length > 0; + } + + /** + * Gets the stored array in class + * + * @return byte[] array if anyone stored, else {@code null} + * @see #isAnyArrayStored() + */ + public byte[] getArray() { + return isAnyArrayStored() ? mArray : null; + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/objects/GeneralObjectContainer.java b/SecurePass/app/src/main/java/javinator9889/securepass/objects/GeneralObjectContainer.java similarity index 96% rename from APP/app/src/main/java/javinator9889/securepass/objects/GeneralObjectContainer.java rename to SecurePass/app/src/main/java/javinator9889/securepass/objects/GeneralObjectContainer.java index 4d3031d..e0a76be 100644 --- a/APP/app/src/main/java/javinator9889/securepass/objects/GeneralObjectContainer.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/objects/GeneralObjectContainer.java @@ -1,115 +1,115 @@ -package javinator9889.securepass.objects; - -import android.util.SparseArray; - -import java.util.Iterator; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -/** - * Interface for accessing {@link ObjectContainer} - * Created by Javinator9889 on 25/04/2018. - */ -public interface GeneralObjectContainer extends Iterable { - /** - * Obtains the stored object at the specified index - * - * @param index position where the object is stored - * @return ObjectType if found, else null - */ - @Nullable - ObjectType getStoredObjectAtIndex(int index); - - /** - * Obtains the latest stored object (latest position) - * - * @return {@code ObjectType} with the object - * @see SparseArray#size() - * @see SparseArray#get(int) - */ - ObjectType getLatestStoredObject(); - - /** - * Stores the object at the latest position by using {@link #storeObject(Object, int)} - * - * @param newObject object to store - */ - void storeObject(@NonNull ObjectType newObject); - - /** - * Inserts the object at the given position - * - * @param newObject object to store - * @param index position where the object will be inserted - */ - void storeObject(@NonNull ObjectType newObject, int index); - - /** - * Checks if the provided {@code ObjectType} is stored - * - * @param objectToSearch the object that will be searched - * @return boolean matching 'true' if found, else 'false' - * @see SparseArray#indexOfValue(Object) - */ - boolean isObjectStored(@NonNull ObjectType objectToSearch); - - /** - * Removes the object that is stored at the specified index - * - * @param index position where the object will be removed - */ - void removeObjectAtIndex(int index); - - /** - * Removes the provided object if exists - * - * @param objectToRemove the object that will be deleted from the SparseArray - * @see #removeObjectAtIndex(int) - * @see #getIndexForObject(Object) - */ - void removeObjectStored(@NonNull ObjectType objectToRemove); - - /** - * Returns an iterator over elements of type {@code ObjectType}. - * - * @return an Iterator. - */ - @Override - Iterator iterator(); - - /** - * Gets the number of elements stored starting at one - * - * @return {@code int} with the number of elements - */ - int getObjectCountFromOne(); - - /** - * Gets the number of elements stored starting at zero - * - * @return {@code int} with the number of elements - * @see #getObjectCountFromOne() - */ - int getObjectCountFromZero(); - - /** - * Clears all the objects - */ - void removeAllObjects(); - - /** - * Obtains the index of a given value - * - * @param object object to obtain the index from - * @return int with the index - if not found, it will be negative - */ - int getIndexForObject(@NonNull ObjectType object); - - /** - * Determines whether there is any object stored - * - * @return 'true' if there is almost one, else 'false' - */ - boolean isAnyObjectStored(); -} +package javinator9889.securepass.objects; + +import android.util.SparseArray; + +import java.util.Iterator; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +/** + * Interface for accessing {@link ObjectContainer} + * Created by Javinator9889 on 25/04/2018. + */ +public interface GeneralObjectContainer extends Iterable { + /** + * Obtains the stored object at the specified index + * + * @param index position where the object is stored + * @return ObjectType if found, else null + */ + @Nullable + ObjectType getStoredObjectAtIndex(int index); + + /** + * Obtains the latest stored object (latest position) + * + * @return {@code ObjectType} with the object + * @see SparseArray#size() + * @see SparseArray#get(int) + */ + ObjectType getLatestStoredObject(); + + /** + * Stores the object at the latest position by using {@link #storeObject(Object, int)} + * + * @param newObject object to store + */ + void storeObject(@NonNull ObjectType newObject); + + /** + * Inserts the object at the given position + * + * @param newObject object to store + * @param index position where the object will be inserted + */ + void storeObject(@NonNull ObjectType newObject, int index); + + /** + * Checks if the provided {@code ObjectType} is stored + * + * @param objectToSearch the object that will be searched + * @return boolean matching 'true' if found, else 'false' + * @see SparseArray#indexOfValue(Object) + */ + boolean isObjectStored(@NonNull ObjectType objectToSearch); + + /** + * Removes the object that is stored at the specified index + * + * @param index position where the object will be removed + */ + void removeObjectAtIndex(int index); + + /** + * Removes the provided object if exists + * + * @param objectToRemove the object that will be deleted from the SparseArray + * @see #removeObjectAtIndex(int) + * @see #getIndexForObject(Object) + */ + void removeObjectStored(@NonNull ObjectType objectToRemove); + + /** + * Returns an iterator over elements of type {@code ObjectType}. + * + * @return an Iterator. + */ + @Override + Iterator iterator(); + + /** + * Gets the number of elements stored starting at one + * + * @return {@code int} with the number of elements + */ + int getObjectCountFromOne(); + + /** + * Gets the number of elements stored starting at zero + * + * @return {@code int} with the number of elements + * @see #getObjectCountFromOne() + */ + int getObjectCountFromZero(); + + /** + * Clears all the objects + */ + void removeAllObjects(); + + /** + * Obtains the index of a given value + * + * @param object object to obtain the index from + * @return int with the index - if not found, it will be negative + */ + int getIndexForObject(@NonNull ObjectType object); + + /** + * Determines whether there is any object stored + * + * @return 'true' if there is almost one, else 'false' + */ + boolean isAnyObjectStored(); +} diff --git a/APP/app/src/main/java/javinator9889/securepass/objects/ObjectContainer.java b/SecurePass/app/src/main/java/javinator9889/securepass/objects/ObjectContainer.java similarity index 92% rename from APP/app/src/main/java/javinator9889/securepass/objects/ObjectContainer.java rename to SecurePass/app/src/main/java/javinator9889/securepass/objects/ObjectContainer.java index 772e61a..f111c7e 100644 --- a/APP/app/src/main/java/javinator9889/securepass/objects/ObjectContainer.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/objects/ObjectContainer.java @@ -1,261 +1,266 @@ -package javinator9889.securepass.objects; - -import android.util.SparseArray; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -/** - * Custom implementation of {@link SparseArray} by accessing values same as in an - * {@link java.util.ArrayList} - * Created by Javinator9889 on 25/04/2018. - */ -public class ObjectContainer implements GeneralObjectContainer { - private SparseArray mObjectsList; - - /** - * Public default constructor - it uses {@link #ObjectContainer(int)} with a default capacity - * of 10 elements (the same as in {@link SparseArray#SparseArray() SparseArray constructor} - * - * @see #ObjectContainer(int) - * @see SparseArray#SparseArray() - */ - public ObjectContainer() { - this(10); - } - - /** - * Public constructor by using the specified capacity - * - * @param initialCapacity how many items are going to be stored - */ - public ObjectContainer(int initialCapacity) { - mObjectsList = new SparseArray<>(initialCapacity); - } - - /** - * Public constructor by giving the objects that will be stored first - uses - * {@link #ObjectContainer(int)} with the amount of provided objects and - * {@link #addAll(Object[])} for storing the objects - * - * @param objects non null objects which will be stored - */ - @SafeVarargs - public ObjectContainer(@NonNull ObjectType... objects) { - this(objects.length); - addAll(objects); - } - - /** - * Saves in the SparseArray the objects provided at - * {@link #ObjectContainer(Object[])} constructor - * - * @param objects objects provided at the constructor - * @see SparseArray#put(int, Object) - */ - private void addAll(@NonNull ObjectType[] objects) { - for (int i = 0; i < objects.length; ++i) - mObjectsList.put(i, objects[i]); - } - - /** - * Obtains the stored object at the specified index - * - * @param index position where the object is stored - * @return ObjectType if found, else null - */ - @Override - @Nullable - public ObjectType getStoredObjectAtIndex(int index) { - return mObjectsList.get(index, null); - } - - /** - * Obtains the latest stored object (latest position) - * - * @return {@code ObjectType} with the object - * @see SparseArray#size() - * @see SparseArray#get(int) - */ - @Override - public ObjectType getLatestStoredObject() { - int latest = mObjectsList.size() - 1; - return mObjectsList.get(latest); - } - - /** - * Stores the object at the latest position by using {@link #storeObject(Object, int)} - * - * @param newObject object to store - */ - @Override - public void storeObject(@NonNull ObjectType newObject) { - int position = mObjectsList.size() - 1; - storeObject(newObject, position); - } - - /** - * Inserts the object at the given position - * - * @param newObject object to store - * @param index position where the object will be inserted - */ - @Override - public void storeObject(@NonNull ObjectType newObject, int index) { - mObjectsList.put(index, newObject); - } - - /** - * Checks if the provided {@code ObjectType} is stored - * - * @param objectToSearch the object that will be searched - * @return boolean matching 'true' if found, else 'false' - * @see SparseArray#indexOfValue(Object) - */ - @Override - public boolean isObjectStored(@NonNull ObjectType objectToSearch) { - return getIndexForObject(objectToSearch) >= 0; - } - - /** - * Removes the object that is stored at the specified index - * - * @param index position where the object will be removed - */ - @Override - public void removeObjectAtIndex(int index) { - if (index >= 0) - mObjectsList.removeAt(index); - } - - /** - * Removes the provided object if exists - * - * @param objectToRemove the object that will be deleted from the SparseArray - * @see #removeObjectAtIndex(int) - * @see #getIndexForObject(Object) - */ - @Override - public void removeObjectStored(@NonNull ObjectType objectToRemove) { - removeObjectAtIndex(getIndexForObject(objectToRemove)); - } - - /** - * Returns an iterator over elements of type {@code ObjectType}. - * - * @return an Iterator. - */ - @Override - public Iterator iterator() { - return new ObjectIterator(); - } - - /** - * Gets the number of elements stored starting at one - * - * @return {@code int} with the number of elements - */ - @Override - public int getObjectCountFromOne() { - return mObjectsList.size(); - } - - /** - * Gets the number of elements stored starting at zero - * - * @return {@code int} with the number of elements - * @see #getObjectCountFromOne() - */ - @Override - public int getObjectCountFromZero() { - return getObjectCountFromOne() - 1; - } - - /** - * Clears all the objects - */ - @Override - public void removeAllObjects() { - mObjectsList.clear(); - } - - /** - * Obtains the index of a given value - * - * @param object object to obtain the index from - * @return int with the index - if not found, it will be negative - */ - @Override - public int getIndexForObject(@NonNull ObjectType object) { - return mObjectsList.indexOfValue(object); - } - - /** - * Determines whether there is any object stored - * - * @return 'true' if there is almost one, else 'false' - */ - @Override - public boolean isAnyObjectStored() { - return mObjectsList.size() > 0; - } - - /** - * Uses {@link SparseArray#toString()} custom implementation - * - * @return String with the result - * @see SparseArray#toString() - */ - @Override - public String toString() { - return mObjectsList.toString(); - } - - /** - * Custom class for making ObjectContainer iterable and applicable for "foreach" - */ - private class ObjectIterator implements Iterator { - private int mCurrentPosition = -1; - private boolean mHasBeenNextCalled = false; - - /** - * Returns {@code true} if the iteration has more elements. - * (In other words, returns {@code true} if {@link #next} would - * return an element rather than throwing an exception.) - * - * @return {@code true} if the iteration has more elements - */ - @Override - public boolean hasNext() { - return mCurrentPosition >= mObjectsList.size(); - } - - /** - * Returns the next element in the iteration. - * - * @return the next element in the iteration - * @throws NoSuchElementException if the iteration has no more elements - */ - @Override - public synchronized ObjectType next() { - ++mCurrentPosition; - mHasBeenNextCalled = true; - return mObjectsList.get(mCurrentPosition, null); - } - - /** - * {@inheritDoc} - */ - @Override - public synchronized void remove() { - if (!mHasBeenNextCalled) - throw new IllegalStateException("You must first call \"next()\" for using this " + - "function"); - mObjectsList.removeAt(mCurrentPosition); - mHasBeenNextCalled = false; - } - } -} +package javinator9889.securepass.objects; + +import android.util.SparseArray; + +import org.jetbrains.annotations.NotNull; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +/** + * Custom implementation of {@link SparseArray} by accessing values same as in an + * {@link java.util.ArrayList} + * Created by Javinator9889 on 25/04/2018. + */ +public class ObjectContainer implements GeneralObjectContainer { + private SparseArray mObjectsList; + + /** + * Public default constructor - it uses {@link #ObjectContainer(int)} with a default capacity + * of 10 elements (the same as in {@link SparseArray#SparseArray() SparseArray constructor} + * + * @see #ObjectContainer(int) + * @see SparseArray#SparseArray() + */ + public ObjectContainer() { + this(10); + } + + /** + * Public constructor by using the specified capacity + * + * @param initialCapacity how many items are going to be stored + */ + public ObjectContainer(int initialCapacity) { + mObjectsList = new SparseArray<>(initialCapacity); + } + + /** + * Public constructor by giving the objects that will be stored first - uses + * {@link #ObjectContainer(int)} with the amount of provided objects and + * {@link #addAll(Object[])} for storing the objects + * + * @param objects non null objects which will be stored + */ + @SafeVarargs + public ObjectContainer(@NonNull ObjectType... objects) { + this(objects.length); + addAll(objects); + } + + /** + * Saves in the SparseArray the objects provided at + * {@link #ObjectContainer(Object[])} constructor + * + * @param objects objects provided at the constructor + * @see SparseArray#put(int, Object) + */ + private void addAll(@NonNull ObjectType[] objects) { + for (int i = 0; i < objects.length; ++i) + mObjectsList.put(i, objects[i]); + } + + /** + * Obtains the stored object at the specified index + * + * @param index position where the object is stored + * @return ObjectType if found, else null + */ + @Override + @Nullable + public ObjectType getStoredObjectAtIndex(int index) { + return mObjectsList.get(index, null); + } + + /** + * Obtains the latest stored object (latest position) + * + * @return {@code ObjectType} with the object + * @see SparseArray#size() + * @see SparseArray#get(int) + */ + @Override + public ObjectType getLatestStoredObject() { + int latest = mObjectsList.size() - 1; + return mObjectsList.get(latest); + } + + /** + * Stores the object at the latest position by using {@link #storeObject(Object, int)} + * + * @param newObject object to store + */ + @Override + public void storeObject(@NonNull ObjectType newObject) { + int position = mObjectsList.size() - 1; + storeObject(newObject, position); + } + + /** + * Inserts the object at the given position + * + * @param newObject object to store + * @param index position where the object will be inserted + */ + @Override + public void storeObject(@NonNull ObjectType newObject, int index) { + mObjectsList.put(index, newObject); + } + + /** + * Checks if the provided {@code ObjectType} is stored + * + * @param objectToSearch the object that will be searched + * @return boolean matching 'true' if found, else 'false' + * @see SparseArray#indexOfValue(Object) + */ + @Override + public boolean isObjectStored(@NonNull ObjectType objectToSearch) { + return getIndexForObject(objectToSearch) >= 0; + } + + /** + * Removes the object that is stored at the specified index + * + * @param index position where the object will be removed + */ + @Override + public void removeObjectAtIndex(int index) { + if (index >= 0) + mObjectsList.removeAt(index); + } + + /** + * Removes the provided object if exists + * + * @param objectToRemove the object that will be deleted from the SparseArray + * @see #removeObjectAtIndex(int) + * @see #getIndexForObject(Object) + */ + @Override + public void removeObjectStored(@NonNull ObjectType objectToRemove) { + removeObjectAtIndex(getIndexForObject(objectToRemove)); + } + + /** + * Returns an iterator over elements of type {@code ObjectType}. + * + * @return an Iterator. + */ + @NotNull + @Override + public Iterator iterator() { + return new ObjectIterator(); + } + + /** + * Gets the number of elements stored starting at one + * + * @return {@code int} with the number of elements + */ + @Override + public int getObjectCountFromOne() { + return mObjectsList.size(); + } + + /** + * Gets the number of elements stored starting at zero + * + * @return {@code int} with the number of elements + * @see #getObjectCountFromOne() + */ + @Override + public int getObjectCountFromZero() { + return getObjectCountFromOne() - 1; + } + + /** + * Clears all the objects + */ + @Override + public void removeAllObjects() { + mObjectsList.clear(); + } + + /** + * Obtains the index of a given value + * + * @param object object to obtain the index from + * @return int with the index - if not found, it will be negative + */ + @Override + public int getIndexForObject(@NonNull ObjectType object) { + return mObjectsList.indexOfValue(object); + } + + /** + * Determines whether there is any object stored + * + * @return 'true' if there is almost one, else 'false' + */ + @Override + public boolean isAnyObjectStored() { + return mObjectsList.size() > 0; + } + + /** + * Uses {@link SparseArray#toString()} custom implementation + * + * @return String with the result + * @see SparseArray#toString() + */ + @NotNull + @Override + public String toString() { + return mObjectsList.toString(); + } + + /** + * Custom class for making ObjectContainer iterable and applicable for "foreach" + */ + private class ObjectIterator implements Iterator { + private int mCurrentPosition = -2; + private boolean mHasBeenNextCalled = false; + + /** + * Returns {@code true} if the iteration has more elements. + * (In other words, returns {@code true} if {@link #next} would + * return an element rather than throwing an exception.) + * + * @return {@code true} if the iteration has more elements + */ + @Override + public boolean hasNext() { + return mCurrentPosition < mObjectsList.size() - 2; + } + + /** + * Returns the next element in the iteration. + * + * @return the next element in the iteration + * @throws NoSuchElementException if the iteration has no more elements + */ + @Override + public synchronized ObjectType next() { + ++mCurrentPosition; + mHasBeenNextCalled = true; +// return mObjectsList.get(mCurrentPosition, null); + return ObjectContainer.this.getStoredObjectAtIndex(mCurrentPosition); + } + + /** + * {@inheritDoc} + */ + @Override + public synchronized void remove() { + if (!mHasBeenNextCalled) + throw new IllegalStateException("You must first call \"next()\" for using this " + + "function"); + mObjectsList.removeAt(mCurrentPosition); + mHasBeenNextCalled = false; + } + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/objects/SingletonFutureContainer.java b/SecurePass/app/src/main/java/javinator9889/securepass/objects/SingletonFutureContainer.java similarity index 97% rename from APP/app/src/main/java/javinator9889/securepass/objects/SingletonFutureContainer.java rename to SecurePass/app/src/main/java/javinator9889/securepass/objects/SingletonFutureContainer.java index b5b7941..8617085 100644 --- a/APP/app/src/main/java/javinator9889/securepass/objects/SingletonFutureContainer.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/objects/SingletonFutureContainer.java @@ -1,98 +1,98 @@ -package javinator9889.securepass.objects; - -import java.util.concurrent.Future; - -/** - * Class for containing Future objects that will be used on each app first start - * Created by Javinator9889 on 03/10/2018. - */ -public class SingletonFutureContainer { - private static SingletonFutureContainer INSTANCE; - private Future mPrivacyText; - private Future mLicenseText; - private Future mToSText; - - /** - * Default synchronized constructor which returns a generated instance (or a new one) - * - * @return {@link #INSTANCE} if existing, else new one - */ - public static synchronized SingletonFutureContainer getInstance() { - if (INSTANCE == null) - INSTANCE = new SingletonFutureContainer(); - return INSTANCE; - } - - /** - * Obtains the privacy text stored - * - * @return Future with the text - * @throws NullPointerException when there is no text stored - */ - public Future getPrivacyText() { - if (mPrivacyText == null) - throw new NullPointerException("There is no privacy text future object stored"); - return mPrivacyText; - } - - /** - * Sets the privacy text future object - * - * @param privacyText future text to store - * @throws NullPointerException when the privacyText is null - */ - public void setPrivacyText(Future privacyText) { - if (privacyText == null) - throw new NullPointerException("privacyText is null"); - this.mPrivacyText = privacyText; - } - - /** - * Obtains the license text stored - * - * @return Future with the text - * @throws NullPointerException when there is no text stored - */ - public Future getLicenseText() { - if (mPrivacyText == null) - throw new NullPointerException("There is no license text future object stored"); - return mLicenseText; - } - - /** - * Sets the license text future object - * - * @param licenseText future text to store - * @throws NullPointerException when the licenseText is null - */ - public void setLicenseText(Future licenseText) { - if (licenseText == null) - throw new NullPointerException("licenseText is null"); - this.mLicenseText = licenseText; - } - - /** - * Obtains the terms of service text stored - * - * @return Future with the text - * @throws NullPointerException when there is no text stored - */ - public Future getToSText() { - if (mPrivacyText == null) - throw new NullPointerException("There is no terms of service text future object " + - "stored"); - return mToSText; - } - - /** - * Sets the license text future object - * - * @param toSText future text to store - * @throws NullPointerException when the toSText is null - */ - public void setToSText(Future toSText) { - if (toSText == null) - throw new NullPointerException("toSText is null"); - this.mToSText = toSText; - } -} +package javinator9889.securepass.objects; + +import java.util.concurrent.Future; + +/** + * Class for containing Future objects that will be used on each app first start + * Created by Javinator9889 on 03/10/2018. + */ +public class SingletonFutureContainer { + private static SingletonFutureContainer INSTANCE; + private Future mPrivacyText; + private Future mLicenseText; + private Future mToSText; + + /** + * Default synchronized constructor which returns a generated instance (or a new one) + * + * @return {@link #INSTANCE} if existing, else new one + */ + public static synchronized SingletonFutureContainer getInstance() { + if (INSTANCE == null) + INSTANCE = new SingletonFutureContainer(); + return INSTANCE; + } + + /** + * Obtains the privacy text stored + * + * @return Future with the text + * @throws NullPointerException when there is no text stored + */ + public Future getPrivacyText() { + if (mPrivacyText == null) + throw new NullPointerException("There is no privacy text future object stored"); + return mPrivacyText; + } + + /** + * Sets the privacy text future object + * + * @param privacyText future text to store + * @throws NullPointerException when the privacyText is null + */ + public void setPrivacyText(Future privacyText) { + if (privacyText == null) + throw new NullPointerException("privacyText is null"); + this.mPrivacyText = privacyText; + } + + /** + * Obtains the license text stored + * + * @return Future with the text + * @throws NullPointerException when there is no text stored + */ + public Future getLicenseText() { + if (mPrivacyText == null) + throw new NullPointerException("There is no license text future object stored"); + return mLicenseText; + } + + /** + * Sets the license text future object + * + * @param licenseText future text to store + * @throws NullPointerException when the licenseText is null + */ + public void setLicenseText(Future licenseText) { + if (licenseText == null) + throw new NullPointerException("licenseText is null"); + this.mLicenseText = licenseText; + } + + /** + * Obtains the terms of service text stored + * + * @return Future with the text + * @throws NullPointerException when there is no text stored + */ + public Future getToSText() { + if (mPrivacyText == null) + throw new NullPointerException("There is no terms of service text future object " + + "stored"); + return mToSText; + } + + /** + * Sets the license text future object + * + * @param toSText future text to store + * @throws NullPointerException when the toSText is null + */ + public void setToSText(Future toSText) { + if (toSText == null) + throw new NullPointerException("toSText is null"); + this.mToSText = toSText; + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/objects/SlidesTypefacesContainer.java b/SecurePass/app/src/main/java/javinator9889/securepass/objects/SlidesTypefacesContainer.java similarity index 96% rename from APP/app/src/main/java/javinator9889/securepass/objects/SlidesTypefacesContainer.java rename to SecurePass/app/src/main/java/javinator9889/securepass/objects/SlidesTypefacesContainer.java index b210623..6207297 100644 --- a/APP/app/src/main/java/javinator9889/securepass/objects/SlidesTypefacesContainer.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/objects/SlidesTypefacesContainer.java @@ -1,49 +1,49 @@ -package javinator9889.securepass.objects; - -import androidx.annotation.FontRes; - -/** - * Class for containing Typeface for - * {@link com.github.paolorotolo.appintro.model.SliderPage} - * Created by Javinator9889 on 12/10/2018. - */ -public class SlidesTypefacesContainer { - private @FontRes - int mTitleTypeface; - private @FontRes - int mDescriptionTypeface; - - /** - * Public available constructor for saving the Typefaces - * - * @param titleTypeface title custom typeface (must be a @FontRes) - * @param descriptionTypeface description custom typeface (must be a @FontRes) - * @see FontRes - */ - public SlidesTypefacesContainer(@FontRes int titleTypeface, @FontRes int descriptionTypeface) { - this.mTitleTypeface = titleTypeface; - this.mDescriptionTypeface = descriptionTypeface; - } - - /** - * Obtains the stored title Typeface - * - * @return int with the @FontRes typeface - * @see FontRes - */ - @FontRes - public int getTitleTypeface() { - return mTitleTypeface; - } - - /** - * Obtains the stored description Typeface - * - * @return int with the @FontRes typeface - * @see FontRes - */ - @FontRes - public int getDescriptionTypeface() { - return mDescriptionTypeface; - } -} +package javinator9889.securepass.objects; + +import androidx.annotation.FontRes; + +/** + * Class for containing Typeface for + * {@link com.github.paolorotolo.appintro.model.SliderPage} + * Created by Javinator9889 on 12/10/2018. + */ +public class SlidesTypefacesContainer { + private @FontRes + int mTitleTypeface; + private @FontRes + int mDescriptionTypeface; + + /** + * Public available constructor for saving the Typefaces + * + * @param titleTypeface title custom typeface (must be a @FontRes) + * @param descriptionTypeface description custom typeface (must be a @FontRes) + * @see FontRes + */ + public SlidesTypefacesContainer(@FontRes int titleTypeface, @FontRes int descriptionTypeface) { + this.mTitleTypeface = titleTypeface; + this.mDescriptionTypeface = descriptionTypeface; + } + + /** + * Obtains the stored title Typeface + * + * @return int with the @FontRes typeface + * @see FontRes + */ + @FontRes + public int getTitleTypeface() { + return mTitleTypeface; + } + + /** + * Obtains the stored description Typeface + * + * @return int with the @FontRes typeface + * @see FontRes + */ + @FontRes + public int getDescriptionTypeface() { + return mDescriptionTypeface; + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/util/DisplayUnitsConverter.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/DisplayUnitsConverter.java similarity index 90% rename from APP/app/src/main/java/javinator9889/securepass/util/DisplayUnitsConverter.java rename to SecurePass/app/src/main/java/javinator9889/securepass/util/DisplayUnitsConverter.java index 5f80fe6..1cc1b98 100644 --- a/APP/app/src/main/java/javinator9889/securepass/util/DisplayUnitsConverter.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/DisplayUnitsConverter.java @@ -1,124 +1,122 @@ -package javinator9889.securepass.util; - -import android.content.Context; -import android.content.res.Resources; - -/** - * Contains methods to convert dp to px, px to dp, sp to px and so on - * Awesome! - * - * @see Converting pixels to dp on stackoverflow.com - * @author Artem Zinnatullin [artem.zinnatullin@gmail.com] - */ -public class DisplayUnitsConverter { - - private DisplayUnitsConverter() {} - - //region with Context - - /** - * Converts dp unit to equivalent pixels, depending on device density. - * - * @param context - * Context to get resources and device specific display metrics - * @param dp - * A value in dp (density independent pixels) unit. Which we need to convert into pixels - * @return An int value to represent px equivalent to dp depending on device density - */ - public static float dpToPx(Context context, final float dp) { - return dp * (context.getResources().getDisplayMetrics().densityDpi / 160f); - } - - /** - * Converts device specific pixels to density independent pixels. - * - * @param context - * Context to get resources and device specific display metrics - * @param px - * A value in px (pixels) unit. Which we need to convert into db - * @return A float value to represent dp equivalent to px value - */ - public static float pxToDp(Context context, final float px) { - return px / (context.getResources().getDisplayMetrics().densityDpi / 160f); - } - - /** - * Converts sp unit to equivalent pixels, depending on device density and user scale options - * - * @param context - * Context to get resources and device and user specific display metrics - * @param sp - * A value in sp to convert to px - * @return A float value to represent px equivalent to sp depending on device density and user's text scale options - */ - public static float spToPx(Context context, final float sp) { - return sp * (context.getResources().getDisplayMetrics().scaledDensity); - } - - /** - * Converts device specific pixels to density independent pixels * user's value of text scale - * - * @param context - * Context to get resources and device and user specific display metrics - * @param px - * A value in px to convert to sp - * @return A float value to represent sp equivalent to px depending on device density and user's text scale options - */ - public static float pxToSp(Context context, final float px) { - return px / (context.getResources().getDisplayMetrics().scaledDensity); - } - - //endregion - - //region without Context - - /** - * Converts dp unit to equivalent pixels, depending on device density. - * Works without Context object - * - * @param dp - * A value in dp (density independent pixels) unit. Which we need to convert into pixels - * @return A float value to represent px equivalent to dp depending on device density - */ - public static float dpToPx(final float dp) { - return dp * (Resources.getSystem().getDisplayMetrics().densityDpi / 160f); - } - - /** - * Converts device specific pixels to density independent pixels. - * Works without Context object - * - * @param px - * A value in px (pixels) unit. Which we need to convert into db - * @return A float value to represent dp equivalent to px value - */ - public static float pxToDp(final float px) { - return px / (Resources.getSystem().getDisplayMetrics().densityDpi / 160f); - } - - /** - * Converts sp unit to equivalent pixels, depending on device density and user scale options - * Works without Context object - * - * @param sp - * A value in sp to convert to px - * @return A float value to represent px equivalent to sp depending on device density and user's text scale options - */ - public static float spToPx(final float sp) { - return sp * (Resources.getSystem().getDisplayMetrics().scaledDensity); - } - - /** - * Converts device specific pixels to density independent pixels * user's value of text scale - * Works without Context object - * - * @param px - * A value in px to convert to sp - * @return A float value to represent sp equivalent to px depending on device density and user's text scale options - */ - public static float pxToSp(final float px) { - return px / (Resources.getSystem().getDisplayMetrics().scaledDensity); - } - - //endregion +package javinator9889.securepass.util; + +import android.content.Context; +import android.content.res.Resources; + +import org.jetbrains.annotations.NotNull; + +/** + * Contains methods to convert dp to px, px to dp, sp to px and so on + * Awesome! + * + * @see Converting pixels to dp on stackoverflow.com + * @author Artem Zinnatullin [artem.zinnatullin@gmail.com] + */ +public class DisplayUnitsConverter { + + private DisplayUnitsConverter() {} + + //region with Context + + /** + * Converts dp unit to equivalent pixels, depending on device density. + * Works without Context object + * + * @param dp + * A value in dp (density independent pixels) unit. Which we need to convert into pixels + * @return A float value to represent px equivalent to dp depending on device density + */ + public static float dpToPx(final float dp) { + return dp * (Resources.getSystem().getDisplayMetrics().densityDpi / 160f); + } + + /** + * Converts dp unit to equivalent pixels, depending on device density. + * + * @param context + * Context to get resources and device specific display metrics + * @param dp + * A value in dp (density independent pixels) unit. Which we need to convert into pixels + * @return An int value to represent px equivalent to dp depending on device density + */ + public static float dpToPx(@NotNull Context context, final float dp) { + return dp * (context.getResources().getDisplayMetrics().densityDpi / 160f); + } + + /** + * Converts device specific pixels to density independent pixels. + * Works without Context object + * + * @param px + * A value in px (pixels) unit. Which we need to convert into db + * @return A float value to represent dp equivalent to px value + */ + public static float pxToDp(final float px) { + return px / (Resources.getSystem().getDisplayMetrics().densityDpi / 160f); + } + + /** + * Converts device specific pixels to density independent pixels. + * + * @param context + * Context to get resources and device specific display metrics + * @param px + * A value in px (pixels) unit. Which we need to convert into db + * @return A float value to represent dp equivalent to px value + */ + public static float pxToDp(@NotNull Context context, final float px) { + return px / (context.getResources().getDisplayMetrics().densityDpi / 160f); + } + + /** + * Converts sp unit to equivalent pixels, depending on device density and user scale options + * Works without Context object + * + * @param sp + * A value in sp to convert to px + * @return A float value to represent px equivalent to sp depending on device density and user's text scale options + */ + public static float spToPx(final float sp) { + return sp * (Resources.getSystem().getDisplayMetrics().scaledDensity); + } + + /** + * Converts sp unit to equivalent pixels, depending on device density and user scale options + * + * @param context + * Context to get resources and device and user specific display metrics + * @param sp + * A value in sp to convert to px + * @return A float value to represent px equivalent to sp depending on device density and user's text scale options + */ + public static float spToPx(@NotNull Context context, final float sp) { + return sp * (context.getResources().getDisplayMetrics().scaledDensity); + } + + /** + * Converts device specific pixels to density independent pixels * user's value of text scale + * Works without Context object + * + * @param px + * A value in px to convert to sp + * @return A float value to represent sp equivalent to px depending on device density and user's text scale options + */ + public static float pxToSp(final float px) { + return px / (Resources.getSystem().getDisplayMetrics().scaledDensity); + } + + /** + * Converts device specific pixels to density independent pixels * user's value of text scale + * + * @param context + * Context to get resources and device and user specific display metrics + * @param px + * A value in px to convert to sp + * @return A float value to represent sp equivalent to px depending on device density and user's text scale options + */ + public static float pxToSp(@NotNull Context context, final float px) { + return px / (context.getResources().getDisplayMetrics().scaledDensity); + } + + //endregion } \ No newline at end of file diff --git a/APP/app/src/main/java/javinator9889/securepass/util/cipher/FileCipher.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/FileCipher.java similarity index 97% rename from APP/app/src/main/java/javinator9889/securepass/util/cipher/FileCipher.java rename to SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/FileCipher.java index cb0a47c..604d8c1 100644 --- a/APP/app/src/main/java/javinator9889/securepass/util/cipher/FileCipher.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/FileCipher.java @@ -1,102 +1,102 @@ -package javinator9889.securepass.util.cipher; - -import android.content.Context; -import androidx.annotation.NonNull; -import android.util.Log; - -import com.google.common.hash.Hashing; -import com.google.common.io.Files; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; - -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.CipherInputStream; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; - -import javinator9889.securepass.BuildConfig; -import javinator9889.securepass.io.IOManager; - -/** - * Created by Javinator9889 on 05/09/2018. - */ -public class FileCipher implements ICipher { - private byte[] ivVector; - private IvParameterSpec ivSpec; - private byte[] password; - - public FileCipher(@NonNull Context activityContext) { - this.password = Hashing.sha256() - .hashString(BuildConfig.APPLICATION_ID, StandardCharsets.UTF_8) - .toString() - .substring(32, 48) - .getBytes(); - IOManager io = IOManager.newInstance(activityContext); - ivVector = new byte[IV_SIZE]; - if (io.isAnyIVVectorStored()) { - File ivFile = io.getIVVector(); - try { - ivVector = Files.toByteArray(ivFile); - } catch (IOException e) { - Log.e("FileCipher", "Error while recovering IV Vector", e); - } - } else { - SecureRandom randomGenerator = new SecureRandom(); - randomGenerator.nextBytes(ivVector); - try { - io.saveIVVector(ivVector); - } catch (IOException e) { - e.printStackTrace(); - } - } - ivSpec = new IvParameterSpec(ivVector); - } - - @Override - public void encryptFile(@NonNull File source, @NonNull File destination) - throws NoSuchPaddingException, NoSuchAlgorithmException, - InvalidAlgorithmParameterException, InvalidKeyException, IOException, - BadPaddingException, IllegalBlockSizeException - { - SecretKeySpec keySpec = new SecretKeySpec(password, ALGORITHM); - Cipher cipher = Cipher.getInstance(TRANSFORMATION); - cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); - byte[] encryptedData = cipher.doFinal(Files.toByteArray(source)); - Files.write(encryptedData, destination); - } - - @Override - public void decryptFile(@NonNull InputStream source, @NonNull File destination) - throws NoSuchPaddingException, NoSuchAlgorithmException, - InvalidAlgorithmParameterException, InvalidKeyException, IOException - { - SecretKeySpec keySpec = new SecretKeySpec(password, ALGORITHM); - Cipher cipher = Cipher.getInstance(TRANSFORMATION); - cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); - byte[] decryptedData = new byte[0]; - try (CipherInputStream inputStream = - new CipherInputStream(source, cipher)) { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - byte[] data = new byte[2048]; - while (inputStream.read(data) != -1) - buffer.write(data); - buffer.flush(); - decryptedData = buffer.toByteArray(); - } catch (IOException e) { - Log.e("DECRYPT", "Error while recovering data", e); - } - Files.write(decryptedData, destination); - } -} +package javinator9889.securepass.util.cipher; + +import android.content.Context; +import androidx.annotation.NonNull; +import android.util.Log; + +import com.google.common.hash.Hashing; +import com.google.common.io.Files; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.CipherInputStream; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +import javinator9889.securepass.BuildConfig; +import javinator9889.securepass.io.IOManager; + +/** + * Created by Javinator9889 on 05/09/2018. + */ +public class FileCipher implements ICipher { + private byte[] ivVector; + private IvParameterSpec ivSpec; + private byte[] password; + + public FileCipher(@NonNull Context activityContext) { + this.password = Hashing.sha256() + .hashString(BuildConfig.APPLICATION_ID, StandardCharsets.UTF_8) + .toString() + .substring(32, 48) + .getBytes(); + IOManager io = IOManager.newInstance(activityContext); + ivVector = new byte[IV_SIZE]; + if (io.isAnyIVVectorStored()) { + File ivFile = io.getIVVector(); + try { + ivVector = Files.toByteArray(ivFile); + } catch (IOException e) { + Log.e("FileCipher", "Error while recovering IV Vector", e); + } + } else { + SecureRandom randomGenerator = new SecureRandom(); + randomGenerator.nextBytes(ivVector); + try { + io.saveIVVector(ivVector); + } catch (IOException e) { + e.printStackTrace(); + } + } + ivSpec = new IvParameterSpec(ivVector); + } + + @Override + public void encryptFile(@NonNull File source, @NonNull File destination) + throws NoSuchPaddingException, NoSuchAlgorithmException, + InvalidAlgorithmParameterException, InvalidKeyException, IOException, + BadPaddingException, IllegalBlockSizeException + { + SecretKeySpec keySpec = new SecretKeySpec(password, ALGORITHM); + Cipher cipher = Cipher.getInstance(TRANSFORMATION); + cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); + byte[] encryptedData = cipher.doFinal(Files.toByteArray(source)); + Files.write(encryptedData, destination); + } + + @Override + public void decryptFile(@NonNull InputStream source, @NonNull File destination) + throws NoSuchPaddingException, NoSuchAlgorithmException, + InvalidAlgorithmParameterException, InvalidKeyException, IOException + { + SecretKeySpec keySpec = new SecretKeySpec(password, ALGORITHM); + Cipher cipher = Cipher.getInstance(TRANSFORMATION); + cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); + byte[] decryptedData = new byte[0]; + try (CipherInputStream inputStream = + new CipherInputStream(source, cipher)) { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + byte[] data = new byte[2048]; + while (inputStream.read(data) != -1) + buffer.write(data); + buffer.flush(); + decryptedData = buffer.toByteArray(); + } catch (IOException e) { + Log.e("DECRYPT", "Error while recovering data", e); + } + Files.write(decryptedData, destination); + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/util/cipher/FileCipherOld.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/FileCipherOld.java similarity index 97% rename from APP/app/src/main/java/javinator9889/securepass/util/cipher/FileCipherOld.java rename to SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/FileCipherOld.java index b3e77b1..89176ec 100644 --- a/APP/app/src/main/java/javinator9889/securepass/util/cipher/FileCipherOld.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/FileCipherOld.java @@ -1,180 +1,180 @@ -package javinator9889.securepass.util.cipher; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.google.common.hash.Hashing; - -import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.OutputStream; -import java.io.Serializable; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.nio.charset.StandardCharsets; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.CipherInputStream; -import javax.crypto.CipherOutputStream; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.SealedObject; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; - -import javinator9889.securepass.data.container.ClassContainer; -import javinator9889.securepass.util.values.Constants.CIPHER.FILE; - -/** - * Created by Javinator9889 on 07/04/2018. - */ -public class FileCipherOld { - private byte[] key; - //private final byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - private final int ivSize = 16; - private byte[] iv; - private IvParameterSpec ivspec; - /*private final IvParameterSpec ivspec = new IvParameterSpec(iv); - SecureRandom random = new SecureRandom();*/ - - private FileCipherOld(@NonNull byte[] key) { - this.key = key; - fixKeyLength(); - iv = new byte[ivSize]; - SecureRandom random = new SecureRandom(); - random.nextBytes(iv); - ivspec = new IvParameterSpec(iv); - } - - private FileCipherOld(@NonNull byte[] key, @NonNull byte[] iv) { - this.key = key; - fixKeyLength(); - this.iv = iv; - ivspec = new IvParameterSpec(iv); - } - - public static FileCipherOld newInstance(@NonNull String key, @Nullable byte[] iv) { - byte[] hashKey = Hashing.sha256().hashString(key, StandardCharsets.UTF_8).asBytes(); - if (iv == null) - return new FileCipherOld(hashKey); - else - return new FileCipherOld(hashKey, iv); - } - - @NonNull - public byte[] getIv() { - return iv; - } - - public Map encrypt(@NonNull Serializable classToEncrypt, - @NonNull OutputStream outputStream) - throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, - IOException, InvalidAlgorithmParameterException { - try { - SecretKeySpec secretKeySpec = new SecretKeySpec(key, FILE.ALGORITHM); - Cipher cipher = Cipher.getInstance(FILE.TRANSFORMATION); - cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivspec); - SealedObject sealedObject = new SealedObject(classToEncrypt, cipher); - - CipherOutputStream outputFile = new CipherOutputStream(outputStream, cipher); - Map mapWithEncryptedValues = new HashMap<>(); - mapWithEncryptedValues.put(sealedObject, outputFile); - return mapWithEncryptedValues; - } catch (IllegalBlockSizeException e) { - e.printStackTrace(); - return null; - } - } - - public void newEncrypt(@NonNull ClassContainer dataToEncrypt, - @NonNull OutputStream outputStream) throws IOException, - NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, - InvalidKeyException { - try { - System.out.print("Password in bytes: " + Arrays.toString(key)); - SecretKeySpec keySpec = new SecretKeySpec(key, FILE.ALGORITHM); - Cipher cipher = Cipher.getInstance(FILE.TRANSFORMATION); - cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivspec); - SealedObject sealedObject = new SealedObject(dataToEncrypt, cipher); - - CipherOutputStream cipherFile = new CipherOutputStream(outputStream, cipher); - ObjectOutputStream outputFile = new ObjectOutputStream(cipherFile); - outputFile.writeObject(sealedObject); - outputFile.close(); - } catch (IllegalBlockSizeException e) { - e.printStackTrace(); - } - } - - public Object decrypt(@NonNull InputStream inputStream) throws IOException, - NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, - InvalidAlgorithmParameterException { - System.out.print("Password in bytes: " + Arrays.toString(key)); - SecretKeySpec secretKeySpec = new SecretKeySpec(key, FILE.ALGORITHM); - Cipher cipher = Cipher.getInstance(FILE.TRANSFORMATION); - cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivspec); - - CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher); - ObjectInputStream decryptedClass = new ObjectInputStream(cipherInputStream); - SealedObject sealedObject; - try { - sealedObject = (SealedObject) decryptedClass.readObject(); - return sealedObject.getObject(cipher); - } catch (BadPaddingException | IllegalBlockSizeException | ClassNotFoundException e) { - e.printStackTrace(); - return null; - } - } - - @SuppressWarnings("unchecked") - private void fixKeyLength() { - int actualMaxKeyLength = 0; - try { - if ((actualMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES")) < 256) { - Class c = Class.forName("javax.crypto.CryptoAllPermissionCollection"); - Constructor con = c.getDeclaredConstructor(); - con.setAccessible(true); - Object allPermissionCollection = con.newInstance(); - Field f = c.getDeclaredField("all_allowed"); - f.setAccessible(true); - f.setBoolean(allPermissionCollection, true); - - c = Class.forName("javax.crypto.CryptoPermissions"); - con = c.getDeclaredConstructor(); - con.setAccessible(true); - Object allPermissions = con.newInstance(); - f = c.getDeclaredField("perms"); - f.setAccessible(true); - ((Map) f.get(allPermissions)).put("*", allPermissionCollection); - - c = Class.forName("javax.crypto.JceSecurityManager"); - f = c.getDeclaredField("defaultPolicy"); - f.setAccessible(true); - Field mf = Field.class.getDeclaredField("modifiers"); - mf.setAccessible(true); - mf.setInt(f, f.getModifiers() & ~Modifier.FINAL); - f.set(null, allPermissions); - - actualMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES"); - } - } catch (Exception e) { - throw new RuntimeException(e); - } - - if (actualMaxKeyLength < 256) - throw new RuntimeException("Impossible to change key length"); - /*else - System.out.println("Changed key length to: " + actualMaxKeyLength);*/ - } -} +package javinator9889.securepass.util.cipher; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.google.common.hash.Hashing; + +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.Serializable; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.nio.charset.StandardCharsets; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.CipherInputStream; +import javax.crypto.CipherOutputStream; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SealedObject; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +import javinator9889.securepass.data.container.ClassContainer; +import javinator9889.securepass.util.values.Constants.CIPHER.FILE; + +/** + * Created by Javinator9889 on 07/04/2018. + */ +public class FileCipherOld { + private byte[] key; + //private final byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + private final int ivSize = 16; + private byte[] iv; + private IvParameterSpec ivspec; + /*private final IvParameterSpec ivspec = new IvParameterSpec(iv); + SecureRandom random = new SecureRandom();*/ + + private FileCipherOld(@NonNull byte[] key) { + this.key = key; + fixKeyLength(); + iv = new byte[ivSize]; + SecureRandom random = new SecureRandom(); + random.nextBytes(iv); + ivspec = new IvParameterSpec(iv); + } + + private FileCipherOld(@NonNull byte[] key, @NonNull byte[] iv) { + this.key = key; + fixKeyLength(); + this.iv = iv; + ivspec = new IvParameterSpec(iv); + } + + public static FileCipherOld newInstance(@NonNull String key, @Nullable byte[] iv) { + byte[] hashKey = Hashing.sha256().hashString(key, StandardCharsets.UTF_8).asBytes(); + if (iv == null) + return new FileCipherOld(hashKey); + else + return new FileCipherOld(hashKey, iv); + } + + @NonNull + public byte[] getIv() { + return iv; + } + + public Map encrypt(@NonNull Serializable classToEncrypt, + @NonNull OutputStream outputStream) + throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, + IOException, InvalidAlgorithmParameterException { + try { + SecretKeySpec secretKeySpec = new SecretKeySpec(key, FILE.ALGORITHM); + Cipher cipher = Cipher.getInstance(FILE.TRANSFORMATION); + cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivspec); + SealedObject sealedObject = new SealedObject(classToEncrypt, cipher); + + CipherOutputStream outputFile = new CipherOutputStream(outputStream, cipher); + Map mapWithEncryptedValues = new HashMap<>(); + mapWithEncryptedValues.put(sealedObject, outputFile); + return mapWithEncryptedValues; + } catch (IllegalBlockSizeException e) { + e.printStackTrace(); + return null; + } + } + + public void newEncrypt(@NonNull ClassContainer dataToEncrypt, + @NonNull OutputStream outputStream) throws IOException, + NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, + InvalidKeyException { + try { + System.out.print("Password in bytes: " + Arrays.toString(key)); + SecretKeySpec keySpec = new SecretKeySpec(key, FILE.ALGORITHM); + Cipher cipher = Cipher.getInstance(FILE.TRANSFORMATION); + cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivspec); + SealedObject sealedObject = new SealedObject(dataToEncrypt, cipher); + + CipherOutputStream cipherFile = new CipherOutputStream(outputStream, cipher); + ObjectOutputStream outputFile = new ObjectOutputStream(cipherFile); + outputFile.writeObject(sealedObject); + outputFile.close(); + } catch (IllegalBlockSizeException e) { + e.printStackTrace(); + } + } + + public Object decrypt(@NonNull InputStream inputStream) throws IOException, + NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, + InvalidAlgorithmParameterException { + System.out.print("Password in bytes: " + Arrays.toString(key)); + SecretKeySpec secretKeySpec = new SecretKeySpec(key, FILE.ALGORITHM); + Cipher cipher = Cipher.getInstance(FILE.TRANSFORMATION); + cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivspec); + + CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher); + ObjectInputStream decryptedClass = new ObjectInputStream(cipherInputStream); + SealedObject sealedObject; + try { + sealedObject = (SealedObject) decryptedClass.readObject(); + return sealedObject.getObject(cipher); + } catch (BadPaddingException | IllegalBlockSizeException | ClassNotFoundException e) { + e.printStackTrace(); + return null; + } + } + + @SuppressWarnings("unchecked") + private void fixKeyLength() { + int actualMaxKeyLength = 0; + try { + if ((actualMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES")) < 256) { + Class c = Class.forName("javax.crypto.CryptoAllPermissionCollection"); + Constructor con = c.getDeclaredConstructor(); + con.setAccessible(true); + Object allPermissionCollection = con.newInstance(); + Field f = c.getDeclaredField("all_allowed"); + f.setAccessible(true); + f.setBoolean(allPermissionCollection, true); + + c = Class.forName("javax.crypto.CryptoPermissions"); + con = c.getDeclaredConstructor(); + con.setAccessible(true); + Object allPermissions = con.newInstance(); + f = c.getDeclaredField("perms"); + f.setAccessible(true); + ((Map) f.get(allPermissions)).put("*", allPermissionCollection); + + c = Class.forName("javax.crypto.JceSecurityManager"); + f = c.getDeclaredField("defaultPolicy"); + f.setAccessible(true); + Field mf = Field.class.getDeclaredField("modifiers"); + mf.setAccessible(true); + mf.setInt(f, f.getModifiers() & ~Modifier.FINAL); + f.set(null, allPermissions); + + actualMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES"); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + + if (actualMaxKeyLength < 256) + throw new RuntimeException("Impossible to change key length"); + /*else + System.out.println("Changed key length to: " + actualMaxKeyLength);*/ + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/util/cipher/ICipher.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/ICipher.java similarity index 87% rename from APP/app/src/main/java/javinator9889/securepass/util/cipher/ICipher.java rename to SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/ICipher.java index f5b2465..bc41e1a 100644 --- a/APP/app/src/main/java/javinator9889/securepass/util/cipher/ICipher.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/ICipher.java @@ -1,29 +1,29 @@ -package javinator9889.securepass.util.cipher; - -import androidx.annotation.NonNull; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; - -import javax.crypto.BadPaddingException; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; - -/** - * Created by Javinator9889 on 05/09/2018. - */ -public interface ICipher { - static final int IV_SIZE = 16; - static final String ALGORITHM = "AES"; - static final String TRANSFORMATION = "AES/CBC/PKCS5Padding"; - void encryptFile(@NonNull File source, @NonNull File destination) throws NoSuchPaddingException, - NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, - IOException, BadPaddingException, IllegalBlockSizeException; - void decryptFile(@NonNull InputStream source, @NonNull File destination) throws - NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, - InvalidKeyException, IOException; -} +package javinator9889.securepass.util.cipher; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +import androidx.annotation.NonNull; + +/** + * Created by Javinator9889 on 05/09/2018. + */ +public interface ICipher { + int IV_SIZE = 16; + String ALGORITHM = "AES"; + String TRANSFORMATION = "AES/CBC/PKCS5Padding"; + void encryptFile(@NonNull File source, @NonNull File destination) throws NoSuchPaddingException, + NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, + IOException, BadPaddingException, IllegalBlockSizeException; + void decryptFile(@NonNull InputStream source, @NonNull File destination) throws + NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, + InvalidKeyException, IOException; +} diff --git a/APP/app/src/main/java/javinator9889/securepass/util/cipher/PasswordCipher.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/PasswordCipher.java similarity index 96% rename from APP/app/src/main/java/javinator9889/securepass/util/cipher/PasswordCipher.java rename to SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/PasswordCipher.java index bbe1902..72711ec 100644 --- a/APP/app/src/main/java/javinator9889/securepass/util/cipher/PasswordCipher.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/PasswordCipher.java @@ -1,15 +1,15 @@ -package javinator9889.securepass.util.cipher; - -import androidx.annotation.NonNull; - -/** - * Created by Javinator9889 on 18/04/2018. - */ -public interface PasswordCipher { - String KEY = "password"; - String DEF_VALUE = "NONE"; - String FOLDER_NAME = "private"; - void putPassword(@NonNull String password); - String getPassword(); - void changeCurrentExistingPassword(@NonNull String password); -} +package javinator9889.securepass.util.cipher; + +import androidx.annotation.NonNull; + +/** + * Created by Javinator9889 on 18/04/2018. + */ +public interface PasswordCipher { + String KEY = "password"; + String DEF_VALUE = "NONE"; + String FOLDER_NAME = "private"; + void putPassword(@NonNull String password); + String getPassword(); + void changeCurrentExistingPassword(@NonNull String password); +} diff --git a/APP/app/src/main/java/javinator9889/securepass/util/cipher/PasswordSaver.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/PasswordSaver.java similarity index 96% rename from APP/app/src/main/java/javinator9889/securepass/util/cipher/PasswordSaver.java rename to SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/PasswordSaver.java index 38c7dd0..e107609 100644 --- a/APP/app/src/main/java/javinator9889/securepass/util/cipher/PasswordSaver.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/PasswordSaver.java @@ -1,42 +1,42 @@ -package javinator9889.securepass.util.cipher; - -import android.content.Context; -import androidx.annotation.NonNull; - -import com.chamber.java.library.SharedChamber; -import com.chamber.java.library.model.ChamberType; - -/** - * Created by Javinator9889 on 19/04/2018. - */ -public class PasswordSaver implements PasswordCipher { - private SharedChamber securedPreferences; - - private PasswordSaver(@NonNull Context context) { - securedPreferences = new SharedChamber.ChamberBuilder(context) - .setChamberType(ChamberType.KEY_256) - .enableCrypto(true, true) - .setFolderName(FOLDER_NAME) - .buildChamber(); - } - - public static PasswordSaver instantiate(@NonNull Context context) { - return new PasswordSaver(context); - } - - @Override - public void putPassword(@NonNull String password) { - securedPreferences.put(KEY, password); - } - - @Override - public String getPassword() { - return securedPreferences.getString(KEY, DEF_VALUE); - } - - @Override - public void changeCurrentExistingPassword(@NonNull String password) { - securedPreferences.remove(KEY); - putPassword(password); - } -} +package javinator9889.securepass.util.cipher; + +import android.content.Context; +import androidx.annotation.NonNull; + +import com.chamber.java.library.SharedChamber; +import com.chamber.java.library.model.ChamberType; + +/** + * Created by Javinator9889 on 19/04/2018. + */ +public class PasswordSaver implements PasswordCipher { + private SharedChamber securedPreferences; + + private PasswordSaver(@NonNull Context context) { + securedPreferences = new SharedChamber.ChamberBuilder(context) + .setChamberType(ChamberType.KEY_256) + .enableCrypto(true, true) + .setFolderName(FOLDER_NAME) + .buildChamber(); + } + + public static PasswordSaver instantiate(@NonNull Context context) { + return new PasswordSaver(context); + } + + @Override + public void putPassword(@NonNull String password) { + securedPreferences.put(KEY, password); + } + + @Override + public String getPassword() { + return securedPreferences.getString(KEY, DEF_VALUE); + } + + @Override + public void changeCurrentExistingPassword(@NonNull String password) { + securedPreferences.remove(KEY); + putPassword(password); + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/database/DatabaseCipher.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/database/DatabaseCipher.java new file mode 100644 index 0000000..5ac285d --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/database/DatabaseCipher.java @@ -0,0 +1,303 @@ +/* + * Copyright © 2018 - present | APP by Javinator9889 + + * This program 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. + + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + + * Created by Javinator9889 on 26/11/2018 - APP. + */ +package javinator9889.securepass.util.cipher.database; + +import android.content.ContentValues; +import android.content.Context; + +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.Arrays; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.Mac; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.spec.GCMParameterSpec; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +import androidx.annotation.NonNull; +import at.favre.lib.crypto.HKDF; +import javinator9889.securepass.io.IOManager; +import javinator9889.securepass.util.scrypt.Scrypt; + +/** + * Class for encrypting database files by using AES algorithm with the latest security options. + */ +public class DatabaseCipher { + private static final String CIPHER_ALGORITHM = "AES/GCM/NoPadding"; + private static final String HMAC_ALGORITHM = "HmacSHA256"; + private Context mContext; + + /** + * Public constructor - context is needed for accessing program files. + * + * @param context application context - cannot be {@code null}. + */ + public DatabaseCipher(@NonNull Context context) { + mContext = context; + } + + /** + * By reading database file as {@code bytes} (by using {@link IOManager#readDatabaseFileAsBytes()}), + * encrypts it as follows: + *

    + *
  • + * Obtains the saved password from file ({@link IOManager#recoverPassword()}). + *
  • + *
  • + * Recovers the key from the derived password ({@link Scrypt#getKey(String)}). + *
  • + *
  • + * Generates a randomly secure IV vector ({@link #generateSecure(SecureRandom, int)}). + *
  • + *
  • + * Generates both authentication and encryption keys from the obtained key ({@link + * #generateKey(byte[], String, int)}). + *
  • + *
  • + * Reads the entire database as {@code byte} ({@link IOManager#readDatabaseFileAsBytes()}). + *
  • + *
  • + * Generates both {@linkplain GCMParameterSpec} and {@linkplain Cipher} with the key length (256 + * bits), the IV vector and the {@linkplain #CIPHER_ALGORITHM cipher algorithm}. + *
  • + *
  • + * Encrypts the database and generates a MAC authentication ({@link #generateMac(byte[], byte[], + * byte[])}). + *
  • + *
  • + * Combines all generated params, cleans the variables and returns the result. If for any reason + * {@code mac} is {@code null}, returns immediately nothing ({@code null}). + *
  • + *
+ * + * @return {@code byte[]} with the encrypted database. If any error while processing MAC, + * returns {@code null}. + * + * @throws NoSuchAlgorithmException if the Android Provider does not support the + * encryption algorithm. + * @throws NoSuchPaddingException if the padding is not valid (it should not be + * thrown as we are not using any padding). + * @throws BadPaddingException if the padding is not valid (can be thrown if the + * algorithm is not valid with the specified padding + * - {@code null}). + * @throws IllegalBlockSizeException if the data to be processed is not a multiple of + * the block size. + * @throws InvalidAlgorithmParameterException if the generated arguments are not valid for this + * algorithm encryption. + * @throws InvalidKeyException if the key size is inappropriate. + */ + public byte[] encryptDatabase() throws NoSuchAlgorithmException, NoSuchPaddingException, + BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException, + InvalidKeyException { + IOManager io = IOManager.newInstance(mContext); + SecureRandom random = new SecureRandom(); + byte[] hashedPass = io.recoverPassword(); + byte[] key = Scrypt.getKey(new String(hashedPass)); + byte[] iv = generateSecure(random, 12); + byte[] authKey = generateKey(key, "authKey", 32); + byte[] encKey = generateKey(key, "encKey", key.length); + byte[] databaseData = io.readDatabaseFileAsBytes(); + GCMParameterSpec parameterSpec = new GCMParameterSpec(hashedPass.length * 8, iv); + final Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); + cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encKey, "AES"), parameterSpec); + byte[] cipheredDatabase = cipher.doFinal(databaseData); + byte[] mac = generateMac(authKey, iv, cipheredDatabase); + if (mac != null) { + byte[] fullyEncryptedDatabase = combineAll(iv, mac, cipheredDatabase); + Arrays.fill(encKey, (byte) 0); + Arrays.fill(authKey, (byte) 0); + return fullyEncryptedDatabase; + } else return null; + } + + /** + * By wrapping the source using {@link ByteBuffer}, recovers IV vector, MAC authentication and + * database encrypted value, returning them as a {@link ContentValues}. + * + * @param source the source where IV, MAC and database was stored. + * + * @return {@code ContentValues} with the obtained values. + * + * @throws IllegalArgumentException if the IV length is not valid ({@code != 16}) or the MAC + * length is not valid ({@code !=32}). + */ + public ContentValues getEncryptedDatabase(@NonNull byte[] source) { + ByteBuffer buffer = ByteBuffer.wrap(source); + int ivLength = (int) buffer.get(); + if (ivLength != 16) + throw new IllegalArgumentException("Invalid IV length"); + byte[] iv = new byte[ivLength]; + buffer.get(iv); + int macLength = (int) buffer.get(); + if (macLength != 32) + throw new IllegalArgumentException("Invalid MAC length"); + byte[] mac = new byte[macLength]; + buffer.get(mac); + byte[] cipherText = new byte[buffer.remaining()]; + buffer.get(cipherText); + ContentValues result = new ContentValues(3); + result.put("IV", iv); + result.put("MAC", mac); + result.put("TEXT", cipherText); + return result; + } + + /** + * By using the {@code ContentValues} with the needed params and the {@code key}, decrypts the + * database when possible: + *
    + *
  • + * Obtains the IV vector, encrypted source and MAC from {@code ContentValues (params)}. + *
  • + *
  • + * Generates both encryption and authentication keys from the provided key ({@link + * #generateKey(byte[], String, int)}). + *
  • + *
  • + * Generates the MAC for authenticating the database source ({@link #generateMac(byte[], byte[], + * byte[])}). + *
  • + *
  • + * Tries to decrypt the database by using the provided params. + *
  • + *
+ * + * @param params {@code ContentValues} generated by calling {@linkplain + * #getEncryptedDatabase(byte[])}. + * @param key the key used for decrypting. + * + * @return {@code byte[]} with the decrypted database. + * + * @throws NoSuchAlgorithmException if the Android Provider does not support the + * encryption algorithm. + * @throws NoSuchPaddingException if the padding is not valid (it should not be + * thrown as we are not using any padding). + * @throws BadPaddingException if the padding is not valid (can be thrown if the + * algorithm is not valid with the specified padding + * - {@code null}). + * @throws IllegalBlockSizeException if the data to be processed is not a multiple of + * the block size. + * @throws InvalidAlgorithmParameterException if the generated arguments are not valid for this + * algorithm encryption. + * @throws InvalidKeyException if the key size is inappropriate. + * @throws SecurityException when the MACs are not the same, so the database + * cannot be authenticated. + */ + public byte[] decryptDatabase(@NonNull ContentValues params, + @NonNull byte[] key) throws NoSuchAlgorithmException, + NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, + BadPaddingException, IllegalBlockSizeException { + byte[] iv = params.getAsByteArray("IV"); + byte[] encryptedSource = params.getAsByteArray("TEXT"); + byte[] mac = params.getAsByteArray("MAC"); + byte[] encKey = generateKey(key, "encKey", key.length); + byte[] macKey = generateKey(key, "authKey", 32); + byte[] refMac = generateMac(macKey, iv, encryptedSource); + if (!MessageDigest.isEqual(refMac, mac)) + throw new SecurityException("Cannot authenticate database"); + final Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); + cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(encKey, "AES"), new IvParameterSpec(iv)); + return cipher.doFinal(encryptedSource); + } + + /** + * Generates a secure {@code byte[]} with the provided params. + * + * @param secureRandom source secure seed. + * @param length the length used for creating the {@code byte[]} result. + * + * @return {@code byte[]} with the new secure. + */ + private byte[] generateSecure(@NonNull SecureRandom secureRandom, int length) { + byte[] result = new byte[length]; + secureRandom.nextBytes(result); + return result; + } + + /** + * Derives a provided key into a new one by using HKDF algorithm. + * + * @param fromKey source key. + * @param info key information used in derivation. + * @param keyLength result key length. + * + * @return {@code byte[]} with the derived key. + */ + private byte[] generateKey(@NonNull byte[] fromKey, @NonNull String info, int keyLength) { + return HKDF + .fromHmacSha256() + .expand(fromKey, info.getBytes(StandardCharsets.UTF_8), keyLength); + } + + /** + * Generates a MAC from the authentication key and the cipher text. + * + * @param authKey authentication key. + * @param iv IV vector. + * @param cipherText encrypted text. + * + * @return {@code byte[]} with the MAC. If any exception occurs, returns {@code null}. + */ + private byte[] generateMac(@NonNull byte[] authKey, + @NonNull byte[] iv, + @NonNull byte[] cipherText) { + try { + SecretKey macKey = new SecretKeySpec(authKey, HMAC_ALGORITHM); + Mac hmac = Mac.getInstance(HMAC_ALGORITHM); + hmac.init(macKey); + hmac.update(iv); + hmac.update(cipherText); + return hmac.doFinal(); + } catch (NoSuchAlgorithmException | InvalidKeyException e) { + e.printStackTrace(); + return null; + } + } + + /** + * After following the encryption steps, combines everything into one single file by using + * {@link ByteBuffer}. + * + * @param iv IV vector. + * @param mac MAC authentication value. + * @param cipherText encrypted text. + * + * @return {@code byte[]} with the complete combination. + */ + private byte[] combineAll(@NonNull byte[] iv, @NonNull byte[] mac, @NonNull byte[] cipherText) { + ByteBuffer byteBuffer = ByteBuffer + .allocate(1 + iv.length + 1 + mac.length + cipherText.length); + byteBuffer.put((byte) iv.length); + byteBuffer.put(iv); + byteBuffer.put((byte) mac.length); + byteBuffer.put(mac); + byteBuffer.put(cipherText); + return byteBuffer.array(); + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/keystore/IPasswordCipher.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/keystore/IPasswordCipher.java new file mode 100644 index 0000000..f8f9061 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/keystore/IPasswordCipher.java @@ -0,0 +1,94 @@ +package javinator9889.securepass.util.cipher.keystore; + +import android.content.Context; + +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.UnrecoverableEntryException; + +import androidx.annotation.NonNull; +import androidx.annotation.RequiresApi; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + *

+ * This program 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. + *

+ * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + *

+ * Created by Javinator9889 on 08/11/2018 - APP. + */ +public interface IPasswordCipher { + /** + * Default alias used when no alias is specified at {@link PasswordCipher#PasswordCipher(Context)}. + */ + String DEFAULT_ALIAS = "SecurePassKeys"; + + /** + * Android KeyStore type for {@link java.security.KeyStore#getInstance(String) KeyStore + * constructor}. + */ + String ANDROID_KEY_STORE = "AndroidKeyStore"; + + /** + * Algorithm for generating RSA keys for AndroidKeyStore. + * + * @since Android API 18 + */ + @RequiresApi(18) + String ALGORITHM_RSA = "RSA"; + + /** + * The key size of each RSA key pair. + */ + int RSA_KEY_SIZE = 4096; + + /** + * By using {@link java.security.KeyStore}, generates new keys for the specified {@code + * keyAlias} if it does not exist on {@code AndroidKeyStore}. + * + * @throws InvalidAlgorithmParameterException if there was not possible to generate new keys. + */ + void createNewKeys() throws InvalidAlgorithmParameterException; + + /** + * Removes the specified key from the {@code AndroidKeyStore} if possible. + */ + void deleteKey(); + + /** + * By using the keys stored at {@code AndroidKeyStore}, it encrypts the specified {@code + * password}, returning the encrypted value as {@code byte[]} for directly saving it into a + * file. + * + * @param passwordToEncrypt non-null {@code byte[]} with the password value to encrypt. + * + * @return {@code byte[]} with the encrypted password. + * + * @throws InvalidKeyException if the key at the entry is invalid. + * @throws UnrecoverableEntryException if the specified protParam were insufficient or invalid. + */ + byte[] encryptPassword(@NonNull byte[] passwordToEncrypt) throws InvalidKeyException, + UnrecoverableEntryException; + + /** + * By using the keys stored at {@code AndroidKeyStore}, it decrypts the specified {@code + * password}, returning the decrypted value as {@code String} for directly using it. + * + * @param encryptedPassword non-null {@code byte[]} with the password value to decrypt. + * + * @return {@code String} with the decrypted password. + * + * @throws InvalidKeyException if the key at the entry is invalid. + * @throws UnrecoverableEntryException if the specified protParam were insufficient or invalid. + */ + String decryptPassword(@NonNull byte[] encryptedPassword) throws InvalidKeyException, + UnrecoverableEntryException; +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/keystore/PasswordCipher.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/keystore/PasswordCipher.java new file mode 100644 index 0000000..ce725b4 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/keystore/PasswordCipher.java @@ -0,0 +1,286 @@ +package javinator9889.securepass.util.cipher.keystore; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.os.Build; +import android.security.KeyPairGeneratorSpec; +import android.security.keystore.KeyGenParameterSpec; +import android.security.keystore.KeyProperties; +import android.util.Log; + +import java.io.IOException; +import java.math.BigInteger; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.KeyPairGenerator; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.UnrecoverableEntryException; +import java.security.cert.CertificateException; +import java.security.spec.AlgorithmParameterSpec; +import java.util.Calendar; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.security.auth.x500.X500Principal; + +import androidx.annotation.NonNull; +import javinator9889.securepass.errors.cipher.NoPrivateKeyException; +import javinator9889.securepass.util.cipher.sign.Signature; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + *

+ * This program 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. + *

+ * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + *

+ * Created by Javinator9889 on 08/11/2018 - APP. + */ +public class PasswordCipher implements IPasswordCipher { + private static final String TAG = "PasswordCipher"; + private String mAlias; + private Context mContext; + private KeyStore mAndroidKeyStore; + + /** + * Public "default" constructor - generates a new instance by using the provided {@link Context} + * and the {@link #DEFAULT_ALIAS default alias} for KeyStore. + * + * @param context non-null context for generating and obtaining keys. + * + * @throws KeyStoreException when some error occurs while obtaining an instance from {@link + * KeyStore#getInstance(String)} and {@link #ANDROID_KEY_STORE + * AndroidKeyStore} is not available for any reason. + */ + public PasswordCipher(@NonNull Context context) throws KeyStoreException { + this(context, DEFAULT_ALIAS); + } + + /** + * Public "default" constructor - generates a new instance by using the provided {@link Context} + * and the {@link #DEFAULT_ALIAS default alias} for KeyStore. + * + * @param context non-null context for generating and obtaining keys. + * @param alias non-null {@code String} for generating the alias for saving keys at + * AndroidKeyStore. + * + * @throws KeyStoreException when some error occurs while obtaining an instance from {@link + * KeyStore#getInstance(String)} and {@link #ANDROID_KEY_STORE + * AndroidKeyStore} is not available for any reason. + * @apiNote {@link CertificateException}, {@link IOException}, {@link NoSuchAlgorithmException} + * exceptions are ignored as here the class is only getting and instance of {@link + * #ANDROID_KEY_STORE AndroidKeyStore}, so those exceptions are never thrown. + */ + public PasswordCipher(@NonNull Context context, @NonNull String alias) throws + KeyStoreException { + mContext = context; + mAlias = alias; + mAndroidKeyStore = KeyStore.getInstance(ANDROID_KEY_STORE); + try { + mAndroidKeyStore.load(null); + } catch (CertificateException | IOException | NoSuchAlgorithmException ignored) { + } + } + + + /** + * By using {@link KeyStore}, generates new keys for the specified {@code keyAlias} if it does + * not exist on {@code AndroidKeyStore}. + * + * @throws InvalidAlgorithmParameterException if there was not possible to generate new keys. + */ + @SuppressLint("WrongConstant") + @Override + public void createNewKeys() throws InvalidAlgorithmParameterException { + try { + if (mAndroidKeyStore.containsAlias(mAlias)) + return; + } catch (KeyStoreException ignored) { // KeyStore is always initialized here + } + KeyPairGenerator generator = null; + try { + generator = KeyPairGenerator.getInstance(ALGORITHM_RSA, ANDROID_KEY_STORE); + } catch (NoSuchAlgorithmException | NoSuchProviderException ignored) { + } + Calendar start = Calendar.getInstance(); + Calendar end = Calendar.getInstance(); + end.add(Calendar.YEAR, 5); + X500Principal subject = new X500Principal("CN=SecurePass, O=Javinator9889"); + BigInteger serialNumber = BigInteger.valueOf(1337); + AlgorithmParameterSpec spec = null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + spec = new KeyGenParameterSpec.Builder(mAlias, + KeyProperties.PURPOSE_ENCRYPT | + KeyProperties.PURPOSE_DECRYPT | + KeyProperties.PURPOSE_SIGN | + KeyProperties.PURPOSE_VERIFY) + .setCertificateNotBefore(start.getTime()) + .setCertificateNotAfter(end.getTime()) + .setBlockModes(KeyProperties.BLOCK_MODE_ECB, KeyProperties.BLOCK_MODE_CBC) + .setCertificateSerialNumber(serialNumber) + .setCertificateSubject(subject) + .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512) + .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1, + KeyProperties.ENCRYPTION_PADDING_PKCS7, + KeyProperties.ENCRYPTION_PADDING_RSA_OAEP) + .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1, + KeyProperties.SIGNATURE_PADDING_RSA_PSS) +// .setIsStrongBoxBacked(true) - need more testings + .setKeySize(RSA_KEY_SIZE) + .setRandomizedEncryptionRequired(true) + .build(); + } else { + try { + spec = new KeyPairGeneratorSpec.Builder(mContext) + .setAlias(mAlias) + .setStartDate(start.getTime()) + .setEndDate(end.getTime()) + .setSerialNumber(serialNumber) + .setKeySize(RSA_KEY_SIZE) + .setSubject(subject) + .setKeyType(ALGORITHM_RSA) + .build(); + } catch (NoSuchAlgorithmException ignored) { + } + } + if (generator != null) { + generator.initialize(spec); + generator.generateKeyPair(); + } + } + + /** + * Removes the specified key from the {@code AndroidKeyStore} if possible. + */ + @Override + public void deleteKey() { + try { + mAndroidKeyStore.deleteEntry(mAlias); + } catch (KeyStoreException e) { + Log.e(TAG, String.format("Entry \"%s\" cannot be deleted", mAlias), e); + } + } + + /** + * By using the keys stored at {@code AndroidKeyStore}, it encrypts the specified {@code + * password}, returning the encrypted value as {@code byte[]} for directly saving it into a + * file. + * + * @param passwordToEncrypt non-null {@code byte[]} with the password value to encrypt. + * + * @return {@code byte[]} with the encrypted password. + * + * @throws InvalidKeyException if the key at the entry is invalid. + * @throws UnrecoverableEntryException if the specified protParam were insufficient or invalid. + */ + @Override + public byte[] encryptPassword(@NonNull byte[] passwordToEncrypt) throws InvalidKeyException, + UnrecoverableEntryException { + try { + KeyStore.Entry entry = mAndroidKeyStore.getEntry(mAlias, null); + if (!(entry instanceof KeyStore.PrivateKeyEntry)) + throw new NoPrivateKeyException(String.format("There is no private key for alias: " + + "\"%s\"", mAlias)); + Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); + cipher.init(Cipher.ENCRYPT_MODE, ((KeyStore.PrivateKeyEntry) entry).getCertificate()); + return cipher.doFinal(passwordToEncrypt); + } catch (NoSuchAlgorithmException | NoSuchPaddingException | BadPaddingException | + IllegalBlockSizeException | KeyStoreException ignored) { + return null; + } + } + + /** + * By using the keys stored at {@code AndroidKeyStore}, it decrypts the specified {@code + * password}, returning the decrypted value as {@code String} for directly using it. + * + * @param encryptedPassword non-null {@code byte[]} with the password value to decrypt. + * + * @return {@code String} with the decrypted password. + * + * @throws InvalidKeyException if the key at the entry is invalid. + * @throws UnrecoverableEntryException if the specified protParam were insufficient or invalid. + */ + @Override + public String decryptPassword(@NonNull byte[] encryptedPassword) throws InvalidKeyException, + UnrecoverableEntryException { + try { + KeyStore.Entry entry = mAndroidKeyStore.getEntry(mAlias, null); + if (!(entry instanceof KeyStore.PrivateKeyEntry)) + throw new NoPrivateKeyException(String.format("There is no private key for alias: " + + "\"%s\"", mAlias)); + Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); + cipher.init(Cipher.DECRYPT_MODE, ((KeyStore.PrivateKeyEntry) entry).getPrivateKey()); + byte[] decryptedValue = cipher.doFinal(encryptedPassword); + return new String(decryptedValue); + } catch (NoSuchAlgorithmException | NoSuchPaddingException | BadPaddingException | + IllegalBlockSizeException | KeyStoreException ignored) { + return null; + } + } + + /** + * Signs a {@code String} by using the provided {@link KeyStore.PrivateKeyEntry} {@code private + * key}. + * + * @param data data to sign - cannot be null + * @param privateKey entry which contains the private key - cannot be null + * + * @return a {@code byte[]} with the signed data if no error occurred. If not, returns {@code + * null}. + * + * @throws InvalidKeyException if the key at the entry is invalid. + */ + private byte[] sign(@NonNull String data, @NonNull PrivateKey privateKey) + throws InvalidKeyException, NoSuchProviderException { + Signature signer = new Signature(); + try { + return signer.sign(data, privateKey); + } catch (NoSuchAlgorithmException | NoSuchPaddingException | BadPaddingException | + IllegalBlockSizeException e) { // those errors should never happen + System.err.println("EXCEPTION!"); + e.printStackTrace(); + return null; + } + } + + /** + * Removes the signature of the given {@code data} by using the public key. + * + * @param data data where removing the sign - cannot be null. + * @param publicKey entry which contains the {@link java.security.KeyStore + * .PrivateKeyEntry#getCertificate() certificate} of the public key - cannot be + * null. + * + * @return {@code String} with the original data before signing, null if any exception occurs. + * + * @throws InvalidKeyException if such the key stored at the entry or the certificate are not + * valid. + */ + private String removeSignature(@NonNull byte[] data, @NonNull PublicKey publicKey) + throws InvalidKeyException, NoSuchProviderException { + Signature signer = new Signature(); + try { + return signer.removeSign(data, publicKey); + } catch (NoSuchAlgorithmException | NoSuchPaddingException | BadPaddingException | + IllegalBlockSizeException e) { // those errors should never happen + System.err.println("EXCEPTION!"); + e.printStackTrace(); + return null; + } + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/sign/Signature.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/sign/Signature.java new file mode 100644 index 0000000..e650c07 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/cipher/sign/Signature.java @@ -0,0 +1,149 @@ +package javinator9889.securepass.util.cipher.sign; + +import android.os.Build; + +import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PrivateKey; +import java.security.PublicKey; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + *

+ * This program 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. + *

+ * This program 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 this program. If + * not, see https://www.gnu.org/licenses/. + *

+ * Created by Javinator9889 on 11/11/2018 - APP. + */ +public class Signature { + private String mAlgorithm; + private String mProvider; + + /** + * Public default constructor for signing - it sets the {@link #mAlgorithm algorithm} to RSA. + */ + public Signature() { + this(null, null); + } + + /** + * Constructor for providing a custom signing algorithm to use with {@link Cipher} - if {@code + * null} or empty string {@code ""}, it sets to RSA. + * + * @param signAlgorithm algorithm to do the signature - if {@code null} or empty string {@code + * ""}, it sets to RSA/ECB/PKCS1Padding. + * @param provider cipher provider - if {@code null} or empty string {@code ""}, it is set + * to "AndroidOpenSSl" (if lower than Marshmallow) or + * "AndroidKeyStoreBCWorkaround" (if Marshmallow or higher). + */ + public Signature(@Nullable String signAlgorithm, @Nullable String provider) { + mAlgorithm = (signAlgorithm != null && !signAlgorithm.equals("")) ? + signAlgorithm : + "RSA"; + mProvider = (provider != null && !provider.equals("")) ? + provider : + (Build.VERSION.SDK_INT < Build.VERSION_CODES.M ? + "AndroidOpenSSL" : + "AndroidKeyStoreBCWorkaround"); + } + + /** + * Signs the data using the provided private key - for signing, an input is ciphered with the + * private key, so for checking the authenticity of the user only the public key can decrypt the + * obtained output. + * + * @param data input data to sign. + * @param privateKey private key used for signing. + * + * @return {@code byte[]} with the input signed. + * + * @throws NoSuchAlgorithmException if transformation is null, empty, in an invalid format, or + * if no Provider supports a CipherSpi implementation for the + * specified algorithm. + * @throws InvalidKeyException InvalidKeyException if the given key is inappropriate for + * initializing this cipher, or requires algorithm parameters + * that cannot be determined from the given key, or if the + * given key has a keysize that exceeds the maximum allowable + * keysize (as determined from the configured jurisdiction + * policy files). + * @throws NoSuchPaddingException if transformation contains a padding scheme that is not + * available. + * @throws BadPaddingException if this cipher is in decryption mode, and (un)padding has + * been requested, but the decrypted data is not bounded by + * the appropriate padding bytes. + * @throws IllegalBlockSizeException if this cipher is a block cipher, no padding has been + * requested (only in encryption mode), and the total input + * length of the data processed by this cipher is not a + * multiple of block size; or if this encryption algorithm is + * unable to process the input data provided. + * @throws NoSuchProviderException if the specified provider is not registered in the security + * provider list. + */ + public byte[] sign(@NonNull String data, @NonNull PrivateKey privateKey) throws + NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, + BadPaddingException, IllegalBlockSizeException, NoSuchProviderException { + Cipher signer = Cipher.getInstance(mAlgorithm); + signer.init(Cipher.ENCRYPT_MODE, privateKey); + return signer.doFinal(data.getBytes()); + } + + /** + * Removes the sign for obtaining the original signed data - as explained at {@link + * #sign(String, PrivateKey) sign method}, for signing first the input is ciphered using the + * private key, so for removing that signature the public key is used, as it is the only key + * that can remove the signature for verifying the authenticity of the user who signed the + * input. + * + * @param data input data that will get the signature removed. + * @param publicKey key necessary for removing the signature. + * + * @return {@code String} with the original data. + * + * @throws NoSuchAlgorithmException if transformation is null, empty, in an invalid format, or + * if no Provider supports a CipherSpi implementation for the + * specified algorithm. + * @throws InvalidKeyException InvalidKeyException if the given key is inappropriate for + * initializing this cipher, or requires algorithm parameters + * that cannot be determined from the given key, or if the + * given key has a keysize that exceeds the maximum allowable + * keysize (as determined from the configured jurisdiction + * policy files). + * @throws NoSuchPaddingException if transformation contains a padding scheme that is not + * available. + * @throws BadPaddingException if this cipher is in decryption mode, and (un)padding has + * been requested, but the decrypted data is not bounded by + * the appropriate padding bytes. + * @throws IllegalBlockSizeException if this cipher is a block cipher, no padding has been + * requested (only in encryption mode), and the total input + * length of the data processed by this cipher is not a + * multiple of block size; or if this encryption algorithm is + * unable to process the input data provided. + * @throws NoSuchProviderException if the specified provider is not registered in the security + * provider list. + */ + public String removeSign(@NonNull byte[] data, @NonNull PublicKey publicKey) throws + NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, + BadPaddingException, IllegalBlockSizeException, NoSuchProviderException { + Cipher signer = Cipher.getInstance(mAlgorithm); + signer.init(Cipher.DECRYPT_MODE, publicKey); + return new String(signer.doFinal(data), StandardCharsets.UTF_8); + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/util/resources/ISharedPreferencesManager.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/resources/ISharedPreferencesManager.java similarity index 97% rename from APP/app/src/main/java/javinator9889/securepass/util/resources/ISharedPreferencesManager.java rename to SecurePass/app/src/main/java/javinator9889/securepass/util/resources/ISharedPreferencesManager.java index 009314d..4189e53 100644 --- a/APP/app/src/main/java/javinator9889/securepass/util/resources/ISharedPreferencesManager.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/resources/ISharedPreferencesManager.java @@ -1,18 +1,18 @@ -package javinator9889.securepass.util.resources; - -/** - * Created by Javinator9889 on 04/04/2018. - */ -public interface ISharedPreferencesManager { - boolean isApplicationInitialized(); - void applicationInitialized(boolean isInitialized); - boolean isDatabaseInitialized(); - void databaseInitialized(boolean isInitialized); - boolean isPrivacyAccepted(); - void setPrivacyAccepted(boolean isAccepted); - boolean areTermsOfServiceAccepted(); - void setTermsOfServiceAccepted(boolean isAccepted); - boolean isSoftwareLicenseAccepted(); - void setSoftwareLicenseAccepted(boolean isAccepted); - boolean isApplicationLicenseAccepted(); -} +package javinator9889.securepass.util.resources; + +/** + * Created by Javinator9889 on 04/04/2018. + */ +public interface ISharedPreferencesManager { + boolean isApplicationInitialized(); + void applicationInitialized(boolean isInitialized); + boolean isDatabaseInitialized(); + void databaseInitialized(boolean isInitialized); + boolean isPrivacyAccepted(); + void setPrivacyAccepted(boolean isAccepted); + boolean areTermsOfServiceAccepted(); + void setTermsOfServiceAccepted(boolean isAccepted); + boolean isSoftwareLicenseAccepted(); + void setSoftwareLicenseAccepted(boolean isAccepted); + boolean isApplicationLicenseAccepted(); +} diff --git a/APP/app/src/main/java/javinator9889/securepass/util/resources/PreferencesManager.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/resources/PreferencesManager.java similarity index 79% rename from APP/app/src/main/java/javinator9889/securepass/util/resources/PreferencesManager.java rename to SecurePass/app/src/main/java/javinator9889/securepass/util/resources/PreferencesManager.java index eb6c5af..115ccb5 100644 --- a/APP/app/src/main/java/javinator9889/securepass/util/resources/PreferencesManager.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/resources/PreferencesManager.java @@ -1,111 +1,119 @@ -package javinator9889.securepass.util.resources; - -import android.content.SharedPreferences; -import androidx.annotation.NonNull; - -import java.util.Map; - -import javinator9889.securepass.SecurePass; - -import static javinator9889.securepass.util.values.Constants.SHARED_PREF.*; - -/** - * Created by Javinator9889 on 06/10/2018. - */ -public class PreferencesManager implements ISharedPreferencesManager { - private Map mKeys; - private volatile SharedPreferences mSharedPreferences; - private static PreferencesManager INSTANCE; - - public static synchronized PreferencesManager getInstance() { - if (INSTANCE == null) - INSTANCE = new PreferencesManager(); - return INSTANCE; - } - - public static synchronized void instantiate(@NonNull SecurePass instance) { - if (INSTANCE == null) - INSTANCE = new PreferencesManager(instance); - } - - private PreferencesManager(@NonNull SecurePass instance) { - this.mSharedPreferences = instance.getSharedPreferences(FILENAME, MODE); - mKeys = KEYS(); - } - - private PreferencesManager() { - SecurePass appInstance = SecurePass.getApplicationInstance(); - this.mSharedPreferences = appInstance - .getSharedPreferences(FILENAME, MODE); - this.mKeys = KEYS(); - } - - private void applyInBackground(@NonNull String keyName, @NonNull Object value, - @NonNull Class clazz) { - SharedPreferences.Editor editor = mSharedPreferences.edit(); - String key = mKeys.get(keyName); - switch (clazz.getSimpleName()) { - case "boolean": - editor.putBoolean(key, Boolean.class.cast(value)); - break; - default: - break; - } - editor.apply(); - } - - @Override - public boolean isApplicationInitialized() { - return mSharedPreferences.getBoolean(mKeys.get(APP_FIRST_EXECUTED), false); - } - - @Override - public void applicationInitialized(boolean isInitialized) { - applyInBackground(APP_FIRST_EXECUTED, isInitialized, Boolean.TYPE); - } - - @Override - public boolean isDatabaseInitialized() { - return mSharedPreferences.getBoolean(mKeys.get(DATABASE_INIT), false); - } - - @Override - public void databaseInitialized(boolean isInitialized) { - applyInBackground(DATABASE_INIT, isInitialized, Boolean.TYPE); - } - - @Override - public boolean isPrivacyAccepted() { - return mSharedPreferences.getBoolean(mKeys.get(PRIVACY_ACCEPT), false); - } - - @Override - public void setPrivacyAccepted(boolean isAccepted) { - applyInBackground(PRIVACY_ACCEPT, isAccepted, Boolean.TYPE); - } - - @Override - public boolean areTermsOfServiceAccepted() { - return mSharedPreferences.getBoolean(mKeys.get(TERMS_OF_SERVICE_ACCEPT), false); - } - - @Override - public void setTermsOfServiceAccepted(boolean isAccepted) { - applyInBackground(TERMS_OF_SERVICE_ACCEPT, isAccepted, Boolean.TYPE); - } - - @Override - public boolean isSoftwareLicenseAccepted() { - return mSharedPreferences.getBoolean(mKeys.get(SOFTWARE_LICENSE_ACCEPT), false); - } - - @Override - public void setSoftwareLicenseAccepted(boolean isAccepted) { - applyInBackground(SOFTWARE_LICENSE_ACCEPT, isAccepted, Boolean.TYPE); - } - - @Override - public boolean isApplicationLicenseAccepted() { - return isPrivacyAccepted() && areTermsOfServiceAccepted() && isSoftwareLicenseAccepted(); - } -} +package javinator9889.securepass.util.resources; + +import android.content.SharedPreferences; + +import java.util.Map; + +import androidx.annotation.NonNull; +import javinator9889.securepass.SecurePass; + +import static javinator9889.securepass.util.values.Constants.SHARED_PREF.APP_FIRST_EXECUTED; +import static javinator9889.securepass.util.values.Constants.SHARED_PREF.DATABASE_INIT; +import static javinator9889.securepass.util.values.Constants.SHARED_PREF.FILENAME; +import static javinator9889.securepass.util.values.Constants.SHARED_PREF.KEYS; +import static javinator9889.securepass.util.values.Constants.SHARED_PREF.MODE; +import static javinator9889.securepass.util.values.Constants.SHARED_PREF.PRIVACY_ACCEPT; +import static javinator9889.securepass.util.values.Constants.SHARED_PREF.SOFTWARE_LICENSE_ACCEPT; +import static javinator9889.securepass.util.values.Constants.SHARED_PREF.TERMS_OF_SERVICE_ACCEPT; + +/** + * Created by Javinator9889 on 06/10/2018. + */ +public class PreferencesManager implements ISharedPreferencesManager { + private Map mKeys; + private volatile SharedPreferences mSharedPreferences; + private static PreferencesManager INSTANCE; + + public static synchronized PreferencesManager getInstance() { + if (INSTANCE == null) + INSTANCE = new PreferencesManager(); + return INSTANCE; + } + + public static synchronized void instantiate(@NonNull SecurePass instance) { + if (INSTANCE == null) + INSTANCE = new PreferencesManager(instance); + } + + private PreferencesManager(@NonNull SecurePass instance) { + this.mSharedPreferences = instance.getSharedPreferences(FILENAME, MODE); + mKeys = KEYS(); + } + + private PreferencesManager() { + SecurePass appInstance = SecurePass.getApplicationInstance(); + this.mSharedPreferences = appInstance + .getSharedPreferences(FILENAME, MODE); + this.mKeys = KEYS(); + } + + private void applyInBackground(@NonNull String keyName, @NonNull Object value, + @NonNull Class clazz) { + SharedPreferences.Editor editor = mSharedPreferences.edit(); + String key = mKeys.get(keyName); + switch (clazz.getSimpleName()) { + case "boolean": + editor.putBoolean(key, Boolean.class.cast(value)); + break; + default: + break; + } + editor.apply(); + } + + @Override + public boolean isApplicationInitialized() { + return mSharedPreferences.getBoolean(mKeys.get(APP_FIRST_EXECUTED), false); + } + + @Override + public void applicationInitialized(boolean isInitialized) { + applyInBackground(APP_FIRST_EXECUTED, isInitialized, Boolean.TYPE); + } + + @Override + public boolean isDatabaseInitialized() { + return false; +// return mSharedPreferences.getBoolean(mKeys.get(DATABASE_INIT), false); + } + + @Override + public void databaseInitialized(boolean isInitialized) { + applyInBackground(DATABASE_INIT, isInitialized, Boolean.TYPE); + } + + @Override + public boolean isPrivacyAccepted() { + return mSharedPreferences.getBoolean(mKeys.get(PRIVACY_ACCEPT), false); + } + + @Override + public void setPrivacyAccepted(boolean isAccepted) { + applyInBackground(PRIVACY_ACCEPT, isAccepted, Boolean.TYPE); + } + + @Override + public boolean areTermsOfServiceAccepted() { + return mSharedPreferences.getBoolean(mKeys.get(TERMS_OF_SERVICE_ACCEPT), false); + } + + @Override + public void setTermsOfServiceAccepted(boolean isAccepted) { + applyInBackground(TERMS_OF_SERVICE_ACCEPT, isAccepted, Boolean.TYPE); + } + + @Override + public boolean isSoftwareLicenseAccepted() { + return mSharedPreferences.getBoolean(mKeys.get(SOFTWARE_LICENSE_ACCEPT), false); + } + + @Override + public void setSoftwareLicenseAccepted(boolean isAccepted) { + applyInBackground(SOFTWARE_LICENSE_ACCEPT, isAccepted, Boolean.TYPE); + } + + @Override + public boolean isApplicationLicenseAccepted() { + return isPrivacyAccepted() && areTermsOfServiceAccepted() && isSoftwareLicenseAccepted(); + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/util/resources/SharedPreferencesManager.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/resources/SharedPreferencesManager.java similarity index 91% rename from APP/app/src/main/java/javinator9889/securepass/util/resources/SharedPreferencesManager.java rename to SecurePass/app/src/main/java/javinator9889/securepass/util/resources/SharedPreferencesManager.java index ca0c7c2..5c22f09 100644 --- a/APP/app/src/main/java/javinator9889/securepass/util/resources/SharedPreferencesManager.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/resources/SharedPreferencesManager.java @@ -1,131 +1,137 @@ -package javinator9889.securepass.util.resources; - -import android.content.SharedPreferences; - -import java.util.HashMap; -import java.util.Map; - -import javinator9889.securepass.SecurePass; -import javinator9889.securepass.util.values.Constants.SHARED_PREF; - -/** - * Created by Javinator9889 on 04/04/2018. - */ -public class SharedPreferencesManager implements ISharedPreferencesManager { - private SharedPreferences preferencesInstance; - private Map sharedPreferencesKeys; - private Map keysType; - - private SharedPreferencesManager() { - SecurePass tempApplicationInstance = SecurePass.getApplicationInstance(); - this.preferencesInstance = tempApplicationInstance.getSharedPreferences( - SHARED_PREF.FILENAME, - SHARED_PREF.MODE); - loadSharedPreferencesKeys(); - } - - public static SharedPreferencesManager newInstance() { - return new SharedPreferencesManager(); - } - - public void initSharedPreferences() { - for (String key : sharedPreferencesKeys.keySet()) { - if (!preferencesInstance.contains(key)) { - SharedPreferences.Editor newEntry = preferencesInstance.edit(); - switch (keysType.get(key).getSimpleName()) { - case "boolean": - newEntry.putBoolean(key, (boolean) sharedPreferencesKeys.get(key)); - break; - case "int": - newEntry.putInt(key, (int) sharedPreferencesKeys.get(key)); - break; - case "String": - newEntry.putString(key, String.valueOf(sharedPreferencesKeys.get(key))); - break; - } - newEntry.apply(); - } - } - } - - private String getKey(int position) { - return String.valueOf(sharedPreferencesKeys.keySet().toArray()[position]); - } - - @Override - public boolean isApplicationInitialized() { - String key = getKey(0); - return preferencesInstance.getBoolean(key, (boolean) sharedPreferencesKeys.get(key)); - } - - @Override - public void applicationInitialized(boolean isInitialized) { - String key = getKey(0); - preferencesInstance.edit().putBoolean(key, isInitialized).apply(); - } - - @Override - public boolean isDatabaseInitialized() { - String key = getKey(1); - return preferencesInstance.getBoolean(key, (boolean) sharedPreferencesKeys.get(key)); - } - - @Override - public void databaseInitialized(boolean isInitialized) { - String key = getKey(1); - preferencesInstance.edit().putBoolean(key, isInitialized).apply(); - } - - @Override - public boolean isPrivacyAccepted() { - String key = getKey(2); - return preferencesInstance.getBoolean(key, (boolean) sharedPreferencesKeys.get(key)); - } - - @Override - public void setPrivacyAccepted(boolean isAccepted) { - String key = getKey(2); - preferencesInstance.edit().putBoolean(key, isAccepted).apply(); - } - - @Override - public boolean areTermsOfServiceAccepted() { - String key = getKey(3); - return preferencesInstance.getBoolean(key, (boolean) sharedPreferencesKeys.get(key)); - } - - @Override - public void setTermsOfServiceAccepted(boolean isAccepted) { - String key = getKey(3); - preferencesInstance.edit().putBoolean(key, isAccepted).apply(); - } - - @Override - public boolean isSoftwareLicenseAccepted() { - String key = getKey(4); - return preferencesInstance.getBoolean(key, (boolean) sharedPreferencesKeys.get(key)); - } - - @Override - public void setSoftwareLicenseAccepted(boolean isAccepted) { - String key = getKey(4); - preferencesInstance.edit().putBoolean(key, isAccepted).apply(); - } - - @Override - public boolean isApplicationLicenseAccepted() { - return isSoftwareLicenseAccepted() && isPrivacyAccepted() && areTermsOfServiceAccepted(); - } - - private void loadSharedPreferencesKeys() { - sharedPreferencesKeys = new HashMap<>(); - keysType = new HashMap<>(); - for (int i = 0; i < SHARED_PREF.VALUES.length; ++i) { - sharedPreferencesKeys.put( - String.valueOf(SHARED_PREF.VALUES[i][0]), - SHARED_PREF.VALUES[i][1]); - keysType.put(String.valueOf(SHARED_PREF.VALUES[i][0]), - SHARED_PREF.VALUES[i][2].getClass()); - } - } -} +package javinator9889.securepass.util.resources; + +import android.content.SharedPreferences; +import android.util.Log; + +import java.util.HashMap; +import java.util.Map; + +import javinator9889.securepass.SecurePass; +import javinator9889.securepass.util.values.Constants.SHARED_PREF; + +/** + * Created by Javinator9889 on 04/04/2018. + */ +public class SharedPreferencesManager implements ISharedPreferencesManager { + private static final String TAG = "SharedPreferences"; + private SharedPreferences preferencesInstance; + private Map sharedPreferencesKeys; + private Map keysType; + + private SharedPreferencesManager() { + SecurePass tempApplicationInstance = SecurePass.getApplicationInstance(); + this.preferencesInstance = tempApplicationInstance.getSharedPreferences( + SHARED_PREF.FILENAME, + SHARED_PREF.MODE); + loadSharedPreferencesKeys(); + } + + public static SharedPreferencesManager newInstance() { + return new SharedPreferencesManager(); + } + + public void initSharedPreferences() { + for (String key : sharedPreferencesKeys.keySet()) { + if (!preferencesInstance.contains(key)) { + SharedPreferences.Editor newEntry = preferencesInstance.edit(); + switch (keysType.get(key).getSimpleName()) { + case "boolean": + newEntry.putBoolean(key, (boolean) sharedPreferencesKeys.get(key)); + break; + case "int": + newEntry.putInt(key, (int) sharedPreferencesKeys.get(key)); + break; + case "String": + newEntry.putString(key, String.valueOf(sharedPreferencesKeys.get(key))); + break; + default: + Log.w(TAG, "Missing case statement - " + + keysType.get(key).getSimpleName()); + break; + } + newEntry.apply(); + } + } + } + + private String getKey(int position) { + return String.valueOf(sharedPreferencesKeys.keySet().toArray()[position]); + } + + @Override + public boolean isApplicationInitialized() { + String key = getKey(0); + return preferencesInstance.getBoolean(key, (boolean) sharedPreferencesKeys.get(key)); + } + + @Override + public void applicationInitialized(boolean isInitialized) { + String key = getKey(0); + preferencesInstance.edit().putBoolean(key, isInitialized).apply(); + } + + @Override + public boolean isDatabaseInitialized() { + String key = getKey(1); + return preferencesInstance.getBoolean(key, (boolean) sharedPreferencesKeys.get(key)); + } + + @Override + public void databaseInitialized(boolean isInitialized) { + String key = getKey(1); + preferencesInstance.edit().putBoolean(key, isInitialized).apply(); + } + + @Override + public boolean isPrivacyAccepted() { + String key = getKey(2); + return preferencesInstance.getBoolean(key, (boolean) sharedPreferencesKeys.get(key)); + } + + @Override + public void setPrivacyAccepted(boolean isAccepted) { + String key = getKey(2); + preferencesInstance.edit().putBoolean(key, isAccepted).apply(); + } + + @Override + public boolean areTermsOfServiceAccepted() { + String key = getKey(3); + return preferencesInstance.getBoolean(key, (boolean) sharedPreferencesKeys.get(key)); + } + + @Override + public void setTermsOfServiceAccepted(boolean isAccepted) { + String key = getKey(3); + preferencesInstance.edit().putBoolean(key, isAccepted).apply(); + } + + @Override + public boolean isSoftwareLicenseAccepted() { + String key = getKey(4); + return preferencesInstance.getBoolean(key, (boolean) sharedPreferencesKeys.get(key)); + } + + @Override + public void setSoftwareLicenseAccepted(boolean isAccepted) { + String key = getKey(4); + preferencesInstance.edit().putBoolean(key, isAccepted).apply(); + } + + @Override + public boolean isApplicationLicenseAccepted() { + return isSoftwareLicenseAccepted() && isPrivacyAccepted() && areTermsOfServiceAccepted(); + } + + private void loadSharedPreferencesKeys() { + sharedPreferencesKeys = new HashMap<>(); + keysType = new HashMap<>(); + for (int i = 0; i < SHARED_PREF.VALUES.length; ++i) { + sharedPreferencesKeys.put( + String.valueOf(SHARED_PREF.VALUES[i][0]), + SHARED_PREF.VALUES[i][1]); + keysType.put(String.valueOf(SHARED_PREF.VALUES[i][0]), + SHARED_PREF.VALUES[i][2].getClass()); + } + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/util/scrypt/Scrypt.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/scrypt/Scrypt.java new file mode 100644 index 0000000..266930d --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/scrypt/Scrypt.java @@ -0,0 +1,176 @@ +/* + * Copyright © 2018 - present | APP by Javinator9889 + + * This program 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. + + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + + * Created by Javinator9889 on 27/11/2018 - APP. + */ +package javinator9889.securepass.util.scrypt; + +import com.lambdaworks.crypto.SCrypt; +import com.lambdaworks.crypto.SCryptUtil; + +import java.nio.charset.StandardCharsets; +import java.security.GeneralSecurityException; +import java.security.SecureRandom; + +import androidx.annotation.NonNull; + +import static com.lambdaworks.codec.Base64.decode; +import static com.lambdaworks.codec.Base64.encode; + +/** + * Scrypt access util class that contains two params: {@code key} and {@code hash}. This class is + * useful for not doing the same operation twice (for obtaining the key and the hash). + */ +public class Scrypt { + private byte[] mKey; + private String mHash; + + /** + * Default constructor - sets params to {@code null}. + */ + public Scrypt() { + super(); + } + + /** + * Constructor that takes one param - useful for checking passwords + * + * @param hash the obtained hash when calling {@link #scrypt(String)} or {@link + * SCryptUtil#scrypt(String, int, int, int)} methods. + */ + public Scrypt(@NonNull String hash) { + mHash = hash; + } + + /** + * Obtains the {@code key} from the stored hashed value of the password. + * + * @param hashed hashed password obtained by using {@link #scrypt(String)}. + * + * @return {@code byte[]} with the key. + */ + public static byte[] getKey(@NonNull String hashed) { + String[] parts = hashed.split("\\$"); + + if (parts.length != 5 || !parts[1].equals("s0")) { + throw new IllegalArgumentException("Invalid hashed value"); + } + + return decode(parts[4].toCharArray()); + } + + /** + * Obtains the derived key after calling {@link #scrypt(String)} method. + * + * @return {@code byte[]} with the key if {@link #scrypt(String)} was called, else {@code null} + * or the latest value available. + */ + public byte[] getKey() { + return mKey; + } + + /** + * Calculates the {@code log2} by using bitwise operations. + * + * @param n value from which obtain {@code log2} + * + * @return {@code int} with the {@code log2}. + */ + private static int log2(int n) { + int log = 0; + if ((n & 0xffff0000) != 0) { + n >>>= 16; + log = 16; + } + if (n >= 256) { + n >>>= 8; + log += 8; + } + if (n >= 16) { + n >>>= 4; + log += 4; + } + if (n >= 4) { + n >>>= 2; + log += 2; + } + return log + (n >>> 1); + } + + /** + * Applies the scrypt to the given password, saving the result to the local variables + * (recoverable using {@link #getHash()} and {@link #getKey()}. + *

+ * It sets by default a 'N' factor (CPU & memory load factor) of 2^15 (32768 iterations). The + * 'r' factor is set to 8, which means that about {@code N · 2r · 64 bytes} of memory will be + * used (2^25 == 32 MiB). Finally, 'p' factor is 1 and key length is of 32 bytes (256 bits). + * + * @param password password for applying the scrypt + * + * @throws GeneralSecurityException when HMAC_SHA256 is not available or if no Provider supports + * a SecureRandomSpi implementation for the specified + * algorithm. + */ + public void scrypt(@NonNull String password) throws GeneralSecurityException { + int N = 1 << 15; + int r = 8; + int p = 1; + int keyLength = 32; + byte[] salt = new byte[16]; + SecureRandom.getInstance("SHA1PRNG").nextBytes(salt); + + mKey = SCrypt.scrypt(password.getBytes(StandardCharsets.UTF_8), salt, N, r, p, keyLength); + String params = Long.toString(log2(N) << 16L | r << 8 | p, 16); + + mHash = "$s0$" + params + '$' + + String.valueOf(encode(salt)) + '$' + + String.valueOf(encode(mKey)); + } + + /** + * Checks that the given password matches the hashed one - {@code hash} value cannot be {@code + * null}. Use {@link #setHash(String)} or {@link #Scrypt(String)} for that. + * + * @param password the password that will be checked. + * + * @return {@code true} whether the passwords are the same or {@code false} if they are not. + */ + public boolean check(@NonNull String password) { + if (mHash == null) + return false; + else + return SCryptUtil.check(password, mHash); + } + + /** + * Obtains the generated hash after calling {@link #scrypt(String)} method. + * + * @return {@code String} with the hash if {@link #scrypt(String)} was called, else {@code null} + * or the latest value available. + */ + public String getHash() { + return mHash; + } + + /** + * Updates the hash value for checking passwords. + * + * @param hash new hash value. + */ + public void setHash(@NonNull String hash) { + mHash = hash; + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/util/values/Constants.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/Constants.java similarity index 94% rename from APP/app/src/main/java/javinator9889/securepass/util/values/Constants.java rename to SecurePass/app/src/main/java/javinator9889/securepass/util/values/Constants.java index 96aa47d..3673d0e 100644 --- a/APP/app/src/main/java/javinator9889/securepass/util/values/Constants.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/Constants.java @@ -1,228 +1,236 @@ -package javinator9889.securepass.util.values; - -import android.content.Context; -import android.content.Intent; - -import java.util.HashMap; - -/** - * Created by Javinator9889 on 26/03/2018. - * Constants of the application that will be used in hole program - */ - -public class Constants { - public static final class SQL { - public static String DB_FILENAME = "SecurePass.db"; - public static String DB_INIT_THREAD_NAME = "DB Initializer"; - public static String DB_DEFAULT_CATEGORY = "INSERT IF NOT EXISTS INTO " + - "Category(name) VALUES (?)"; - - // INSERT SQL OPERATIONS - public static final class CATEGORY { - public static String NAME = "Category"; - public static String C_ID = "idCategory"; - public static String C_NAME = "name"; - } - - public static final class ENTRY { - public static final String NAME = "Entry"; - public static final String E_ID = "idEntry"; - public static final String E_NAME = "name"; -// public static final String E_PASSWORD = "password"; - public static final String E_ICON = "icon"; -// public static final String E_DESCRIPTION = "description"; - public static final String E_PARENT_CATEGORY = "cidCategory"; - public static final String E_PARENT_CONFIGURATION = "idConfiguration"; - } - - public static final class PASSWORD { - public static final String NAME = "Password"; - public static final String P_ID = "idPassword"; - public static final String P_PASSWORD = "password"; - public static final String P_DESCRIPTION = "field_desc"; - public static final String P_PARENT_ENTRY = "idEntry"; - public static final String P_PARENT_CATEGORY = "cidCategory"; - } - - public static final class SMALL_TEXT { - public static final String NAME = "SmallText"; - public static final String S_ID = "idSmallText"; - public static final String S_TEXT = "text"; - public static final String S_DESCRIPTION = "field_desc"; - public static final String S_PARENT_ENTRY = "idEntry"; - public static final String S_PARENT_CATEGORY = "cidCategory"; - } - - public static final class LONG_TEXT { - public static final String NAME = "LongText"; - public static final String L_ID = "idLongText"; - public static final String L_TEXT = "text"; - public static final String L_DESCRIPTION = "field_desc"; - public static final String L_PARENT_ENTRY = "idEntry"; - public static final String L_PARENT_CATEGORY = "cidCategory"; - } - - public static final class IMAGE { - public static final String NAME = "Image"; - public static final String I_ID = "idImage"; - public static final String I_SOURCE = "source"; - public static final String I_DESCRIPTION = "field_desc"; - public static final String I_PARENT_ENTRY = "idEntry"; - public static final String I_PARENT_CATEGORY = "cidCategory"; - } - - public static final class CONFIGURATION { - public static final String NAME = "Configuration"; - public static final String C_ID = "idConfiguration"; - public static final String C_NAME = "configName"; - } - - private static class COMMON_CONFIG { - public static final String F_ID = "idConfig"; - public static final String F_DESCRIPTION = "desc"; - public static final String F_SORT_ORDER = "sortOrder"; - public static final String F_PARENT_CONFIG_ID = "idConfiguration"; - } - - public static final class PASS_CONFIG extends COMMON_CONFIG { - public static final String NAME = "PassConfig"; - } - - public static final class SMALL_TEXT_CONFIG extends COMMON_CONFIG { - public static final String NAME = "SmallTextConfig"; - } - - public static final class LONG_TEXT_CONFIG extends COMMON_CONFIG { - public static final String NAME = "LongTextConfig"; - } - - public static final class IMAGES_CONFIG extends COMMON_CONFIG { - public static final String NAME = "ImagesConfig"; - } - - public static final class QR_CODE { - public static final String NAME = "QRCode"; - public static final String Q_ID = "idQRCode"; - public static final String Q_NAME = "name"; - public static final String Q_DESCRIPTION = "description"; - public static final String Q_DATA = "data"; - public static final String Q_PARENT_ENTRY = "fidEntry"; - } - - public static final class SECURITY_CODE { - public static final String NAME = "SecurityCodes"; - public static final String S_ID = "idSecurityCodes"; - public static final String S_ACCOUNT_NAME = "accountName"; - } - - public static final class FIELD { - public static final String NAME = "Fields"; - public static final String F_ID = "idField"; - public static final String F_CODE = "code"; - public static final String F_USED = "used"; - public static final String F_PARENT_SECURITY_CODE = "fidSecurityCodes"; - } - - public static String DB_NEW_ENTRY = "INSERT INTO Entry VALUES(?, ?, ?, ?, ?)"; - public static String DB_NEW_CATEGORY = "INSERT INTO Category VALUES (?)"; - public static String DB_NEW_QR = "INSERT INTO QRCode VALUES (?, ?, ?, ?)"; - public static String DB_NEW_SECURITY_CODE = "INSERT INTO SecurityCodes VALUES (?)"; - public static String DB_NEW_FIELD = "INSERT INTO Fields VALUES (?, ?, ?)"; - - //DELETE SQL OPERATIONS - public static String DB_DELETE_ENTRY_WHERE_CLAUSE = "Entry.idEntry = ?"; - public static String DB_DELETE_CATEGORY_WHERE_CLAUSE = "Category.idCategory = ?"; - public static String DB_DELETE_QR_CODE_WHERE_CLAUSE = "QRCode.idQRCode = ?"; - public static String DB_DELETE_FIELD_FROM_SECURITY_CODE_WHERE_CLAUSE = - "Fields.fidSecurityCodes = ?"; - public static String DB_DELETE_SECURITY_CODE_WHERE_CLAUSE = - "SecurityCodes.idSecurityCodes = ?"; - public static String DB_DELETE_FIELD_WHERE_CLAUSE = "Fields.idField = ?"; - - // UPDATE SQL OPERATIONS - public static String DB_UPDATE_FOR_DELETED_CATEGORY_WHERE_CLAUSE = "Entry.cidCategory = ?"; - public static String DB_UPDATE_ENTRY_WHERE_CLAUSE = "Entry.idEntry = ?"; - public static String DB_UPDATE_CATEGORY_WHERE_CLAUSE = "Category.idCategory = ?"; - public static String DB_UPDATE_QR_CODE_WHERE_CLAUSE = "QRCode.idQRCode = ?"; - public static String DB_UPDATE_SECURITY_CODE_WHERE_CLAUSE = - "SecurityCodes.idSecurityCodes = ?"; - public static String DB_UPDATE_FIELD_WHERE_CLAUSE = "Fields.idField = ?"; - public static String DB_UPDATE_PASSWORD_WHERE_CLAUSE = PASSWORD.NAME + "." + PASSWORD.P_ID - + " = ?"; - public static String DB_UPDATE_SMALL_TEXT_WHERE_CLAUSE = SMALL_TEXT.NAME + "." + - SMALL_TEXT.S_ID + " = ?"; - public static String DB_UPDATE_LONG_TEXT_WHERE_CLAUSE = LONG_TEXT.NAME + "." + - LONG_TEXT.L_ID + " = ?"; - public static String DB_UPDATE_IMAGE_WHERE_CLAUSE = IMAGE.NAME + "." + IMAGE.I_ID + " = ?"; - - // SELECT SQL OPERATIONS - public static String DB_SELECT_CATEGORIES = "SELECT * FROM Categories"; - public static String DB_SELECT_ENTRIES = "SELECT * FROM Entries"; - public static String DB_SELECT_QR_CODES = "SELECT * FROM QRCode"; - public static String DB_SELECT_SECURITY_CODES = "SELECT * FROM SecurityCodes"; - public static String DB_SELECT_FIELDS = "SELECT * FROM Fields"; - } - - public static final class CIPHER { - - public static final class FILE { - public static final String TRANSFORMATION = "AES/CBC/PKCS5Padding"; - public static final String ALGORITHM = "AES"; - } - } - - public static final class IO { - } - - public static final class FIRST_SETUP { - } - - public static final class SHARED_PREF { - public static final String FILENAME = "userPreferences"; - public static final int MODE = Context.MODE_PRIVATE; - public static final String APP_FIRST_EXECUTED = "AFE"; - public static final String DATABASE_INIT = "DBI"; - public static final String PRIVACY_ACCEPT = "PRA"; - public static final String TERMS_OF_SERVICE_ACCEPT = "TSA"; - public static final String SOFTWARE_LICENSE_ACCEPT = "SLA"; -// public HashMap KEYS = new HashMap<>(5); - public static HashMap KEYS() { - HashMap keys = new HashMap<>(5); - keys.put(APP_FIRST_EXECUTED, "isApplicationFirstExecuted"); - keys.put(DATABASE_INIT, "isDatabaseInitialized"); - keys.put(PRIVACY_ACCEPT, "isPrivacyAccepted"); - keys.put(TERMS_OF_SERVICE_ACCEPT, "areTermsOfServiceAccepted"); - keys.put(SOFTWARE_LICENSE_ACCEPT, "isSoftwareLicenseAccepted"); - return keys; - } - public static final Object[][] VALUES = new Object[][]{ - {"isApplicationFirstExecuted", false, boolean.class}, - {"isDatabaseInitialized", false, boolean.class}, - {"isPrivacyAccepted", false, boolean.class}, - {"areTermsOfServiceAccepted", false, boolean.class}, - {"isSoftwareLicenseAccepted", false, boolean.class} - }; - } - - public static final class DRIVE { - //public static final int REQUEST_CODE_SIGN_IN = 0; - //public static final int REQUEST_CODE_OPEN_ITEM = 1; - public static final int HASHSET_INITIAL_CAPACITY = 2; - public static final String MIME_TYPE = "application/x-sqlite3"; - public static final String IV_MIME_TYPE = "application/octet-stream"; - public static final Intent FILL_IN_INTENT = null; - public static final int FLAGS_MASK = 0; - public static final int FLAGS_VALUES = 0; - public static final int EXTRA_FLAGS = 0; - public static final boolean STARRED = true; - public static final String GOOGLE_PLAY_NOT_AVAILABLE = "Google Play Services are not " + - "available on this device"; - public static final String GOOGLE_ACCOUNT_NOT_SIGNED_IN = "Google Account has not signed" + - " in - impossible to use Google Drive API"; - public static final String GOOGLE_DRIVE_FILE_NOT_CREATED = "Unable to create a file on" + - " Google Drive"; - public static final String GOOGLE_FILE_NO_SELECTED = "No file selected"; - public static final String FILE_TITLE = "secpass.bak"; - public static final String IV_FILE = "latestIv.vector"; - } -} +package javinator9889.securepass.util.values; + +import android.content.Context; +import android.content.Intent; +import android.util.Base64; + +import java.nio.charset.StandardCharsets; +import java.util.HashMap; + +/** + * Created by Javinator9889 on 26/03/2018. + * Constants of the application that will be used in hole program + */ + +public class Constants { + public static final class SQL { + public static String DB_FILENAME = "SecurePass.db"; + public static String DB_INIT_THREAD_NAME = "DB Initializer"; + public static String DB_DEFAULT_CATEGORY = "INSERT IF NOT EXISTS INTO " + + "Category(name) VALUES (?)"; + + // INSERT SQL OPERATIONS + public static final class CATEGORY { + public static String NAME = "Category"; + public static String C_ID = "idCategory"; + public static String C_NAME = "name"; + } + + public static final class ENTRY { + public static final String NAME = "Entry"; + public static final String E_ID = "idEntry"; + public static final String E_NAME = "name"; +// public static final String E_PASSWORD = "password"; + public static final String E_ICON = "icon"; +// public static final String E_DESCRIPTION = "description"; + public static final String E_PARENT_CATEGORY = "cidCategory"; + public static final String E_PARENT_CONFIGURATION = "idConfiguration"; + } + + public static final class PASSWORD { + public static final String NAME = "Password"; + public static final String P_ID = "idPassword"; + public static final String P_PASSWORD = "password"; + public static final String P_DESCRIPTION = "field_desc"; + public static final String P_PARENT_ENTRY = "idEntry"; + public static final String P_PARENT_CATEGORY = "cidCategory"; + } + + public static final class SMALL_TEXT { + public static final String NAME = "SmallText"; + public static final String S_ID = "idSmallText"; + public static final String S_TEXT = "text"; + public static final String S_DESCRIPTION = "field_desc"; + public static final String S_PARENT_ENTRY = "idEntry"; + public static final String S_PARENT_CATEGORY = "cidCategory"; + } + + public static final class LONG_TEXT { + public static final String NAME = "LongText"; + public static final String L_ID = "idLongText"; + public static final String L_TEXT = "text"; + public static final String L_DESCRIPTION = "field_desc"; + public static final String L_PARENT_ENTRY = "idEntry"; + public static final String L_PARENT_CATEGORY = "cidCategory"; + } + + public static final class IMAGE { + public static final String NAME = "Image"; + public static final String I_ID = "idImage"; + public static final String I_SOURCE = "source"; + public static final String I_DESCRIPTION = "field_desc"; + public static final String I_PARENT_ENTRY = "idEntry"; + public static final String I_PARENT_CATEGORY = "cidCategory"; + } + + public static final class CONFIGURATION { + public static final String NAME = "Configuration"; + public static final String C_ID = "idConfiguration"; + public static final String C_NAME = "configName"; + } + + private static class COMMON_CONFIG { + public static final String F_ID = "idConfig"; + public static final String F_DESCRIPTION = "desc"; + public static final String F_SORT_ORDER = "sortOrder"; + public static final String F_PARENT_CONFIG_ID = "idConfiguration"; + } + + public static final class PASS_CONFIG extends COMMON_CONFIG { + public static final String NAME = "PassConfig"; + } + + public static final class SMALL_TEXT_CONFIG extends COMMON_CONFIG { + public static final String NAME = "SmallTextConfig"; + } + + public static final class LONG_TEXT_CONFIG extends COMMON_CONFIG { + public static final String NAME = "LongTextConfig"; + } + + public static final class IMAGES_CONFIG extends COMMON_CONFIG { + public static final String NAME = "ImagesConfig"; + } + + public static final class QR_CODE { + public static final String NAME = "QRCode"; + public static final String Q_ID = "idQRCode"; + public static final String Q_NAME = "name"; + public static final String Q_DESCRIPTION = "description"; + public static final String Q_DATA = "data"; + public static final String Q_PARENT_ENTRY = "fidEntry"; + } + + public static final class SECURITY_CODE { + public static final String NAME = "SecurityCodes"; + public static final String S_ID = "idSecurityCodes"; + public static final String S_ACCOUNT_NAME = "accountName"; + } + + public static final class FIELD { + public static final String NAME = "Fields"; + public static final String F_ID = "idField"; + public static final String F_CODE = "code"; + public static final String F_USED = "used"; + public static final String F_PARENT_SECURITY_CODE = "fidSecurityCodes"; + } + + public static String DB_NEW_ENTRY = "INSERT INTO Entry VALUES(?, ?, ?, ?, ?)"; + public static String DB_NEW_CATEGORY = "INSERT INTO Category VALUES (?)"; + public static String DB_NEW_QR = "INSERT INTO QRCode VALUES (?, ?, ?, ?)"; + public static String DB_NEW_SECURITY_CODE = "INSERT INTO SecurityCodes VALUES (?)"; + public static String DB_NEW_FIELD = "INSERT INTO Fields VALUES (?, ?, ?)"; + + //DELETE SQL OPERATIONS + public static String DB_DELETE_ENTRY_WHERE_CLAUSE = "Entry.idEntry = ?"; + public static String DB_DELETE_CATEGORY_WHERE_CLAUSE = "Category.idCategory = ?"; + public static String DB_DELETE_QR_CODE_WHERE_CLAUSE = "QRCode.idQRCode = ?"; + public static String DB_DELETE_FIELD_FROM_SECURITY_CODE_WHERE_CLAUSE = + "Fields.fidSecurityCodes = ?"; + public static String DB_DELETE_SECURITY_CODE_WHERE_CLAUSE = + "SecurityCodes.idSecurityCodes = ?"; + public static String DB_DELETE_FIELD_WHERE_CLAUSE = "Fields.idField = ?"; + + // UPDATE SQL OPERATIONS + public static String DB_UPDATE_FOR_DELETED_CATEGORY_WHERE_CLAUSE = "Entry.cidCategory = ?"; + public static String DB_UPDATE_ENTRY_WHERE_CLAUSE = "Entry.idEntry = ?"; + public static String DB_UPDATE_CATEGORY_WHERE_CLAUSE = "Category.idCategory = ?"; + public static String DB_UPDATE_QR_CODE_WHERE_CLAUSE = "QRCode.idQRCode = ?"; + public static String DB_UPDATE_SECURITY_CODE_WHERE_CLAUSE = + "SecurityCodes.idSecurityCodes = ?"; + public static String DB_UPDATE_FIELD_WHERE_CLAUSE = "Fields.idField = ?"; + public static String DB_UPDATE_PASSWORD_WHERE_CLAUSE = PASSWORD.NAME + "." + PASSWORD.P_ID + + " = ?"; + public static String DB_UPDATE_SMALL_TEXT_WHERE_CLAUSE = SMALL_TEXT.NAME + "." + + SMALL_TEXT.S_ID + " = ?"; + public static String DB_UPDATE_LONG_TEXT_WHERE_CLAUSE = LONG_TEXT.NAME + "." + + LONG_TEXT.L_ID + " = ?"; + public static String DB_UPDATE_IMAGE_WHERE_CLAUSE = IMAGE.NAME + "." + IMAGE.I_ID + " = ?"; + + // SELECT SQL OPERATIONS + public static String DB_SELECT_CATEGORIES = "SELECT * FROM Categories"; + public static String DB_SELECT_ENTRIES = "SELECT * FROM Entries"; + public static String DB_SELECT_QR_CODES = "SELECT * FROM QRCode"; + public static String DB_SELECT_SECURITY_CODES = "SELECT * FROM SecurityCodes"; + public static String DB_SELECT_FIELDS = "SELECT * FROM Fields"; + } + + public static final class CIPHER { + public static final class FILE { + public static final String TRANSFORMATION = "AES/CBC/PKCS5Padding"; + public static final String ALGORITHM = "AES"; + } + + public static final class PASSWORD { + public static final String ALIAS = Base64.encodeToString( + "SecurePassUserPassword".getBytes(StandardCharsets.UTF_8), + Base64.DEFAULT); + public static final String FILENAME = "usrpass"; + } + } + + public static final class IO { + } + + public static final class FIRST_SETUP { + } + + public static final class SHARED_PREF { + public static final String FILENAME = "userPreferences"; + public static final int MODE = Context.MODE_PRIVATE; + public static final String APP_FIRST_EXECUTED = "AFE"; + public static final String DATABASE_INIT = "DBI"; + public static final String PRIVACY_ACCEPT = "PRA"; + public static final String TERMS_OF_SERVICE_ACCEPT = "TSA"; + public static final String SOFTWARE_LICENSE_ACCEPT = "SLA"; +// public HashMap KEYS = new HashMap<>(5); + public static HashMap KEYS() { + HashMap keys = new HashMap<>(5); + keys.put(APP_FIRST_EXECUTED, "isApplicationFirstExecuted"); + keys.put(DATABASE_INIT, "isDatabaseInitialized"); + keys.put(PRIVACY_ACCEPT, "isPrivacyAccepted"); + keys.put(TERMS_OF_SERVICE_ACCEPT, "areTermsOfServiceAccepted"); + keys.put(SOFTWARE_LICENSE_ACCEPT, "isSoftwareLicenseAccepted"); + return keys; + } + public static final Object[][] VALUES = new Object[][]{ + {"isApplicationFirstExecuted", false, boolean.class}, + {"isDatabaseInitialized", false, boolean.class}, + {"isPrivacyAccepted", false, boolean.class}, + {"areTermsOfServiceAccepted", false, boolean.class}, + {"isSoftwareLicenseAccepted", false, boolean.class} + }; + } + + public static final class DRIVE { + //public static final int REQUEST_CODE_SIGN_IN = 0; + //public static final int REQUEST_CODE_OPEN_ITEM = 1; + public static final int HASHSET_INITIAL_CAPACITY = 2; + public static final String MIME_TYPE = "application/x-sqlite3"; + public static final String IV_MIME_TYPE = "application/octet-stream"; + public static final Intent FILL_IN_INTENT = null; + public static final int FLAGS_MASK = 0; + public static final int FLAGS_VALUES = 0; + public static final int EXTRA_FLAGS = 0; + public static final boolean STARRED = true; + public static final String GOOGLE_PLAY_NOT_AVAILABLE = "Google Play Services are not " + + "available on this device"; + public static final String GOOGLE_ACCOUNT_NOT_SIGNED_IN = "Google Account has not signed" + + " in - impossible to use Google Drive API"; + public static final String GOOGLE_DRIVE_FILE_NOT_CREATED = "Unable to create a file on" + + " Google Drive"; + public static final String GOOGLE_FILE_NO_SELECTED = "No file selected"; + public static final String FILE_TITLE = "secpass.bak"; + public static final String IV_FILE = "latestIv.vector"; + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/util/values/DatabaseTables.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/DatabaseTables.java similarity index 90% rename from APP/app/src/main/java/javinator9889/securepass/util/values/DatabaseTables.java rename to SecurePass/app/src/main/java/javinator9889/securepass/util/values/DatabaseTables.java index bb259ed..d46bc6e 100644 --- a/APP/app/src/main/java/javinator9889/securepass/util/values/DatabaseTables.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/DatabaseTables.java @@ -1,9 +1,9 @@ -package javinator9889.securepass.util.values; - -/** - * Created by Javinator9889 on 18/05/2018. - */ -public enum DatabaseTables { - CATEGORY, ENTRY, QR_CODE, SECURITY_CODE, FIELD, IMAGE, PASSWORD, LONG_TEXT, SMALL_TEXT, - CONFIGURATION, PASS_CONFIG, SMALL_TEXT_CONFIG, LONG_TEXT_CONFIG, IMAGES_CONFIG -} +package javinator9889.securepass.util.values; + +/** + * Created by Javinator9889 on 18/05/2018. + */ +public enum DatabaseTables { + CATEGORY, ENTRY, QR_CODE, SECURITY_CODE, FIELD, IMAGE, PASSWORD, LONG_TEXT, SMALL_TEXT, + CONFIGURATION, PASS_CONFIG, SMALL_TEXT_CONFIG, LONG_TEXT_CONFIG, IMAGES_CONFIG; +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/CategoryFields.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/CategoryFields.java new file mode 100644 index 0000000..f674e76 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/CategoryFields.java @@ -0,0 +1,58 @@ +package javinator9889.securepass.util.values.database; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 30/10/2018 - APP. + */ +public enum CategoryFields implements FieldsOperations { + ID("idCategory", 0), + NAME("name", 1); + + private String mFieldName; + private int mFieldIndex; + + /** + * Private constructor that sets the table field name and index order + * + * @param fieldName name for identifying the column in the database + * @param fieldIndex column index + */ + CategoryFields(String fieldName, int fieldIndex) { + mFieldName = fieldName; + mFieldIndex = fieldIndex; + } + + /** + * Obtains current field name + * + * @return {@code String} with the column identifier + */ + @Override + public String getFieldName() { + return mFieldName; + } + + /** + * Obtains current field index + * + * @return {@code int} with the column index + */ + @Override + public int getFieldIndex() { + return mFieldIndex; + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/ConfigFieldsFields.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/ConfigFieldsFields.java new file mode 100644 index 0000000..5a892c0 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/ConfigFieldsFields.java @@ -0,0 +1,60 @@ +package javinator9889.securepass.util.values.database; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 30/10/2018 - APP. + */ +public enum ConfigFieldsFields implements FieldsOperations { + ID("idConfig", 0), + DESCRIPTION("desc", 1), + ORDER("sortOrder", 2), + CONFIGURATION("idConfiguration", 3); + + private String mFieldName; + private int mFieldIndex; + + /** + * Private constructor that sets the table field name and index order + * + * @param fieldName name for identifying the column in the database + * @param fieldIndex column index + */ + ConfigFieldsFields(String fieldName, int fieldIndex) { + mFieldName = fieldName; + mFieldIndex = fieldIndex; + } + + /** + * Obtains current field name + * + * @return {@code String} with the column identifier + */ + @Override + public String getFieldName() { + return mFieldName; + } + + /** + * Obtains current field index + * + * @return {@code int} with the column index + */ + @Override + public int getFieldIndex() { + return mFieldIndex; + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/ConfigurationFields.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/ConfigurationFields.java new file mode 100644 index 0000000..0ecef45 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/ConfigurationFields.java @@ -0,0 +1,58 @@ +package javinator9889.securepass.util.values.database; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 30/10/2018 - APP. + */ +public enum ConfigurationFields implements FieldsOperations { + ID("idConfiguration", 0), + NAME("configName", 1); + + private String mFieldName; + private int mFieldIndex; + + /** + * Private constructor that sets the table field name and index order + * + * @param fieldName name for identifying the column in the database + * @param fieldIndex column index + */ + ConfigurationFields(String fieldName, int fieldIndex) { + mFieldName = fieldName; + mFieldIndex = fieldIndex; + } + + /** + * Obtains current field name + * + * @return {@code String} with the column identifier + */ + @Override + public String getFieldName() { + return mFieldName; + } + + /** + * Obtains current field index + * + * @return {@code int} with the column index + */ + @Override + public int getFieldIndex() { + return mFieldIndex; + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/EntryFields.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/EntryFields.java new file mode 100644 index 0000000..299bf98 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/EntryFields.java @@ -0,0 +1,59 @@ +package javinator9889.securepass.util.values.database; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 30/10/2018 - APP. + */ +public enum EntryFields implements FieldsOperations { + ID("idEntry", 0), + ICON("icon", 1), + NAME("name", 2), + CATEGORY("cidCategory", 3), + CONFIGURATION("idConfiguration", 4); + + private String mFieldName; + private int mFieldIndex; + + /** + * Private constructor that sets the table field name and index order + * + * @param fieldName name for identifying the column in the database + * @param fieldIndex column index + */ + EntryFields(String fieldName, int fieldIndex) { + mFieldName = fieldName; + mFieldIndex = fieldIndex; + } + + /** + * Obtains current field name + * + * @return {@code String} with the column identifier + */ + public String getFieldName() { + return mFieldName; + } + + /** + * Obtains current field index + * + * @return {@code int} with the column index + */ + public int getFieldIndex() { + return mFieldIndex; + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/FieldsFields.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/FieldsFields.java new file mode 100644 index 0000000..0a2edf6 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/FieldsFields.java @@ -0,0 +1,60 @@ +package javinator9889.securepass.util.values.database; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 30/10/2018 - APP. + */ +public enum FieldsFields implements FieldsOperations { + ID("idField", 0), + CODE("code", 1), + USED("used", 2), + SECURITY_CODES("fidSecurityCodes", 3); + + private String mFieldName; + private int mFieldIndex; + + /** + * Private constructor that sets the table field name and index order + * + * @param fieldName name for identifying the column in the database + * @param fieldIndex column index + */ + FieldsFields(String fieldName, int fieldIndex) { + mFieldName = fieldName; + mFieldIndex = fieldIndex; + } + + /** + * Obtains current field name + * + * @return {@code String} with the column identifier + */ + @Override + public String getFieldName() { + return mFieldName; + } + + /** + * Obtains current field index + * + * @return {@code int} with the column index + */ + @Override + public int getFieldIndex() { + return mFieldIndex; + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/io/database/operations/entry/IEntryGetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/FieldsOperations.java similarity index 61% rename from APP/app/src/main/java/javinator9889/securepass/io/database/operations/entry/IEntryGetOperations.java rename to SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/FieldsOperations.java index 2a51320..74e4516 100644 --- a/APP/app/src/main/java/javinator9889/securepass/io/database/operations/entry/IEntryGetOperations.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/FieldsOperations.java @@ -1,22 +1,35 @@ -package javinator9889.securepass.io.database.operations.entry; - -/** - * Copyright © 2018 - present | APP by Javinator9889 - * - * This program 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. - * - * This program 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 this program. If not, see https://www.gnu.org/licenses/. - * - * Created by Javinator9889 on 28/10/2018 - APP. - */ -public interface IEntryGetOperations { -} +package javinator9889.securepass.util.values.database; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 30/10/2018 - APP. + */ +public interface FieldsOperations { + /** + * Obtains current field name + * + * @return {@code String} with the column identifier + */ + String getFieldName(); + + /** + * Obtains current field index + * + * @return {@code int} with the column index + */ + int getFieldIndex(); +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/ImageFields.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/ImageFields.java new file mode 100644 index 0000000..b4edf8d --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/ImageFields.java @@ -0,0 +1,61 @@ +package javinator9889.securepass.util.values.database; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 30/10/2018 - APP. + */ +public enum ImageFields implements FieldsOperations { + ID("idImage", 0), + SOURCE("source", 1), + DESCRIPTION("field_desc", 2), + ORDER("sortOrder", 3), + ENTRY("idEntry", 4); + + private String mFieldName; + private int mFieldIndex; + + /** + * Private constructor that sets the table field name and index order + * + * @param fieldName name for identifying the column in the database + * @param fieldIndex column index + */ + ImageFields(String fieldName, int fieldIndex) { + mFieldName = fieldName; + mFieldIndex = fieldIndex; + } + + /** + * Obtains current field name + * + * @return {@code String} with the column identifier + */ + @Override + public String getFieldName() { + return mFieldName; + } + + /** + * Obtains current field index + * + * @return {@code int} with the column index + */ + @Override + public int getFieldIndex() { + return mFieldIndex; + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/LongTextFields.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/LongTextFields.java new file mode 100644 index 0000000..3f02e25 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/LongTextFields.java @@ -0,0 +1,61 @@ +package javinator9889.securepass.util.values.database; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 30/10/2018 - APP. + */ +public enum LongTextFields implements FieldsOperations { + ID("idLongText", 0), + TEXT("text", 1), + DESCRIPTION("field_desc", 2), + ORDER("sortOrder", 3), + ENTRY("idEntry", 4); + + private String mFieldName; + private int mFieldIndex; + + /** + * Private constructor that sets the table field name and index order + * + * @param fieldName name for identifying the column in the database + * @param fieldIndex column index + */ + LongTextFields(String fieldName, int fieldIndex) { + mFieldName = fieldName; + mFieldIndex = fieldIndex; + } + + /** + * Obtains current field name + * + * @return {@code String} with the column identifier + */ + @Override + public String getFieldName() { + return mFieldName; + } + + /** + * Obtains current field index + * + * @return {@code int} with the column index + */ + @Override + public int getFieldIndex() { + return mFieldIndex; + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/PasswordFields.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/PasswordFields.java new file mode 100644 index 0000000..e640f3d --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/PasswordFields.java @@ -0,0 +1,61 @@ +package javinator9889.securepass.util.values.database; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 30/10/2018 - APP. + */ +public enum PasswordFields implements FieldsOperations { + ID("idPassword", 0), + PASSWORD("password", 1), + DESCRIPTION("field_desc", 2), + ORDER("sortOrder", 3), + ENTRY("idEntry", 4); + + private String mFieldName; + private int mFieldIndex; + + /** + * Private constructor that sets the table field name and index order + * + * @param fieldName name for identifying the column in the database + * @param fieldIndex column index + */ + PasswordFields(String fieldName, int fieldIndex) { + mFieldName = fieldName; + mFieldIndex = fieldIndex; + } + + /** + * Obtains current field name + * + * @return {@code String} with the column identifier + */ + @Override + public String getFieldName() { + return mFieldName; + } + + /** + * Obtains current field index + * + * @return {@code int} with the column index + */ + @Override + public int getFieldIndex() { + return mFieldIndex; + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/QRCodeFields.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/QRCodeFields.java new file mode 100644 index 0000000..21a79dc --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/QRCodeFields.java @@ -0,0 +1,61 @@ +package javinator9889.securepass.util.values.database; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 30/10/2018 - APP. + */ +public enum QRCodeFields implements FieldsOperations { + ID("idQRCode", 0), + NAME("name", 1), + DESCRIPTION("description", 2), + DATA("data", 3), + ENTRY("fidEntry", 4); + + private String mFieldName; + private int mFieldIndex; + + /** + * Private constructor that sets the table field name and index order + * + * @param fieldName name for identifying the column in the database + * @param fieldIndex column index + */ + QRCodeFields(String fieldName, int fieldIndex) { + mFieldName = fieldName; + mFieldIndex = fieldIndex; + } + + /** + * Obtains current field name + * + * @return {@code String} with the column identifier + */ + @Override + public String getFieldName() { + return mFieldName; + } + + /** + * Obtains current field index + * + * @return {@code int} with the column index + */ + @Override + public int getFieldIndex() { + return mFieldIndex; + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/SecurityCodesFields.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/SecurityCodesFields.java new file mode 100644 index 0000000..b8b25b7 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/SecurityCodesFields.java @@ -0,0 +1,58 @@ +package javinator9889.securepass.util.values.database; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 30/10/2018 - APP. + */ +public enum SecurityCodesFields implements FieldsOperations { + ID("idSecurityCodes", 0), + NAME("accountName", 1); + + private String mFieldName; + private int mFieldIndex; + + /** + * Private constructor that sets the table field name and index order + * + * @param fieldName name for identifying the column in the database + * @param fieldIndex column index + */ + SecurityCodesFields(String fieldName, int fieldIndex) { + mFieldName = fieldName; + mFieldIndex = fieldIndex; + } + + /** + * Obtains current field name + * + * @return {@code String} with the column identifier + */ + @Override + public String getFieldName() { + return mFieldName; + } + + /** + * Obtains current field index + * + * @return {@code int} with the column index + */ + @Override + public int getFieldIndex() { + return mFieldIndex; + } +} diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/SmallTextFields.java b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/SmallTextFields.java new file mode 100644 index 0000000..fe49a25 --- /dev/null +++ b/SecurePass/app/src/main/java/javinator9889/securepass/util/values/database/SmallTextFields.java @@ -0,0 +1,61 @@ +package javinator9889.securepass.util.values.database; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 30/10/2018 - APP. + */ +public enum SmallTextFields implements FieldsOperations { + ID("idSmallText", 0), + TEXT("text", 1), + DESCRIPTION("field_desc", 2), + ORDER("sortOrder", 3), + ENTRY("idEntry", 4); + + private String mFieldName; + private int mFieldIndex; + + /** + * Private constructor that sets the table field name and index order + * + * @param fieldName name for identifying the column in the database + * @param fieldIndex column index + */ + SmallTextFields(String fieldName, int fieldIndex) { + mFieldName = fieldName; + mFieldIndex = fieldIndex; + } + + /** + * Obtains current field name + * + * @return {@code String} with the column identifier + */ + @Override + public String getFieldName() { + return mFieldName; + } + + /** + * Obtains current field index + * + * @return {@code int} with the column index + */ + @Override + public int getFieldIndex() { + return mFieldIndex; + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/views/TabLayoutAdapter.java b/SecurePass/app/src/main/java/javinator9889/securepass/views/TabLayoutAdapter.java similarity index 97% rename from APP/app/src/main/java/javinator9889/securepass/views/TabLayoutAdapter.java rename to SecurePass/app/src/main/java/javinator9889/securepass/views/TabLayoutAdapter.java index 4cdcc24..8be0677 100644 --- a/APP/app/src/main/java/javinator9889/securepass/views/TabLayoutAdapter.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/views/TabLayoutAdapter.java @@ -1,149 +1,149 @@ -package javinator9889.securepass.views; - -import android.graphics.Typeface; -import android.os.Bundle; -import android.view.MenuItem; -import android.widget.LinearLayout; -import android.widget.TextView; - -import com.ogaclejapan.smarttablayout.SmartTabLayout; -import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItemAdapter; -import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItems; - -import androidx.annotation.FontRes; -import androidx.annotation.IdRes; -import androidx.annotation.Nullable; -import androidx.appcompat.app.ActionBar; -import androidx.appcompat.app.AppCompatActivity; -import androidx.core.content.res.ResourcesCompat; -import androidx.fragment.app.FragmentPagerAdapter; -import androidx.viewpager.widget.ViewPager; - -/** - * Copyright © 2018 - present | APP by Javinator9889 - * - * This program 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. - * - * This program 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 this program. If not, see https://www.gnu.org/licenses/. - * - * Created by Javinator9889 on 25/10/2018 - APP. - */ -public abstract class TabLayoutAdapter extends AppCompatActivity - implements SmartTabLayout.OnTabClickListener, ViewPager.OnPageChangeListener { - private int mCurrentPosition = 0; - private ViewPager mViewPager; - private SmartTabLayout mTabLayout; - private boolean mMustChangeTypeface = false; - private @FontRes int mSelectedTextFontRes = 0; - private @FontRes int mNonSelectedTextFontRes = 0; - private @IdRes int mTabIdRes; - private @IdRes int mViewPagerIdRes; - private boolean mMustShowBackButtonOnActionBar = false; - - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mTabLayout = findViewById(mTabIdRes); - mViewPager = findViewById(mViewPagerIdRes); - FragmentPagerItems availableTabs = getItems(); - FragmentPagerAdapter adapter = new FragmentPagerItemAdapter(getSupportFragmentManager(), - availableTabs); - mViewPager.setAdapter(adapter); - mTabLayout.setViewPager(mViewPager); - mTabLayout.setOnPageChangeListener(this); - mTabLayout.setOnTabClickListener(this); - ActionBar actionBar = getSupportActionBar(); - if (actionBar != null) - actionBar.setDisplayHomeAsUpEnabled(mMustShowBackButtonOnActionBar); - } - - @Override - public void onBackPressed() { - if (mCurrentPosition > 0) { - --mCurrentPosition; - mViewPager.setCurrentItem(mCurrentPosition, true); - } else - super.onBackPressed(); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == android.R.id.home) { - mCurrentPosition = 0; - onBackPressed(); - } - return super.onOptionsItemSelected(item); - } - - @Override - public void onTabClicked(int position) { - mCurrentPosition = position; - if (mMustChangeTypeface && mNonSelectedTextFontRes != 0 && mSelectedTextFontRes != 0) - changeTextTypeface(position, mSelectedTextFontRes, mNonSelectedTextFontRes); - } - - @Override - public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { - - } - - @Override - public void onPageSelected(int position) { - onTabClicked(position); - } - - @Override - public void onPageScrollStateChanged(int state) { - - } - - public void setMustChangeTypeface(boolean mustChangeTypeface) { - mMustChangeTypeface = mustChangeTypeface; - } - - public void setSelectedTextFontRes(@FontRes int selectedTextFontRes) { - mSelectedTextFontRes = selectedTextFontRes; - } - - public void setNonSelectedTextFontRes(@FontRes int nonSelectedTextFontRes) { - mNonSelectedTextFontRes = nonSelectedTextFontRes; - } - - public void setTabIdRes(@IdRes int tabIdRes) { - mTabIdRes = tabIdRes; - } - - public void setViewPagerIdRes(@IdRes int viewPagerIdRes) { - mViewPagerIdRes = viewPagerIdRes; - } - - public void setMustShowBackButtonOnActionBar(boolean mustShowBackButtonOnActionBar) { - mMustShowBackButtonOnActionBar = mustShowBackButtonOnActionBar; - } - - void changeTextTypeface(int position, - @FontRes int selectedFontRes, - @FontRes int nonSelectedFontRes) { - Typeface nonSelectedTextFont = ResourcesCompat.getFont(this, nonSelectedFontRes); - Typeface selectedTextFont = ResourcesCompat.getFont(this, selectedFontRes); - LinearLayout availableTabs = LinearLayout.class.cast(mTabLayout.getChildAt(0)); - for (int i = 0; i < availableTabs.getChildCount(); ++i) { - TextView currentText = TextView.class.cast(availableTabs.getChildAt(i)); - if (i != position) - currentText.setTypeface(nonSelectedTextFont); - else - currentText.setTypeface(selectedTextFont); - } - } - - protected abstract FragmentPagerItems getItems(); -} +package javinator9889.securepass.views; + +import android.graphics.Typeface; +import android.os.Bundle; +import android.view.MenuItem; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.ogaclejapan.smarttablayout.SmartTabLayout; +import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItemAdapter; +import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItems; + +import androidx.annotation.FontRes; +import androidx.annotation.IdRes; +import androidx.annotation.Nullable; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.content.res.ResourcesCompat; +import androidx.fragment.app.FragmentPagerAdapter; +import androidx.viewpager.widget.ViewPager; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 25/10/2018 - APP. + */ +public abstract class TabLayoutAdapter extends AppCompatActivity + implements SmartTabLayout.OnTabClickListener, ViewPager.OnPageChangeListener { + private int mCurrentPosition = 0; + private ViewPager mViewPager; + private SmartTabLayout mTabLayout; + private boolean mMustChangeTypeface = false; + private @FontRes int mSelectedTextFontRes = 0; + private @FontRes int mNonSelectedTextFontRes = 0; + private @IdRes int mTabIdRes; + private @IdRes int mViewPagerIdRes; + private boolean mMustShowBackButtonOnActionBar = false; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mTabLayout = findViewById(mTabIdRes); + mViewPager = findViewById(mViewPagerIdRes); + FragmentPagerItems availableTabs = getItems(); + FragmentPagerAdapter adapter = new FragmentPagerItemAdapter(getSupportFragmentManager(), + availableTabs); + mViewPager.setAdapter(adapter); + mTabLayout.setViewPager(mViewPager); + mTabLayout.setOnPageChangeListener(this); + mTabLayout.setOnTabClickListener(this); + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) + actionBar.setDisplayHomeAsUpEnabled(mMustShowBackButtonOnActionBar); + } + + @Override + public void onBackPressed() { + if (mCurrentPosition > 0) { + --mCurrentPosition; + mViewPager.setCurrentItem(mCurrentPosition, true); + } else + super.onBackPressed(); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + mCurrentPosition = 0; + onBackPressed(); + } + return super.onOptionsItemSelected(item); + } + + @Override + public void onTabClicked(int position) { + mCurrentPosition = position; + if (mMustChangeTypeface && mNonSelectedTextFontRes != 0 && mSelectedTextFontRes != 0) + changeTextTypeface(position, mSelectedTextFontRes, mNonSelectedTextFontRes); + } + + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + onTabClicked(position); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + + public void setMustChangeTypeface(boolean mustChangeTypeface) { + mMustChangeTypeface = mustChangeTypeface; + } + + public void setSelectedTextFontRes(@FontRes int selectedTextFontRes) { + mSelectedTextFontRes = selectedTextFontRes; + } + + public void setNonSelectedTextFontRes(@FontRes int nonSelectedTextFontRes) { + mNonSelectedTextFontRes = nonSelectedTextFontRes; + } + + public void setTabIdRes(@IdRes int tabIdRes) { + mTabIdRes = tabIdRes; + } + + public void setViewPagerIdRes(@IdRes int viewPagerIdRes) { + mViewPagerIdRes = viewPagerIdRes; + } + + public void setMustShowBackButtonOnActionBar(boolean mustShowBackButtonOnActionBar) { + mMustShowBackButtonOnActionBar = mustShowBackButtonOnActionBar; + } + + void changeTextTypeface(int position, + @FontRes int selectedFontRes, + @FontRes int nonSelectedFontRes) { + Typeface nonSelectedTextFont = ResourcesCompat.getFont(this, nonSelectedFontRes); + Typeface selectedTextFont = ResourcesCompat.getFont(this, selectedFontRes); + LinearLayout availableTabs = LinearLayout.class.cast(mTabLayout.getChildAt(0)); + for (int i = 0; i < availableTabs.getChildCount(); ++i) { + TextView currentText = TextView.class.cast(availableTabs.getChildAt(i)); + if (i != position) + currentText.setTypeface(nonSelectedTextFont); + else + currentText.setTypeface(selectedTextFont); + } + } + + protected abstract FragmentPagerItems getItems(); +} diff --git a/APP/app/src/main/java/javinator9889/securepass/views/activities/FirstSetup.java b/SecurePass/app/src/main/java/javinator9889/securepass/views/activities/FirstSetup.java similarity index 97% rename from APP/app/src/main/java/javinator9889/securepass/views/activities/FirstSetup.java rename to SecurePass/app/src/main/java/javinator9889/securepass/views/activities/FirstSetup.java index 5de206c..6f5a3e2 100644 --- a/APP/app/src/main/java/javinator9889/securepass/views/activities/FirstSetup.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/views/activities/FirstSetup.java @@ -1,149 +1,149 @@ -package javinator9889.securepass.views.activities; - -import android.content.Intent; -import android.graphics.Color; -import android.graphics.Typeface; -import android.os.Bundle; -import android.widget.Toast; - -import com.github.paolorotolo.appintro.AppIntro; -import com.github.paolorotolo.appintro.AppIntro2; -import com.github.paolorotolo.appintro.AppIntroBaseFragment; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -import androidx.annotation.Nullable; -import androidx.core.content.res.ResourcesCompat; -import androidx.fragment.app.Fragment; -import javinator9889.securepass.R; -import javinator9889.securepass.objects.SlidesTypefacesContainer; -import javinator9889.securepass.util.resources.ISharedPreferencesManager; -import javinator9889.securepass.util.resources.PreferencesManager; -import javinator9889.securepass.views.fragments.firstsetup.PasswordRegistration; -import javinator9889.securepass.views.fragments.firstsetup.slides.EulaConfirmation; -import javinator9889.securepass.views.fragments.firstsetup.slides.SlidePage; - -/** - * Created by Javinator9889 on 29/03/2018. - */ -public class FirstSetup extends AppIntro2 { - private List mFragmentList; - private String[] mTitles; - private String[] mDescriptions; - private int[] mDrawables; - private int[] mBackgroundColors; - private int[] mFontColors; - private int mElementsCount = 0; - private @Nullable String mTitleFont; - private @Nullable String mDescFont; - - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - Objects.requireNonNull(getSupportActionBar()).hide(); - initParams(); - createFragmentList(); - mTitleFont = "fonts/raleway_semibold.ttf"; - mDescFont = "fonts/raleway.ttf"; -// Typeface titleFont = ResourcesCompat.getFont(this, R.font.raleway_semibold); -// Typeface descFont = ResourcesCompat.getFont(this, R.font.raleway); - for (AppIntroBaseFragment baseFragment : mFragmentList) addSlide(baseFragment); - showSkipButton(false); - setFadeAnimation(); - } - - private void initParams() { - initTitles(); - initDescriptions(); - initDrawables(); - initBackgroundColors(); - initFontColors(); - mElementsCount = mTitles.length - 1; - } - - private void initTitles() { - this.mTitles = getResources().getStringArray(R.array.titles); - } - - private void initDescriptions() { - this.mDescriptions = getResources() - .getStringArray(R.array.descriptions); - } - - private void initDrawables() { - this.mDrawables = new int[]{ - R.drawable.speed, - R.drawable.secure_image, - R.drawable.data_security, - R.drawable.user_friendly, - R.drawable.privacy - }; - } - - private void initBackgroundColors() { - this.mBackgroundColors = new int[]{ - Color.BLUE, - Color.GRAY, - Color.GREEN, - Color.YELLOW, - Color.LTGRAY - }; - } - - private void initFontColors() { - this.mFontColors = new int[] { - Color.WHITE, - Color.WHITE, - Color.WHITE, - Color.BLACK, - Color.BLACK - }; - } - - private void createFragmentList() { - this.mFragmentList = new ArrayList<>(); - SlidesTypefacesContainer container = new SlidesTypefacesContainer(R.font.raleway_semibold, - R.font.raleway); - for (int i = 0; i < mElementsCount; ++i) { - SlidePage currentSlideFragmentToBeAdded = SlidePage.newInstance( - mTitles[i], - mDescriptions[i], - mDrawables[i], - mBackgroundColors[i], - mFontColors[i], - mFontColors[i], - container - ); - mFragmentList.add(currentSlideFragmentToBeAdded); - } - int elementToAdd = mTitles.length - 1; - EulaConfirmation eulaConfirmation = EulaConfirmation.newInstance( - mTitles[elementToAdd], - mDescriptions[elementToAdd], - mDrawables[elementToAdd], - mBackgroundColors[elementToAdd], - mFontColors[elementToAdd], - mFontColors[elementToAdd], - container); - eulaConfirmation.addPackageContext(this); - mFragmentList.add(eulaConfirmation); - } - - @Override - public void onDonePressed(Fragment currentFragment) { - super.onDonePressed(currentFragment); - ISharedPreferencesManager sharedPreferences = PreferencesManager.getInstance(); - if (sharedPreferences.isApplicationLicenseAccepted()) { - Intent startPasswordRegistration = new Intent( - this, - PasswordRegistration.class); - startActivity(startPasswordRegistration); - this.finish(); - } else { - Toast.makeText(this, R.string.no_checkbox_clicked, Toast.LENGTH_LONG).show(); - } - } -} +package javinator9889.securepass.views.activities; + +import android.content.Intent; +import android.graphics.Color; +import android.graphics.Typeface; +import android.os.Bundle; +import android.widget.Toast; + +import com.github.paolorotolo.appintro.AppIntro; +import com.github.paolorotolo.appintro.AppIntro2; +import com.github.paolorotolo.appintro.AppIntroBaseFragment; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import androidx.annotation.Nullable; +import androidx.core.content.res.ResourcesCompat; +import androidx.fragment.app.Fragment; +import javinator9889.securepass.R; +import javinator9889.securepass.objects.SlidesTypefacesContainer; +import javinator9889.securepass.util.resources.ISharedPreferencesManager; +import javinator9889.securepass.util.resources.PreferencesManager; +import javinator9889.securepass.views.fragments.firstsetup.PasswordRegistration; +import javinator9889.securepass.views.fragments.firstsetup.slides.EulaConfirmation; +import javinator9889.securepass.views.fragments.firstsetup.slides.SlidePage; + +/** + * Created by Javinator9889 on 29/03/2018. + */ +public class FirstSetup extends AppIntro2 { + private List mFragmentList; + private String[] mTitles; + private String[] mDescriptions; + private int[] mDrawables; + private int[] mBackgroundColors; + private int[] mFontColors; + private int mElementsCount = 0; + private @Nullable String mTitleFont; + private @Nullable String mDescFont; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Objects.requireNonNull(getSupportActionBar()).hide(); + initParams(); + createFragmentList(); + mTitleFont = "fonts/raleway_semibold.ttf"; + mDescFont = "fonts/raleway.ttf"; +// Typeface titleFont = ResourcesCompat.getFont(this, R.font.raleway_semibold); +// Typeface descFont = ResourcesCompat.getFont(this, R.font.raleway); + for (AppIntroBaseFragment baseFragment : mFragmentList) addSlide(baseFragment); + showSkipButton(false); + setFadeAnimation(); + } + + private void initParams() { + initTitles(); + initDescriptions(); + initDrawables(); + initBackgroundColors(); + initFontColors(); + mElementsCount = mTitles.length - 1; + } + + private void initTitles() { + this.mTitles = getResources().getStringArray(R.array.titles); + } + + private void initDescriptions() { + this.mDescriptions = getResources() + .getStringArray(R.array.descriptions); + } + + private void initDrawables() { + this.mDrawables = new int[]{ + R.drawable.speed, + R.drawable.secure_image, + R.drawable.data_security, + R.drawable.user_friendly, + R.drawable.privacy + }; + } + + private void initBackgroundColors() { + this.mBackgroundColors = new int[]{ + Color.BLUE, + Color.GRAY, + Color.GREEN, + Color.YELLOW, + Color.LTGRAY + }; + } + + private void initFontColors() { + this.mFontColors = new int[] { + Color.WHITE, + Color.WHITE, + Color.WHITE, + Color.BLACK, + Color.BLACK + }; + } + + private void createFragmentList() { + this.mFragmentList = new ArrayList<>(); + SlidesTypefacesContainer container = new SlidesTypefacesContainer(R.font.raleway_semibold, + R.font.raleway); + for (int i = 0; i < mElementsCount; ++i) { + SlidePage currentSlideFragmentToBeAdded = SlidePage.newInstance( + mTitles[i], + mDescriptions[i], + mDrawables[i], + mBackgroundColors[i], + mFontColors[i], + mFontColors[i], + container + ); + mFragmentList.add(currentSlideFragmentToBeAdded); + } + int elementToAdd = mTitles.length - 1; + EulaConfirmation eulaConfirmation = EulaConfirmation.newInstance( + mTitles[elementToAdd], + mDescriptions[elementToAdd], + mDrawables[elementToAdd], + mBackgroundColors[elementToAdd], + mFontColors[elementToAdd], + mFontColors[elementToAdd], + container); + eulaConfirmation.addPackageContext(this); + mFragmentList.add(eulaConfirmation); + } + + @Override + public void onDonePressed(Fragment currentFragment) { + super.onDonePressed(currentFragment); + ISharedPreferencesManager sharedPreferences = PreferencesManager.getInstance(); + if (sharedPreferences.isApplicationLicenseAccepted()) { + Intent startPasswordRegistration = new Intent( + this, + PasswordRegistration.class); + startActivity(startPasswordRegistration); + this.finish(); + } else { + Toast.makeText(this, R.string.no_checkbox_clicked, Toast.LENGTH_LONG).show(); + } + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/views/activities/LauncherActivity.java b/SecurePass/app/src/main/java/javinator9889/securepass/views/activities/LauncherActivity.java similarity index 97% rename from APP/app/src/main/java/javinator9889/securepass/views/activities/LauncherActivity.java rename to SecurePass/app/src/main/java/javinator9889/securepass/views/activities/LauncherActivity.java index beb2881..d9b803f 100644 --- a/APP/app/src/main/java/javinator9889/securepass/views/activities/LauncherActivity.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/views/activities/LauncherActivity.java @@ -1,72 +1,72 @@ -package javinator9889.securepass.views.activities; - -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatActivity; - -import java.io.IOException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; - -import javinator9889.securepass.R; -import javinator9889.securepass.SecurePass; -import javinator9889.securepass.io.IOManager; -import javinator9889.securepass.objects.SingletonFutureContainer; -import javinator9889.securepass.util.resources.ISharedPreferencesManager; -import javinator9889.securepass.util.resources.PreferencesManager; -import javinator9889.securepass.util.resources.SharedPreferencesManager; -import javinator9889.securepass.views.fragments.DriveContent; -import ru.noties.markwon.Markwon; - -/** - * Created by Javinator9889 on 04/04/2018. - */ -public class LauncherActivity extends AppCompatActivity { - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - ISharedPreferencesManager preferencesManager = PreferencesManager.getInstance(); - preferencesManager.databaseInitialized(false); - if (!preferencesManager.isApplicationInitialized()) { - prepareFutures(); - Intent firstSetupLauncher = new Intent(this, FirstSetup.class); - startActivity(firstSetupLauncher); - this.finish(); - } else { - //to-do - } - } - - private void prepareFutures() { - Context fragmentContext = getApplicationContext(); - IOManager ioManager = IOManager.newInstance(fragmentContext); - ExecutorService service = Executors.newFixedThreadPool(SecurePass.getNumberOfProcessors()); - Future gnuMarkdownText = service.submit(() -> { - String gnuLicenseText = getString(R.string.eula_terms); - return Markwon.markdown(fragmentContext, gnuLicenseText); - }); - Future privacyText = service.submit(() -> { - try { - String sourceText = ioManager.loadPrivacyTextMD(); - return Markwon.markdown(fragmentContext, sourceText); - } catch (IOException e) { - return "Unavailable"; - } - }); - Future termsConditionsText = service.submit(() -> { - try { - String sourceText = ioManager.loadTermsConditionsTextMD(); - return Markwon.markdown(fragmentContext, sourceText); - } catch (IOException e) { - return "Unavailable"; - } - }); - SingletonFutureContainer futureContainer = SingletonFutureContainer.getInstance(); - futureContainer.setLicenseText(gnuMarkdownText); - futureContainer.setPrivacyText(privacyText); - futureContainer.setToSText(termsConditionsText); - } -} +package javinator9889.securepass.views.activities; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import java.io.IOException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import javinator9889.securepass.R; +import javinator9889.securepass.SecurePass; +import javinator9889.securepass.io.IOManager; +import javinator9889.securepass.objects.SingletonFutureContainer; +import javinator9889.securepass.util.resources.ISharedPreferencesManager; +import javinator9889.securepass.util.resources.PreferencesManager; +import javinator9889.securepass.util.resources.SharedPreferencesManager; +import javinator9889.securepass.views.fragments.DriveContent; +import ru.noties.markwon.Markwon; + +/** + * Created by Javinator9889 on 04/04/2018. + */ +public class LauncherActivity extends AppCompatActivity { + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + ISharedPreferencesManager preferencesManager = PreferencesManager.getInstance(); + preferencesManager.databaseInitialized(false); + if (!preferencesManager.isApplicationInitialized()) { + prepareFutures(); + Intent firstSetupLauncher = new Intent(this, FirstSetup.class); + startActivity(firstSetupLauncher); + this.finish(); + } else { + //to-do + } + } + + private void prepareFutures() { + Context fragmentContext = getApplicationContext(); + IOManager ioManager = IOManager.newInstance(fragmentContext); + ExecutorService service = Executors.newFixedThreadPool(SecurePass.getNumberOfProcessors()); + Future gnuMarkdownText = service.submit(() -> { + String gnuLicenseText = getString(R.string.eula_terms); + return Markwon.markdown(fragmentContext, gnuLicenseText); + }); + Future privacyText = service.submit(() -> { + try { + String sourceText = ioManager.loadPrivacyTextMD(); + return Markwon.markdown(fragmentContext, sourceText); + } catch (IOException e) { + return "Unavailable"; + } + }); + Future termsConditionsText = service.submit(() -> { + try { + String sourceText = ioManager.loadTermsConditionsTextMD(); + return Markwon.markdown(fragmentContext, sourceText); + } catch (IOException e) { + return "Unavailable"; + } + }); + SingletonFutureContainer futureContainer = SingletonFutureContainer.getInstance(); + futureContainer.setLicenseText(gnuMarkdownText); + futureContainer.setPrivacyText(privacyText); + futureContainer.setToSText(termsConditionsText); + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/views/activities/MainActivity.java b/SecurePass/app/src/main/java/javinator9889/securepass/views/activities/MainActivity.java similarity index 97% rename from APP/app/src/main/java/javinator9889/securepass/views/activities/MainActivity.java rename to SecurePass/app/src/main/java/javinator9889/securepass/views/activities/MainActivity.java index 839e7dc..2c5d522 100644 --- a/APP/app/src/main/java/javinator9889/securepass/views/activities/MainActivity.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/views/activities/MainActivity.java @@ -1,87 +1,87 @@ -package javinator9889.securepass.views.activities; - -import android.graphics.Color; -import android.os.Bundle; -import android.view.View; -import android.widget.Toast; - -import com.mikepenz.material_design_iconic_typeface_library.MaterialDesignIconic; -import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItem; -import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItems; - -import java.util.Random; - -import androidx.annotation.Nullable; -import androidx.core.content.res.ResourcesCompat; -import javinator9889.securepass.R; -import javinator9889.securepass.views.TabLayoutAdapter; -import javinator9889.securepass.views.activities.menus.FloatingActionButtonMenuAdapter; -import javinator9889.securepass.views.fragments.EntriesDisplayer; -import uk.co.markormesher.android_fab.FloatingActionButton; - -/** - * Created by Javinator9889 on 11/10/2018. - */ -public class MainActivity extends TabLayoutAdapter implements View.OnClickListener { - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - setContentView(R.layout.main_view); - setTabIdRes(R.id.main_view_tabs); - setViewPagerIdRes(R.id.main_viewpager); - setSelectedTextFontRes(R.font.raleway_semibold); - setNonSelectedTextFontRes(R.font.raleway); - setMustChangeTypeface(true); - setMustShowBackButtonOnActionBar(false); - super.onCreate(savedInstanceState); - } - - @Override - protected FragmentPagerItems getItems() { - // Stress test -// int amount = new Random().nextInt(10000); - int amount = 100; - FragmentPagerItems items = new FragmentPagerItems(this); - items.add(FragmentPagerItem.of("Title test", EntriesDisplayer.class)); - items.add(FragmentPagerItem.of("Another tab", EntriesDisplayer.class)); - for (int i = 0; i < amount; ++i) - items.add(FragmentPagerItem.of("Tab #" + i, EntriesDisplayer.class)); - Toast.makeText(this, "Generated: " + amount + " tabs", Toast.LENGTH_LONG).show(); - return items; - } - - @Override - protected void onStart() { - FloatingActionButton button = findViewById(R.id.fab); - button.setOnClickListener(this); - button.setContentCoverEnabled(true); - FloatingActionButtonMenuAdapter menuAdapter = FloatingActionButtonMenuAdapter - .Builder(getApplicationContext(), 3) - .addMenuItem("item 1", MaterialDesignIconic.Icon.gmi_collection_image_o) - .addMenuItem("item 2", MaterialDesignIconic.Icon.gmi_collection_add) - .addMenuItem("item 3", MaterialDesignIconic.Icon.gmi_account) - .setLabelsCustomTypeface(R.font.raleway_semibold) - .setCustomIconsColor(ResourcesCompat.getColor(getResources(), R.color - .colorPrimary, null)) - .setLabelsCustomBackgroundColor(Color.WHITE) - .withIconRotationEnabled(true) - .build(); - button.setSpeedDialMenuAdapter(menuAdapter); - super.onStart(); - } - - @Override - public void onClick(View v) { - switch (v.getId()) { - case R.id.fab: - FloatingActionButton button = v.findViewById(R.id.fab); - if (button.isSpeedDialMenuOpen()) - button.closeSpeedDialMenu(); - else - button.openSpeedDialMenu(); - break; - default: - System.err.println("ID: " + v.getId()); - break; - } - } -} +package javinator9889.securepass.views.activities; + +import android.graphics.Color; +import android.os.Bundle; +import android.view.View; +import android.widget.Toast; + +import com.mikepenz.material_design_iconic_typeface_library.MaterialDesignIconic; +import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItem; +import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItems; + +import java.util.Random; + +import androidx.annotation.Nullable; +import androidx.core.content.res.ResourcesCompat; +import javinator9889.securepass.R; +import javinator9889.securepass.views.TabLayoutAdapter; +import javinator9889.securepass.views.activities.menus.FloatingActionButtonMenuAdapter; +import javinator9889.securepass.views.fragments.EntriesDisplayer; +import uk.co.markormesher.android_fab.FloatingActionButton; + +/** + * Created by Javinator9889 on 11/10/2018. + */ +public class MainActivity extends TabLayoutAdapter implements View.OnClickListener { + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + setContentView(R.layout.main_view); + setTabIdRes(R.id.main_view_tabs); + setViewPagerIdRes(R.id.main_viewpager); + setSelectedTextFontRes(R.font.raleway_semibold); + setNonSelectedTextFontRes(R.font.raleway); + setMustChangeTypeface(true); + setMustShowBackButtonOnActionBar(false); + super.onCreate(savedInstanceState); + } + + @Override + protected FragmentPagerItems getItems() { + // Stress test +// int amount = new Random().nextInt(10000); + int amount = 100; + FragmentPagerItems items = new FragmentPagerItems(this); + items.add(FragmentPagerItem.of("Title test", EntriesDisplayer.class)); + items.add(FragmentPagerItem.of("Another tab", EntriesDisplayer.class)); + for (int i = 0; i < amount; ++i) + items.add(FragmentPagerItem.of("Tab #" + i, EntriesDisplayer.class)); + Toast.makeText(this, "Generated: " + amount + " tabs", Toast.LENGTH_LONG).show(); + return items; + } + + @Override + protected void onStart() { + FloatingActionButton button = findViewById(R.id.fab); + button.setOnClickListener(this); + button.setContentCoverEnabled(true); + FloatingActionButtonMenuAdapter menuAdapter = FloatingActionButtonMenuAdapter + .Builder(getApplicationContext(), 3) + .addMenuItem("item 1", MaterialDesignIconic.Icon.gmi_collection_image_o) + .addMenuItem("item 2", MaterialDesignIconic.Icon.gmi_collection_add) + .addMenuItem("item 3", MaterialDesignIconic.Icon.gmi_account) + .setLabelsCustomTypeface(R.font.raleway_semibold) + .setCustomIconsColor(ResourcesCompat.getColor(getResources(), R.color + .colorPrimary, null)) + .setLabelsCustomBackgroundColor(Color.WHITE) + .withIconRotationEnabled(true) + .build(); + button.setSpeedDialMenuAdapter(menuAdapter); + super.onStart(); + } + + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.fab: + FloatingActionButton button = v.findViewById(R.id.fab); + if (button.isSpeedDialMenuOpen()) + button.closeSpeedDialMenu(); + else + button.openSpeedDialMenu(); + break; + default: + System.err.println("ID: " + v.getId()); + break; + } + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/views/activities/ShowEulaActivity.java b/SecurePass/app/src/main/java/javinator9889/securepass/views/activities/ShowEulaActivity.java similarity index 97% rename from APP/app/src/main/java/javinator9889/securepass/views/activities/ShowEulaActivity.java rename to SecurePass/app/src/main/java/javinator9889/securepass/views/activities/ShowEulaActivity.java index 617a296..1e0fe83 100644 --- a/APP/app/src/main/java/javinator9889/securepass/views/activities/ShowEulaActivity.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/views/activities/ShowEulaActivity.java @@ -1,46 +1,46 @@ -package javinator9889.securepass.views.activities; - -import android.os.Bundle; - -import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItem; -import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItems; - -import androidx.annotation.Nullable; -import androidx.annotation.StringRes; -import androidx.fragment.app.Fragment; -import javinator9889.securepass.R; -import javinator9889.securepass.views.TabLayoutAdapter; -import javinator9889.securepass.views.fragments.termsofservice.LicenseFragment; -import javinator9889.securepass.views.fragments.termsofservice.PrivacyFragment; -import javinator9889.securepass.views.fragments.termsofservice.TermsFragment; - -/** - * Created by Javinator9889 on 17/04/2018. - */ -public class ShowEulaActivity extends TabLayoutAdapter { - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - setContentView(R.layout.full_eula); - setTabIdRes(R.id.viewpagertab); - setViewPagerIdRes(R.id.viewpager); - setSelectedTextFontRes(R.font.raleway_semibold); - setNonSelectedTextFontRes(R.font.raleway); - setMustChangeTypeface(true); - setMustShowBackButtonOnActionBar(true); - super.onCreate(savedInstanceState); - } - - @Override - @SuppressWarnings("unchecked") - protected FragmentPagerItems getItems() { - FragmentPagerItems items = new FragmentPagerItems(this); - Class[] availableItems = new Class[]{PrivacyFragment.class, - TermsFragment.class, LicenseFragment.class}; - @StringRes int[] availableTitles = new int[]{R.string.privacy_name, R.string.tos_name, - R.string.eula_name}; - final int itemsCount = availableItems.length; - for (int i = 0; i < itemsCount; ++i) - items.add(FragmentPagerItem.of(getString(availableTitles[i]), availableItems[i])); - return items; - } -} +package javinator9889.securepass.views.activities; + +import android.os.Bundle; + +import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItem; +import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItems; + +import androidx.annotation.Nullable; +import androidx.annotation.StringRes; +import androidx.fragment.app.Fragment; +import javinator9889.securepass.R; +import javinator9889.securepass.views.TabLayoutAdapter; +import javinator9889.securepass.views.fragments.termsofservice.LicenseFragment; +import javinator9889.securepass.views.fragments.termsofservice.PrivacyFragment; +import javinator9889.securepass.views.fragments.termsofservice.TermsFragment; + +/** + * Created by Javinator9889 on 17/04/2018. + */ +public class ShowEulaActivity extends TabLayoutAdapter { + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + setContentView(R.layout.full_eula); + setTabIdRes(R.id.viewpagertab); + setViewPagerIdRes(R.id.viewpager); + setSelectedTextFontRes(R.font.raleway_semibold); + setNonSelectedTextFontRes(R.font.raleway); + setMustChangeTypeface(true); + setMustShowBackButtonOnActionBar(true); + super.onCreate(savedInstanceState); + } + + @Override + @SuppressWarnings("unchecked") + protected FragmentPagerItems getItems() { + FragmentPagerItems items = new FragmentPagerItems(this); + Class[] availableItems = new Class[]{PrivacyFragment.class, + TermsFragment.class, LicenseFragment.class}; + @StringRes int[] availableTitles = new int[]{R.string.privacy_name, R.string.tos_name, + R.string.eula_name}; + final int itemsCount = availableItems.length; + for (int i = 0; i < itemsCount; ++i) + items.add(FragmentPagerItem.of(getString(availableTitles[i]), availableItems[i])); + return items; + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/views/activities/menus/FloatingActionButtonMenuAdapter.java b/SecurePass/app/src/main/java/javinator9889/securepass/views/activities/menus/FloatingActionButtonMenuAdapter.java similarity index 97% rename from APP/app/src/main/java/javinator9889/securepass/views/activities/menus/FloatingActionButtonMenuAdapter.java rename to SecurePass/app/src/main/java/javinator9889/securepass/views/activities/menus/FloatingActionButtonMenuAdapter.java index 1b85297..26289d6 100644 --- a/APP/app/src/main/java/javinator9889/securepass/views/activities/menus/FloatingActionButtonMenuAdapter.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/views/activities/menus/FloatingActionButtonMenuAdapter.java @@ -1,201 +1,201 @@ -package javinator9889.securepass.views.activities.menus; - -import android.content.Context; -import android.graphics.Color; -import android.graphics.Typeface; -import android.util.SparseArray; -import android.widget.TextView; - -import com.mikepenz.iconics.IconicsDrawable; -import com.mikepenz.iconics.typeface.IIcon; - -import org.jetbrains.annotations.NotNull; - -import androidx.annotation.ColorInt; -import androidx.annotation.ColorRes; -import androidx.annotation.FontRes; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.content.res.ResourcesCompat; -import uk.co.markormesher.android_fab.SpeedDialMenuAdapter; -import uk.co.markormesher.android_fab.SpeedDialMenuItem; - -/** - * Copyright © 2018 - present | APP by Javinator9889 - * - * This program 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. - * - * This program 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 this program. If not, see https://www.gnu.org/licenses/. - * - * Created by Javinator9889 on 24/10/2018 - APP. - */ -public class FloatingActionButtonMenuAdapter extends SpeedDialMenuAdapter { - private SparseArray mMenuItems; - private Typeface mCustomTypeface; - private boolean mIsCustomBackgroundColorEnabled; - private int mCustomBackgroundColor; - private boolean mEnableIconRotating; - - private FloatingActionButtonMenuAdapter(SparseArray menuItems, - @Nullable Typeface customTypeface, - int customBackgroundColor, - boolean enableIconRotating) { - System.out.println(customBackgroundColor); - mMenuItems = menuItems; - mCustomTypeface = customTypeface; - mEnableIconRotating = enableIconRotating; - if (customBackgroundColor == Integer.MAX_VALUE) - mIsCustomBackgroundColorEnabled = false; - else { - mIsCustomBackgroundColorEnabled = true; - mCustomBackgroundColor = customBackgroundColor; - } - } - - @Override - public int getCount() { - return mMenuItems.size(); - } - - @NotNull - @Override - public SpeedDialMenuItem getMenuItem(@NotNull Context context, int key) { - return mMenuItems.get(key, null); - } - - @Override - public float fabRotationDegrees() { - return mEnableIconRotating ? 135F : 0F; - } - - @Override - public void onPrepareItemLabel(@NotNull Context context, - int position, - @NotNull TextView label) { - label.setTypeface(mCustomTypeface); - } - - @Override - public int getBackgroundColour(int position) { - if (!mIsCustomBackgroundColorEnabled) - return super.getBackgroundColour(position); - else - return mCustomBackgroundColor; - } - - public static Builder Builder(@NonNull Context context) { - return new Builder(context); - } - - public static Builder Builder(@NonNull Context context, int numberOfItems) { - return new Builder(context, numberOfItems); - } - - public static final class Builder { - private SparseArray mMenuItems; - private int mMenuItemsLatestPosition; - private Context mContext; - private Typeface mCustomTypeface; - private int mCustomBackgroundColor = Integer.MAX_VALUE; - private @ColorInt int mCustomIconsColor = Integer.MAX_VALUE; - private boolean mEnableIconRotating = false; - - private Builder(@NonNull Context context) { - mContext = context; - mMenuItems = new SparseArray<>(); - mMenuItemsLatestPosition = 0; - } - - private Builder(@NonNull Context context, int numberOfItems) { - mContext = context; - mMenuItems = new SparseArray<>(numberOfItems); - mMenuItemsLatestPosition = 0; - } - - public Builder addMenuItem(@NonNull String label, @NonNull IIcon icon) { - IconicsDrawable menuItemIcon = new IconicsDrawable(mContext, icon); - if (mCustomIconsColor != Integer.MAX_VALUE) - menuItemIcon.color(mCustomIconsColor); - SpeedDialMenuItem newItem = new SpeedDialMenuItem(mContext, menuItemIcon, label); - mMenuItems.put(mMenuItemsLatestPosition, newItem); - ++mMenuItemsLatestPosition; - return this; - } - - public Builder addMenuItem(@NonNull SpeedDialMenuItem menuItem) { - mMenuItems.put(mMenuItemsLatestPosition, menuItem); - ++mMenuItemsLatestPosition; - return this; - } - - public Builder addAll(@NonNull SpeedDialMenuItem... menuItems) { - for (SpeedDialMenuItem menuItem : menuItems) { - mMenuItems.put(mMenuItemsLatestPosition, menuItem); - ++mMenuItemsLatestPosition; - } - return this; - } - - public Builder setLabelsCustomTypeface(@FontRes int customFont) { - mCustomTypeface = ResourcesCompat.getFont(mContext, customFont); - return this; - } - - /** - * Sets custom background color for labels. If not specified, uses [255, 192, 192, 192] - * @param alpha Alpha component of the color | [0, ..., 255] - * @param red Red component of the color | [0, ..., 255] - * @param green Green component of the color | [0, ..., 255] - * @param blue Blue component of the color | [0, ..., 255] - * @return Builder class instance (itself) - */ - public Builder setLabelsCustomBackgroundColor(int alpha, int red, int green, int blue) { - mCustomBackgroundColor = Color.argb(alpha, red, green, blue); - return this; - } - - public Builder setLabelsCustomBackgroundColor(@ColorInt int color) { - mCustomBackgroundColor = color; - return this; - } - - public Builder setLabelsCustomBackgroundColorRes(@ColorRes int color) { - mCustomBackgroundColor = ResourcesCompat - .getColor(mContext.getResources(), color, null); - return this; - } - - public Builder setCustomIconsColor(@ColorInt int color) { - mCustomIconsColor = color; - if (mMenuItems.size() > 0) { - for (int i = 0; i < mMenuItems.size(); ++i) { - SpeedDialMenuItem menuItem = mMenuItems.get(i); - IconicsDrawable icon = IconicsDrawable.class.cast(menuItem.getIcon()); - icon.color(color); - } - } - return this; - } - - public Builder withIconRotationEnabled(boolean isIconRotationEnabled) { - mEnableIconRotating = isIconRotationEnabled; - return this; - } - - public FloatingActionButtonMenuAdapter build() { - return new FloatingActionButtonMenuAdapter(mMenuItems, - mCustomTypeface, - mCustomBackgroundColor, - mEnableIconRotating); - } - } -} +package javinator9889.securepass.views.activities.menus; + +import android.content.Context; +import android.graphics.Color; +import android.graphics.Typeface; +import android.util.SparseArray; +import android.widget.TextView; + +import com.mikepenz.iconics.IconicsDrawable; +import com.mikepenz.iconics.typeface.IIcon; + +import org.jetbrains.annotations.NotNull; + +import androidx.annotation.ColorInt; +import androidx.annotation.ColorRes; +import androidx.annotation.FontRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.content.res.ResourcesCompat; +import uk.co.markormesher.android_fab.SpeedDialMenuAdapter; +import uk.co.markormesher.android_fab.SpeedDialMenuItem; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 24/10/2018 - APP. + */ +public class FloatingActionButtonMenuAdapter extends SpeedDialMenuAdapter { + private SparseArray mMenuItems; + private Typeface mCustomTypeface; + private boolean mIsCustomBackgroundColorEnabled; + private int mCustomBackgroundColor; + private boolean mEnableIconRotating; + + private FloatingActionButtonMenuAdapter(SparseArray menuItems, + @Nullable Typeface customTypeface, + int customBackgroundColor, + boolean enableIconRotating) { + System.out.println(customBackgroundColor); + mMenuItems = menuItems; + mCustomTypeface = customTypeface; + mEnableIconRotating = enableIconRotating; + if (customBackgroundColor == Integer.MAX_VALUE) + mIsCustomBackgroundColorEnabled = false; + else { + mIsCustomBackgroundColorEnabled = true; + mCustomBackgroundColor = customBackgroundColor; + } + } + + @Override + public int getCount() { + return mMenuItems.size(); + } + + @NotNull + @Override + public SpeedDialMenuItem getMenuItem(@NotNull Context context, int key) { + return mMenuItems.get(key, null); + } + + @Override + public float fabRotationDegrees() { + return mEnableIconRotating ? 135F : 0F; + } + + @Override + public void onPrepareItemLabel(@NotNull Context context, + int position, + @NotNull TextView label) { + label.setTypeface(mCustomTypeface); + } + + @Override + public int getBackgroundColour(int position) { + if (!mIsCustomBackgroundColorEnabled) + return super.getBackgroundColour(position); + else + return mCustomBackgroundColor; + } + + public static Builder Builder(@NonNull Context context) { + return new Builder(context); + } + + public static Builder Builder(@NonNull Context context, int numberOfItems) { + return new Builder(context, numberOfItems); + } + + public static final class Builder { + private SparseArray mMenuItems; + private int mMenuItemsLatestPosition; + private Context mContext; + private Typeface mCustomTypeface; + private int mCustomBackgroundColor = Integer.MAX_VALUE; + private @ColorInt int mCustomIconsColor = Integer.MAX_VALUE; + private boolean mEnableIconRotating = false; + + private Builder(@NonNull Context context) { + mContext = context; + mMenuItems = new SparseArray<>(); + mMenuItemsLatestPosition = 0; + } + + private Builder(@NonNull Context context, int numberOfItems) { + mContext = context; + mMenuItems = new SparseArray<>(numberOfItems); + mMenuItemsLatestPosition = 0; + } + + public Builder addMenuItem(@NonNull String label, @NonNull IIcon icon) { + IconicsDrawable menuItemIcon = new IconicsDrawable(mContext, icon); + if (mCustomIconsColor != Integer.MAX_VALUE) + menuItemIcon.color(mCustomIconsColor); + SpeedDialMenuItem newItem = new SpeedDialMenuItem(mContext, menuItemIcon, label); + mMenuItems.put(mMenuItemsLatestPosition, newItem); + ++mMenuItemsLatestPosition; + return this; + } + + public Builder addMenuItem(@NonNull SpeedDialMenuItem menuItem) { + mMenuItems.put(mMenuItemsLatestPosition, menuItem); + ++mMenuItemsLatestPosition; + return this; + } + + public Builder addAll(@NonNull SpeedDialMenuItem... menuItems) { + for (SpeedDialMenuItem menuItem : menuItems) { + mMenuItems.put(mMenuItemsLatestPosition, menuItem); + ++mMenuItemsLatestPosition; + } + return this; + } + + public Builder setLabelsCustomTypeface(@FontRes int customFont) { + mCustomTypeface = ResourcesCompat.getFont(mContext, customFont); + return this; + } + + /** + * Sets custom background color for labels. If not specified, uses [255, 192, 192, 192] + * @param alpha Alpha component of the color | [0, ..., 255] + * @param red Red component of the color | [0, ..., 255] + * @param green Green component of the color | [0, ..., 255] + * @param blue Blue component of the color | [0, ..., 255] + * @return Builder class instance (itself) + */ + public Builder setLabelsCustomBackgroundColor(int alpha, int red, int green, int blue) { + mCustomBackgroundColor = Color.argb(alpha, red, green, blue); + return this; + } + + public Builder setLabelsCustomBackgroundColor(@ColorInt int color) { + mCustomBackgroundColor = color; + return this; + } + + public Builder setLabelsCustomBackgroundColorRes(@ColorRes int color) { + mCustomBackgroundColor = ResourcesCompat + .getColor(mContext.getResources(), color, null); + return this; + } + + public Builder setCustomIconsColor(@ColorInt int color) { + mCustomIconsColor = color; + if (mMenuItems.size() > 0) { + for (int i = 0; i < mMenuItems.size(); ++i) { + SpeedDialMenuItem menuItem = mMenuItems.get(i); + IconicsDrawable icon = IconicsDrawable.class.cast(menuItem.getIcon()); + icon.color(color); + } + } + return this; + } + + public Builder withIconRotationEnabled(boolean isIconRotationEnabled) { + mEnableIconRotating = isIconRotationEnabled; + return this; + } + + public FloatingActionButtonMenuAdapter build() { + return new FloatingActionButtonMenuAdapter(mMenuItems, + mCustomTypeface, + mCustomBackgroundColor, + mEnableIconRotating); + } + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/views/fragments/DriveContent.java b/SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/DriveContent.java similarity index 95% rename from APP/app/src/main/java/javinator9889/securepass/views/fragments/DriveContent.java rename to SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/DriveContent.java index ba67300..39bef1a 100644 --- a/APP/app/src/main/java/javinator9889/securepass/views/fragments/DriveContent.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/DriveContent.java @@ -1,146 +1,149 @@ -package javinator9889.securepass.views.fragments; - -import android.content.Intent; -import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.FragmentActivity; -import android.util.Log; -import android.view.View; -import android.widget.Button; -import android.widget.Toast; - -import com.google.android.gms.auth.api.signin.GoogleSignIn; -import com.google.android.gms.auth.api.signin.GoogleSignInAccount; -import com.google.android.gms.common.ConnectionResult; -import com.google.android.gms.common.api.GoogleApiClient; -import com.google.android.gms.drive.Drive; -import com.google.android.gms.drive.DriveClient; -import com.google.android.gms.drive.DriveId; -import com.google.android.gms.drive.DriveResourceClient; -import com.google.android.gms.drive.OpenFileActivityOptions; - -import javinator9889.securepass.R; -import javinator9889.securepass.backup.drive.DriveDownloader; -import javinator9889.securepass.backup.drive.DriveUploader; -import javinator9889.securepass.backup.drive.IDriveDownloader; -import javinator9889.securepass.backup.drive.IDriveUploader; -import javinator9889.securepass.backup.drive.base.GoogleDriveBase; -import javinator9889.securepass.backup.drive.base.IDriveBase; - -import static javinator9889.securepass.backup.drive.base.IDriveBase.REQUEST_CODE_OPEN_ITEM; -import static javinator9889.securepass.backup.drive.base.IDriveBase.REQUEST_CODE_SIGN_IN; - -/** - * Created by Javinator9889 on 21/04/2018. - */ -public class DriveContent extends FragmentActivity implements Button.OnClickListener, - GoogleApiClient.OnConnectionFailedListener { - private static final String TAG = "drive-quickstart"; - private IDriveBase googleDrive; -// private IDriveUploader uploader; -// private IDriveDownloader downloader; - - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.drive); - System.out.println("Created"); - } - - @Override - protected void onPostCreate(@Nullable Bundle savedInstanceState) { - System.out.println("On post-create"); - super.onPostCreate(savedInstanceState); -// this.googleDrive = new GoogleDriveBase(this, this); -// uploader = new DriveUploader(this, this); -// downloader = new DriveDownloader(this, this); - Button signin = findViewById(R.id.signin); - Button upload = findViewById(R.id.upload); - Button download = findViewById(R.id.download); - signin.setOnClickListener(this); - upload.setOnClickListener(this); - download.setOnClickListener(this); - System.out.println("Finished"); - } - - @Override - public void onClick(View v) { - switch (v.getId()) { - case R.id.signin: - /*Intent signIn = new Intent(this, GoogleDriveBase.class); - startActivity(signIn);*/ -// googleDrive.signIn(); - System.out.println("Sign-in"); - googleDrive = new GoogleDriveBase(this, this); - googleDrive.signIn(); - break; - case R.id.upload: -// ClassContainer container = DataClassForTests.CONTAINER_TEST_CLASS(); - /*Intent appFolder = new Intent(this, CreateFileInAppFolder.class); - appFolder.putExtra("data", container); - startActivity(appFolder);*/ -// googleDrive.uploadFile(container); - System.out.println("Upload"); - IDriveUploader uploader = new DriveUploader(this, this); - uploader.uploadDatabase(); - break; - case R.id.download: - /*Intent download = new Intent(this, - RetrieveContentWithDownloadProgress.class); - startActivity(download);*/ -// googleDrive.restoreData(); - System.out.println("Download"); - IDriveDownloader downloader = new DriveDownloader(this, this); - downloader.restoreData(); - break; - } - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - System.out.println("Activity result"); - switch (requestCode) { - case REQUEST_CODE_SIGN_IN: - if (resultCode == RESULT_OK) { - GoogleSignInAccount latestSignedInAccount = GoogleSignIn - .getLastSignedInAccount(this); - if (latestSignedInAccount != null) { - DriveClient mDriveClient = Drive - .getDriveClient(this, latestSignedInAccount); - DriveResourceClient mDriveResourceClient = - Drive.getDriveResourceClient(this, latestSignedInAccount); - //googleDrive.setDriveClient(mDriveClient); - googleDrive.setDriveResourceClient(mDriveResourceClient); - googleDrive.setLoggedIn(true); - } /*else - startActivityForResult(mGoogleSignInClient.getSignInIntent(), - REQUEST_CODE_SIGN_IN);*/ - Toast.makeText(this, "Successfully signed in", Toast.LENGTH_LONG) - .show(); - //finish(); - } - break; - case REQUEST_CODE_OPEN_ITEM: // not necessary - if (resultCode == RESULT_OK) { - DriveId id = data.getParcelableExtra( - OpenFileActivityOptions.EXTRA_RESPONSE_DRIVE_ID); - //googleDrive.setResult(id); - } else - /*googleDrive.setException(new GoogleDriveUnableToOpenFileException( - "Unable to open file"));*/ - break; - default: - Log.e(TAG, "Result for activity no contemplated. RequestCode: " + requestCode + - " | ResultCode: " + resultCode + " | Intent data: " + data.toString()); -// finish(); - } - } - - @Override - public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { - Toast.makeText(this, "Error de conexion!", Toast.LENGTH_SHORT).show(); - Log.e(TAG, "OnConnectionFailed: " + connectionResult); - } -} +package javinator9889.securepass.views.fragments; + +import android.content.Intent; +import android.os.Bundle; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentActivity; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.Toast; + +import com.google.android.gms.auth.api.signin.GoogleSignIn; +import com.google.android.gms.auth.api.signin.GoogleSignInAccount; +import com.google.android.gms.common.ConnectionResult; +import com.google.android.gms.common.api.GoogleApiClient; +import com.google.android.gms.drive.Drive; +import com.google.android.gms.drive.DriveClient; +import com.google.android.gms.drive.DriveId; +import com.google.android.gms.drive.DriveResourceClient; +import com.google.android.gms.drive.OpenFileActivityOptions; + +import javinator9889.securepass.R; +import javinator9889.securepass.backup.drive.DriveDownloader; +import javinator9889.securepass.backup.drive.DriveUploader; +import javinator9889.securepass.backup.drive.IDriveDownloader; +import javinator9889.securepass.backup.drive.IDriveUploader; +import javinator9889.securepass.backup.drive.base.GoogleDriveBase; +import javinator9889.securepass.backup.drive.base.IDriveBase; + +import static javinator9889.securepass.backup.drive.base.IDriveBase.REQUEST_CODE_OPEN_ITEM; +import static javinator9889.securepass.backup.drive.base.IDriveBase.REQUEST_CODE_SIGN_IN; + +/** + * Created by Javinator9889 on 21/04/2018. + */ +public class DriveContent extends FragmentActivity implements Button.OnClickListener, + GoogleApiClient.OnConnectionFailedListener { + private static final String TAG = "drive-quickstart"; + private IDriveBase googleDrive; +// private IDriveUploader uploader; +// private IDriveDownloader downloader; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.drive); + System.out.println("Created"); + } + + @Override + protected void onPostCreate(@Nullable Bundle savedInstanceState) { + System.out.println("On post-create"); + super.onPostCreate(savedInstanceState); +// this.googleDrive = new GoogleDriveBase(this, this); +// uploader = new DriveUploader(this, this); +// downloader = new DriveDownloader(this, this); + Button signin = findViewById(R.id.signin); + Button upload = findViewById(R.id.upload); + Button download = findViewById(R.id.download); + signin.setOnClickListener(this); + upload.setOnClickListener(this); + download.setOnClickListener(this); + System.out.println("Finished"); + } + + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.signin: + /*Intent signIn = new Intent(this, GoogleDriveBase.class); + startActivity(signIn);*/ +// googleDrive.signIn(); + System.out.println("Sign-in"); + googleDrive = new GoogleDriveBase(this, this); + googleDrive.signIn(); + break; + case R.id.upload: +// ClassContainer container = DataClassForTests.CONTAINER_TEST_CLASS(); + /*Intent appFolder = new Intent(this, CreateFileInAppFolder.class); + appFolder.putExtra("data", container); + startActivity(appFolder);*/ +// googleDrive.uploadFile(container); + System.out.println("Upload"); + IDriveUploader uploader = new DriveUploader(this, this); + uploader.uploadDatabase(); + break; + case R.id.download: + /*Intent download = new Intent(this, + RetrieveContentWithDownloadProgress.class); + startActivity(download);*/ +// googleDrive.restoreData(); + System.out.println("Download"); + IDriveDownloader downloader = new DriveDownloader(this, this); + downloader.restoreData(); + break; + default: + Log.w(TAG, "Missing ID statement - DriveContent:69 - " + v.getId()); + break; + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + System.out.println("Activity result"); + switch (requestCode) { + case REQUEST_CODE_SIGN_IN: + if (resultCode == RESULT_OK) { + GoogleSignInAccount latestSignedInAccount = GoogleSignIn + .getLastSignedInAccount(this); + if (latestSignedInAccount != null) { + DriveClient mDriveClient = Drive + .getDriveClient(this, latestSignedInAccount); + DriveResourceClient mDriveResourceClient = + Drive.getDriveResourceClient(this, latestSignedInAccount); + //googleDrive.setDriveClient(mDriveClient); + googleDrive.setDriveResourceClient(mDriveResourceClient); + googleDrive.setLoggedIn(true); + } /*else + startActivityForResult(mGoogleSignInClient.getSignInIntent(), + REQUEST_CODE_SIGN_IN);*/ + Toast.makeText(this, "Successfully signed in", Toast.LENGTH_LONG) + .show(); + //finish(); + } + break; + case REQUEST_CODE_OPEN_ITEM: // not necessary + if (resultCode == RESULT_OK) { + DriveId id = data.getParcelableExtra( + OpenFileActivityOptions.EXTRA_RESPONSE_DRIVE_ID); + //googleDrive.setResult(id); + } else + /*googleDrive.setException(new GoogleDriveUnableToOpenFileException( + "Unable to open file"));*/ + break; + default: + Log.e(TAG, "Result for activity no contemplated. RequestCode: " + requestCode + + " | ResultCode: " + resultCode + " | Intent data: " + data.toString()); +// finish(); + } + } + + @Override + public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { + Toast.makeText(this, "Error de conexion!", Toast.LENGTH_SHORT).show(); + Log.e(TAG, "OnConnectionFailed: " + connectionResult); + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/views/fragments/EntriesDisplayer.java b/SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/EntriesDisplayer.java similarity index 97% rename from APP/app/src/main/java/javinator9889/securepass/views/fragments/EntriesDisplayer.java rename to SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/EntriesDisplayer.java index f08760d..9728194 100644 --- a/APP/app/src/main/java/javinator9889/securepass/views/fragments/EntriesDisplayer.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/EntriesDisplayer.java @@ -1,39 +1,39 @@ -package javinator9889.securepass.views.fragments; - -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import javinator9889.securepass.R; - -/** - * Copyright © 2018 - present | APP by Javinator9889 - * - * This program 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. - * - * This program 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 this program. If not, see https://www.gnu.org/licenses/. - * - * Created by Javinator9889 on 25/10/2018 - APP. - */ -public class EntriesDisplayer extends Fragment { - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, - @Nullable ViewGroup container, - @Nullable Bundle savedInstanceState) { - return inflater.inflate(R.layout.main_view_container, container, false); - } -} +package javinator9889.securepass.views.fragments; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import javinator9889.securepass.R; + +/** + * Copyright © 2018 - present | APP by Javinator9889 + * + * This program 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. + * + * This program 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 this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 25/10/2018 - APP. + */ +public class EntriesDisplayer extends Fragment { + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + return inflater.inflate(R.layout.main_view_container, container, false); + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/views/fragments/firstsetup/PasswordRegistration.java b/SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/firstsetup/PasswordRegistration.java similarity index 80% rename from APP/app/src/main/java/javinator9889/securepass/views/fragments/firstsetup/PasswordRegistration.java rename to SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/firstsetup/PasswordRegistration.java index 0432852..b7a8828 100644 --- a/APP/app/src/main/java/javinator9889/securepass/views/fragments/firstsetup/PasswordRegistration.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/firstsetup/PasswordRegistration.java @@ -1,119 +1,129 @@ -package javinator9889.securepass.views.fragments.firstsetup; - -import android.content.Intent; -import android.graphics.Color; -import android.os.Bundle; -import androidx.annotation.Nullable; -import androidx.fragment.app.FragmentActivity; -import android.util.Log; -import android.view.View; -import android.widget.Button; -import android.widget.EditText; -import android.widget.Toast; - -import com.afollestad.materialdialogs.MaterialDialog; -import com.github.paolorotolo.appintro.ISlideBackgroundColorHolder; -import com.google.common.hash.Hashing; - -import java.nio.charset.StandardCharsets; - -import javinator9889.securepass.R; -import javinator9889.securepass.io.IOManager; -import javinator9889.securepass.io.database.DatabaseManager; -import javinator9889.securepass.util.resources.ISharedPreferencesManager; -import javinator9889.securepass.util.resources.PreferencesManager; -import javinator9889.securepass.views.activities.MainActivity; - -/** - * Created by Javinator9889 on 08/04/2018. - */ -public class PasswordRegistration extends FragmentActivity implements ISlideBackgroundColorHolder, - View.OnClickListener { - private static final String TAG = "PasswordRegistration"; - private EditText firstPasswordEntry; - private EditText passwordConfirmation; - private int backgroundColor = Color.LTGRAY; - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.request_intro); - Button confirmButton = findViewById(R.id.confirmButton); - firstPasswordEntry = findViewById(R.id.firstPasswordEntry); - passwordConfirmation = findViewById(R.id.passwordConfirmation); - confirmButton.setOnClickListener(this); - } - - @Override - public int getDefaultBackgroundColor() { - return this.backgroundColor; - } - - @Override - public void setBackgroundColor(int backgroundColor) { - this.backgroundColor = backgroundColor; - } - - @Override - public void onClick(View v) { - switch (v.getId()) { - case R.id.confirmButton: - if (validate()) { - MaterialDialog savingPasswordProgress = new MaterialDialog - .Builder(v.getContext()) - .title(R.string.saving_pass) - .content(R.string.saving_pass_more_info) - .progress(true, 0) - .build(); - savingPasswordProgress.show(); - IOManager io = IOManager.newInstance(this); - String passwordWithHashApplied = Hashing.sha256() - .hashString(this.firstPasswordEntry.getText().toString(), - StandardCharsets.UTF_8).toString(); - io.storePassword(passwordWithHashApplied); - /*Intent googleDriveLauncher = new Intent(this, DriveContent.class); - startActivity(googleDriveLauncher); - savingPasswordProgress.dismiss();*/ - //finish(); - // This will try to create a DB - DatabaseManager manager = DatabaseManager - .newInstance(this, passwordWithHashApplied); - Thread databaseThread = manager.getDatabaseInitializer(); - try { - databaseThread.join(); - ISharedPreferencesManager preferencesManager = PreferencesManager - .getInstance(); - preferencesManager.databaseInitialized(true); - savingPasswordProgress.dismiss(); - Intent launcher = new Intent(this, MainActivity.class); - this.startActivity(launcher); - this.finish(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - else - Toast.makeText(v.getContext(), R.string.passwords_does_not_match, - Toast.LENGTH_LONG).show(); - break; - default: - Log.e(TAG, "Non-contemplated button click"); - break; - } - } - - private boolean validate() { - try { - String firstPasswordHash = Hashing.sha256() - .hashString(this.firstPasswordEntry.getText().toString(), - StandardCharsets.UTF_8).toString(); - String passwordConfirmationHash = Hashing.sha256() - .hashString(this.passwordConfirmation.getText().toString(), - StandardCharsets.UTF_8).toString(); - return firstPasswordHash.equals(passwordConfirmationHash); - } catch (NullPointerException e) { - Log.e(TAG, "NullPointerException with texts. Full trace: " + e.getMessage()); - return false; - } - } -} +package javinator9889.securepass.views.fragments.firstsetup; + +import android.content.Intent; +import android.graphics.Color; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Toast; + +import com.afollestad.materialdialogs.MaterialDialog; +import com.github.paolorotolo.appintro.ISlideBackgroundColorHolder; + +import java.nio.charset.StandardCharsets; +import java.security.GeneralSecurityException; + +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentActivity; +import javinator9889.securepass.R; +import javinator9889.securepass.io.IOManager; +import javinator9889.securepass.io.database.DatabaseManager; +import javinator9889.securepass.util.resources.ISharedPreferencesManager; +import javinator9889.securepass.util.resources.PreferencesManager; +import javinator9889.securepass.util.scrypt.Scrypt; +import javinator9889.securepass.views.activities.MainActivity; + +import static com.google.common.hash.Hashing.sha256; + +/** + * Created by Javinator9889 on 08/04/2018. + */ +public class PasswordRegistration extends FragmentActivity implements ISlideBackgroundColorHolder, + View.OnClickListener { + private static final String TAG = "PasswordRegistration"; + private EditText firstPasswordEntry; + private EditText passwordConfirmation; + private int backgroundColor = Color.LTGRAY; + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.request_intro); + Button confirmButton = findViewById(R.id.confirmButton); + firstPasswordEntry = findViewById(R.id.firstPasswordEntry); + passwordConfirmation = findViewById(R.id.passwordConfirmation); + confirmButton.setOnClickListener(this); + } + + @Override + public int getDefaultBackgroundColor() { + return this.backgroundColor; + } + + @Override + public void setBackgroundColor(int backgroundColor) { + this.backgroundColor = backgroundColor; + } + + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.confirmButton: + if (validate()) { + MaterialDialog savingPasswordProgress = new MaterialDialog + .Builder(v.getContext()) + .title(R.string.saving_pass) + .content(R.string.saving_pass_more_info) + .progress(true, 0) + .build(); + savingPasswordProgress.show(); + IOManager io = IOManager.newInstance(this); + Scrypt scrypter = new Scrypt(); + try { + scrypter.scrypt(firstPasswordEntry.getText().toString()); + } catch (GeneralSecurityException ex) { + ex.printStackTrace(); + } + io.savePassword(scrypter.getHash()); +// String passwordWithHashApplied = Hashing.sha256() +// .hashString(this.firstPasswordEntry.getText().toString(), +// StandardCharsets.UTF_8).toString(); +// io.storePassword(passwordWithHashApplied); + /*Intent googleDriveLauncher = new Intent(this, DriveContent.class); + startActivity(googleDriveLauncher); + savingPasswordProgress.dismiss();*/ + //finish(); + // This will try to create a DB + DatabaseManager manager = DatabaseManager + .getInstance(this, new String(scrypter.getKey())); + Thread databaseThread = manager.getDatabaseInitializer(); + try { + databaseThread.join(); + ISharedPreferencesManager preferencesManager = PreferencesManager + .getInstance(); + preferencesManager.databaseInitialized(true); + savingPasswordProgress.dismiss(); + Intent launcher = new Intent(this, MainActivity.class); + this.startActivity(launcher); + this.finish(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + else + Toast.makeText(v.getContext(), R.string.passwords_does_not_match, + Toast.LENGTH_LONG).show(); + break; + default: + Log.e(TAG, "Non-contemplated button click"); + break; + } + } + + private boolean validate() { + try { + String firstPasswordHash = sha256() + .hashString(this.firstPasswordEntry.getText().toString(), + StandardCharsets.UTF_8).toString(); + String passwordConfirmationHash = sha256() + .hashString(this.passwordConfirmation.getText().toString(), + StandardCharsets.UTF_8).toString(); + return firstPasswordHash.equals(passwordConfirmationHash); + } catch (NullPointerException e) { + Log.e(TAG, "NullPointerException with texts. Full trace: " + e.getMessage()); + return false; + } + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/views/fragments/firstsetup/slides/EulaConfirmation.java b/SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/firstsetup/slides/EulaConfirmation.java similarity index 97% rename from APP/app/src/main/java/javinator9889/securepass/views/fragments/firstsetup/slides/EulaConfirmation.java rename to SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/firstsetup/slides/EulaConfirmation.java index 21b6ddd..b799600 100644 --- a/APP/app/src/main/java/javinator9889/securepass/views/fragments/firstsetup/slides/EulaConfirmation.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/firstsetup/slides/EulaConfirmation.java @@ -1,134 +1,134 @@ -package javinator9889.securepass.views.fragments.firstsetup.slides; - -import android.content.Context; -import android.content.Intent; -import android.graphics.Typeface; -import android.os.Bundle; - -import androidx.annotation.ColorInt; -import androidx.annotation.DrawableRes; -import androidx.annotation.FontRes; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import android.util.Log; -import android.view.View; -import android.widget.Button; -import android.widget.CheckBox; -import android.widget.TextView; - -import com.github.paolorotolo.appintro.AppIntroBaseFragment; -import com.github.paolorotolo.appintro.ISlideBackgroundColorHolder; -import com.github.paolorotolo.appintro.model.SliderPage; - -import androidx.core.content.res.ResourcesCompat; -import javinator9889.securepass.R; -import javinator9889.securepass.objects.SlidesTypefacesContainer; -import javinator9889.securepass.views.activities.ShowEulaActivity; - -/** - * Created by Javinator9889 on 13/04/2018. - */ -public class EulaConfirmation extends AppIntroBaseFragment implements Button.OnClickListener, - ISlideBackgroundColorHolder { - private Context packageContext; - private Button gotoEulaButton; - private @Nullable SlidesTypefacesContainer mContainer; - - public static EulaConfirmation newInstance(CharSequence title, - CharSequence description, - @DrawableRes int imageDrawable, - @ColorInt int bgColor, - @ColorInt int titleColor, - @ColorInt int descColor, - @Nullable SlidesTypefacesContainer container) { - SliderPage sliderPage = new SliderPage(); - sliderPage.setTitle(title); - sliderPage.setTitleTypeface(null); - sliderPage.setDescription(description); - sliderPage.setDescTypeface(null); - sliderPage.setImageDrawable(imageDrawable); - sliderPage.setBgColor(bgColor); - sliderPage.setTitleColor(titleColor); - sliderPage.setDescColor(descColor); - - return newInstance(sliderPage, container); - } - - private static EulaConfirmation newInstance(SliderPage sliderPage, - @Nullable SlidesTypefacesContainer container) { - EulaConfirmation slide = new EulaConfirmation(); - Bundle args = new Bundle(); - args.putString(ARG_TITLE, sliderPage.getTitleString()); - args.putString(ARG_TITLE_TYPEFACE, sliderPage.getTitleTypeface()); - args.putString(ARG_DESC, sliderPage.getDescriptionString()); - args.putString(ARG_DESC_TYPEFACE, sliderPage.getDescTypeface()); - args.putInt(ARG_DRAWABLE, sliderPage.getImageDrawable()); - args.putInt(ARG_BG_COLOR, sliderPage.getBgColor()); - args.putInt(ARG_TITLE_COLOR, sliderPage.getTitleColor()); - args.putInt(ARG_DESC_COLOR, sliderPage.getDescColor()); - slide.setArguments(args); - slide.setContainer(container); - - return slide; - } - - public void setContainer(@Nullable SlidesTypefacesContainer container) { - this.mContainer = container; - } - - public void addPackageContext(Context packageContext) { - this.packageContext = packageContext; - } - - @Override - public int getDefaultBackgroundColor() { - return super.getDefaultBackgroundColor(); - } - - @Override - public void setBackgroundColor(int backgroundColor) { - super.setBackgroundColor(backgroundColor); - } - - @Override - protected int getLayoutId() { - return R.layout.eula_intro; - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - TextView titleText = view.findViewById(R.id.title); - TextView descriptionText = - view.findViewById(R.id.description); - if (mContainer != null) { - Typeface titleFont = ResourcesCompat.getFont(view.getContext(), - mContainer.getTitleTypeface()); - titleText.setTypeface(titleFont); - Typeface descriptionFont = ResourcesCompat.getFont(view.getContext(), - mContainer.getDescriptionTypeface()); - descriptionText.setTypeface(descriptionFont); - } - gotoEulaButton = view.findViewById(R.id.goto_full_eula_button); - gotoEulaButton.setOnClickListener(this); - super.onViewCreated(view, savedInstanceState); - } - - public Button getGotoEulaButton() { - return gotoEulaButton; - } - - @Override - public void onClick(View v) { - switch (v.getId()) { - case R.id.goto_full_eula_button: - Intent startEulaActivity = new Intent(packageContext, ShowEulaActivity.class); -// startEulaActivity.putExtra("bundle", mExtra); - startActivity(startEulaActivity); - break; - default: - Log.e("FIRSTSETUP", "Clicked something non-contemplated. ID: " - + v.getId()); - break; - } - } -} +package javinator9889.securepass.views.fragments.firstsetup.slides; + +import android.content.Context; +import android.content.Intent; +import android.graphics.Typeface; +import android.os.Bundle; + +import androidx.annotation.ColorInt; +import androidx.annotation.DrawableRes; +import androidx.annotation.FontRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.TextView; + +import com.github.paolorotolo.appintro.AppIntroBaseFragment; +import com.github.paolorotolo.appintro.ISlideBackgroundColorHolder; +import com.github.paolorotolo.appintro.model.SliderPage; + +import androidx.core.content.res.ResourcesCompat; +import javinator9889.securepass.R; +import javinator9889.securepass.objects.SlidesTypefacesContainer; +import javinator9889.securepass.views.activities.ShowEulaActivity; + +/** + * Created by Javinator9889 on 13/04/2018. + */ +public class EulaConfirmation extends AppIntroBaseFragment implements Button.OnClickListener, + ISlideBackgroundColorHolder { + private Context packageContext; + private Button gotoEulaButton; + private @Nullable SlidesTypefacesContainer mContainer; + + public static EulaConfirmation newInstance(CharSequence title, + CharSequence description, + @DrawableRes int imageDrawable, + @ColorInt int bgColor, + @ColorInt int titleColor, + @ColorInt int descColor, + @Nullable SlidesTypefacesContainer container) { + SliderPage sliderPage = new SliderPage(); + sliderPage.setTitle(title); + sliderPage.setTitleTypeface(null); + sliderPage.setDescription(description); + sliderPage.setDescTypeface(null); + sliderPage.setImageDrawable(imageDrawable); + sliderPage.setBgColor(bgColor); + sliderPage.setTitleColor(titleColor); + sliderPage.setDescColor(descColor); + + return newInstance(sliderPage, container); + } + + private static EulaConfirmation newInstance(SliderPage sliderPage, + @Nullable SlidesTypefacesContainer container) { + EulaConfirmation slide = new EulaConfirmation(); + Bundle args = new Bundle(); + args.putString(ARG_TITLE, sliderPage.getTitleString()); + args.putString(ARG_TITLE_TYPEFACE, sliderPage.getTitleTypeface()); + args.putString(ARG_DESC, sliderPage.getDescriptionString()); + args.putString(ARG_DESC_TYPEFACE, sliderPage.getDescTypeface()); + args.putInt(ARG_DRAWABLE, sliderPage.getImageDrawable()); + args.putInt(ARG_BG_COLOR, sliderPage.getBgColor()); + args.putInt(ARG_TITLE_COLOR, sliderPage.getTitleColor()); + args.putInt(ARG_DESC_COLOR, sliderPage.getDescColor()); + slide.setArguments(args); + slide.setContainer(container); + + return slide; + } + + public void setContainer(@Nullable SlidesTypefacesContainer container) { + this.mContainer = container; + } + + public void addPackageContext(Context packageContext) { + this.packageContext = packageContext; + } + + @Override + public int getDefaultBackgroundColor() { + return super.getDefaultBackgroundColor(); + } + + @Override + public void setBackgroundColor(int backgroundColor) { + super.setBackgroundColor(backgroundColor); + } + + @Override + protected int getLayoutId() { + return R.layout.eula_intro; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + TextView titleText = view.findViewById(R.id.title); + TextView descriptionText = + view.findViewById(R.id.description); + if (mContainer != null) { + Typeface titleFont = ResourcesCompat.getFont(view.getContext(), + mContainer.getTitleTypeface()); + titleText.setTypeface(titleFont); + Typeface descriptionFont = ResourcesCompat.getFont(view.getContext(), + mContainer.getDescriptionTypeface()); + descriptionText.setTypeface(descriptionFont); + } + gotoEulaButton = view.findViewById(R.id.goto_full_eula_button); + gotoEulaButton.setOnClickListener(this); + super.onViewCreated(view, savedInstanceState); + } + + public Button getGotoEulaButton() { + return gotoEulaButton; + } + + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.goto_full_eula_button: + Intent startEulaActivity = new Intent(packageContext, ShowEulaActivity.class); +// startEulaActivity.putExtra("bundle", mExtra); + startActivity(startEulaActivity); + break; + default: + Log.e("FIRSTSETUP", "Clicked something non-contemplated. ID: " + + v.getId()); + break; + } + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/views/fragments/firstsetup/slides/SlidePage.java b/SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/firstsetup/slides/SlidePage.java similarity index 97% rename from APP/app/src/main/java/javinator9889/securepass/views/fragments/firstsetup/slides/SlidePage.java rename to SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/firstsetup/slides/SlidePage.java index 447c313..c7ab262 100644 --- a/APP/app/src/main/java/javinator9889/securepass/views/fragments/firstsetup/slides/SlidePage.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/firstsetup/slides/SlidePage.java @@ -1,109 +1,109 @@ -package javinator9889.securepass.views.fragments.firstsetup.slides; - -import android.graphics.Typeface; -import android.os.Bundle; -import android.view.View; -import android.widget.TextView; - -import androidx.annotation.ColorInt; -import androidx.annotation.DrawableRes; - -import com.github.paolorotolo.appintro.AppIntroBaseFragment; -import com.github.paolorotolo.appintro.ISlideBackgroundColorHolder; -import com.github.paolorotolo.appintro.model.SliderPage; -import com.github.paolorotolo.appintro.R.id; - -import androidx.annotation.FontRes; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.content.res.ResourcesCompat; -import javinator9889.securepass.R; -import javinator9889.securepass.objects.SlidesTypefacesContainer; - -/** - * Created by Javinator9889 on 03/04/2018. - */ -public class SlidePage extends AppIntroBaseFragment implements ISlideBackgroundColorHolder { - private @FontRes int mTitleTypeface = -1; - private @FontRes int mDescriptionTypeface = -1; - - @Override - public int getDefaultBackgroundColor() { - return super.getDefaultBackgroundColor(); - } - - @Override - public void setBackgroundColor(int backgroundColor) { - super.setBackgroundColor(backgroundColor); - } - - public static SlidePage newInstance(CharSequence title, - CharSequence description, - @DrawableRes int imageDrawable, - @ColorInt int bgColor, - @ColorInt int titleColor, - @ColorInt int descColor, - @Nullable SlidesTypefacesContainer container) { - SliderPage sliderPage = new SliderPage(); - sliderPage.setTitle(title); - sliderPage.setTitleTypeface(null); - sliderPage.setDescription(description); - sliderPage.setDescTypeface(null); - sliderPage.setImageDrawable(imageDrawable); - sliderPage.setBgColor(bgColor); - sliderPage.setTitleColor(titleColor); - sliderPage.setDescColor(descColor); - - return newInstance(sliderPage, container); - } - - private static SlidePage newInstance(SliderPage sliderPage, - @Nullable SlidesTypefacesContainer container) { - SlidePage slide = new SlidePage(); - Bundle args = new Bundle(); - args.putString(ARG_TITLE, sliderPage.getTitleString()); - args.putString(ARG_TITLE_TYPEFACE, sliderPage.getTitleTypeface()); - args.putString(ARG_DESC, sliderPage.getDescriptionString()); - args.putString(ARG_DESC_TYPEFACE, sliderPage.getDescTypeface()); - args.putInt(ARG_DRAWABLE, sliderPage.getImageDrawable()); - args.putInt(ARG_BG_COLOR, sliderPage.getBgColor()); - args.putInt(ARG_TITLE_COLOR, sliderPage.getTitleColor()); - args.putInt(ARG_DESC_COLOR, sliderPage.getDescColor()); - slide.setArguments(args); - if (container != null) { - slide.setTitleTypeface(container.getTitleTypeface()); - slide.setDescriptionTypeface(container.getDescriptionTypeface()); - } - - return slide; - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - TextView titleText = view.findViewById(id.title); - TextView descriptionText = view.findViewById(id.description); - if (mTitleTypeface != -1) { - Typeface titleFont = ResourcesCompat.getFont(view.getContext(), mTitleTypeface); - titleText.setTypeface(titleFont); - } - if (mDescriptionTypeface != -1) { - Typeface descriptionFont = ResourcesCompat.getFont(view.getContext(), - mDescriptionTypeface); - descriptionText.setTypeface(descriptionFont); - } - } - - private void setTitleTypeface(@FontRes int titleTypeface) { - this.mTitleTypeface = titleTypeface; - } - - private void setDescriptionTypeface(@FontRes int descriptionTypeface) { - this.mDescriptionTypeface = descriptionTypeface; - } - - @Override - protected int getLayoutId() { - return R.layout.appintro_fragment_intro; - } -} +package javinator9889.securepass.views.fragments.firstsetup.slides; + +import android.graphics.Typeface; +import android.os.Bundle; +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.ColorInt; +import androidx.annotation.DrawableRes; + +import com.github.paolorotolo.appintro.AppIntroBaseFragment; +import com.github.paolorotolo.appintro.ISlideBackgroundColorHolder; +import com.github.paolorotolo.appintro.model.SliderPage; +import com.github.paolorotolo.appintro.R.id; + +import androidx.annotation.FontRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.content.res.ResourcesCompat; +import javinator9889.securepass.R; +import javinator9889.securepass.objects.SlidesTypefacesContainer; + +/** + * Created by Javinator9889 on 03/04/2018. + */ +public class SlidePage extends AppIntroBaseFragment implements ISlideBackgroundColorHolder { + private @FontRes int mTitleTypeface = -1; + private @FontRes int mDescriptionTypeface = -1; + + @Override + public int getDefaultBackgroundColor() { + return super.getDefaultBackgroundColor(); + } + + @Override + public void setBackgroundColor(int backgroundColor) { + super.setBackgroundColor(backgroundColor); + } + + public static SlidePage newInstance(CharSequence title, + CharSequence description, + @DrawableRes int imageDrawable, + @ColorInt int bgColor, + @ColorInt int titleColor, + @ColorInt int descColor, + @Nullable SlidesTypefacesContainer container) { + SliderPage sliderPage = new SliderPage(); + sliderPage.setTitle(title); + sliderPage.setTitleTypeface(null); + sliderPage.setDescription(description); + sliderPage.setDescTypeface(null); + sliderPage.setImageDrawable(imageDrawable); + sliderPage.setBgColor(bgColor); + sliderPage.setTitleColor(titleColor); + sliderPage.setDescColor(descColor); + + return newInstance(sliderPage, container); + } + + private static SlidePage newInstance(SliderPage sliderPage, + @Nullable SlidesTypefacesContainer container) { + SlidePage slide = new SlidePage(); + Bundle args = new Bundle(); + args.putString(ARG_TITLE, sliderPage.getTitleString()); + args.putString(ARG_TITLE_TYPEFACE, sliderPage.getTitleTypeface()); + args.putString(ARG_DESC, sliderPage.getDescriptionString()); + args.putString(ARG_DESC_TYPEFACE, sliderPage.getDescTypeface()); + args.putInt(ARG_DRAWABLE, sliderPage.getImageDrawable()); + args.putInt(ARG_BG_COLOR, sliderPage.getBgColor()); + args.putInt(ARG_TITLE_COLOR, sliderPage.getTitleColor()); + args.putInt(ARG_DESC_COLOR, sliderPage.getDescColor()); + slide.setArguments(args); + if (container != null) { + slide.setTitleTypeface(container.getTitleTypeface()); + slide.setDescriptionTypeface(container.getDescriptionTypeface()); + } + + return slide; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + TextView titleText = view.findViewById(id.title); + TextView descriptionText = view.findViewById(id.description); + if (mTitleTypeface != -1) { + Typeface titleFont = ResourcesCompat.getFont(view.getContext(), mTitleTypeface); + titleText.setTypeface(titleFont); + } + if (mDescriptionTypeface != -1) { + Typeface descriptionFont = ResourcesCompat.getFont(view.getContext(), + mDescriptionTypeface); + descriptionText.setTypeface(descriptionFont); + } + } + + private void setTitleTypeface(@FontRes int titleTypeface) { + this.mTitleTypeface = titleTypeface; + } + + private void setDescriptionTypeface(@FontRes int descriptionTypeface) { + this.mDescriptionTypeface = descriptionTypeface; + } + + @Override + protected int getLayoutId() { + return R.layout.appintro_fragment_intro; + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/views/fragments/termsofservice/LicenseFragment.java b/SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/termsofservice/LicenseFragment.java similarity index 97% rename from APP/app/src/main/java/javinator9889/securepass/views/fragments/termsofservice/LicenseFragment.java rename to SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/termsofservice/LicenseFragment.java index 8a09e18..e4122aa 100644 --- a/APP/app/src/main/java/javinator9889/securepass/views/fragments/termsofservice/LicenseFragment.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/termsofservice/LicenseFragment.java @@ -1,47 +1,47 @@ -package javinator9889.securepass.views.fragments.termsofservice; - -import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.CompoundButton; - -import javinator9889.securepass.R; -import javinator9889.securepass.objects.SingletonFutureContainer; -import javinator9889.securepass.util.resources.ISharedPreferencesManager; -import javinator9889.securepass.views.fragments.termsofservice.base.ToSBaseFragment; - -/** - * Created by Javinator9889 on 23/09/2018. - */ -public class LicenseFragment extends ToSBaseFragment { - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, - @Nullable Bundle savedInstanceState) { - setTextId(R.id.license_text); - setCheckboxId(R.id.checkBoxLicense); - setScrollViewId(R.id.license_scroll); - return inflater.inflate(R.layout.license, container, false); - } - - @Override - protected void setText() { - SingletonFutureContainer futureContainer = SingletonFutureContainer.getInstance(); - super.setSourceText(futureContainer.getLicenseText()); - } - - @Override - protected void setCheckbox() { - ISharedPreferencesManager sharedPreferences = getSharedPreferences(); - super.setCheckboxStatus(sharedPreferences.isSoftwareLicenseAccepted()); - } - - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - super.setCheckboxStatus(isChecked); - getSharedPreferences().setSoftwareLicenseAccepted(isChecked); - } -} +package javinator9889.securepass.views.fragments.termsofservice; + +import android.os.Bundle; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CompoundButton; + +import javinator9889.securepass.R; +import javinator9889.securepass.objects.SingletonFutureContainer; +import javinator9889.securepass.util.resources.ISharedPreferencesManager; +import javinator9889.securepass.views.fragments.termsofservice.base.ToSBaseFragment; + +/** + * Created by Javinator9889 on 23/09/2018. + */ +public class LicenseFragment extends ToSBaseFragment { + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + setTextId(R.id.license_text); + setCheckboxId(R.id.checkBoxLicense); + setScrollViewId(R.id.license_scroll); + return inflater.inflate(R.layout.license, container, false); + } + + @Override + protected void setText() { + SingletonFutureContainer futureContainer = SingletonFutureContainer.getInstance(); + super.setSourceText(futureContainer.getLicenseText()); + } + + @Override + protected void setCheckbox() { + ISharedPreferencesManager sharedPreferences = getSharedPreferences(); + super.setCheckboxStatus(sharedPreferences.isSoftwareLicenseAccepted()); + } + + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + super.setCheckboxStatus(isChecked); + getSharedPreferences().setSoftwareLicenseAccepted(isChecked); + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/views/fragments/termsofservice/PrivacyFragment.java b/SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/termsofservice/PrivacyFragment.java similarity index 97% rename from APP/app/src/main/java/javinator9889/securepass/views/fragments/termsofservice/PrivacyFragment.java rename to SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/termsofservice/PrivacyFragment.java index 7d76e33..c3ca8e3 100644 --- a/APP/app/src/main/java/javinator9889/securepass/views/fragments/termsofservice/PrivacyFragment.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/termsofservice/PrivacyFragment.java @@ -1,47 +1,47 @@ -package javinator9889.securepass.views.fragments.termsofservice; - -import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.CompoundButton; - -import javinator9889.securepass.R; -import javinator9889.securepass.objects.SingletonFutureContainer; -import javinator9889.securepass.util.resources.ISharedPreferencesManager; -import javinator9889.securepass.views.fragments.termsofservice.base.ToSBaseFragment; - -/** - * Created by Javinator9889 on 23/09/2018. - */ -public class PrivacyFragment extends ToSBaseFragment { - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, - @Nullable Bundle savedInstanceState) { - setTextId(R.id.privacy_policy); - setCheckboxId(R.id.checkBoxPrivacy); - setScrollViewId(R.id.privacy_scroll); - return inflater.inflate(R.layout.privacy, container, false); - } - - @Override - protected void setText() { - SingletonFutureContainer futureContainer = SingletonFutureContainer.getInstance(); - super.setSourceText(futureContainer.getPrivacyText()); - } - - @Override - protected void setCheckbox() { - ISharedPreferencesManager sharedPreferences = getSharedPreferences(); - super.setCheckboxStatus(sharedPreferences.isPrivacyAccepted()); - } - - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - super.setCheckboxStatus(isChecked); - getSharedPreferences().setPrivacyAccepted(isChecked); - } -} +package javinator9889.securepass.views.fragments.termsofservice; + +import android.os.Bundle; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CompoundButton; + +import javinator9889.securepass.R; +import javinator9889.securepass.objects.SingletonFutureContainer; +import javinator9889.securepass.util.resources.ISharedPreferencesManager; +import javinator9889.securepass.views.fragments.termsofservice.base.ToSBaseFragment; + +/** + * Created by Javinator9889 on 23/09/2018. + */ +public class PrivacyFragment extends ToSBaseFragment { + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + setTextId(R.id.privacy_policy); + setCheckboxId(R.id.checkBoxPrivacy); + setScrollViewId(R.id.privacy_scroll); + return inflater.inflate(R.layout.privacy, container, false); + } + + @Override + protected void setText() { + SingletonFutureContainer futureContainer = SingletonFutureContainer.getInstance(); + super.setSourceText(futureContainer.getPrivacyText()); + } + + @Override + protected void setCheckbox() { + ISharedPreferencesManager sharedPreferences = getSharedPreferences(); + super.setCheckboxStatus(sharedPreferences.isPrivacyAccepted()); + } + + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + super.setCheckboxStatus(isChecked); + getSharedPreferences().setPrivacyAccepted(isChecked); + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/views/fragments/termsofservice/TermsFragment.java b/SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/termsofservice/TermsFragment.java similarity index 97% rename from APP/app/src/main/java/javinator9889/securepass/views/fragments/termsofservice/TermsFragment.java rename to SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/termsofservice/TermsFragment.java index 07fbeaf..b828162 100644 --- a/APP/app/src/main/java/javinator9889/securepass/views/fragments/termsofservice/TermsFragment.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/termsofservice/TermsFragment.java @@ -1,47 +1,47 @@ -package javinator9889.securepass.views.fragments.termsofservice; - -import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.CompoundButton; - -import javinator9889.securepass.R; -import javinator9889.securepass.objects.SingletonFutureContainer; -import javinator9889.securepass.util.resources.ISharedPreferencesManager; -import javinator9889.securepass.views.fragments.termsofservice.base.ToSBaseFragment; - -/** - * Created by Javinator9889 on 23/09/2018. - */ -public class TermsFragment extends ToSBaseFragment { - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, - @Nullable Bundle savedInstanceState) { - setTextId(R.id.terms_conditions_text); - setCheckboxId(R.id.checkBoxToS); - setScrollViewId(R.id.tos_scroll); - return inflater.inflate(R.layout.terms_conditions, container, false); - } - - @Override - protected void setText() { - SingletonFutureContainer futureContainer = SingletonFutureContainer.getInstance(); - super.setSourceText(futureContainer.getToSText()); - } - - @Override - protected void setCheckbox() { - ISharedPreferencesManager sharedPreferences = getSharedPreferences(); - super.setCheckboxStatus(sharedPreferences.areTermsOfServiceAccepted()); - } - - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - super.setCheckboxStatus(isChecked); - getSharedPreferences().setTermsOfServiceAccepted(isChecked); - } -} +package javinator9889.securepass.views.fragments.termsofservice; + +import android.os.Bundle; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CompoundButton; + +import javinator9889.securepass.R; +import javinator9889.securepass.objects.SingletonFutureContainer; +import javinator9889.securepass.util.resources.ISharedPreferencesManager; +import javinator9889.securepass.views.fragments.termsofservice.base.ToSBaseFragment; + +/** + * Created by Javinator9889 on 23/09/2018. + */ +public class TermsFragment extends ToSBaseFragment { + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + setTextId(R.id.terms_conditions_text); + setCheckboxId(R.id.checkBoxToS); + setScrollViewId(R.id.tos_scroll); + return inflater.inflate(R.layout.terms_conditions, container, false); + } + + @Override + protected void setText() { + SingletonFutureContainer futureContainer = SingletonFutureContainer.getInstance(); + super.setSourceText(futureContainer.getToSText()); + } + + @Override + protected void setCheckbox() { + ISharedPreferencesManager sharedPreferences = getSharedPreferences(); + super.setCheckboxStatus(sharedPreferences.areTermsOfServiceAccepted()); + } + + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + super.setCheckboxStatus(isChecked); + getSharedPreferences().setTermsOfServiceAccepted(isChecked); + } +} diff --git a/APP/app/src/main/java/javinator9889/securepass/views/fragments/termsofservice/base/ToSBaseFragment.java b/SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/termsofservice/base/ToSBaseFragment.java similarity index 97% rename from APP/app/src/main/java/javinator9889/securepass/views/fragments/termsofservice/base/ToSBaseFragment.java rename to SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/termsofservice/base/ToSBaseFragment.java index fea245a..c7d35a1 100644 --- a/APP/app/src/main/java/javinator9889/securepass/views/fragments/termsofservice/base/ToSBaseFragment.java +++ b/SecurePass/app/src/main/java/javinator9889/securepass/views/fragments/termsofservice/base/ToSBaseFragment.java @@ -1,114 +1,114 @@ -package javinator9889.securepass.views.fragments.termsofservice.base; - -import android.os.Bundle; -import androidx.annotation.IdRes; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.CheckBox; -import android.widget.CompoundButton; -import android.widget.ScrollView; -import android.widget.TextView; - -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; - -import javinator9889.securepass.util.resources.ISharedPreferencesManager; -import javinator9889.securepass.util.resources.PreferencesManager; -import ru.noties.markwon.Markwon; - -/** - * Created by Javinator9889 on 23/09/2018. - */ -public abstract class ToSBaseFragment extends Fragment - implements CompoundButton.OnCheckedChangeListener { - private Future mText; - private @IdRes int mTextId; - private @IdRes int mCheckboxId; - private @IdRes int mScrollView; - private boolean mCheckboxStatus; - private ISharedPreferencesManager mSharedPreferences; - - @Nullable - @Override - public abstract View onCreateView(@NonNull LayoutInflater inflater, - @Nullable ViewGroup container, - @Nullable Bundle savedInstanceState); - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mSharedPreferences = PreferencesManager.getInstance(); - setText(); - setCheckbox(); - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - TextView textToChange = view.findViewById(mTextId); - final CheckBox checkBox = view.findViewById(mCheckboxId); - final ScrollView scrollView = view.findViewById(mScrollView); - try { - Markwon.setText(textToChange, mText.get()); - } catch (InterruptedException | ExecutionException e) { - textToChange.setText(String.format("Error | %s", e.getMessage())); - } finally { - checkBox.setEnabled(mCheckboxStatus); - checkBox.setChecked(mCheckboxStatus); - checkBox.setOnCheckedChangeListener(this); - scrollView.getViewTreeObserver() - .addOnScrollChangedListener(() -> { - int totalLength = scrollView.getHeight() + scrollView.getScrollY(); - if (scrollView.getChildAt(0).getBottom() == totalLength) - if (!checkBox.isEnabled()) - checkBox.setEnabled(true); - }); - } - } - - protected void setSourceText(Future futureText) { - mText = futureText; - } - - protected void setTextId(@IdRes int resourceId) { - this.mTextId = resourceId; - } - - protected void setCheckboxId(@IdRes int resourceId) { - this.mCheckboxId = resourceId; - } - - protected void setScrollViewId(@IdRes int resourceId) { - this.mScrollView = resourceId; - } - - protected void setCheckboxStatus(boolean status) { - this.mCheckboxStatus = status; - } - - protected Future getText() {return mText;} - - @IdRes - protected int getCheckboxId() { - return mCheckboxId; - } - - @IdRes - protected int getTextId() { - return mTextId; - } - - protected ISharedPreferencesManager getSharedPreferences() { - return mSharedPreferences; - } - - protected abstract void setText(); - - protected abstract void setCheckbox(); - - public abstract void onCheckedChanged(CompoundButton buttonView, boolean isChecked); -} +package javinator9889.securepass.views.fragments.termsofservice.base; + +import android.os.Bundle; +import androidx.annotation.IdRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.ScrollView; +import android.widget.TextView; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import javinator9889.securepass.util.resources.ISharedPreferencesManager; +import javinator9889.securepass.util.resources.PreferencesManager; +import ru.noties.markwon.Markwon; + +/** + * Created by Javinator9889 on 23/09/2018. + */ +public abstract class ToSBaseFragment extends Fragment + implements CompoundButton.OnCheckedChangeListener { + private Future mText; + private @IdRes int mTextId; + private @IdRes int mCheckboxId; + private @IdRes int mScrollView; + private boolean mCheckboxStatus; + private ISharedPreferencesManager mSharedPreferences; + + @Nullable + @Override + public abstract View onCreateView(@NonNull LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState); + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mSharedPreferences = PreferencesManager.getInstance(); + setText(); + setCheckbox(); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + TextView textToChange = view.findViewById(mTextId); + final CheckBox checkBox = view.findViewById(mCheckboxId); + final ScrollView scrollView = view.findViewById(mScrollView); + try { + Markwon.setText(textToChange, mText.get()); + } catch (InterruptedException | ExecutionException e) { + textToChange.setText(String.format("Error | %s", e.getMessage())); + } finally { + checkBox.setEnabled(mCheckboxStatus); + checkBox.setChecked(mCheckboxStatus); + checkBox.setOnCheckedChangeListener(this); + scrollView.getViewTreeObserver() + .addOnScrollChangedListener(() -> { + int totalLength = scrollView.getHeight() + scrollView.getScrollY(); + if (scrollView.getChildAt(0).getBottom() == totalLength) + if (!checkBox.isEnabled()) + checkBox.setEnabled(true); + }); + } + } + + protected void setSourceText(Future futureText) { + mText = futureText; + } + + protected void setTextId(@IdRes int resourceId) { + this.mTextId = resourceId; + } + + protected void setCheckboxId(@IdRes int resourceId) { + this.mCheckboxId = resourceId; + } + + protected void setScrollViewId(@IdRes int resourceId) { + this.mScrollView = resourceId; + } + + protected void setCheckboxStatus(boolean status) { + this.mCheckboxStatus = status; + } + + protected Future getText() {return mText;} + + @IdRes + protected int getCheckboxId() { + return mCheckboxId; + } + + @IdRes + protected int getTextId() { + return mTextId; + } + + protected ISharedPreferencesManager getSharedPreferences() { + return mSharedPreferences; + } + + protected abstract void setText(); + + protected abstract void setCheckbox(); + + public abstract void onCheckedChanged(CompoundButton buttonView, boolean isChecked); +} diff --git a/APP/app/src/main/res/color/custom_tab.xml b/SecurePass/app/src/main/res/color/custom_tab.xml similarity index 94% rename from APP/app/src/main/res/color/custom_tab.xml rename to SecurePass/app/src/main/res/color/custom_tab.xml index 8e90fe6..b0de627 100644 --- a/APP/app/src/main/res/color/custom_tab.xml +++ b/SecurePass/app/src/main/res/color/custom_tab.xml @@ -1,5 +1,5 @@ - - - - + + + + \ No newline at end of file diff --git a/APP/app/src/main/res/drawable-hdpi/ic_info_outline_black_24dp.png b/SecurePass/app/src/main/res/drawable-hdpi/ic_info_outline_black_24dp.png similarity index 100% rename from APP/app/src/main/res/drawable-hdpi/ic_info_outline_black_24dp.png rename to SecurePass/app/src/main/res/drawable-hdpi/ic_info_outline_black_24dp.png diff --git a/APP/app/src/main/res/drawable-mdpi/ic_info_outline_black_24dp.png b/SecurePass/app/src/main/res/drawable-mdpi/ic_info_outline_black_24dp.png similarity index 100% rename from APP/app/src/main/res/drawable-mdpi/ic_info_outline_black_24dp.png rename to SecurePass/app/src/main/res/drawable-mdpi/ic_info_outline_black_24dp.png diff --git a/APP/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/SecurePass/app/src/main/res/drawable-v24/ic_launcher_foreground.xml similarity index 98% rename from APP/app/src/main/res/drawable-v24/ic_launcher_foreground.xml rename to SecurePass/app/src/main/res/drawable-v24/ic_launcher_foreground.xml index c7bd21d..ddb26ad 100644 --- a/APP/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ b/SecurePass/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -1,34 +1,34 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/APP/app/src/main/res/drawable-xhdpi/ic_info_outline_black_24dp.png b/SecurePass/app/src/main/res/drawable-xhdpi/ic_info_outline_black_24dp.png similarity index 100% rename from APP/app/src/main/res/drawable-xhdpi/ic_info_outline_black_24dp.png rename to SecurePass/app/src/main/res/drawable-xhdpi/ic_info_outline_black_24dp.png diff --git a/APP/app/src/main/res/drawable-xxhdpi/ic_info_outline_black_24dp.png b/SecurePass/app/src/main/res/drawable-xxhdpi/ic_info_outline_black_24dp.png similarity index 100% rename from APP/app/src/main/res/drawable-xxhdpi/ic_info_outline_black_24dp.png rename to SecurePass/app/src/main/res/drawable-xxhdpi/ic_info_outline_black_24dp.png diff --git a/APP/app/src/main/res/drawable-xxxhdpi/ic_info_outline_black_24dp.png b/SecurePass/app/src/main/res/drawable-xxxhdpi/ic_info_outline_black_24dp.png similarity index 100% rename from APP/app/src/main/res/drawable-xxxhdpi/ic_info_outline_black_24dp.png rename to SecurePass/app/src/main/res/drawable-xxxhdpi/ic_info_outline_black_24dp.png diff --git a/APP/app/src/main/res/drawable/data_security.png b/SecurePass/app/src/main/res/drawable/data_security.png similarity index 100% rename from APP/app/src/main/res/drawable/data_security.png rename to SecurePass/app/src/main/res/drawable/data_security.png diff --git a/APP/app/src/main/res/drawable/ic_add.xml b/SecurePass/app/src/main/res/drawable/ic_add.xml similarity index 94% rename from APP/app/src/main/res/drawable/ic_add.xml rename to SecurePass/app/src/main/res/drawable/ic_add.xml index 02a1fb1..604db87 100644 --- a/APP/app/src/main/res/drawable/ic_add.xml +++ b/SecurePass/app/src/main/res/drawable/ic_add.xml @@ -1,10 +1,10 @@ - - - + + + \ No newline at end of file diff --git a/APP/app/src/main/res/drawable/ic_launcher_background.xml b/SecurePass/app/src/main/res/drawable/ic_launcher_background.xml similarity index 97% rename from APP/app/src/main/res/drawable/ic_launcher_background.xml rename to SecurePass/app/src/main/res/drawable/ic_launcher_background.xml index d5fccc5..3a37cf6 100644 --- a/APP/app/src/main/res/drawable/ic_launcher_background.xml +++ b/SecurePass/app/src/main/res/drawable/ic_launcher_background.xml @@ -1,170 +1,170 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/APP/app/src/main/res/drawable/privacy.png b/SecurePass/app/src/main/res/drawable/privacy.png similarity index 100% rename from APP/app/src/main/res/drawable/privacy.png rename to SecurePass/app/src/main/res/drawable/privacy.png diff --git a/APP/app/src/main/res/drawable/rounded_button.xml b/SecurePass/app/src/main/res/drawable/rounded_button.xml similarity index 96% rename from APP/app/src/main/res/drawable/rounded_button.xml rename to SecurePass/app/src/main/res/drawable/rounded_button.xml index b16b9bf..f693cce 100644 --- a/APP/app/src/main/res/drawable/rounded_button.xml +++ b/SecurePass/app/src/main/res/drawable/rounded_button.xml @@ -1,14 +1,14 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + \ No newline at end of file diff --git a/APP/app/src/main/res/drawable/secure_image.png b/SecurePass/app/src/main/res/drawable/secure_image.png similarity index 100% rename from APP/app/src/main/res/drawable/secure_image.png rename to SecurePass/app/src/main/res/drawable/secure_image.png diff --git a/APP/app/src/main/res/drawable/speed.png b/SecurePass/app/src/main/res/drawable/speed.png similarity index 100% rename from APP/app/src/main/res/drawable/speed.png rename to SecurePass/app/src/main/res/drawable/speed.png diff --git a/APP/app/src/main/res/drawable/user_friendly.png b/SecurePass/app/src/main/res/drawable/user_friendly.png similarity index 100% rename from APP/app/src/main/res/drawable/user_friendly.png rename to SecurePass/app/src/main/res/drawable/user_friendly.png diff --git a/APP/app/src/main/res/font/advent_pro_bold.xml b/SecurePass/app/src/main/res/font/advent_pro_bold.xml similarity index 98% rename from APP/app/src/main/res/font/advent_pro_bold.xml rename to SecurePass/app/src/main/res/font/advent_pro_bold.xml index 90b6cd2..212cba4 100644 --- a/APP/app/src/main/res/font/advent_pro_bold.xml +++ b/SecurePass/app/src/main/res/font/advent_pro_bold.xml @@ -1,7 +1,7 @@ - - - + + + diff --git a/APP/app/src/main/res/font/alegreya_sans.xml b/SecurePass/app/src/main/res/font/alegreya_sans.xml similarity index 98% rename from APP/app/src/main/res/font/alegreya_sans.xml rename to SecurePass/app/src/main/res/font/alegreya_sans.xml index 5628ac7..9c763cd 100644 --- a/APP/app/src/main/res/font/alegreya_sans.xml +++ b/SecurePass/app/src/main/res/font/alegreya_sans.xml @@ -1,7 +1,7 @@ - - - + + + diff --git a/APP/app/src/main/res/font/alegreya_sans_thin.xml b/SecurePass/app/src/main/res/font/alegreya_sans_thin.xml similarity index 98% rename from APP/app/src/main/res/font/alegreya_sans_thin.xml rename to SecurePass/app/src/main/res/font/alegreya_sans_thin.xml index 0779243..cf4286d 100644 --- a/APP/app/src/main/res/font/alegreya_sans_thin.xml +++ b/SecurePass/app/src/main/res/font/alegreya_sans_thin.xml @@ -1,7 +1,7 @@ - - - + + + diff --git a/APP/app/src/main/assets/fonts/raleway.ttf b/SecurePass/app/src/main/res/font/raleway.ttf similarity index 100% rename from APP/app/src/main/assets/fonts/raleway.ttf rename to SecurePass/app/src/main/res/font/raleway.ttf diff --git a/APP/app/src/main/assets/fonts/raleway_semibold.ttf b/SecurePass/app/src/main/res/font/raleway_semibold.ttf similarity index 100% rename from APP/app/src/main/assets/fonts/raleway_semibold.ttf rename to SecurePass/app/src/main/res/font/raleway_semibold.ttf diff --git a/APP/app/src/main/res/font/roboto.xml b/SecurePass/app/src/main/res/font/roboto.xml similarity index 98% rename from APP/app/src/main/res/font/roboto.xml rename to SecurePass/app/src/main/res/font/roboto.xml index 2641caf..09de7e0 100644 --- a/APP/app/src/main/res/font/roboto.xml +++ b/SecurePass/app/src/main/res/font/roboto.xml @@ -1,7 +1,7 @@ - - - + + + diff --git a/APP/app/src/main/res/font/roboto_light.xml b/SecurePass/app/src/main/res/font/roboto_light.xml similarity index 98% rename from APP/app/src/main/res/font/roboto_light.xml rename to SecurePass/app/src/main/res/font/roboto_light.xml index 28fbc0d..09b8428 100644 --- a/APP/app/src/main/res/font/roboto_light.xml +++ b/SecurePass/app/src/main/res/font/roboto_light.xml @@ -1,7 +1,7 @@ - - - + + + diff --git a/APP/app/src/main/res/layout/custom_tab.xml b/SecurePass/app/src/main/res/layout/custom_tab.xml similarity index 91% rename from APP/app/src/main/res/layout/custom_tab.xml rename to SecurePass/app/src/main/res/layout/custom_tab.xml index 8b5f729..f39c8e9 100644 --- a/APP/app/src/main/res/layout/custom_tab.xml +++ b/SecurePass/app/src/main/res/layout/custom_tab.xml @@ -1,12 +1,12 @@ - - + \ No newline at end of file diff --git a/APP/app/src/main/res/layout/drive.xml b/SecurePass/app/src/main/res/layout/drive.xml similarity index 96% rename from APP/app/src/main/res/layout/drive.xml rename to SecurePass/app/src/main/res/layout/drive.xml index e252ed8..c85181d 100644 --- a/APP/app/src/main/res/layout/drive.xml +++ b/SecurePass/app/src/main/res/layout/drive.xml @@ -1,37 +1,37 @@ - - - -