Skip to content

Commit 81a4665

Browse files
committed
Add ability to enter DB password on runtime
1 parent 4295948 commit 81a4665

File tree

15 files changed

+75
-80
lines changed

15 files changed

+75
-80
lines changed

README.md

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,6 @@ If you are using `build.gradle.kts`, add the following:
7070
debugImplementation("com.github.amitshekhariitbhu.Android-Debug-Database:debug-db-encrypt:1.0.7")
7171
```
7272

73-
And to provide the password for the DB, you should add this in the Gradle:
74-
DB_PASSWORD_{VARIABLE}, if for example, PERSON is the database name: DB_PASSWORD_PERSON
75-
```groovy
76-
debug {
77-
resValue("string", "DB_PASSWORD_PERSON", "password")
78-
}
79-
```
80-
8173
Use `debugImplementation` so that it will only compile in your debug build and not in your release build.
8274

8375
That’s all, just start the application, you will see in the logcat an entry like follows :
@@ -147,11 +139,11 @@ public static void setCustomDatabaseFiles(Context context) {
147139
Class<?> debugDB = Class.forName("com.amitshekhar.DebugDB");
148140
Class[] argTypes = new Class[]{HashMap.class};
149141
Method setCustomDatabaseFiles = debugDB.getMethod("setCustomDatabaseFiles", argTypes);
150-
HashMap<String, Pair<File, String>> customDatabaseFiles = new HashMap<>();
142+
HashMap<String, File> customDatabaseFiles = new HashMap<>();
151143
// set your custom database files
152144
customDatabaseFiles.put(ExtTestDBHelper.DATABASE_NAME,
153-
new Pair<>(new File(context.getFilesDir() + "/" + ExtTestDBHelper.DIR_NAME +
154-
"/" + ExtTestDBHelper.DATABASE_NAME), ""));
145+
new File(context.getFilesDir() + "/" + ExtTestDBHelper.DIR_NAME +
146+
"/" + ExtTestDBHelper.DATABASE_NAME));
155147
setCustomDatabaseFiles.invoke(null, customDatabaseFiles);
156148
} catch (Exception ignore) {
157149

debug-db-base/src/main/assets/app.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ function getDBList() {
7979
$.ajax({url: "getDbList", success: function(result){
8080

8181
result = JSON.parse(result);
82+
if (!result.supportEncryptedDb) {
83+
$('#password').hide();
84+
$('#password-label').hide();
85+
}
8286
var dbList = result.rows;
8387
$('#db-list').empty();
8488
var isSelectionDone = false;
@@ -130,8 +134,8 @@ function openDatabaseAndGetTableList(db, isDownloadable) {
130134
isDatabaseSelected = true;
131135
}
132136

133-
134-
$.ajax({url: "getTableList?database="+db, success: function(result){
137+
var password = $('#password').val();
138+
$.ajax({url: "getTableList?database="+db+"&password="+password, success: function(result){
135139

136140
result = JSON.parse(result);
137141
var tableList = result.rows;

debug-db-base/src/main/assets/index.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@
107107
<div class="row padding-twenty">
108108
<div class="col-sm-12">
109109
<div class="form-group">
110+
<label for="password" id="password-label">DB password</label>
111+
<input class="form-control" id="password">
110112
<label for="query">Query</label>
111113
<input class="form-control" id="query">
112114
</div>

debug-db-base/src/main/java/com/amitshekhar/DebugDB.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public static void shutDown() {
7676
}
7777
}
7878

79-
public static void setCustomDatabaseFiles(HashMap<String, Pair<File, String>> customDatabaseFiles) {
79+
public static void setCustomDatabaseFiles(HashMap<String, File> customDatabaseFiles) {
8080
if (clientServer != null) {
8181
clientServer.setCustomDatabaseFiles(customDatabaseFiles);
8282
}

debug-db-base/src/main/java/com/amitshekhar/model/Response.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public class Response {
3333
public boolean isSuccessful;
3434
public String error;
3535
public int dbVersion;
36+
public boolean supportEncryptedDb;
3637

3738
public Response() {
3839

debug-db-base/src/main/java/com/amitshekhar/server/ClientServer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public void run() {
8787
}
8888
}
8989

90-
public void setCustomDatabaseFiles(HashMap<String, Pair<File, String>> customDatabaseFiles) {
90+
public void setCustomDatabaseFiles(HashMap<String, File> customDatabaseFiles) {
9191
mRequestHandler.setCustomDatabaseFiles(customDatabaseFiles);
9292
}
9393

debug-db-base/src/main/java/com/amitshekhar/server/RequestHandler.java

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ public class RequestHandler {
6565
private final DBFactory mDbFactory;
6666
private boolean isDbOpened;
6767
private SQLiteDB sqLiteDB;
68-
private HashMap<String, Pair<File, String>> mDatabaseFiles;
69-
private HashMap<String, Pair<File, String>> mCustomDatabaseFiles;
68+
private HashMap<String, File> mDatabaseFiles;
69+
private HashMap<String, File> mCustomDatabaseFiles;
7070
private String mSelectedDatabase = null;
7171
private HashMap<String, SupportSQLiteDatabase> mRoomInMemoryDatabases = new HashMap<>();
7272

@@ -165,7 +165,7 @@ public void handle(Socket socket) throws IOException {
165165
}
166166
}
167167

168-
public void setCustomDatabaseFiles(HashMap<String, Pair<File, String>> customDatabaseFiles) {
168+
public void setCustomDatabaseFiles(HashMap<String, File> customDatabaseFiles) {
169169
mCustomDatabaseFiles = customDatabaseFiles;
170170
}
171171

@@ -178,13 +178,12 @@ private void writeServerError(PrintStream output) {
178178
output.flush();
179179
}
180180

181-
private void openDatabase(String database) {
181+
private void openDatabase(String database, String password) {
182182
closeDatabase();
183183
if (mRoomInMemoryDatabases.containsKey(database)) {
184184
sqLiteDB = new InMemoryDebugSQLiteDB(mRoomInMemoryDatabases.get(database));
185185
} else {
186-
File databaseFile = mDatabaseFiles.get(database).first;
187-
String password = mDatabaseFiles.get(database).second;
186+
File databaseFile = mDatabaseFiles.get(database);
188187
sqLiteDB = mDbFactory.create(mContext, databaseFile.getAbsolutePath(), password);
189188
}
190189
isDbOpened = true;
@@ -205,8 +204,10 @@ private String getDBListResponse() {
205204
}
206205
Response response = new Response();
207206
if (mDatabaseFiles != null) {
208-
for (HashMap.Entry<String, Pair<File, String>> entry : mDatabaseFiles.entrySet()) {
209-
String[] dbEntry = {entry.getKey(), !entry.getValue().second.equals("") ? "true" : "false", "true"};
207+
for (HashMap.Entry<String, File> entry : mDatabaseFiles.entrySet()) {
208+
String[] dbEntry = { entry.getKey(),
209+
Utils.isDbEncrypted(entry.getKey(), mDatabaseFiles) ? "true" : "false",
210+
"true" };
210211
response.rows.add(dbEntry);
211212
}
212213
}
@@ -218,6 +219,7 @@ private String getDBListResponse() {
218219
}
219220
response.rows.add(new String[]{Constants.APP_SHARED_PREFERENCES, "false", "false"});
220221
response.isSuccessful = true;
222+
response.supportEncryptedDb = mDbFactory.supportEncryptedDb();
221223
return mGson.toJson(response);
222224
}
223225

@@ -292,10 +294,9 @@ private String executeQueryAndGetResponse(String route) {
292294
}
293295

294296
private String getTableListResponse(String route) {
295-
String database = null;
296-
if (route.contains("?database=")) {
297-
database = route.substring(route.indexOf("=") + 1, route.length());
298-
}
297+
Uri uri = Uri.parse(route);
298+
String database = uri.getQueryParameter("database");
299+
String password = uri.getQueryParameter("password");
299300

300301
Response response;
301302

@@ -305,7 +306,7 @@ private String getTableListResponse(String route) {
305306
mSelectedDatabase = Constants.APP_SHARED_PREFERENCES;
306307
} else {
307308
try {
308-
openDatabase(database);
309+
openDatabase(database, password);
309310
response = DatabaseHelper.getAllTableName(sqLiteDB);
310311
} catch (Exception e) {
311312
response = new Response();
@@ -397,7 +398,7 @@ private String deleteSelectedDatabaseAndGetResponse() {
397398
try {
398399
closeDatabase();
399400

400-
File dbFile = mDatabaseFiles.get(mSelectedDatabase).first;
401+
File dbFile = mDatabaseFiles.get(mSelectedDatabase);
401402
response.isSuccessful = dbFile.delete();
402403

403404
if (response.isSuccessful) {

debug-db-base/src/main/java/com/amitshekhar/sqlite/DBFactory.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@ public interface DBFactory {
66

77
SQLiteDB create(Context context, String path, String password);
88

9+
boolean supportEncryptedDb();
10+
911
}

debug-db-base/src/main/java/com/amitshekhar/utils/DatabaseFileProvider.java

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,8 @@
2020
package com.amitshekhar.utils;
2121

2222
import android.content.Context;
23-
import android.util.Pair;
2423

2524
import java.io.File;
26-
import java.text.MessageFormat;
2725
import java.util.HashMap;
2826

2927
/**
@@ -32,39 +30,19 @@
3230

3331
public class DatabaseFileProvider {
3432

35-
private final static String DB_PASSWORD_RESOURCE = "DB_PASSWORD_{0}";
36-
3733
private DatabaseFileProvider() {
3834
// This class in not publicly instantiable
3935
}
4036

41-
public static HashMap<String, Pair<File, String>> getDatabaseFiles(Context context) {
42-
HashMap<String, Pair<File, String>> databaseFiles = new HashMap<>();
37+
public static HashMap<String, File> getDatabaseFiles(Context context) {
38+
HashMap<String, File> databaseFiles = new HashMap<>();
4339
try {
4440
for (String databaseName : context.databaseList()) {
45-
String password = getDbPasswordFromStringResources(context, databaseName);
46-
databaseFiles.put(databaseName, new Pair<>(context.getDatabasePath(databaseName), password));
41+
databaseFiles.put(databaseName, context.getDatabasePath(databaseName));
4742
}
4843
} catch (Exception e) {
4944
e.printStackTrace();
5045
}
5146
return databaseFiles;
5247
}
53-
54-
private static String getDbPasswordFromStringResources(Context context, String name) {
55-
String nameWithoutExt = name;
56-
if (nameWithoutExt.endsWith(".db")) {
57-
nameWithoutExt = nameWithoutExt.substring(0, nameWithoutExt.lastIndexOf('.'));
58-
}
59-
String resourceName = MessageFormat.format(DB_PASSWORD_RESOURCE, nameWithoutExt.toUpperCase());
60-
String password = "";
61-
62-
int resourceId = context.getResources().getIdentifier(resourceName, "string", context.getPackageName());
63-
64-
if (resourceId != 0) {
65-
password = context.getString(resourceId);
66-
}
67-
68-
return password;
69-
}
7048
}

debug-db-base/src/main/java/com/amitshekhar/utils/Utils.java

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,15 @@
2121

2222
import android.content.res.AssetManager;
2323
import android.text.TextUtils;
24-
import android.util.Log;
25-
import android.util.Pair;
2624

2725
import java.io.ByteArrayOutputStream;
26+
import java.io.DataInputStream;
2827
import java.io.File;
2928
import java.io.FileInputStream;
3029
import java.io.FileNotFoundException;
3130
import java.io.IOException;
3231
import java.io.InputStream;
33-
import java.util.HashMap;
32+
import java.util.Map;
3433

3534
/**
3635
* Created by amitshekhar on 06/02/17.
@@ -83,35 +82,44 @@ public static byte[] loadContent(String fileName, AssetManager assetManager) thr
8382
}
8483
}
8584

86-
public static byte[] getDatabase(String selectedDatabase, HashMap<String, Pair<File, String>> databaseFiles) {
85+
public static byte[] getDatabase(String selectedDatabase, Map<String, File> databaseFiles) {
8786
if (TextUtils.isEmpty(selectedDatabase) || !databaseFiles.containsKey(selectedDatabase)) {
8887
return null;
8988
}
9089

9190
byte[] byteArray = new byte[0];
92-
try {
93-
File file = databaseFiles.get(selectedDatabase).first;
91+
File file = databaseFiles.get(selectedDatabase);
9492

95-
byteArray = null;
96-
try {
97-
InputStream inputStream = new FileInputStream(file);
98-
ByteArrayOutputStream bos = new ByteArrayOutputStream();
99-
byte[] b = new byte[(int) file.length()];
100-
int bytesRead;
93+
try (InputStream is = new FileInputStream(file);
94+
ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
95+
byte[] b = new byte[(int) file.length()];
96+
int bytesRead;
10197

102-
while ((bytesRead = inputStream.read(b)) != -1) {
103-
bos.write(b, 0, bytesRead);
104-
}
105-
106-
byteArray = bos.toByteArray();
107-
} catch (IOException e) {
108-
Log.e(TAG, "getDatabase: ", e);
98+
while ((bytesRead = is.read(b)) != -1) {
99+
bos.write(b, 0, bytesRead);
109100
}
101+
102+
byteArray = bos.toByteArray();
110103
} catch (Exception e) {
111104
e.printStackTrace();
112105
}
113106

114107
return byteArray;
115108
}
116109

110+
public static boolean isDbEncrypted(String database, Map<String, File> databaseFiles) {
111+
if (TextUtils.isEmpty(database) || !databaseFiles.containsKey(database)) {
112+
return false;
113+
}
114+
File file = databaseFiles.get(database);
115+
try (DataInputStream is = new DataInputStream(new FileInputStream(file))) {
116+
byte[] b = new byte[16];
117+
is.readFully(b);
118+
String string = new String(b);
119+
return !"SQLite format 3\000".equals(string);
120+
} catch (Exception e) {
121+
e.printStackTrace();
122+
}
123+
return false;
124+
}
117125
}

0 commit comments

Comments
 (0)