permissions on additional fields (WIP)
This commit is contained in:
+48
-16
@@ -30,7 +30,10 @@ import org.mifosng.platform.api.data.EntityIdentifier;
|
||||
import org.mifosng.platform.api.data.GenericResultsetData;
|
||||
import org.mifosng.platform.api.infrastructure.ApiJsonSerializerService;
|
||||
import org.mifosng.platform.api.infrastructure.ApiParameterHelper;
|
||||
import org.mifosng.platform.exceptions.NoAuthorizationException;
|
||||
import org.mifosng.platform.exceptions.PlatformApiDataValidationException;
|
||||
import org.mifosng.platform.security.PlatformSecurityContext;
|
||||
import org.mifosng.platform.user.domain.AppUser;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -42,38 +45,55 @@ import org.springframework.stereotype.Component;
|
||||
@Scope("singleton")
|
||||
public class AdditionalFieldsApiResource {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(AdditionalFieldsApiResource.class);
|
||||
private final static Logger logger = LoggerFactory
|
||||
.getLogger(AdditionalFieldsApiResource.class);
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
|
||||
@Autowired
|
||||
public AdditionalFieldsApiResource(final PlatformSecurityContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private ReadExtraDataAndReportingService readExtraDataAndReportingService;
|
||||
|
||||
|
||||
@Autowired
|
||||
private ApiJsonSerializerService apiJsonSerializerService;
|
||||
|
||||
@GET
|
||||
@Consumes({MediaType.APPLICATION_JSON})
|
||||
@Produces({MediaType.APPLICATION_JSON})
|
||||
public String datasets(@QueryParam("type") final String type, @Context final UriInfo uriInfo) {
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String datasets(@QueryParam("type") final String type,
|
||||
@Context final UriInfo uriInfo) {
|
||||
|
||||
List<AdditionalFieldsSetData> result = this.readExtraDataAndReportingService.retrieveExtraDatasetNames(type);
|
||||
List<AdditionalFieldsSetData> result = this.readExtraDataAndReportingService
|
||||
.retrieveExtraDatasetNames(type);
|
||||
|
||||
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
|
||||
return this.apiJsonSerializerService.serializeAdditionalFieldsSetDataToJson(prettyPrint, result);
|
||||
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo
|
||||
.getQueryParameters());
|
||||
return this.apiJsonSerializerService
|
||||
.serializeAdditionalFieldsSetDataToJson(prettyPrint, result);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{type}/{set}/{id}")
|
||||
@Consumes({MediaType.APPLICATION_JSON})
|
||||
@Produces({MediaType.APPLICATION_JSON})
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String extraData(@PathParam("type") final String type,
|
||||
@PathParam("set") final String set, @PathParam("id") final Long id,
|
||||
@Context final UriInfo uriInfo) {
|
||||
|
||||
try {
|
||||
GenericResultsetData result = this.readExtraDataAndReportingService.retrieveExtraData(type, set, id);
|
||||
checkUserPermissionForSet(type, set, "READ");
|
||||
|
||||
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
|
||||
return this.apiJsonSerializerService.serializeGenericResultsetDataToJson(prettyPrint, result);
|
||||
try {
|
||||
GenericResultsetData result = this.readExtraDataAndReportingService
|
||||
.retrieveExtraData(type, set, id);
|
||||
|
||||
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo
|
||||
.getQueryParameters());
|
||||
return this.apiJsonSerializerService
|
||||
.serializeGenericResultsetDataToJson(prettyPrint, result);
|
||||
} catch (InvalidSqlException e) {
|
||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
ApiParameterError error = ApiParameterError.parameterError(
|
||||
@@ -88,12 +108,14 @@ public class AdditionalFieldsApiResource {
|
||||
|
||||
@POST
|
||||
@Path("{type}/{set}/{id}")
|
||||
@Consumes({MediaType.APPLICATION_JSON})
|
||||
@Produces({MediaType.APPLICATION_JSON})
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public Response saveExtraData(@PathParam("type") final String type,
|
||||
@PathParam("set") final String set, @PathParam("id") final Long id,
|
||||
final String jsonRequestBody) {
|
||||
|
||||
checkUserPermissionForSet(type, set, "UPDATE");
|
||||
|
||||
try {
|
||||
|
||||
Map<String, String> queryParams = new HashMap<String, String>();
|
||||
@@ -139,4 +161,14 @@ public class AdditionalFieldsApiResource {
|
||||
"Validation errors exist.", dataValidationErrors);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkUserPermissionForSet(String type, String set,
|
||||
String accessType) {
|
||||
AppUser currentUser = context.authenticatedUser();
|
||||
if (currentUser.hasNotPermissionForSet(type, set, accessType)) {
|
||||
throw new NoAuthorizationException("Not Authorised to Use Set: "
|
||||
+ set + " of Type: " + type);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,102 +25,109 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_appuser", uniqueConstraints=@UniqueConstraint(columnNames = {"username"}, name="username_org"))
|
||||
public class AppUser extends AbstractAuditableCustom<AppUser, Long> implements PlatformUser {
|
||||
@Table(name = "m_appuser", uniqueConstraints = @UniqueConstraint(columnNames = { "username" }, name = "username_org"))
|
||||
public class AppUser extends AbstractAuditableCustom<AppUser, Long> implements
|
||||
PlatformUser {
|
||||
|
||||
@Column(name = "email", nullable=false, length=100)
|
||||
private String email;
|
||||
@Column(name = "email", nullable = false, length = 100)
|
||||
private String email;
|
||||
|
||||
@Column(name = "username", nullable=false, length=100)
|
||||
private String username;
|
||||
|
||||
@Column(name = "firstname", nullable=false, length=100)
|
||||
private String firstname;
|
||||
|
||||
@Column(name = "lastname", nullable=false, length=100)
|
||||
private String lastname;
|
||||
@Column(name = "username", nullable = false, length = 100)
|
||||
private String username;
|
||||
|
||||
@Column(name = "password", nullable=false)
|
||||
private String password;
|
||||
@Column(name = "firstname", nullable = false, length = 100)
|
||||
private String firstname;
|
||||
|
||||
@Column(name = "nonexpired", nullable=false)
|
||||
private boolean accountNonExpired;
|
||||
@Column(name = "lastname", nullable = false, length = 100)
|
||||
private String lastname;
|
||||
|
||||
@Column(name = "nonlocked", nullable=false)
|
||||
private final boolean accountNonLocked;
|
||||
@Column(name = "password", nullable = false)
|
||||
private String password;
|
||||
|
||||
@Column(name = "nonexpired_credentials", nullable=false)
|
||||
private final boolean credentialsNonExpired;
|
||||
@Column(name = "nonexpired", nullable = false)
|
||||
private boolean accountNonExpired;
|
||||
|
||||
@Column(name = "enabled", nullable=false)
|
||||
private boolean enabled;
|
||||
@Column(name = "nonlocked", nullable = false)
|
||||
private final boolean accountNonLocked;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Column(name = "firsttime_login_remaining", nullable=false)
|
||||
private boolean firstTimeLoginRemaining;
|
||||
|
||||
@Column(name = "is_deleted", nullable=false)
|
||||
private boolean deleted;
|
||||
@Column(name = "nonexpired_credentials", nullable = false)
|
||||
private final boolean credentialsNonExpired;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "office_id")
|
||||
private Office office;
|
||||
@Column(name = "enabled", nullable = false)
|
||||
private boolean enabled;
|
||||
|
||||
@ManyToMany(fetch = FetchType.EAGER)
|
||||
@JoinTable(name = "m_appuser_role", joinColumns = @JoinColumn(name = "appuser_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
|
||||
private Set<Role> roles;
|
||||
@SuppressWarnings("unused")
|
||||
@Column(name = "firsttime_login_remaining", nullable = false)
|
||||
private boolean firstTimeLoginRemaining;
|
||||
|
||||
@Column(name = "is_deleted", nullable = false)
|
||||
private boolean deleted;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "office_id")
|
||||
private Office office;
|
||||
|
||||
@ManyToMany(fetch = FetchType.EAGER)
|
||||
@JoinTable(name = "m_appuser_role", joinColumns = @JoinColumn(name = "appuser_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
|
||||
private Set<Role> roles;
|
||||
|
||||
public static AppUser createNew(final Office office,
|
||||
final Set<Role> allRoles, final String username, final String email,
|
||||
final String firstname, final String lastname, final String password) {
|
||||
|
||||
final Set<Role> allRoles, final String username,
|
||||
final String email, final String firstname, final String lastname,
|
||||
final String password) {
|
||||
|
||||
boolean userEnabled = true;
|
||||
boolean userAccountNonExpired = true;
|
||||
boolean userCredentialsNonExpired = true;
|
||||
boolean userAccountNonLocked = true;
|
||||
|
||||
|
||||
Collection<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
|
||||
authorities.add(new SimpleGrantedAuthority("DUMMY_ROLE_NOT_USED_OR_PERSISTED_TO_AVOID_EXCEPTION"));
|
||||
|
||||
User user = new User(username, password, userEnabled, userAccountNonExpired, userCredentialsNonExpired, userAccountNonLocked, authorities);
|
||||
authorities.add(new SimpleGrantedAuthority(
|
||||
"DUMMY_ROLE_NOT_USED_OR_PERSISTED_TO_AVOID_EXCEPTION"));
|
||||
|
||||
User user = new User(username, password, userEnabled,
|
||||
userAccountNonExpired, userCredentialsNonExpired,
|
||||
userAccountNonLocked, authorities);
|
||||
return new AppUser(office, user, allRoles, email, firstname, lastname);
|
||||
}
|
||||
|
||||
protected AppUser() {
|
||||
this.office = null;
|
||||
this.email = null;
|
||||
this.username = null;
|
||||
this.password = null;
|
||||
this.accountNonExpired = false;
|
||||
this.accountNonLocked = false;
|
||||
this.credentialsNonExpired = false;
|
||||
this.enabled = false;
|
||||
this.roles = new HashSet<Role>();
|
||||
this.firstTimeLoginRemaining = true;
|
||||
}
|
||||
|
||||
public AppUser(final Office office, final User user, final Set<Role> roles, final String email, final String firstname, final String lastname) {
|
||||
this.office = office;
|
||||
this.email = email.trim();
|
||||
this.username = user.getUsername().trim();
|
||||
this.firstname = firstname.trim();
|
||||
this.lastname = lastname.trim();
|
||||
this.password = user.getPassword().trim();
|
||||
this.accountNonExpired = user.isAccountNonExpired();
|
||||
this.accountNonLocked = user.isAccountNonLocked();
|
||||
this.credentialsNonExpired = user.isCredentialsNonExpired();
|
||||
this.enabled = user.isEnabled();
|
||||
this.roles = roles;
|
||||
protected AppUser() {
|
||||
this.office = null;
|
||||
this.email = null;
|
||||
this.username = null;
|
||||
this.password = null;
|
||||
this.accountNonExpired = false;
|
||||
this.accountNonLocked = false;
|
||||
this.credentialsNonExpired = false;
|
||||
this.enabled = false;
|
||||
this.roles = new HashSet<Role>();
|
||||
this.firstTimeLoginRemaining = true;
|
||||
}
|
||||
}
|
||||
|
||||
public AppUser(final Office office, final User user, final Set<Role> roles,
|
||||
final String email, final String firstname, final String lastname) {
|
||||
this.office = office;
|
||||
this.email = email.trim();
|
||||
this.username = user.getUsername().trim();
|
||||
this.firstname = firstname.trim();
|
||||
this.lastname = lastname.trim();
|
||||
this.password = user.getPassword().trim();
|
||||
this.accountNonExpired = user.isAccountNonExpired();
|
||||
this.accountNonLocked = user.isAccountNonLocked();
|
||||
this.credentialsNonExpired = user.isCredentialsNonExpired();
|
||||
this.enabled = user.isEnabled();
|
||||
this.roles = roles;
|
||||
this.firstTimeLoginRemaining = true;
|
||||
}
|
||||
|
||||
public void updatePassword(final String encodePassword) {
|
||||
this.password = encodePassword;
|
||||
this.firstTimeLoginRemaining = false;
|
||||
}
|
||||
|
||||
public void update(final Set<Role> allRoles, final Office office, final UserCommand userCommand) {
|
||||
|
||||
|
||||
public void update(final Set<Role> allRoles, final Office office,
|
||||
final UserCommand userCommand) {
|
||||
|
||||
if (userCommand.isRolesChanged() && !allRoles.isEmpty()) {
|
||||
this.roles.clear();
|
||||
this.roles = allRoles;
|
||||
@@ -141,9 +148,10 @@ public class AppUser extends AbstractAuditableCustom<AppUser, Long> implements P
|
||||
this.email = userCommand.getEmail();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete is a <i>soft delete</i>. Updates flag so it wont appear in query/report results.
|
||||
* Delete is a <i>soft delete</i>. Updates flag so it wont appear in
|
||||
* query/report results.
|
||||
*
|
||||
* Any fields with unique constraints and prepended with id of record.
|
||||
*/
|
||||
@@ -159,53 +167,54 @@ public class AppUser extends AbstractAuditableCustom<AppUser, Long> implements P
|
||||
return deleted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<GrantedAuthority> getAuthorities() {
|
||||
return this.populateGrantedAuthorities();
|
||||
}
|
||||
@Override
|
||||
public Collection<GrantedAuthority> getAuthorities() {
|
||||
return this.populateGrantedAuthorities();
|
||||
}
|
||||
|
||||
private List<GrantedAuthority> populateGrantedAuthorities() {
|
||||
List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
|
||||
for (Role role :this.roles) {
|
||||
Collection<Permission> permissions = role.getPermissions();
|
||||
for (Permission permission : permissions) {
|
||||
grantedAuthorities.add(new SimpleGrantedAuthority(permission.code()));
|
||||
}
|
||||
}
|
||||
return grantedAuthorities;
|
||||
}
|
||||
private List<GrantedAuthority> populateGrantedAuthorities() {
|
||||
List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
|
||||
for (Role role : this.roles) {
|
||||
Collection<Permission> permissions = role.getPermissions();
|
||||
for (Permission permission : permissions) {
|
||||
grantedAuthorities.add(new SimpleGrantedAuthority(permission
|
||||
.code()));
|
||||
}
|
||||
}
|
||||
return grantedAuthorities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return this.password;
|
||||
}
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return this.password;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return this.username;
|
||||
}
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return this.username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccountNonExpired() {
|
||||
return this.accountNonExpired;
|
||||
}
|
||||
@Override
|
||||
public boolean isAccountNonExpired() {
|
||||
return this.accountNonExpired;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccountNonLocked() {
|
||||
return this.accountNonLocked;
|
||||
}
|
||||
@Override
|
||||
public boolean isAccountNonLocked() {
|
||||
return this.accountNonLocked;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCredentialsNonExpired() {
|
||||
return this.credentialsNonExpired;
|
||||
}
|
||||
@Override
|
||||
public boolean isCredentialsNonExpired() {
|
||||
return this.credentialsNonExpired;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public String getFirstname() {
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public String getFirstname() {
|
||||
return firstname;
|
||||
}
|
||||
|
||||
@@ -213,50 +222,82 @@ public class AppUser extends AbstractAuditableCustom<AppUser, Long> implements P
|
||||
return lastname;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return this.email;
|
||||
}
|
||||
public String getEmail() {
|
||||
return this.email;
|
||||
}
|
||||
|
||||
public Set<Role> getRoles() {
|
||||
return this.roles;
|
||||
}
|
||||
public Set<Role> getRoles() {
|
||||
return this.roles;
|
||||
}
|
||||
|
||||
public Office getOffice() {
|
||||
return this.office;
|
||||
}
|
||||
public Office getOffice() {
|
||||
return this.office;
|
||||
}
|
||||
|
||||
public boolean canNotApproveLoanInPast() {
|
||||
return hasNotPermissionForAnyOf("CAN_APPROVE_LOAN_IN_THE_PAST_ROLE", "PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE");
|
||||
return hasNotPermissionForAnyOf("CAN_APPROVE_LOAN_IN_THE_PAST_ROLE",
|
||||
"PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE");
|
||||
}
|
||||
|
||||
public boolean canNotRejectLoanInPast() {
|
||||
return hasNotPermissionForAnyOf("CAN_REJECT_LOAN_IN_THE_PAST_ROLE", "PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE");
|
||||
return hasNotPermissionForAnyOf("CAN_REJECT_LOAN_IN_THE_PAST_ROLE",
|
||||
"PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE");
|
||||
}
|
||||
|
||||
public boolean canNotWithdrawByClientLoanInPast() {
|
||||
return hasNotPermissionForAnyOf("CAN_WITHDRAW_LOAN_IN_THE_PAST_ROLE", "PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE");
|
||||
return hasNotPermissionForAnyOf("CAN_WITHDRAW_LOAN_IN_THE_PAST_ROLE",
|
||||
"PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE");
|
||||
}
|
||||
|
||||
public boolean canNotDisburseLoanInPast() {
|
||||
return hasNotPermissionForAnyOf("CAN_DISBURSE_LOAN_IN_THE_PAST_ROLE", "PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE");
|
||||
return hasNotPermissionForAnyOf("CAN_DISBURSE_LOAN_IN_THE_PAST_ROLE",
|
||||
"PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE");
|
||||
}
|
||||
|
||||
public boolean canNotMakeRepaymentOnLoanInPast() {
|
||||
return hasNotPermissionForAnyOf("CAN_MAKE_LOAN_REPAYMENT_IN_THE_PAST_ROLE", "PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE");
|
||||
return hasNotPermissionForAnyOf(
|
||||
"CAN_MAKE_LOAN_REPAYMENT_IN_THE_PAST_ROLE",
|
||||
"PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE");
|
||||
}
|
||||
|
||||
public boolean hasNotPermissionForReport(String reportName) {
|
||||
|
||||
|
||||
for (Role role : this.roles) {
|
||||
if ((role.getName().equalsIgnoreCase("Super User")) || (role.getName().equalsIgnoreCase("Read Only"))) {
|
||||
if (role.getName().equalsIgnoreCase("Super User"))
|
||||
return false;
|
||||
if (role.getName().equalsIgnoreCase("Read Only"))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasPermissionTo("CAN_RUN_" + reportName)) return false;
|
||||
|
||||
|
||||
if (hasPermissionTo("CAN_RUN_" + reportName))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public boolean hasNotPermissionForSet(String type, String set,
|
||||
String accessType) {
|
||||
|
||||
for (Role role : this.roles) {
|
||||
|
||||
if (role.getName().equalsIgnoreCase("Super User"))
|
||||
return false;
|
||||
|
||||
if (accessType.equalsIgnoreCase("READ")) {
|
||||
|
||||
if (role.getName().equalsIgnoreCase("Read Only"))
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
String matchPermission = "CAN_" + accessType + "_" + type + "_x" + set;
|
||||
if (hasPermissionTo(matchPermission))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean hasNotPermissionForAnyOf(final String... permissionCodes) {
|
||||
boolean hasNotPermission = true;
|
||||
for (String permissionCode : permissionCodes) {
|
||||
@@ -280,7 +321,6 @@ public class AppUser extends AbstractAuditableCustom<AppUser, Long> implements P
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
|
||||
public boolean hasIdOf(final Long userId) {
|
||||
return getId().equals(userId);
|
||||
|
||||
Reference in New Issue
Block a user