add download of sync servers on misp instance (without credentials)

pull/4/head
Felix Prahl-Kamps 2019-08-23 13:51:09 +02:00
parent 8f2de6787d
commit f59778872b
7 changed files with 194 additions and 22 deletions

View File

@ -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) -> {

View File

@ -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);

View File

@ -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");
} }
} }
} }

View File

@ -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();
} }

View File

@ -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);

View File

@ -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;
}
} }

View File

@ -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"