mirror of https://github.com/MISP/misp-bump
simplified credentials saving and loading
check if credentials set AND user info downloaded for loginpull/5/head
parent
abe0fb7cb5
commit
91546087d0
|
@ -118,7 +118,7 @@ public class ExchangeActivity extends AppCompatActivity {
|
|||
SyncInformation syncInformation = new SyncInformation();
|
||||
syncInformation.organisation = preferenceManager.getUserOrganisation().toSyncOrganisation();
|
||||
syncInformation.syncUserAuthkey = new RandomString(40).nextString();
|
||||
syncInformation.baseUrl = preferenceManager.getServerUrl();
|
||||
syncInformation.baseUrl = preferenceManager.getUserCredentials().first;
|
||||
syncInformation.syncUserPassword = new RandomString(16).nextString();
|
||||
syncInformation.syncUserEmail = preferenceManager.getUserInfo().email;
|
||||
return syncInformation;
|
||||
|
|
|
@ -33,7 +33,7 @@ public class LoginActivity extends AppCompatActivity {
|
|||
private PreferenceManager preferenceManager;
|
||||
|
||||
private ConstraintLayout constraintLayout;
|
||||
private TextInputLayout serverAutomationKey;
|
||||
private TextInputLayout serverAuthkey;
|
||||
private TextInputLayout serverUrl;
|
||||
private ProgressBar progressBar;
|
||||
|
||||
|
@ -81,7 +81,7 @@ public class LoginActivity extends AppCompatActivity {
|
|||
downloadInfoButton.setOnClickListener(onLogin);
|
||||
|
||||
serverUrl = findViewById(R.id.login_server_url);
|
||||
serverAutomationKey = findViewById(R.id.login_automation_key);
|
||||
serverAuthkey = findViewById(R.id.login_automation_key);
|
||||
progressBar = findViewById(R.id.login_progressbar);
|
||||
}
|
||||
|
||||
|
@ -92,12 +92,12 @@ public class LoginActivity extends AppCompatActivity {
|
|||
@Override
|
||||
public void onClick(View v) {
|
||||
final String url = Objects.requireNonNull(serverUrl.getEditText()).getText().toString();
|
||||
final String authkey = Objects.requireNonNull(serverAutomationKey.getEditText()).getText().toString();
|
||||
final String authkey = Objects.requireNonNull(serverAuthkey.getEditText()).getText().toString();
|
||||
|
||||
boolean error = false;
|
||||
|
||||
serverUrl.setError(null);
|
||||
serverAutomationKey.setError(null);
|
||||
serverAuthkey.setError(null);
|
||||
|
||||
if (!isValidUrl(url)) {
|
||||
error = true;
|
||||
|
@ -106,7 +106,7 @@ public class LoginActivity extends AppCompatActivity {
|
|||
|
||||
if (!isValidAutomationKey(authkey)) {
|
||||
error = true;
|
||||
serverAutomationKey.setError("Invalid automation key");
|
||||
serverAuthkey.setError("Invalid automation key");
|
||||
}
|
||||
|
||||
if (error) {
|
||||
|
@ -145,14 +145,10 @@ public class LoginActivity extends AppCompatActivity {
|
|||
@Override
|
||||
public void success(Organisation organisation) {
|
||||
preferenceManager.setUserOrgInfo(organisation);
|
||||
|
||||
// save authkey
|
||||
preferenceManager.setAutomationKey(authkey);
|
||||
|
||||
// save url
|
||||
preferenceManager.setServerUrl(url);
|
||||
preferenceManager.setUserCredentials(url, authkey);
|
||||
|
||||
progressBar.setVisibility(View.GONE);
|
||||
|
||||
Intent home = new Intent(getApplicationContext(), HomeActivity.class);
|
||||
startActivity(home);
|
||||
finish();
|
||||
|
|
|
@ -17,6 +17,7 @@ import androidx.appcompat.app.AlertDialog;
|
|||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||
import androidx.core.util.Pair;
|
||||
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
|
@ -48,7 +49,8 @@ public class ProfileActivity extends AppCompatActivity {
|
|||
setContentView(R.layout.activity_profile);
|
||||
|
||||
preferenceManager = PreferenceManager.getInstance(this);
|
||||
mispRestClient = MispRestClient.getInstance(preferenceManager.getServerUrl(), preferenceManager.getAuthKey());
|
||||
Pair<String, String> credentials = preferenceManager.getUserCredentials();
|
||||
mispRestClient = MispRestClient.getInstance(credentials.first, credentials.second);
|
||||
|
||||
init();
|
||||
populateInformationViews();
|
||||
|
|
|
@ -2,12 +2,10 @@ package lu.circl.mispbump.activities;
|
|||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import lu.circl.mispbump.auxiliary.PreferenceManager;
|
||||
import lu.circl.mispbump.models.restModels.User;
|
||||
|
||||
/**
|
||||
* Starts either the login or home activity.
|
||||
|
@ -32,7 +30,6 @@ public class StartUpActivity extends AppCompatActivity {
|
|||
|
||||
private boolean isUserLoggedIn() {
|
||||
PreferenceManager preferenceManager = PreferenceManager.getInstance(this);
|
||||
User user = preferenceManager.getUserInfo();
|
||||
return user != null;
|
||||
return preferenceManager.getUserCredentials() != null && preferenceManager.getUserInfo() != null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import androidx.annotation.Nullable;
|
|||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.util.Pair;
|
||||
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
|
||||
|
@ -99,7 +100,8 @@ public class UploadActivity extends AppCompatActivity {
|
|||
setContentView(R.layout.activity_upload);
|
||||
|
||||
preferenceManager = PreferenceManager.getInstance(UploadActivity.this);
|
||||
restClient = MispRestClient.getInstance(preferenceManager.getServerUrl(), preferenceManager.getAuthKey());
|
||||
Pair<String, String> credentials = preferenceManager.getUserCredentials();
|
||||
restClient = MispRestClient.getInstance(credentials.first, credentials.second);
|
||||
|
||||
parseExtra();
|
||||
initViews();
|
||||
|
|
|
@ -61,12 +61,12 @@ public class MispRestClient {
|
|||
return instance;
|
||||
}
|
||||
|
||||
public void initMispRestInterface(String url, String authkey) {
|
||||
private void initMispRestInterface(String url, String authkey) {
|
||||
try {
|
||||
Retrofit retrofit = new Retrofit.Builder()
|
||||
.baseUrl(url)
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
.client(getCustomClient(true, false, authkey))
|
||||
.client(getCustomClient(true, true, authkey))
|
||||
.build();
|
||||
|
||||
mispRestInterface = retrofit.create(MispRestInterface.class);
|
||||
|
@ -370,7 +370,7 @@ public class MispRestClient {
|
|||
if (response.body() != null) {
|
||||
callback.success(response.body().organisation);
|
||||
} else {
|
||||
callback.failure("Response body was nul");
|
||||
callback.failure("Response was empty");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -410,7 +410,6 @@ public class MispRestClient {
|
|||
@Override
|
||||
public void onResponse(@NonNull Call<List<MispOrganisation>> call, @NonNull Response<List<MispOrganisation>> response) {
|
||||
if (!response.isSuccessful()) {
|
||||
// TODO handle
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -606,6 +605,12 @@ public class MispRestClient {
|
|||
return "Server is not available (no route to host)";
|
||||
}
|
||||
|
||||
try {
|
||||
throw new Exception(t);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return t.getMessage();
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@ package lu.circl.mispbump.auxiliary;
|
|||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import androidx.core.util.Pair;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
|
@ -28,9 +30,7 @@ public class PreferenceManager {
|
|||
|
||||
private static final String PREFERENCES_FILE = "user_settings";
|
||||
|
||||
private static final String SERVER_URL = "server_url";
|
||||
private static final String AUTOMATION_KEY = "user_automation";
|
||||
|
||||
private static final String USER_CREDENTIALS = "user_credentials";
|
||||
private static final String USER_INFOS = "user_infos";
|
||||
private static final String USER_ORG_INFOS = "user_org_infos";
|
||||
|
||||
|
@ -62,6 +62,7 @@ public class PreferenceManager {
|
|||
|
||||
/**
|
||||
* Save downloaded MISP roles on device.
|
||||
*
|
||||
* @param roles {@link Role}
|
||||
*/
|
||||
public void setRoles(Role[] roles) {
|
||||
|
@ -78,7 +79,8 @@ public class PreferenceManager {
|
|||
* @return {@link Role}[] or null
|
||||
*/
|
||||
public Role[] getRoles() {
|
||||
Type type = new TypeToken<Role[]>() {}.getType();
|
||||
Type type = new TypeToken<Role[]>() {
|
||||
}.getType();
|
||||
String rolesString = preferences.getString(MISP_ROLES, "");
|
||||
|
||||
assert rolesString != null;
|
||||
|
@ -209,147 +211,34 @@ public class PreferenceManager {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Encrypts the automation key and stores it in preferences.
|
||||
*
|
||||
* @param automationKey key entered in {@link lu.circl.mispbump.activities.LoginActivity}
|
||||
*/
|
||||
public void setAutomationKey(String automationKey) {
|
||||
public void setUserCredentials(String url, String authkey) {
|
||||
try {
|
||||
KeyStoreWrapper keyStoreWrapper = new KeyStoreWrapper(KeyStoreWrapper.AUTOMATION_ALIAS);
|
||||
KeyStoreWrapper keyStoreWrapper = new KeyStoreWrapper(KeyStoreWrapper.USER_CREDENTIALS_ALIAS);
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
editor.putString(AUTOMATION_KEY, keyStoreWrapper.encrypt(automationKey));
|
||||
editor.putString(USER_CREDENTIALS, keyStoreWrapper.encrypt(new Gson().toJson(new Pair<>(url, authkey))));
|
||||
editor.apply();
|
||||
} catch (NoSuchPaddingException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvalidKeyException e) {
|
||||
e.printStackTrace();
|
||||
} catch (BadPaddingException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalBlockSizeException e) {
|
||||
} catch (NoSuchAlgorithmException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException | NoSuchPaddingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts the stored automation key and returns it.
|
||||
*
|
||||
* @return decrypted automation key associated with the current user. If no user exists an empty
|
||||
* String is returned.
|
||||
*/
|
||||
public String getAuthKey() {
|
||||
|
||||
if (!preferences.contains(AUTOMATION_KEY)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
try {
|
||||
KeyStoreWrapper keyStoreWrapper = new KeyStoreWrapper(KeyStoreWrapper.AUTOMATION_ALIAS);
|
||||
return keyStoreWrapper.decrypt(preferences.getString(AUTOMATION_KEY, ""));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvalidKeyException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvalidAlgorithmParameterException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchPaddingException e) {
|
||||
e.printStackTrace();
|
||||
} catch (BadPaddingException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalBlockSizeException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the key to decrypt this entry and the entry itself.
|
||||
*/
|
||||
public void clearAutomationKey() {
|
||||
// remove the key from KeyStore
|
||||
KeyStoreWrapper keyStoreWrapper = new KeyStoreWrapper(KeyStoreWrapper.AUTOMATION_ALIAS);
|
||||
keyStoreWrapper.deleteStoredKey();
|
||||
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
editor.remove(AUTOMATION_KEY);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Encrypts the server url and stores it in preferences.
|
||||
*
|
||||
* @param serverUrl url of the corresponding misp instance
|
||||
*/
|
||||
public void setServerUrl(String serverUrl) {
|
||||
try {
|
||||
|
||||
KeyStoreWrapper keyStoreWrapper = new KeyStoreWrapper(KeyStoreWrapper.SERVER_URL_ALIAS);
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
editor.putString(SERVER_URL, keyStoreWrapper.encrypt(serverUrl));
|
||||
editor.apply();
|
||||
|
||||
} catch (NoSuchPaddingException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvalidKeyException e) {
|
||||
e.printStackTrace();
|
||||
} catch (BadPaddingException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalBlockSizeException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts the stored server url and returns it
|
||||
*
|
||||
* @return decrypted misp instance url
|
||||
*/
|
||||
public String getServerUrl() {
|
||||
|
||||
if (!preferences.contains(SERVER_URL)) {
|
||||
public Pair<String, String> getUserCredentials() {
|
||||
if (!preferences.contains(USER_CREDENTIALS)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
KeyStoreWrapper keyStoreWrapper = new KeyStoreWrapper(KeyStoreWrapper.SERVER_URL_ALIAS);
|
||||
return keyStoreWrapper.decrypt(preferences.getString(SERVER_URL, null));
|
||||
|
||||
} catch (NoSuchPaddingException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvalidAlgorithmParameterException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvalidKeyException e) {
|
||||
e.printStackTrace();
|
||||
} catch (BadPaddingException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalBlockSizeException e) {
|
||||
KeyStoreWrapper keyStoreWrapper = new KeyStoreWrapper(KeyStoreWrapper.USER_CREDENTIALS_ALIAS);
|
||||
Type type = new TypeToken<Pair<String, String>>() {}.getType();
|
||||
String serializedCreds = keyStoreWrapper.decrypt(preferences.getString(USER_CREDENTIALS, ""));
|
||||
return new Gson().fromJson(serializedCreds, type);
|
||||
} catch (InvalidKeyException | InvalidAlgorithmParameterException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException | NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the key to decrypt this entry and the entry itself.
|
||||
*/
|
||||
public void clearServerUrl() {
|
||||
// remove the key from KeyStore
|
||||
KeyStoreWrapper keyStoreWrapper = new KeyStoreWrapper(KeyStoreWrapper.SERVER_URL_ALIAS);
|
||||
keyStoreWrapper.deleteStoredKey();
|
||||
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
editor.remove(SERVER_URL);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
|
||||
private List<UploadInformation> cachedUploadInformationList;
|
||||
|
||||
|
@ -357,7 +246,8 @@ public class PreferenceManager {
|
|||
KeyStoreWrapper ksw = new KeyStoreWrapper(KeyStoreWrapper.UPLOAD_INFORMATION_ALIAS);
|
||||
String storedUploadInfoString = preferences.getString(UPLOAD_INFO, null);
|
||||
|
||||
Type type = new TypeToken<List<UploadInformation>>() {}.getType();
|
||||
Type type = new TypeToken<List<UploadInformation>>() {
|
||||
}.getType();
|
||||
|
||||
if (storedUploadInfoString == null || storedUploadInfoString.isEmpty()) {
|
||||
cachedUploadInformationList = new ArrayList<>();
|
||||
|
@ -462,8 +352,8 @@ public class PreferenceManager {
|
|||
public void clearAllData() {
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
|
||||
clearServerUrl();
|
||||
clearAutomationKey();
|
||||
// clearServerUrl();
|
||||
// clearAutomationKey();
|
||||
clearUploadInformation();
|
||||
|
||||
editor.clear();
|
||||
|
|
|
@ -29,8 +29,7 @@ public class KeyStoreWrapper {
|
|||
|
||||
public static final String USER_INFO_ALIAS = "ALIAS_USER_INFO";
|
||||
public static final String USER_ORGANISATION_INFO_ALIAS = "ALIAS_USER_ORGANISATION_INFO";
|
||||
public static final String AUTOMATION_ALIAS = "ALIAS_AUTOMATION_KEY";
|
||||
public static final String SERVER_URL_ALIAS = "ALIAS_SERVER_URL";
|
||||
public static final String USER_CREDENTIALS_ALIAS = "ALIAS_USER_CREDENTIALS";
|
||||
public static final String UPLOAD_INFORMATION_ALIAS = "ALIAS_UPLOAD_INFORMATION";
|
||||
|
||||
private static final String KEYSTORE_PROVIDER = "AndroidKeyStore";
|
||||
|
|
Loading…
Reference in New Issue