package org.commcare.provider;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import org.commcare.AppUtils;
import org.commcare.CommCareApp;
import org.commcare.CommCareApplication;
import org.commcare.activities.LoginActivity;
import org.commcare.android.database.app.models.UserKeyRecord;
import org.commcare.android.database.global.models.ApplicationRecord;
import org.commcare.models.database.SqlStorage;
import org.commcare.preferences.DevSessionRestorer;
import org.joda.time.DateTime;
import java.util.Date;
/**
* Process broadcasts requesting to
* - uninstall app
* - save the current commcare user session.
* - log into the currently seated app
* - invalidate sync token to force recovery on sync
* - invalidate user key record, future login will hit HQ for a new UKR
* - set a flag that will include a param to clear the cache on the next restore request
*
* @author Phillip Mates (pmates@dimagi.com).
*/
public class DebugControlsReceiver extends BroadcastReceiver {
private final static String FAKE_CASE_DB_HASH = "fake_case_db_hash";
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.endsWith("SessionCaptureAction")) {
captureSession();
} else if (action.endsWith("UninstallApp")) {
uninstallApp(intent.getStringExtra("app_id"));
} else if (action.endsWith("LoginWithCreds")) {
login(context, intent.getStringExtra("username"), intent.getStringExtra("password"));
} else if (action.endsWith("TriggerSyncRecover")) {
storeFakeCaseDbHash();
} else if (action.endsWith("ExpireUserKeyRecord")) {
invalidateUserKeyRecord(intent.getStringExtra("username"));
} else if (action.endsWith("ClearCacheOnRestore")) {
CommCareApplication.instance().setInvalidateCacheFlag(true);
}
}
private static void captureSession() {
DevSessionRestorer.saveSessionToPrefs();
DevSessionRestorer.enableAutoLogin();
DevSessionRestorer.enableSessionSaving();
}
private static void uninstallApp(String appId) {
ApplicationRecord appRecord = AppUtils.getAppById(appId);
if (appRecord != null) {
CommCareApplication.instance().expireUserSession();
CommCareApplication.instance().uninstall(appRecord);
}
}
private static void login(Context context, String username, String password) {
DevSessionRestorer.enableAutoLogin();
DevSessionRestorer.storeAutoLoginCreds(username, password);
Intent loginIntent = new Intent(context, LoginActivity.class);
loginIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(loginIntent);
}
private static void storeFakeCaseDbHash() {
SharedPreferences prefs = CommCareApplication.instance().getCurrentApp().getAppPreferences();
prefs.edit().putString(FAKE_CASE_DB_HASH, "FAKE").apply();
}
private static void invalidateUserKeyRecord(String username) {
CommCareApp app = CommCareApplication.instance().getCurrentApp();
SqlStorage<UserKeyRecord> storage = app.getStorage(UserKeyRecord.class);
UserKeyRecord invalidUkr = null;
Date yesterday = DateTime.now().minusDays(1).toDate();
for (UserKeyRecord ukr : storage.getRecordsForValue(UserKeyRecord.META_USERNAME, username)) {
if (ukr.isActive() && ukr.isCurrentlyValid()) {
invalidUkr = new UserKeyRecord(
ukr.getUsername(), ukr.getPasswordHash(),
ukr.getEncryptedKey(), ukr.getWrappedPassword(),
ukr.getValidFrom(), yesterday, ukr.getUuid(),
ukr.getType());
invalidUkr.setID(ukr.getID());
break;
}
}
if (invalidUkr != null) {
storage.write(invalidUkr);
}
}
public static String getFakeCaseDbHash() {
SharedPreferences prefs = CommCareApplication.instance().getCurrentApp().getAppPreferences();
String fakeHash = prefs.getString(FAKE_CASE_DB_HASH, null);
prefs.edit().remove(FAKE_CASE_DB_HASH).apply();
return fakeHash;
}
}