feat: Roles and Permission
diff --git a/app/src/main/java/com/mifos/apache/fineract/data/datamanager/DataManagerRoles.java b/app/src/main/java/com/mifos/apache/fineract/data/datamanager/DataManagerRoles.java
new file mode 100644
index 0000000..e1ea804
--- /dev/null
+++ b/app/src/main/java/com/mifos/apache/fineract/data/datamanager/DataManagerRoles.java
@@ -0,0 +1,36 @@
+package com.mifos.apache.fineract.data.datamanager;
+
+import com.mifos.apache.fineract.data.local.PreferencesHelper;
+import com.mifos.apache.fineract.data.models.rolesandpermission.Role;
+import com.mifos.apache.fineract.data.remote.BaseApiManager;
+
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import io.reactivex.Observable;
+
+/**
+ * @author Rajan Maurya
+ *         On 24/08/17.
+ */
+@Singleton
+public class DataManagerRoles extends MifosBaseDataManager {
+
+    private final BaseApiManager baseApiManager;
+    private final PreferencesHelper preferencesHelper;
+
+    @Inject
+    public DataManagerRoles(BaseApiManager baseApiManager,
+            DataManagerAuth dataManagerAuth, PreferencesHelper preferencesHelper) {
+        super(dataManagerAuth, preferencesHelper);
+        this.baseApiManager = baseApiManager;
+        this.preferencesHelper = preferencesHelper;
+    }
+
+    public Observable<List<Role>> getRoles() {
+        return authenticatedObservableApi(
+                baseApiManager.getRolesAndPermissionsService().getRoles());
+    }
+}
diff --git a/app/src/main/java/com/mifos/apache/fineract/data/models/rolesandpermission/AllowedOperation.java b/app/src/main/java/com/mifos/apache/fineract/data/models/rolesandpermission/AllowedOperation.java
new file mode 100644
index 0000000..e1d36cc
--- /dev/null
+++ b/app/src/main/java/com/mifos/apache/fineract/data/models/rolesandpermission/AllowedOperation.java
@@ -0,0 +1,19 @@
+package com.mifos.apache.fineract.data.models.rolesandpermission;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * @author Rajan Maurya
+ *         On 24/08/17.
+ */
+public enum AllowedOperation {
+
+    @SerializedName("READ")
+    READ, //GET, HEAD
+
+    @SerializedName("CHANGE")
+    CHANGE, //POST, PUT
+
+    @SerializedName("DELETE")
+    DELETE //DELETE
+}
diff --git a/app/src/main/java/com/mifos/apache/fineract/data/models/rolesandpermission/Permission.java b/app/src/main/java/com/mifos/apache/fineract/data/models/rolesandpermission/Permission.java
new file mode 100644
index 0000000..fbf4c20
--- /dev/null
+++ b/app/src/main/java/com/mifos/apache/fineract/data/models/rolesandpermission/Permission.java
@@ -0,0 +1,73 @@
+package com.mifos.apache.fineract.data.models.rolesandpermission;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Rajan Maurya
+ *         On 24/08/17.
+ */
+public class Permission implements Parcelable {
+
+    @SerializedName("permittableEndpointGroupIdentifier")
+    private String permittableEndpointGroupIdentifier;
+
+    @SerializedName("allowedOperations")
+    private List<AllowedOperation> allowedOperations;
+
+    public String getPermittableEndpointGroupIdentifier() {
+        return permittableEndpointGroupIdentifier;
+    }
+
+    public void setPermittableEndpointGroupIdentifier(String permittableEndpointGroupIdentifier) {
+        this.permittableEndpointGroupIdentifier = permittableEndpointGroupIdentifier;
+    }
+
+    public List<AllowedOperation> getAllowedOperations() {
+        return allowedOperations;
+    }
+
+    public void setAllowedOperations(
+            List<AllowedOperation> allowedOperations) {
+        this.allowedOperations = allowedOperations;
+    }
+
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(this.permittableEndpointGroupIdentifier);
+        dest.writeList(this.allowedOperations);
+    }
+
+    public Permission() {
+    }
+
+    protected Permission(Parcel in) {
+        this.permittableEndpointGroupIdentifier = in.readString();
+        this.allowedOperations = new ArrayList<AllowedOperation>();
+        in.readList(this.allowedOperations, AllowedOperation.class.getClassLoader());
+    }
+
+    public static final Parcelable.Creator<Permission> CREATOR =
+            new Parcelable.Creator<Permission>() {
+                @Override
+                public Permission createFromParcel(Parcel source) {
+                    return new Permission(source);
+                }
+
+                @Override
+                public Permission[] newArray(int size) {
+                    return new Permission[size];
+                }
+            };
+}
diff --git a/app/src/main/java/com/mifos/apache/fineract/data/models/rolesandpermission/Role.java b/app/src/main/java/com/mifos/apache/fineract/data/models/rolesandpermission/Role.java
new file mode 100644
index 0000000..acfedaf
--- /dev/null
+++ b/app/src/main/java/com/mifos/apache/fineract/data/models/rolesandpermission/Role.java
@@ -0,0 +1,69 @@
+package com.mifos.apache.fineract.data.models.rolesandpermission;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.util.List;
+
+/**
+ * @author Rajan Maurya
+ *         On 24/08/17.
+ */
+public class Role implements Parcelable {
+
+    @SerializedName("identifier")
+    private String identifier;
+
+    @SerializedName("permissions")
+    private List<Permission> permissions;
+
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    public void setIdentifier(String identifier) {
+        this.identifier = identifier;
+    }
+
+    public List<Permission> getPermissions() {
+        return permissions;
+    }
+
+    public void setPermissions(
+            List<Permission> permissions) {
+        this.permissions = permissions;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(this.identifier);
+        dest.writeTypedList(this.permissions);
+    }
+
+    public Role() {
+    }
+
+    protected Role(Parcel in) {
+        this.identifier = in.readString();
+        this.permissions = in.createTypedArrayList(Permission.CREATOR);
+    }
+
+    public static final Parcelable.Creator<Role> CREATOR = new Parcelable.Creator<Role>() {
+        @Override
+        public Role createFromParcel(Parcel source) {
+            return new Role(source);
+        }
+
+        @Override
+        public Role[] newArray(int size) {
+            return new Role[size];
+        }
+    };
+}
diff --git a/app/src/main/java/com/mifos/apache/fineract/data/remote/BaseApiManager.java b/app/src/main/java/com/mifos/apache/fineract/data/remote/BaseApiManager.java
index 678e965..085aef8 100644
--- a/app/src/main/java/com/mifos/apache/fineract/data/remote/BaseApiManager.java
+++ b/app/src/main/java/com/mifos/apache/fineract/data/remote/BaseApiManager.java
@@ -8,6 +8,7 @@
 import com.mifos.apache.fineract.data.services.DepositService;
 import com.mifos.apache.fineract.data.services.IndividualLendingService;
 import com.mifos.apache.fineract.data.services.LoanService;
+import com.mifos.apache.fineract.data.services.RolesService;
 
 import java.util.concurrent.TimeUnit;
 
@@ -33,6 +34,7 @@
     private static LoanService loanApi;
     private static IndividualLendingService individualLendingService;
     private static AnonymousService anonymousService;
+    private static RolesService rolesService;
 
 
     public BaseApiManager(Context context) {
@@ -46,6 +48,7 @@
         depositApi = createApi(DepositService.class);
         loanApi = createApi(LoanService.class);
         individualLendingService = createApi(IndividualLendingService.class);
+        rolesService = createApi(RolesService.class);
     }
 
     private static void initAnonymous() {
@@ -121,4 +124,8 @@
     public AnonymousService getAnonymousService() {
         return anonymousService;
     }
+
+    public RolesService getRolesAndPermissionsService() {
+        return rolesService;
+    }
 }
diff --git a/app/src/main/java/com/mifos/apache/fineract/data/services/RolesService.java b/app/src/main/java/com/mifos/apache/fineract/data/services/RolesService.java
new file mode 100644
index 0000000..377c8e9
--- /dev/null
+++ b/app/src/main/java/com/mifos/apache/fineract/data/services/RolesService.java
@@ -0,0 +1,19 @@
+package com.mifos.apache.fineract.data.services;
+
+import com.mifos.apache.fineract.data.models.rolesandpermission.Role;
+import com.mifos.apache.fineract.data.remote.EndPoints;
+
+import java.util.List;
+
+import io.reactivex.Observable;
+import retrofit2.http.GET;
+
+/**
+ * @author Rajan Maurya
+ *         On 24/08/17.
+ */
+public interface RolesService {
+
+    @GET(EndPoints.API_IDENTITY_PATH + "/roles")
+    Observable<List<Role>> getRoles();
+}
diff --git a/app/src/main/java/com/mifos/apache/fineract/injection/component/ActivityComponent.java b/app/src/main/java/com/mifos/apache/fineract/injection/component/ActivityComponent.java
index 8d8c3b2..277ca5e 100644
--- a/app/src/main/java/com/mifos/apache/fineract/injection/component/ActivityComponent.java
+++ b/app/src/main/java/com/mifos/apache/fineract/injection/component/ActivityComponent.java
@@ -34,6 +34,7 @@
 import com.mifos.apache.fineract.ui.online.loanaccounts.loandetails.CustomerLoanDetailsFragment;
 import com.mifos.apache.fineract.ui.online.login.LoginActivity;
 import com.mifos.apache.fineract.ui.online.loanaccounts.plannedpayment.PlannedPaymentFragment;
+import com.mifos.apache.fineract.ui.online.roles.roleslist.RolesFragment;
 
 import dagger.Subcomponent;
 
@@ -97,4 +98,6 @@
     void inject(CustomerActivitiesFragment customerActivitiesFragment);
 
     void inject(DashboardActivity dashboardActivity);
+
+    void inject(RolesFragment rolesFragment);
 }
diff --git a/app/src/main/java/com/mifos/apache/fineract/injection/component/ApplicationComponent.java b/app/src/main/java/com/mifos/apache/fineract/injection/component/ApplicationComponent.java
index 0f143f7..a546b6f 100644
--- a/app/src/main/java/com/mifos/apache/fineract/injection/component/ApplicationComponent.java
+++ b/app/src/main/java/com/mifos/apache/fineract/injection/component/ApplicationComponent.java
@@ -10,6 +10,7 @@
 import com.mifos.apache.fineract.data.datamanager.DataManagerDeposit;
 import com.mifos.apache.fineract.data.datamanager.DataManagerIndividualLending;
 import com.mifos.apache.fineract.data.datamanager.DataManagerLoans;
+import com.mifos.apache.fineract.data.datamanager.DataManagerRoles;
 import com.mifos.apache.fineract.data.local.PreferencesHelper;
 import com.mifos.apache.fineract.data.remote.BaseApiManager;
 import com.mifos.apache.fineract.data.remote.MifosInterceptor;
@@ -34,6 +35,7 @@
     DataManagerLoans dataManagerLoans();
     DataManagerIndividualLending dataManagerIndividualLending();
     DataManagerAnonymous dataManagerAnonymous();
+    DataManagerRoles dataManagerRolesAndPermissions();
     BaseApiManager baseApiManager();
     PreferencesHelper preferencesHelper();
 
diff --git a/app/src/main/java/com/mifos/apache/fineract/ui/adapters/RolesAdapter.java b/app/src/main/java/com/mifos/apache/fineract/ui/adapters/RolesAdapter.java
new file mode 100644
index 0000000..76a9d92
--- /dev/null
+++ b/app/src/main/java/com/mifos/apache/fineract/ui/adapters/RolesAdapter.java
@@ -0,0 +1,108 @@
+package com.mifos.apache.fineract.ui.adapters;
+
+import android.content.Context;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.mifos.apache.fineract.R;
+import com.mifos.apache.fineract.data.models.rolesandpermission.Role;
+import com.mifos.apache.fineract.injection.ApplicationContext;
+import com.mifos.apache.fineract.ui.base.OnItemClickListener;
+import com.mifos.apache.fineract.ui.views.TextDrawable;
+import com.mifos.apache.fineract.utils.ColorGenerator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+
+/**
+ * @author Rajan Maurya
+ *         On 24/08/17.
+ */
+public class RolesAdapter extends RecyclerView.Adapter<RolesAdapter.ViewHolder> {
+
+    private Context context;
+    private List<Role> roles;
+    private ColorGenerator colorGenerator;
+    private OnItemClickListener onItemClickListener;
+
+    @Inject
+    public RolesAdapter(@ApplicationContext Context context) {
+        this.context = context;
+        colorGenerator = ColorGenerator.MATERIAL;
+        roles = new ArrayList<>();
+    }
+
+    @Override
+    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+        View view = LayoutInflater.from(parent.getContext())
+                .inflate(R.layout.item_roles, parent, false);
+        return new ViewHolder(view);
+    }
+
+    @Override
+    public void onBindViewHolder(ViewHolder holder, int position) {
+        Role role = roles.get(position);
+
+        TextDrawable drawable = TextDrawable.builder()
+                .beginConfig().toUpperCase().endConfig()
+                .buildRound(role.getIdentifier().substring(0, 1),
+                        colorGenerator.getColor(role.getIdentifier()));
+        holder.ivRole.setImageDrawable(drawable);
+
+        holder.tvRoleName.setText(role.getIdentifier());
+    }
+
+    @Override
+    public int getItemCount() {
+        return roles.size();
+    }
+
+    public void setRoles(List<Role> roles) {
+        this.roles = roles;
+        notifyDataSetChanged();
+    }
+
+    public void setOnItemClickListener(OnItemClickListener itemClickListener) {
+        onItemClickListener = itemClickListener;
+    }
+
+    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener,
+            View.OnLongClickListener {
+
+        @BindView(R.id.iv_role)
+        ImageView ivRole;
+
+        @BindView(R.id.tv_role_name)
+        TextView tvRoleName;
+
+        @BindView(R.id.ll_role)
+        LinearLayout llRole;
+
+        public ViewHolder(View v) {
+            super(v);
+            ButterKnife.bind(this, v);
+            llRole.setOnClickListener(this);
+        }
+
+        @Override
+        public void onClick(View v) {
+            onItemClickListener.onItemClick(v, getAdapterPosition());
+        }
+
+        @Override
+        public boolean onLongClick(View v) {
+            onItemClickListener.onItemLongPress(v, getAdapterPosition());
+            return true;
+        }
+    }
+}
diff --git a/app/src/main/java/com/mifos/apache/fineract/ui/online/DashboardActivity.java b/app/src/main/java/com/mifos/apache/fineract/ui/online/DashboardActivity.java
index dec9b29..cbc4e28 100644
--- a/app/src/main/java/com/mifos/apache/fineract/ui/online/DashboardActivity.java
+++ b/app/src/main/java/com/mifos/apache/fineract/ui/online/DashboardActivity.java
@@ -18,6 +18,7 @@
 import com.mifos.apache.fineract.ui.online.customers.customerlist.CustomersFragment;
 import com.mifos.apache.fineract.ui.online.dashboard.DashboardFragment;
 import com.mifos.apache.fineract.ui.online.launcher.LauncherActivity;
+import com.mifos.apache.fineract.ui.online.roles.roleslist.RolesFragment;
 import com.mifos.apache.fineract.utils.MaterialDialog;
 
 import javax.inject.Inject;
@@ -92,6 +93,9 @@
             case R.id.item_dashboard:
                 replaceFragment(DashboardFragment.newInstance(), true, R.id.container);
                 break;
+            case R.id.item_roles:
+                replaceFragment(RolesFragment.newInstance(), true, R.id.container);
+                break;
             case R.id.item_customer:
                 replaceFragment(CustomersFragment.newInstance(), true, R.id.container);
                 break;
diff --git a/app/src/main/java/com/mifos/apache/fineract/ui/online/roles/roleslist/RolesContract.java b/app/src/main/java/com/mifos/apache/fineract/ui/online/roles/roleslist/RolesContract.java
new file mode 100644
index 0000000..b93cc7d
--- /dev/null
+++ b/app/src/main/java/com/mifos/apache/fineract/ui/online/roles/roleslist/RolesContract.java
@@ -0,0 +1,35 @@
+package com.mifos.apache.fineract.ui.online.roles.roleslist;
+
+import com.mifos.apache.fineract.data.models.rolesandpermission.Role;
+import com.mifos.apache.fineract.ui.base.MvpView;
+
+import java.util.List;
+
+/**
+ * @author Rajan Maurya
+ *         On 24/08/17.
+ */
+public interface RolesContract {
+
+    interface View extends MvpView {
+
+        void showUserInterface();
+
+        void showRoles(List<Role> roles);
+
+        void showEmptyRoles();
+
+        void showRecyclerView(Boolean status);
+
+        void showProgressbar();
+
+        void hideProgressbar();
+
+        void showError(String message);
+    }
+
+    interface Presenter {
+
+        void fetchRoles();
+    }
+}
diff --git a/app/src/main/java/com/mifos/apache/fineract/ui/online/roles/roleslist/RolesFragment.java b/app/src/main/java/com/mifos/apache/fineract/ui/online/roles/roleslist/RolesFragment.java
new file mode 100644
index 0000000..36e24ea
--- /dev/null
+++ b/app/src/main/java/com/mifos/apache/fineract/ui/online/roles/roleslist/RolesFragment.java
@@ -0,0 +1,170 @@
+package com.mifos.apache.fineract.ui.online.roles.roleslist;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.content.ContextCompat;
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import com.mifos.apache.fineract.R;
+import com.mifos.apache.fineract.data.models.rolesandpermission.Role;
+import com.mifos.apache.fineract.ui.adapters.RolesAdapter;
+import com.mifos.apache.fineract.ui.base.MifosBaseActivity;
+import com.mifos.apache.fineract.ui.base.MifosBaseFragment;
+import com.mifos.apache.fineract.ui.base.OnItemClickListener;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.OnClick;
+
+/**
+ * @author Rajan Maurya
+ *         On 24/08/17.
+ */
+public class RolesFragment extends MifosBaseFragment implements RolesContract.View,
+        OnItemClickListener, SwipeRefreshLayout.OnRefreshListener {
+
+    @BindView(R.id.rv_roles)
+    RecyclerView rvRoles;
+
+    @BindView(R.id.swipe_container)
+    SwipeRefreshLayout swipeRefreshLayout;
+
+    @BindView(R.id.rl_error)
+    RelativeLayout rlError;
+
+    @BindView(R.id.iv_retry)
+    ImageView ivRetry;
+
+    @BindView(R.id.tv_error)
+    TextView tvError;
+
+    View rootView;
+
+    @Inject
+    RolesPresenter rolesPresenter;
+
+    @Inject
+    RolesAdapter rolesAdapter;
+
+    public static RolesFragment newInstance() {
+        RolesFragment fragment = new RolesFragment();
+        Bundle args = new Bundle();
+        fragment.setArguments(args);
+        return fragment;
+    }
+
+    @Nullable
+    @Override
+    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
+            @Nullable Bundle savedInstanceState) {
+        rootView = inflater.inflate(R.layout.fragment_roles_list, container, false);
+        ((MifosBaseActivity) getActivity()).getActivityComponent().inject(this);
+        ButterKnife.bind(this, rootView);
+        rolesPresenter.attachView(this);
+        setToolbarTitle(getString(R.string.manage_roles));
+
+        showUserInterface();
+
+        return rootView;
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        rolesPresenter.fetchRoles();
+    }
+
+    @Override
+    public void onRefresh() {
+        rolesPresenter.fetchRoles();
+    }
+
+    @OnClick(R.id.iv_retry)
+    void reloadRoles() {
+        rlError.setVisibility(View.GONE);
+        rvRoles.setVisibility(View.GONE);
+        rolesPresenter.fetchRoles();
+    }
+
+    @Override
+    public void showUserInterface() {
+        LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
+        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
+        rvRoles.setLayoutManager(layoutManager);
+        rvRoles.setHasFixedSize(true);
+        rolesAdapter.setOnItemClickListener(this);
+        rvRoles.setAdapter(rolesAdapter);
+        swipeRefreshLayout.setColorSchemeColors(getActivity()
+                .getResources().getIntArray(R.array.swipeRefreshColors));
+        swipeRefreshLayout.setOnRefreshListener(this);
+    }
+
+    @Override
+    public void showRoles(List<Role> roles) {
+        showRecyclerView(true);
+        rolesAdapter.setRoles(roles);
+    }
+
+    @Override
+    public void showEmptyRoles() {
+        showRecyclerView(false);
+        tvError.setText(R.string.empty_roles);
+        ivRetry.setImageDrawable(ContextCompat.getDrawable(getActivity(),
+                R.drawable.ic_assignment_turned_in_black_24dp));
+    }
+
+    @Override
+    public void showRecyclerView(Boolean status) {
+        if (status) {
+            rvRoles.setVisibility(View.VISIBLE);
+            rlError.setVisibility(View.GONE);
+        } else {
+            rvRoles.setVisibility(View.GONE);
+            rlError.setVisibility(View.VISIBLE);
+        }
+    }
+
+    @Override
+    public void showProgressbar() {
+        swipeRefreshLayout.setRefreshing(true);
+    }
+
+    @Override
+    public void hideProgressbar() {
+        swipeRefreshLayout.setRefreshing(false);
+    }
+
+    @Override
+    public void showError(String message) {
+        showRecyclerView(false);
+        tvError.setText(message);
+    }
+
+    @Override
+    public void onItemClick(View childView, int position) {
+
+    }
+
+    @Override
+    public void onItemLongPress(View childView, int position) {
+
+    }
+
+    @Override
+    public void onDestroyView() {
+        super.onDestroyView();
+        rolesPresenter.detachView();
+    }
+}
diff --git a/app/src/main/java/com/mifos/apache/fineract/ui/online/roles/roleslist/RolesPresenter.java b/app/src/main/java/com/mifos/apache/fineract/ui/online/roles/roleslist/RolesPresenter.java
new file mode 100644
index 0000000..278c259
--- /dev/null
+++ b/app/src/main/java/com/mifos/apache/fineract/ui/online/roles/roleslist/RolesPresenter.java
@@ -0,0 +1,71 @@
+package com.mifos.apache.fineract.ui.online.roles.roleslist;
+
+import android.content.Context;
+
+import com.mifos.apache.fineract.R;
+import com.mifos.apache.fineract.data.datamanager.DataManagerRoles;
+import com.mifos.apache.fineract.data.models.rolesandpermission.Role;
+import com.mifos.apache.fineract.injection.ApplicationContext;
+import com.mifos.apache.fineract.injection.ConfigPersistent;
+import com.mifos.apache.fineract.ui.base.BasePresenter;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.disposables.CompositeDisposable;
+import io.reactivex.observers.DisposableObserver;
+import io.reactivex.schedulers.Schedulers;
+
+/**
+ * @author Rajan Maurya
+ *         On 24/08/17.
+ */
+@ConfigPersistent
+public class RolesPresenter extends BasePresenter<RolesContract.View>
+        implements RolesContract.Presenter {
+
+    private final DataManagerRoles dataManagerRoles;
+    private CompositeDisposable compositeDisposable;
+
+    @Inject
+    protected RolesPresenter(@ApplicationContext Context context,
+            DataManagerRoles dataManagerRoles) {
+        super(context);
+        this.dataManagerRoles = dataManagerRoles;
+        compositeDisposable = new CompositeDisposable();
+    }
+
+    @Override
+    public void fetchRoles() {
+        checkViewAttached();
+        getMvpView().showProgressbar();
+        compositeDisposable.add(dataManagerRoles.getRoles()
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribeWith(new DisposableObserver<List<Role>>() {
+                    @Override
+                    public void onNext(List<Role> roles) {
+                        getMvpView().hideProgressbar();
+                        if (!roles.isEmpty()) {
+                            getMvpView().showRoles(roles);
+                        } else {
+                            getMvpView().showEmptyRoles();
+                        }
+                    }
+
+                    @Override
+                    public void onError(Throwable e) {
+                        getMvpView().hideProgressbar();
+                        getMvpView().showError(context.getString(R.string.error_fetching_roles));
+                    }
+
+                    @Override
+                    public void onComplete() {
+
+                    }
+                })
+        );
+    }
+}
diff --git a/app/src/main/java/com/mifos/apache/fineract/ui/views/TextDrawable.java b/app/src/main/java/com/mifos/apache/fineract/ui/views/TextDrawable.java
index 521ef91..d4e65cb 100644
--- a/app/src/main/java/com/mifos/apache/fineract/ui/views/TextDrawable.java
+++ b/app/src/main/java/com/mifos/apache/fineract/ui/views/TextDrawable.java
@@ -275,44 +275,44 @@
     }
 
     public interface IConfigBuilder {
-        public IConfigBuilder width(int width);
+        IConfigBuilder width(int width);
 
-        public IConfigBuilder height(int height);
+        IConfigBuilder height(int height);
 
-        public IConfigBuilder textColor(int color);
+        IConfigBuilder textColor(int color);
 
-        public IConfigBuilder withBorder(int thickness);
+        IConfigBuilder withBorder(int thickness);
 
-        public IConfigBuilder useFont(Typeface font);
+        IConfigBuilder useFont(Typeface font);
 
-        public IConfigBuilder fontSize(int size);
+        IConfigBuilder fontSize(int size);
 
-        public IConfigBuilder bold();
+        IConfigBuilder bold();
 
-        public IConfigBuilder toUpperCase();
+        IConfigBuilder toUpperCase();
 
-        public IShapeBuilder endConfig();
+        IShapeBuilder endConfig();
     }
 
     public static interface IBuilder {
 
-        public TextDrawable build(String text, int color);
+        TextDrawable build(String text, int color);
     }
 
     public static interface IShapeBuilder {
 
-        public IConfigBuilder beginConfig();
+        IConfigBuilder beginConfig();
 
-        public IBuilder rect();
+        IBuilder rect();
 
-        public IBuilder round();
+        IBuilder round();
 
-        public IBuilder roundRect(int radius);
+        IBuilder roundRect(int radius);
 
-        public TextDrawable buildRect(String text, int color);
+        TextDrawable buildRect(String text, int color);
 
-        public TextDrawable buildRoundRect(String text, int color, int radius);
+        TextDrawable buildRoundRect(String text, int color, int radius);
 
-        public TextDrawable buildRound(String text, int color);
+        TextDrawable buildRound(String text, int color);
     }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/mifos/apache/fineract/utils/ColorGenerator.java b/app/src/main/java/com/mifos/apache/fineract/utils/ColorGenerator.java
new file mode 100644
index 0000000..eb59645
--- /dev/null
+++ b/app/src/main/java/com/mifos/apache/fineract/utils/ColorGenerator.java
@@ -0,0 +1,65 @@
+package com.mifos.apache.fineract.utils;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+
+public class ColorGenerator {
+
+    public static final ColorGenerator DEFAULT;
+
+    public static final ColorGenerator MATERIAL;
+
+    static {
+        DEFAULT = create(Arrays.asList(
+                0xfff16364,
+                0xfff58559,
+                0xfff9a43e,
+                0xffe4c62e,
+                0xff67bf74,
+                0xff59a2be,
+                0xff2093cd,
+                0xffad62a7,
+                0xff805781
+        ));
+        MATERIAL = create(Arrays.asList(
+                0xffe57373,
+                0xfff06292,
+                0xffba68c8,
+                0xff9575cd,
+                0xff7986cb,
+                0xff64b5f6,
+                0xff4fc3f7,
+                0xff4dd0e1,
+                0xff4db6ac,
+                0xff81c784,
+                0xffaed581,
+                0xffff8a65,
+                0xffd4e157,
+                0xffffd54f,
+                0xffffb74d,
+                0xffa1887f,
+                0xff90a4ae
+        ));
+    }
+
+    private final List<Integer> colors;
+    private final Random random;
+
+    public static ColorGenerator create(List<Integer> colorList) {
+        return new ColorGenerator(colorList);
+    }
+
+    private ColorGenerator(List<Integer> colorList) {
+        colors = colorList;
+        random = new Random(System.currentTimeMillis());
+    }
+
+    public int getRandomColor() {
+        return colors.get(random.nextInt(colors.size()));
+    }
+
+    public int getColor(Object key) {
+        return colors.get(Math.abs(key.hashCode()) % colors.size());
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/mifos/apache/fineract/utils/ScrollFabBehavior.java b/app/src/main/java/com/mifos/apache/fineract/utils/ScrollFabBehavior.java
new file mode 100644
index 0000000..82ad339
--- /dev/null
+++ b/app/src/main/java/com/mifos/apache/fineract/utils/ScrollFabBehavior.java
@@ -0,0 +1,45 @@
+package com.mifos.apache.fineract.utils;
+
+import android.content.Context;
+import android.support.design.widget.CoordinatorLayout;
+import android.support.design.widget.FloatingActionButton;
+import android.support.v4.view.ViewCompat;
+import android.util.AttributeSet;
+import android.view.View;
+
+public class ScrollFabBehavior extends FloatingActionButton.Behavior {
+
+    public ScrollFabBehavior(Context context, AttributeSet attrs) {
+        super();
+    }
+
+    @Override
+    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout,
+            FloatingActionButton child, View directTargetChild,
+            View target, int nestedScrollAxes) {
+        return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL ||
+                super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target,
+                        nestedScrollAxes);
+    }
+
+    @Override
+    public void onNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child,
+            View target, int dxConsumed, int dyConsumed, int dxUnconsumed,
+            int dyUnconsumed) {
+        super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed,
+                dyUnconsumed);
+        if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE) {
+            // Reason to set fab visiblity as INVISIBLE :
+            // https://stackoverflow.com/a/41386278/4672688
+            child.hide(new FloatingActionButton.OnVisibilityChangedListener() {
+                @Override
+                public void onHidden(FloatingActionButton fab) {
+                    super.onHidden(fab);
+                    fab.setVisibility(View.INVISIBLE);
+                }
+            });
+        } else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) {
+            child.show();
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_roles_list.xml b/app/src/main/res/layout/fragment_roles_list.xml
new file mode 100644
index 0000000..c422a41
--- /dev/null
+++ b/app/src/main/res/layout/fragment_roles_list.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.design.widget.CoordinatorLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_height="match_parent"
+    android:layout_width="match_parent">
+
+    <android.support.v4.widget.SwipeRefreshLayout
+        android:id="@+id/swipe_container"
+        android:layout_height="match_parent"
+        android:layout_width="match_parent">
+
+        <android.support.v7.widget.RecyclerView
+            android:id="@+id/rv_roles"
+            android:layout_centerHorizontal="true"
+            android:layout_height="0dp"
+            android:layout_weight="1"
+            android:layout_width="wrap_content"/>
+    </android.support.v4.widget.SwipeRefreshLayout>
+
+    <include
+        layout="@layout/layout_error"
+        android:id="@+id/rl_error"
+        android:visibility="gone"/>
+
+    <android.support.design.widget.FloatingActionButton
+        android:clickable="true"
+        android:id="@+id/fab_add_role"
+        android:layout_gravity="bottom|end"
+        android:layout_height="wrap_content"
+        android:layout_margin="@dimen/layout_padding_16dp"
+        android:layout_width="wrap_content"
+        app:layout_behavior="com.mifos.apache.fineract.utils.ScrollFabBehavior"
+        app:srcCompat="@drawable/ic_add_black_24dp"/>
+
+</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_roles.xml b/app/src/main/res/layout/item_roles.xml
new file mode 100644
index 0000000..96c5210
--- /dev/null
+++ b/app/src/main/res/layout/item_roles.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:clickable="true"
+    android:foreground="?android:attr/selectableItemBackground"
+    android:id="@+id/ll_role"
+    android:layout_height="wrap_content"
+    android:layout_width="match_parent"
+    android:orientation="vertical"
+    android:paddingTop="@dimen/layout_padding_8dp">
+
+    <LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:app="http://schemas.android.com/apk/res-auto"
+        android:id="@+id/linearLayout"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="@dimen/layout_padding_8dp"
+        android:layout_width="match_parent"
+        android:minHeight="?attr/listPreferredItemHeight"
+        android:orientation="horizontal">
+
+        <ImageView
+            android:contentDescription="@string/roles"
+            android:id="@+id/iv_role"
+            android:layout_gravity="center_vertical"
+            android:layout_height="45dp"
+            android:layout_width="45dp"
+            android:layout_marginLeft="@dimen/layout_padding_16dp"
+            android:layout_marginStart="@dimen/layout_padding_16dp"
+            app:srcCompat="@drawable/ic_account_circle_black_24dp"
+            />
+
+        <LinearLayout
+            android:gravity="center_vertical"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:layout_width="0dp"
+            android:orientation="vertical"
+            android:paddingLeft="16dp"
+            android:paddingRight="16dp"
+            android:paddingStart="16dp">
+
+            <TextView
+                style="@style/Base.TextAppearance.AppCompat.Medium"
+                android:ellipsize="end"
+                android:id="@+id/tv_role_name"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:lines="1"
+                android:textColor="@color/black"
+                tools:text="Role Name"/>
+
+        </LinearLayout>
+
+    </LinearLayout>
+
+    <View
+        android:background="#c7c6c6"
+        android:layout_height="0.2dp"
+        android:layout_width="wrap_content"/>
+
+</LinearLayout>
diff --git a/app/src/main/res/menu/menu_navigation_drawer.xml b/app/src/main/res/menu/menu_navigation_drawer.xml
index 3f4dcf4..ac89428 100644
--- a/app/src/main/res/menu/menu_navigation_drawer.xml
+++ b/app/src/main/res/menu/menu_navigation_drawer.xml
@@ -10,6 +10,13 @@
             android:icon="@drawable/ic_dashboard_black_24dp"
             android:id="@+id/item_dashboard"
             android:title="@string/dashboard"/>
+
+        <item
+            android:checked="true"
+            android:icon="@drawable/ic_lock_black_24dp"
+            android:id="@+id/item_roles"
+            android:title="@string/roles_and_permissions"/>
+
         <item
             android:checked="true"
             android:icon="@drawable/ic_customer_black_24dp"
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index bc9af44..7cb87ff 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -20,6 +20,7 @@
     <string name="manage_loan_accounts">Manage loan accounts</string>
     <string name="loan_accounts">Loan accounts</string>
     <string name="deposit_accounts">Deposit accounts</string>
+    <string name="roles_and_permissions">Roles/Permissions</string>
     <string name="manage_deposit_accounts">Manage deposit accounts</string>
     <string name="contact_information">Contact information</string>
     <string name="address">Address</string>
@@ -169,6 +170,7 @@
     <string name="no_beneficiary">No beneficiaries</string>
     <string name="activities_created_by_on">%1$s, %2$s</string>
     <string name="logout">Logout</string>
+    <string name="manage_roles">Manage roles</string>
 
     <!--Edit Text hint required-->
     <string name="required_account">Account*</string>
@@ -199,6 +201,7 @@
     <string name="empty_income_to_show">There is no income to show</string>
     <string name="empty_scans_to_show">There is no scans to show</string>
     <string name="empty_customer_activities">There is no activities to show</string>
+    <string name="empty_roles">There is no roles to show</string>
 
     <!--Edit Text validations-->
     <string name="value_must_greater_or_equal_to">Value must be greater than or equal to&#160; %1$s</string>
@@ -239,6 +242,7 @@
     <string name="error_creating_deposit_account">Error creating deposit account</string>
     <string name="error_updating_deposit_account">Error updating deposit account</string>
     <string name="error_fetching_customer_activities">Error fetching customer activities</string>
+    <string name="error_fetching_roles">Error fetching roles</string>
 
 
     <!--Material Dialog-->
@@ -314,6 +318,7 @@
     <string name="mifos_logo_image">Mifos logo image</string>
     <string name="status_image">Status Image</string>
     <string name="customer_image">Customer image</string>
+    <string name="roles">Roles</string>
     <string name="calender_image">Calender image</string>
     <string name="colon">:&#160;</string>
     <string name="debt_income_edit_image">Debt edit delete image</string>
diff --git a/config/quality/findbugs/android-exclude-filter.xml b/config/quality/findbugs/android-exclude-filter.xml
index f549140..4dc4166 100644
--- a/config/quality/findbugs/android-exclude-filter.xml
+++ b/config/quality/findbugs/android-exclude-filter.xml
@@ -26,6 +26,12 @@
         <Bug pattern="MS_MUTABLE_COLLECTION" />
     </Match>
 
+    <!--Ignore RV_ABSOLUTE_VALUE_OF_HASHCODE in ColorGenerator-->
+    <Match>
+        <Class name="com.mifos.apache.fineract.utils.ColorGenerator"/>
+        <Bug pattern="RV_ABSOLUTE_VALUE_OF_HASHCODE" />
+    </Match>
+
     <!-- Ignore DM_DEFAULT_ENCODING in TestDataFactory-->
     <Match>
         <Class name="com.mifos.apache.fineract.TestDataFactory" />