diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/exception/AbstractPlatformAccessDeniedException.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/exception/AbstractPlatformAccessDeniedException.java new file mode 100644 index 000000000..e7776c7b9 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/exception/AbstractPlatformAccessDeniedException.java @@ -0,0 +1,32 @@ +package org.mifosplatform.infrastructure.core.exception; + +/** + * A {@link RuntimeException} thrown when the authenticated user don't have + * enough permissions to access. + */ +public abstract class AbstractPlatformAccessDeniedException extends RuntimeException { + + private final String globalisationMessageCode; + private final String defaultUserMessage; + private final Object[] defaultUserMessageArgs; + + public AbstractPlatformAccessDeniedException(final String globalisationMessageCode, final String defaultUserMessage, + final Object... defaultUserMessageArgs) { + this.globalisationMessageCode = globalisationMessageCode; + this.defaultUserMessage = defaultUserMessage; + this.defaultUserMessageArgs = defaultUserMessageArgs; + } + + public String getGlobalisationMessageCode() { + return this.globalisationMessageCode; + } + + public String getDefaultUserMessage() { + return this.defaultUserMessage; + } + + public Object[] getDefaultUserMessageArgs() { + return this.defaultUserMessageArgs; + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/exception/PermissionDeniedException.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/exception/PermissionDeniedException.java new file mode 100644 index 000000000..98d12b815 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/exception/PermissionDeniedException.java @@ -0,0 +1,11 @@ +package org.mifosplatform.infrastructure.security.exception; + +import org.mifosplatform.infrastructure.core.exception.AbstractPlatformAccessDeniedException; + +public class PermissionDeniedException extends AbstractPlatformAccessDeniedException { + + public PermissionDeniedException(final String code, final String defaultMessage, final Long userId) { + super(code, defaultMessage, userId); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/Client.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/Client.java index 57d1dc7d3..cd9c2fe88 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/Client.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/Client.java @@ -418,6 +418,10 @@ public final class Client extends AbstractPersistable { public void setDisplayName(final String displayName) { this.displayName = displayName; } + + public Office getOffice() { + return this.office; + } private Long staffId() { Long staffId = null; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java index 6766d1888..e109012a8 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java @@ -17,6 +17,7 @@ import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException; +import org.mifosplatform.infrastructure.security.exception.PermissionDeniedException; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.organisation.office.domain.Office; import org.mifosplatform.organisation.office.domain.OfficeRepository; @@ -36,6 +37,7 @@ import org.mifosplatform.portfolio.group.domain.GroupRepository; import org.mifosplatform.portfolio.group.exception.GroupNotFoundException; import org.mifosplatform.portfolio.note.domain.Note; import org.mifosplatform.portfolio.note.domain.NoteRepository; +import org.mifosplatform.useradministration.domain.AppUser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -172,11 +174,22 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP public CommandProcessingResult updateClient(final Long clientId, final JsonCommand command) { try { - this.context.authenticatedUser(); + AppUser user = context.authenticatedUser(); this.fromApiJsonDeserializer.validateForUpdate(command.json()); final Client clientForUpdate = this.clientRepository.findOneWithNotFoundDetection(clientId); + final String clientHierarchy = clientForUpdate.getOffice().getHierarchy(); + + // Don't allow other office user to update + final Office loginUserOffice = user.getOffice(); + final String userHierarchy = loginUserOffice.getHierarchy(); + + if (!clientHierarchy.startsWith(userHierarchy)) { + final String code = "error.msg.not.enough.permissions.to.access.resource"; + final String defaultMessage = "The User with id " + user.getId() + " don't have permission to update this client"; + throw new PermissionDeniedException(code, defaultMessage, user.getId()); + } final Map changes = clientForUpdate.update(command); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/Group.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/Group.java index d397ce7d8..baa305742 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/Group.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/Group.java @@ -370,4 +370,8 @@ public final class Group extends AbstractPersistable { public void setParent(final Group parent) { this.parent = parent; } + + public Office getOffice() { + return this.office; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java index 9a6935811..3cc819aad 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java @@ -21,6 +21,7 @@ import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException; +import org.mifosplatform.infrastructure.security.exception.PermissionDeniedException; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.organisation.office.domain.Office; import org.mifosplatform.organisation.office.domain.OfficeRepository; @@ -45,6 +46,7 @@ import org.mifosplatform.portfolio.loanaccount.domain.Loan; import org.mifosplatform.portfolio.loanaccount.domain.LoanRepository; import org.mifosplatform.portfolio.note.domain.Note; import org.mifosplatform.portfolio.note.domain.NoteRepository; +import org.mifosplatform.useradministration.domain.AppUser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -213,8 +215,21 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group private CommandProcessingResult updateGroupingType(final Long groupId, final JsonCommand command, final GroupTypes groupingType) { try { + AppUser user = this.context.authenticatedUser(); final Group groupForUpdate = this.groupRepository.findOneWithNotFoundDetection(groupId); final Long officeId = groupForUpdate.officeId(); + final Office groupOffice = groupForUpdate.getOffice(); + final String groupHierarchy = groupOffice.getHierarchy(); + + //Don't allow other office user to update + final Office loginUserOffice = this.context.authenticatedUser().getOffice(); + final String userHierarchy = loginUserOffice.getHierarchy(); + + if (!groupHierarchy.startsWith(userHierarchy)) { + final String code = "error.msg.not.enough.permissions.to.access.resource"; + final String defaultMessage = "The User with id "+user.getId()+" don't have permission to update this "+ groupingType.getValue(); + throw new PermissionDeniedException(code, defaultMessage, user.getId()); + } final Map actualChanges = groupForUpdate.update(command);