mirror of https://github.com/MISP/misp-bump
add download of sync servers on misp instance (without credentials)
parent
8f2de6787d
commit
f59778872b
|
@ -14,8 +14,10 @@ import androidx.core.app.ActivityOptionsCompat;
|
||||||
import androidx.core.util.Pair;
|
import androidx.core.util.Pair;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||||
|
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -24,9 +26,13 @@ import lu.circl.mispbump.adapters.SyncInfoAdapter;
|
||||||
import lu.circl.mispbump.auxiliary.MispRestClient;
|
import lu.circl.mispbump.auxiliary.MispRestClient;
|
||||||
import lu.circl.mispbump.auxiliary.PreferenceManager;
|
import lu.circl.mispbump.auxiliary.PreferenceManager;
|
||||||
import lu.circl.mispbump.interfaces.OnRecyclerItemClickListener;
|
import lu.circl.mispbump.interfaces.OnRecyclerItemClickListener;
|
||||||
|
import lu.circl.mispbump.models.ExchangeInformation;
|
||||||
import lu.circl.mispbump.models.SyncInformation;
|
import lu.circl.mispbump.models.SyncInformation;
|
||||||
|
import lu.circl.mispbump.models.restModels.MispServer;
|
||||||
|
import lu.circl.mispbump.models.restModels.MispUser;
|
||||||
import lu.circl.mispbump.models.restModels.Organisation;
|
import lu.circl.mispbump.models.restModels.Organisation;
|
||||||
import lu.circl.mispbump.models.restModels.Role;
|
import lu.circl.mispbump.models.restModels.Role;
|
||||||
|
import lu.circl.mispbump.models.restModels.Server;
|
||||||
import lu.circl.mispbump.models.restModels.User;
|
import lu.circl.mispbump.models.restModels.User;
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,16 +40,23 @@ public class HomeActivity extends AppCompatActivity {
|
||||||
|
|
||||||
private List<SyncInformation> syncInformationList;
|
private List<SyncInformation> syncInformationList;
|
||||||
private PreferenceManager preferenceManager;
|
private PreferenceManager preferenceManager;
|
||||||
|
private MispRestClient restClient;
|
||||||
|
|
||||||
private RecyclerView recyclerView;
|
private RecyclerView recyclerView;
|
||||||
private SyncInfoAdapter syncInfoAdapter;
|
private SyncInfoAdapter syncInfoAdapter;
|
||||||
private TextView emptyRecyclerView;
|
private TextView emptyRecyclerView;
|
||||||
|
|
||||||
|
private SwipeRefreshLayout swipeRefreshLayout;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_home);
|
setContentView(R.layout.activity_home);
|
||||||
|
|
||||||
preferenceManager = PreferenceManager.getInstance(this);
|
preferenceManager = PreferenceManager.getInstance(this);
|
||||||
|
Pair<String, String> credentials = preferenceManager.getUserCredentials();
|
||||||
|
restClient = MispRestClient.getInstance(credentials.first, credentials.second);
|
||||||
|
|
||||||
initViews();
|
initViews();
|
||||||
initRecyclerView();
|
initRecyclerView();
|
||||||
|
@ -86,6 +99,13 @@ public class HomeActivity extends AppCompatActivity {
|
||||||
|
|
||||||
FloatingActionButton syncFab = findViewById(R.id.home_fab);
|
FloatingActionButton syncFab = findViewById(R.id.home_fab);
|
||||||
syncFab.setOnClickListener(v -> startActivity(new Intent(HomeActivity.this, ExchangeActivity.class)));
|
syncFab.setOnClickListener(v -> startActivity(new Intent(HomeActivity.this, ExchangeActivity.class)));
|
||||||
|
|
||||||
|
swipeRefreshLayout = findViewById(R.id.swipeRefresh);
|
||||||
|
swipeRefreshLayout.setOnRefreshListener(() -> {
|
||||||
|
checkUnimportedSyncs();
|
||||||
|
|
||||||
|
syncInfoAdapter.setItems(syncInformationList);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initRecyclerView() {
|
private void initRecyclerView() {
|
||||||
|
@ -105,9 +125,6 @@ public class HomeActivity extends AppCompatActivity {
|
||||||
} else {
|
} else {
|
||||||
emptyRecyclerView.setVisibility(View.GONE);
|
emptyRecyclerView.setVisibility(View.GONE);
|
||||||
recyclerView.setVisibility(View.VISIBLE);
|
recyclerView.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
// TODO Update from server if available
|
|
||||||
|
|
||||||
syncInfoAdapter.setItems(syncInformationList);
|
syncInfoAdapter.setItems(syncInformationList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,6 +174,103 @@ public class HomeActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkUnimportedSyncs() {
|
||||||
|
restClient.getAllServers(new MispRestClient.AllRawServersCallback() {
|
||||||
|
@Override
|
||||||
|
public void success(List<MispServer> mispServers) {
|
||||||
|
if (mispServers.size() < 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<SyncInformation> syncInformationList = preferenceManager.getSyncInformationList();
|
||||||
|
|
||||||
|
for (MispServer mispServer : mispServers) {
|
||||||
|
|
||||||
|
boolean existsOffline = false;
|
||||||
|
|
||||||
|
for (SyncInformation syncInformation : syncInformationList) {
|
||||||
|
int localServerId = syncInformation.getRemote().getServer().getId();
|
||||||
|
int remoteServerId = mispServer.getServer().getId();
|
||||||
|
|
||||||
|
if (remoteServerId == localServerId) {
|
||||||
|
existsOffline = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!existsOffline) {
|
||||||
|
// mispServer is not locally available
|
||||||
|
SyncInformation syncInformation = new SyncInformation();
|
||||||
|
|
||||||
|
ExchangeInformation local = new ExchangeInformation();
|
||||||
|
local.setOrganisation(preferenceManager.getUserOrganisation().toSyncOrganisation());
|
||||||
|
User syncUser = preferenceManager.getUserInfo().toSyncUser();
|
||||||
|
syncUser.setAuthkey("Could not be recovered");
|
||||||
|
syncUser.setPassword("Could not be recovered");
|
||||||
|
local.setSyncUser(syncUser);
|
||||||
|
local.setServer(new Server(preferenceManager.getUserCredentials().first));
|
||||||
|
|
||||||
|
ExchangeInformation remote = new ExchangeInformation();
|
||||||
|
remote.setServer(mispServer.getServer());
|
||||||
|
|
||||||
|
restClient.getOrganisation(mispServer.getRemoteOrganisation().getId(), new MispRestClient.OrganisationCallback() {
|
||||||
|
@Override
|
||||||
|
public void success(Organisation organisation) {
|
||||||
|
remote.setOrganisation(organisation);
|
||||||
|
|
||||||
|
restClient.getAllUsers(new MispRestClient.AllMispUsersCallback() {
|
||||||
|
@Override
|
||||||
|
public void success(List<MispUser> users) {
|
||||||
|
for (MispUser mispUser : users) {
|
||||||
|
|
||||||
|
boolean isSyncUserRole = false;
|
||||||
|
|
||||||
|
Role[] roles = preferenceManager.getRoles();
|
||||||
|
|
||||||
|
for (Role role : roles) {
|
||||||
|
if (role.getId().equals(mispUser.getRole().getId())) {
|
||||||
|
isSyncUserRole = role.isSyncUserRole();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mispUser.getOrganisation().getId().equals(organisation.getId()) && isSyncUserRole) {
|
||||||
|
remote.setSyncUser(mispUser.getUser());
|
||||||
|
|
||||||
|
syncInformation.setLocal(local);
|
||||||
|
syncInformation.setRemote(remote);
|
||||||
|
|
||||||
|
preferenceManager.addSyncInformation(syncInformation);
|
||||||
|
refreshRecyclerView();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void failure(String error) {
|
||||||
|
swipeRefreshLayout.setRefreshing(false);
|
||||||
|
Snackbar.make(recyclerView, error, Snackbar.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void failure(String error) {
|
||||||
|
swipeRefreshLayout.setRefreshing(false);
|
||||||
|
Snackbar.make(recyclerView, error, Snackbar.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
swipeRefreshLayout.setRefreshing(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void failure(String error) {
|
||||||
|
swipeRefreshLayout.setRefreshing(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private OnRecyclerItemClickListener<Integer> onRecyclerItemClickListener() {
|
private OnRecyclerItemClickListener<Integer> onRecyclerItemClickListener() {
|
||||||
return (v, index) -> {
|
return (v, index) -> {
|
||||||
|
|
|
@ -19,7 +19,7 @@ public class LauncherActivity extends AppCompatActivity {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
if (isUserLoggedIn()) {
|
if (isUserLoggedIn()) {
|
||||||
Intent home = new Intent(this, NetworkTestActivity.class);
|
Intent home = new Intent(this, HomeActivity.class);
|
||||||
startActivity(home);
|
startActivity(home);
|
||||||
} else {
|
} else {
|
||||||
Intent login = new Intent(this, LoginActivity.class);
|
Intent login = new Intent(this, LoginActivity.class);
|
||||||
|
|
|
@ -4,7 +4,6 @@ package lu.circl.mispbump.activities;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.ActionBar;
|
import androidx.appcompat.app.ActionBar;
|
||||||
|
@ -29,8 +28,6 @@ public class UploadActivity extends AppCompatActivity {
|
||||||
|
|
||||||
public static final String EXTRA_SYNC_INFO_UUID = "EXTRA_SYNC_INFO_UUID";
|
public static final String EXTRA_SYNC_INFO_UUID = "EXTRA_SYNC_INFO_UUID";
|
||||||
|
|
||||||
private View rootLayout;
|
|
||||||
|
|
||||||
private PreferenceManager preferenceManager;
|
private PreferenceManager preferenceManager;
|
||||||
private MispRestClient mispRest;
|
private MispRestClient mispRest;
|
||||||
private SyncInformation syncInformation;
|
private SyncInformation syncInformation;
|
||||||
|
@ -42,8 +39,6 @@ public class UploadActivity extends AppCompatActivity {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_upload);
|
setContentView(R.layout.activity_upload);
|
||||||
|
|
||||||
rootLayout = findViewById(R.id.rootLayout);
|
|
||||||
|
|
||||||
preferenceManager = PreferenceManager.getInstance(UploadActivity.this);
|
preferenceManager = PreferenceManager.getInstance(UploadActivity.this);
|
||||||
|
|
||||||
Pair<String, String> credentials = preferenceManager.getUserCredentials();
|
Pair<String, String> credentials = preferenceManager.getUserCredentials();
|
||||||
|
@ -173,7 +168,7 @@ public class UploadActivity extends AppCompatActivity {
|
||||||
Server server = syncInformation.getRemote().getServer();
|
Server server = syncInformation.getRemote().getServer();
|
||||||
server.setName(syncInformation.getRemote().getOrganisation().getName() + "'s Sync Server");
|
server.setName(syncInformation.getRemote().getOrganisation().getName() + "'s Sync Server");
|
||||||
server.setRemoteOrgId(syncInformation.getRemote().getOrganisation().getId());
|
server.setRemoteOrgId(syncInformation.getRemote().getOrganisation().getId());
|
||||||
server.setAuthkey(syncInformation.getLocal().getSyncUser().getAuthkey());
|
server.setAuthkey(syncInformation.getRemote().getSyncUser().getAuthkey());
|
||||||
server.setPull(syncInformation.getRemote().getServer().getPull());
|
server.setPull(syncInformation.getRemote().getServer().getPull());
|
||||||
server.setPush(syncInformation.getRemote().getServer().getPush());
|
server.setPush(syncInformation.getRemote().getServer().getPush());
|
||||||
server.setCachingEnabled(syncInformation.getRemote().getServer().getCachingEnabled());
|
server.setCachingEnabled(syncInformation.getRemote().getServer().getCachingEnabled());
|
||||||
|
@ -231,8 +226,8 @@ public class UploadActivity extends AppCompatActivity {
|
||||||
mispRest.getUser(syncInformation.getLocal().getSyncUser().getEmail(), new MispRestClient.UserCallback() {
|
mispRest.getUser(syncInformation.getLocal().getSyncUser().getEmail(), new MispRestClient.UserCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void success(User user) {
|
public void success(User user) {
|
||||||
userAction.done("User already on MISP instance");
|
|
||||||
userAdded(user);
|
userAdded(user);
|
||||||
|
userAction.done("User already on MISP instance");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -265,6 +260,8 @@ public class UploadActivity extends AppCompatActivity {
|
||||||
if (server != null) {
|
if (server != null) {
|
||||||
serverAction.done();
|
serverAction.done();
|
||||||
preferenceManager.addSyncInformation(syncInformation);
|
preferenceManager.addSyncInformation(syncInformation);
|
||||||
|
} else {
|
||||||
|
serverAction.error("Could not create Sync Server");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,10 @@ public class SyncInfoAdapter extends RecyclerView.Adapter<SyncInfoAdapter.ViewHo
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemCount() {
|
public int getItemCount() {
|
||||||
|
if (items == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return items.size();
|
return items.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -215,7 +215,7 @@ public class MispRestClient {
|
||||||
callback.failure(extractError(response));
|
callback.failure(extractError(response));
|
||||||
} else {
|
} else {
|
||||||
if (response.body() != null) {
|
if (response.body() != null) {
|
||||||
callback.success(response.body().user);
|
callback.success(response.body().getUser());
|
||||||
} else {
|
} else {
|
||||||
callback.failure("response body was null");
|
callback.failure("response body was null");
|
||||||
}
|
}
|
||||||
|
@ -246,7 +246,7 @@ public class MispRestClient {
|
||||||
callback.failure(extractError(response));
|
callback.failure(extractError(response));
|
||||||
} else {
|
} else {
|
||||||
if (response.body() != null) {
|
if (response.body() != null) {
|
||||||
callback.success(response.body().user);
|
callback.success(response.body().getUser());
|
||||||
} else {
|
} else {
|
||||||
callback.failure("response body was null");
|
callback.failure("response body was null");
|
||||||
}
|
}
|
||||||
|
@ -282,6 +282,27 @@ public class MispRestClient {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void getAllUsers(final AllMispUsersCallback callback) {
|
||||||
|
Call<List<MispUser>> call = mispService.getAllUsers();
|
||||||
|
|
||||||
|
call.enqueue(new Callback<List<MispUser>>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(@NonNull Call<List<MispUser>> call, @NonNull Response<List<MispUser>> response) {
|
||||||
|
if (!response.isSuccessful()) {
|
||||||
|
callback.failure("Failed onResponse");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
callback.success(response.body());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(@NonNull Call<List<MispUser>> call, @NonNull Throwable t) {
|
||||||
|
callback.failure(extractError(t));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public void getAllUsers(final AllUsersCallback callback) {
|
public void getAllUsers(final AllUsersCallback callback) {
|
||||||
Call<List<MispUser>> call = mispService.getAllUsers();
|
Call<List<MispUser>> call = mispService.getAllUsers();
|
||||||
|
|
||||||
|
@ -299,7 +320,7 @@ public class MispRestClient {
|
||||||
User[] users = new User[mispUsers.size()];
|
User[] users = new User[mispUsers.size()];
|
||||||
|
|
||||||
for (int i = 0; i < users.length; i++) {
|
for (int i = 0; i < users.length; i++) {
|
||||||
users[i] = mispUsers.get(i).user;
|
users[i] = mispUsers.get(i).getUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
callback.success(users);
|
callback.success(users);
|
||||||
|
@ -328,7 +349,7 @@ public class MispRestClient {
|
||||||
callback.failure(extractError(response));
|
callback.failure(extractError(response));
|
||||||
} else {
|
} else {
|
||||||
assert response.body() != null;
|
assert response.body() != null;
|
||||||
callback.success(response.body().user);
|
callback.success(response.body().getUser());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -616,6 +637,12 @@ public class MispRestClient {
|
||||||
void failure(String error);
|
void failure(String error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface AllMispUsersCallback {
|
||||||
|
void success(List<MispUser> users);
|
||||||
|
|
||||||
|
void failure(String error);
|
||||||
|
}
|
||||||
|
|
||||||
public interface OrganisationCallback {
|
public interface OrganisationCallback {
|
||||||
void success(Organisation organisation);
|
void success(Organisation organisation);
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,40 @@
|
||||||
package lu.circl.mispbump.models.restModels;
|
package lu.circl.mispbump.models.restModels;
|
||||||
|
|
||||||
|
|
||||||
import com.google.gson.annotations.Expose;
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
|
||||||
public class MispUser {
|
public class MispUser {
|
||||||
|
|
||||||
@SerializedName("User")
|
@SerializedName("User")
|
||||||
@Expose
|
private User user;
|
||||||
public User user;
|
|
||||||
|
|
||||||
public MispUser(User user) {
|
@SerializedName("Role")
|
||||||
|
private Role role;
|
||||||
|
|
||||||
|
@SerializedName("Organisation")
|
||||||
|
private Organisation organisation;
|
||||||
|
|
||||||
|
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
public void setUser(User user) {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Role getRole() {
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
public void setRole(Role role) {
|
||||||
|
this.role = role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Organisation getOrganisation() {
|
||||||
|
return organisation;
|
||||||
|
}
|
||||||
|
public void setOrganisation(Organisation organisation) {
|
||||||
|
this.organisation = organisation;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,18 @@
|
||||||
app:popupTheme="@style/PopupTheme"/>
|
app:popupTheme="@style/PopupTheme"/>
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
android:id="@+id/recyclerView"
|
android:id="@+id/swipeRefresh"
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"/>
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recyclerView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/empty"
|
android:id="@+id/empty"
|
||||||
|
|
Loading…
Reference in New Issue