diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/HiddenServicesActivity.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/HiddenServicesActivity.java index dc233bb3..9de02966 100644 --- a/app/src/main/java/org/torproject/android/ui/hiddenservices/HiddenServicesActivity.java +++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/HiddenServicesActivity.java @@ -26,16 +26,8 @@ import org.torproject.android.ui.hiddenservices.storage.PermissionManager; public class HiddenServicesActivity extends AppCompatActivity { public final int WRITE_EXTERNAL_STORAGE_FROM_ACTIONBAR = 1; - private ContentResolver mCR; + private ContentResolver mResolver; private OnionListAdapter mAdapter; - private Toolbar toolbar; - private String[] mProjection = new String[]{ - HSContentProvider.HiddenService._ID, - HSContentProvider.HiddenService.NAME, - HSContentProvider.HiddenService.PORT, - HSContentProvider.HiddenService.DOMAIN, - HSContentProvider.HiddenService.CREATED_BY_USER - }; private String mWhere = HSContentProvider.HiddenService.CREATED_BY_USER + "=1"; @@ -44,11 +36,11 @@ public class HiddenServicesActivity extends AppCompatActivity { super.onCreate(savedInstanceState); setContentView(R.layout.layout_hs_list_view); - toolbar = (Toolbar) findViewById(R.id.toolbar); + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); getSupportActionBar().setDisplayHomeAsUpEnabled(true); - mCR = getContentResolver(); + mResolver = getContentResolver(); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @@ -61,11 +53,13 @@ public class HiddenServicesActivity extends AppCompatActivity { mAdapter = new OnionListAdapter( this, - mCR.query(HSContentProvider.CONTENT_URI, mProjection, mWhere, null, null), + mResolver.query( + HSContentProvider.CONTENT_URI, HSContentProvider.PROJECTION, mWhere, null, null + ), 0 ); - mCR.registerContentObserver( + mResolver.registerContentObserver( HSContentProvider.CONTENT_URI, true, new HSObserver(new Handler()) ); @@ -143,8 +137,8 @@ public class HiddenServicesActivity extends AppCompatActivity { @Override public void onChange(boolean selfChange) { - mAdapter.changeCursor(mCR.query( - HSContentProvider.CONTENT_URI, mProjection, mWhere, null, null + mAdapter.changeCursor(mResolver.query( + HSContentProvider.CONTENT_URI, HSContentProvider.PROJECTION, mWhere, null, null )); } } diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/BackupUtils.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/BackupUtils.java index 70da3022..07a9600c 100644 --- a/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/BackupUtils.java +++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/BackupUtils.java @@ -1,18 +1,26 @@ package org.torproject.android.ui.hiddenservices.backup; +import android.content.ContentResolver; import android.content.Context; +import android.database.Cursor; import android.widget.Toast; +import org.json.JSONException; +import org.json.JSONObject; import org.torproject.android.service.R; import org.torproject.android.service.TorServiceConstants; +import org.torproject.android.ui.hiddenservices.providers.HSContentProvider; import org.torproject.android.ui.hiddenservices.storage.ExternalStorage; import java.io.File; +import java.io.FileWriter; import java.io.IOException; public class BackupUtils { private File mHSBasePath; private Context mContext; + private ContentResolver mResolver; + private final String configFileName = "config.json"; public BackupUtils(Context context) { mContext = context; @@ -20,26 +28,86 @@ public class BackupUtils { mContext.getFilesDir().getAbsolutePath(), TorServiceConstants.HIDDEN_SERVICES_DIR ); + + mResolver = mContext.getContentResolver(); } public String createZipBackup(Integer port) { + String configFilePath = mHSBasePath + "/hs" + port + "/" + configFileName; + String hostnameFilePath = mHSBasePath + "/hs" + port + "/hostname"; + String keyFilePath = mHSBasePath + "/hs" + port + "/private_key"; + File storage_path = ExternalStorage.getOrCreateBackupDir(); if (storage_path == null) return null; + Cursor portData = mResolver.query( + HSContentProvider.CONTENT_URI, + HSContentProvider.PROJECTION, + HSContentProvider.HiddenService.PORT + "=" + port, + null, + null + ); + + JSONObject config = new JSONObject(); + try { + if (portData.getCount() != 1) + return null; + + portData.moveToNext(); + + config.put( + HSContentProvider.HiddenService.NAME, + portData.getString(portData.getColumnIndex(HSContentProvider.HiddenService.NAME)) + ); + + config.put( + HSContentProvider.HiddenService.PORT, + portData.getInt(portData.getColumnIndex(HSContentProvider.HiddenService.PORT)) + ); + + config.put( + HSContentProvider.HiddenService.ONION_PORT, + portData.getInt(portData.getColumnIndex(HSContentProvider.HiddenService.ONION_PORT)) + ); + + config.put( + HSContentProvider.HiddenService.DOMAIN, + portData.getString(portData.getColumnIndex(HSContentProvider.HiddenService.DOMAIN)) + ); + + config.put( + HSContentProvider.HiddenService.CREATED_BY_USER, + portData.getInt(portData.getColumnIndex(HSContentProvider.HiddenService.CREATED_BY_USER)) + ); + } catch (JSONException e) { + e.printStackTrace(); + return null; + } catch (NullPointerException e) { + e.printStackTrace(); + return null; + } + + try { + FileWriter file = new FileWriter(configFilePath); + file.write(config.toString()); + file.close(); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + + portData.close(); + String zip_path = storage_path.getAbsolutePath() + "/hs" + port + ".zip"; - String files[] = { - mHSBasePath + "/hs" + port + "/hostname", - mHSBasePath + "/hs" + port + "/private_key" - }; + String files[] = {hostnameFilePath, keyFilePath, configFilePath}; ZipIt zip = new ZipIt(files, zip_path); - if (!zip.zip()) { + if (!zip.zip()) return null; - } return zip_path; } diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/providers/HSContentProvider.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/providers/HSContentProvider.java index 856c6853..2270f5d1 100644 --- a/app/src/main/java/org/torproject/android/ui/hiddenservices/providers/HSContentProvider.java +++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/providers/HSContentProvider.java @@ -19,39 +19,47 @@ public class HSContentProvider extends ContentProvider { private static final String AUTH = "org.torproject.android.ui.hiddenservices.providers"; public static final Uri CONTENT_URI = Uri.parse("content://" + AUTH + "/hs"); + + public static final String[] PROJECTION = new String[]{ + HiddenService._ID, + HiddenService.NAME, + HiddenService.PORT, + HiddenService.DOMAIN, + HiddenService.ONION_PORT, + HiddenService.CREATED_BY_USER + }; + //UriMatcher private static final int ONIONS = 1; private static final int ONION_ID = 2; private static final UriMatcher uriMatcher; - //Inicializamos el UriMatcher static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(AUTH, "hs", ONIONS); uriMatcher.addURI(AUTH, "hs/#", ONION_ID); } - private HSDatabase mServerDB; + private HSDatabase mServervices; private Context mContext; @Override public boolean onCreate() { mContext = getContext(); - mServerDB = new HSDatabase(mContext); + mServervices = new HSDatabase(mContext); return true; } @Nullable @Override public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { - //Si es una consulta a un ID concreto construimos el WHERE String where = selection; if (uriMatcher.match(uri) == ONION_ID) { where = "_id=" + uri.getLastPathSegment(); } - SQLiteDatabase db = mServerDB.getReadableDatabase(); + SQLiteDatabase db = mServervices.getReadableDatabase(); return db.query(HSDatabase.HS_DATA_TABLE_NAME, projection, where, selectionArgs, null, null, sortOrder); @@ -77,7 +85,7 @@ public class HSContentProvider extends ContentProvider { public Uri insert(@NonNull Uri uri, ContentValues values) { long regId; - SQLiteDatabase db = mServerDB.getWritableDatabase(); + SQLiteDatabase db = mServervices.getWritableDatabase(); regId = db.insert(HSDatabase.HS_DATA_TABLE_NAME, null, values); @@ -89,13 +97,12 @@ public class HSContentProvider extends ContentProvider { @Override public int delete(@NonNull Uri uri, String selection, String[] selectionArgs) { - //Si es una consulta a un ID concreto construimos el WHERE String where = selection; if (uriMatcher.match(uri) == ONION_ID) { where = "_id=" + uri.getLastPathSegment(); } - SQLiteDatabase db = mServerDB.getWritableDatabase(); + SQLiteDatabase db = mServervices.getWritableDatabase(); Integer rows = db.delete(HSDatabase.HS_DATA_TABLE_NAME, where, selectionArgs); @@ -107,7 +114,7 @@ public class HSContentProvider extends ContentProvider { @Override public int update(@NonNull Uri uri, ContentValues values, String selection, String[] selectionArgs) { - SQLiteDatabase db = mServerDB.getWritableDatabase(); + SQLiteDatabase db = mServervices.getWritableDatabase(); String where = selection; if (uriMatcher.match(uri) == ONION_ID) {