Role Functionality with test cases

This commit is contained in:
Satish Sajjan
2014-12-26 17:51:36 +05:30
parent a19d345d88
commit 9b3f56f6f6
27 changed files with 612 additions and 89 deletions
@@ -967,17 +967,32 @@ public class CommandWrapper {
public boolean isInactivateSavingsAccountCharge() {
return this.actionName.equalsIgnoreCase("INACTIVATE") && this.entityName.equalsIgnoreCase("SAVINGSACCOUNTCHARGE");
}
public boolean isRefundByTransfer() {
return this.actionName.equalsIgnoreCase("REFUNDBYTRANSFER");
}
public boolean isLoanRefundByCash() {
return this.actionName.equalsIgnoreCase("REFUNDBYCASH") && this.entityName.equalsIgnoreCase("LOAN");
}
public boolean isUndoLoanRefund() {
return this.actionName.equalsIgnoreCase("UNDOREFUND") && this.entityName.equalsIgnoreCase("LOAN");
}
public boolean isDisable() {
return isDisableOperation() && this.entityId != null;
}
public boolean isDisableOperation() {
return this.actionName.equalsIgnoreCase("DISABLE");
}
public boolean isEnable() {
return isEnableOperation() && this.entityId != null;
}
public boolean isEnableOperation() {
return this.actionName.equalsIgnoreCase("ENABLE");
}
}
@@ -61,7 +61,7 @@ public class CommandWrapperBuilder {
this.subentityId = withSubEntityId;
return this;
}
public CommandWrapperBuilder withTellerId(final Long withTellerId) {
this.tellerId = withTellerId;
return this;
@@ -703,7 +703,7 @@ public class CommandWrapperBuilder {
this.href = "/loans/" + loanId + "/transactions/" + transactionId;
return this;
}
public CommandWrapperBuilder refundLoanTransactionByCash(final Long loanId) {
this.actionName = "REFUNDBYCASH";
this.entityName = "LOAN";
@@ -2200,7 +2200,7 @@ public class CommandWrapperBuilder {
this.json = "{}";
return this;
}
public CommandWrapperBuilder refundByTransfer() {
this.actionName = "REFUNDBYTRANSFER";
this.entityName = "ACCOUNTTRANSFER";
@@ -2208,7 +2208,7 @@ public class CommandWrapperBuilder {
this.href = "/refundByTransfer";
return this;
}
public CommandWrapperBuilder createTeller() {
this.actionName = "CREATE";
this.entityName = "TELLER";
@@ -2258,7 +2258,7 @@ public class CommandWrapperBuilder {
this.href = "/tellers/" + tellerId + "/cashiers/" + cashierId;
return this;
}
public CommandWrapperBuilder allocateCashToCashier(final Long tellerId, final Long cashierId) {
this.actionName = "ALLOCATECASHTOCASHIER";
this.entityName = "TELLER";
@@ -2267,7 +2267,7 @@ public class CommandWrapperBuilder {
this.href = "/tellers/" + tellerId + "/cashiers/" + cashierId + "/allocate";
return this;
}
public CommandWrapperBuilder settleCashFromCashier(final Long tellerId, final Long cashierId) {
this.actionName = "SETTLECASHFROMCASHIER";
this.entityName = "TELLER";
@@ -2277,4 +2277,31 @@ public class CommandWrapperBuilder {
return this;
}
public CommandWrapperBuilder deleteRole(Long roleId) {
this.actionName = "DELETE";
this.entityName = "ROLE";
this.entityId = roleId;
this.href = "/roles/" + roleId;
this.json = "{}";
return this;
}
public CommandWrapperBuilder disableRole(Long roleId) {
this.actionName = "DISABLE";
this.entityName = "ROLE";
this.entityId = roleId;
this.href = "/roles/" + roleId + "/disbales";
this.json = "{}";
return this;
}
public CommandWrapperBuilder enableRole(Long roleId) {
this.actionName = "ENABLE";
this.entityName = "ROLE";
this.entityId = roleId;
this.href = "/roles/" + roleId + "/enable";
this.json = "{}";
return this;
}
}
@@ -136,6 +136,6 @@ public class PortfolioCommandSourceWritePlatformServiceImpl implements Portfolio
final AppUser maker = this.context.authenticatedUser();
commandSourceInput.markAsRejected(maker, DateTime.now());
this.commandSourceRepository.save(commandSourceInput);
return makerCheckerId ;
return makerCheckerId;
}
}
@@ -221,15 +221,19 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
} else if (wrapper.isPermissionResource()) {
handler = this.applicationContext.getBean("updateMakerCheckerPermissionsCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isRoleResource()) {
if (wrapper.isCreate()) {
handler = this.applicationContext.getBean("createRoleCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isUpdate()) {
handler = this.applicationContext.getBean("updateRoleCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isDelete()) {
handler = this.applicationContext.getBean("deleteRoleCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isDisable()) {
handler = this.applicationContext.getBean("disableRoleCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isEnable()) {
handler = this.applicationContext.getBean("enableRoleCommandHandler", NewCommandSourceHandler.class);
} else {
throw new UnsupportedCommandException(wrapper.commandName());
}
} else if (wrapper.isUserResource()) {
if (wrapper.isCreate()) {
handler = this.applicationContext.getBean("createUserCommandHandler", NewCommandSourceHandler.class);
@@ -11,16 +11,19 @@ import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.commands.domain.CommandWrapper;
import org.mifosplatform.commands.service.CommandWrapperBuilder;
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
@@ -46,8 +49,8 @@ public class RolesApiResource {
/**
* The set of parameters that are supported in response for {@link RoleData}
*/
private final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList("id", "name", "description",
"availablePermissions", "selectedPermissions"));
private final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList("id", "name", "description", "availablePermissions",
"selectedPermissions"));
/**
* The set of parameters that are supported in response for {@link RoleData}
@@ -124,6 +127,35 @@ public class RolesApiResource {
return this.toApiJsonSerializer.serialize(settings, role, this.RESPONSE_DATA_PARAMETERS);
}
/**
* Roles enable or disable
*
* @param roleId
* @param commandParam
* @param apiRequestBodyAsJson
* @return
*/
@POST
@Path("{roleId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String actionsOnRoles(@PathParam("roleId") final Long roleId, @QueryParam("command") final String commandParam,
final String apiRequestBodyAsJson) {
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
CommandProcessingResult result = null;
if (is(commandParam, "disable")) {
final CommandWrapper commandRequest = builder.disableRole(roleId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "enable")) {
final CommandWrapper commandRequest = builder.enableRole(roleId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
}
return this.toApiJsonSerializer.serialize(result);
}
@PUT
@Path("{roleId}")
@Consumes({ MediaType.APPLICATION_JSON })
@@ -171,4 +203,30 @@ public class RolesApiResource {
return this.toApiJsonSerializer.serialize(result);
}
/**
* Delete Role
*
* @param roleId
* @return
*/
@DELETE
@Path("{roleId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String deleteRole(@PathParam("roleId") final Long roleId) {
final CommandWrapper commandRequest = new CommandWrapperBuilder() //
.deleteRole(roleId) //
.build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
private boolean is(final String commandParam, final String commandValue) {
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
}
}
@@ -16,15 +16,17 @@ public class RoleData implements Serializable {
private final Long id;
private final String name;
private final String description;
private final Boolean disabled;
public RolePermissionsData toRolePermissionData(final Collection<PermissionData> permissionUsageData) {
return new RolePermissionsData(this.id, this.name, this.description, permissionUsageData);
return new RolePermissionsData(this.id, this.name, this.description, this.disabled, permissionUsageData);
}
public RoleData(final Long id, final String name, final String description) {
public RoleData(final Long id, final String name, final String description, final Boolean disabled) {
this.id = id;
this.name = name;
this.description = description;
this.disabled = disabled;
}
@Override
@@ -18,15 +18,18 @@ public class RolePermissionsData {
private final String name;
@SuppressWarnings("unused")
private final String description;
@SuppressWarnings("unused")
private final Boolean disabled;
@SuppressWarnings("unused")
private final Collection<PermissionData> permissionUsageData;
public RolePermissionsData(final Long id, final String name, final String description,
public RolePermissionsData(final Long id, final String name, final String description, final Boolean disabled,
final Collection<PermissionData> permissionUsageData) {
this.id = id;
this.name = name;
this.description = description;
this.disabled = disabled;
this.permissionUsageData = permissionUsageData;
}
}
@@ -494,7 +494,6 @@ public class AppUser extends AbstractPersistable<Long> implements PlatformUser {
}
public void validateHasCheckerPermissionTo(final String function) {
final String checkerPermissionName = function.toUpperCase() + "_CHECKER";
if (hasNotPermissionTo("CHECKER_SUPER_USER") && hasNotPermissionTo(checkerPermissionName)) {
final String authorizationMessage = "User has no authority to be a checker for: " + function;
@@ -10,5 +10,5 @@ import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface AppUserRepository extends JpaRepository<AppUser, Long>, JpaSpecificationExecutor<AppUser>, PlatformUserRepository {
// no behaviour added
}
@@ -34,6 +34,9 @@ public class Role extends AbstractPersistable<Long> {
@Column(name = "description", nullable = false, length = 500)
private String description;
@Column(name = "is_disabled", nullable = false)
private Boolean disabled;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "m_role_permission", joinColumns = @JoinColumn(name = "role_id"), inverseJoinColumns = @JoinColumn(name = "permission_id"))
private final Set<Permission> permissions = new HashSet<>();
@@ -51,6 +54,7 @@ public class Role extends AbstractPersistable<Long> {
public Role(final String name, final String description) {
this.name = name.trim();
this.description = description.trim();
this.disabled = false;
}
public Map<String, Object> update(final JsonCommand command) {
@@ -109,6 +113,22 @@ public class Role extends AbstractPersistable<Long> {
}
public RoleData toData() {
return new RoleData(getId(), this.name, this.description);
return new RoleData(getId(), this.name, this.description, this.disabled);
}
public void disableRole() {
this.disabled = true;
}
public Boolean isDisabled() {
return this.disabled;
}
public void enableRole() {
this.disabled = false;
}
public Boolean isEnabled() {
return this.disabled;
}
}
@@ -7,7 +7,12 @@ package org.mifosplatform.useradministration.domain;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface RoleRepository extends JpaRepository<Role, Long>, JpaSpecificationExecutor<Role> {
// no added behaviour
@Query("SELECT COUNT(*) FROM AppUser a JOIN a.roles r WHERE r.id = :roleId")
Integer getCountOfRolesAssociatedWithUsers(@Param("roleId") Long roleId);
}
@@ -0,0 +1,16 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.useradministration.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
public class RoleAssociatedException extends AbstractPlatformDomainRuleException {
public RoleAssociatedException(final String errorcode, final Long id) {
super(errorcode, "Role with identifier " + id + " associated with users", id);
}
}
@@ -0,0 +1,32 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.useradministration.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.useradministration.service.RoleWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class DeleteRoleCommandHandler implements NewCommandSourceHandler {
private final RoleWritePlatformService writePlatformService;
@Autowired
public DeleteRoleCommandHandler(final RoleWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Override
@Transactional
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.deleteRole(command.entityId());
}
}
@@ -0,0 +1,30 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.useradministration.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.useradministration.service.RoleWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class DisableRoleCommandHandler implements NewCommandSourceHandler {
private final RoleWritePlatformService writePlatformService;
@Autowired
public DisableRoleCommandHandler(final RoleWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Override
public CommandProcessingResult processCommand(JsonCommand command) {
return this.writePlatformService.disableRole(command.entityId());
}
}
@@ -0,0 +1,32 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.useradministration.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.useradministration.service.RoleWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class EnableRoleCommandHandler implements NewCommandSourceHandler {
private final RoleWritePlatformService writePlatformService;
@Autowired
public EnableRoleCommandHandler(final RoleWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(JsonCommand command) {
return this.writePlatformService.enableRole(command.entityId());
}
}
@@ -89,7 +89,7 @@ public class AppUserReadPlatformServiceImpl implements AppUserReadPlatformServic
public AppUserData retrieveNewUserDetails() {
final Collection<OfficeData> offices = this.officeReadPlatformService.retrieveAllOfficesForDropdown();
final Collection<RoleData> availableRoles = this.roleReadPlatformService.retrieveAll();
final Collection<RoleData> availableRoles = this.roleReadPlatformService.retrieveAllActiveRoles();
return AppUserData.template(offices, availableRoles);
}
@@ -13,6 +13,8 @@ public interface RoleReadPlatformService {
Collection<RoleData> retrieveAll();
Collection<RoleData> retrieveAllActiveRoles();
RoleData retrieveOne(Long roleId);
Collection<RoleData> retrieveAppUserRoles(Long appUserId);
@@ -38,6 +38,13 @@ public class RoleReadPlatformServiceImpl implements RoleReadPlatformService {
return this.jdbcTemplate.query(sql, this.roleRowMapper);
}
@Override
public Collection<RoleData> retrieveAllActiveRoles() {
final String sql = "select " + this.roleRowMapper.schema() + " where r.is_disabled = 0 order by r.id";
return this.jdbcTemplate.query(sql, this.roleRowMapper);
}
@Override
public RoleData retrieveOne(final Long id) {
@@ -58,12 +65,13 @@ public class RoleReadPlatformServiceImpl implements RoleReadPlatformService {
final Long id = JdbcSupport.getLong(rs, "id");
final String name = rs.getString("name");
final String description = rs.getString("description");
return new RoleData(id, name, description);
final Boolean disabled = rs.getBoolean("disabled");
return new RoleData(id, name, description, disabled);
}
public String schema() {
return " r.id as id, r.name as name, r.description as description from m_role r";
return " r.id as id, r.name as name, r.description as description, r.is_disabled as disabled from m_role r";
}
}
@@ -72,6 +80,6 @@ public class RoleReadPlatformServiceImpl implements RoleReadPlatformService {
final String sql = "select " + this.roleRowMapper.schema() + " inner join m_appuser_role"
+ " ar on ar.role_id = r.id where ar.appuser_id= ?";
return this.jdbcTemplate.query(sql,this.roleRowMapper,new Object[]{appUserId});
return this.jdbcTemplate.query(sql, this.roleRowMapper, new Object[] { appUserId });
}
}
@@ -15,4 +15,10 @@ public interface RoleWritePlatformService {
CommandProcessingResult updateRole(Long roleId, JsonCommand command);
CommandProcessingResult updateRolePermissions(Long roleId, JsonCommand command);
CommandProcessingResult deleteRole(Long roleId);
CommandProcessingResult disableRole(Long roleId);
CommandProcessingResult enableRole(Long roleId);
}
@@ -20,6 +20,7 @@ import org.mifosplatform.useradministration.domain.PermissionRepository;
import org.mifosplatform.useradministration.domain.Role;
import org.mifosplatform.useradministration.domain.RoleRepository;
import org.mifosplatform.useradministration.exception.PermissionNotFoundException;
import org.mifosplatform.useradministration.exception.RoleAssociatedException;
import org.mifosplatform.useradministration.exception.RoleNotFoundException;
import org.mifosplatform.useradministration.serialization.PermissionsCommandFromApiJsonDeserializer;
import org.slf4j.Logger;
@@ -62,7 +63,6 @@ public class RoleWritePlatformServiceJpaRepositoryImpl implements RoleWritePlatf
this.roleCommandFromApiJsonDeserializer.validateForCreate(command.json());
final Role entity = Role.fromJson(command);
this.roleRepository.save(entity);
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(entity.getId()).build();
@@ -172,7 +172,91 @@ public class RoleWritePlatformServiceJpaRepositoryImpl implements RoleWritePlatf
if (permission.hasCode(permissionCode)) { return permission; }
}
}
throw new PermissionNotFoundException(permissionCode);
}
/**
* Method for Delete Role
*/
@Transactional
@Override
public CommandProcessingResult deleteRole(Long roleId) {
try {
/**
* Checking the role present in DB or not using role_id
*/
final Role role = this.roleRepository.findOne(roleId);
if (role == null) { throw new RoleNotFoundException(roleId); }
/**
* Roles associated with users can't be deleted
*/
final Integer count = this.roleRepository.getCountOfRolesAssociatedWithUsers(roleId);
if (count > 0) { throw new RoleAssociatedException("error.msg.role.associated.with.users.deleted", roleId); }
this.roleRepository.delete(role);
return new CommandProcessingResultBuilder().withEntityId(roleId).build();
} catch (final DataIntegrityViolationException e) {
throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue",
"Unknown data integrity issue with resource: " + e.getMostSpecificCause());
}
}
/**
* Method for disabling the role
*/
@Transactional
@Override
public CommandProcessingResult disableRole(Long roleId) {
try {
/**
* Checking the role present in DB or not using role_id
*/
final Role role = this.roleRepository.findOne(roleId);
if (role == null) { throw new RoleNotFoundException(roleId); }
//if(role.isDisabled()){throw new RoleNotFoundException(roleId);}
/**
* Roles associated with users can't be disable
*/
final Integer count = this.roleRepository.getCountOfRolesAssociatedWithUsers(roleId);
if (count > 0) { throw new RoleAssociatedException("error.msg.role.associated.with.users.disabled", roleId); }
/**
* Disabling the role
*/
role.disableRole();
this.roleRepository.save(role);
return new CommandProcessingResultBuilder().withEntityId(roleId).build();
} catch (final DataIntegrityViolationException e) {
throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue",
"Unknown data integrity issue with resource: " + e.getMostSpecificCause());
}
}
/**
* Method for Enabling the role
*/
@Transactional
@Override
public CommandProcessingResult enableRole(Long roleId) {
try {
/**
* Checking the role present in DB or not using role_id
*/
final Role role = this.roleRepository.findOne(roleId);
if (role == null) { throw new RoleNotFoundException(roleId); }
//if(!role.isEnabled()){throw new RoleNotFoundException(roleId);}
role.enableRole();
this.roleRepository.save(role);
return new CommandProcessingResultBuilder().withEntityId(roleId).build();
} catch (final DataIntegrityViolationException e) {
throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue",
"Unknown data integrity issue with resource: " + e.getMostSpecificCause());
}
}
}
@@ -0,0 +1,5 @@
ALTER TABLE `m_role` ADD COLUMN `is_disabled` BIT NULL DEFAULT b'0' AFTER `description`;
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('authorisation', 'DISABLE_ROLE', 'ROLE', 'DISABLE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('authorisation', 'DISABLE_ROLE_CHECKER', 'ROLE', 'DISABLE_CHECKER', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('authorisation', 'ENABLE_ROLE', 'ROLE', 'ENABLE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('authorisation', 'ENABLE_ROLE_CHECKER', 'ROLE', 'ENABLE_CHECKER', 0);