From 0549858dea644beb407ec379a517f63b29e32919 Mon Sep 17 00:00:00 2001 From: Keith Woodlock Date: Mon, 26 Nov 2012 21:32:53 +0000 Subject: [PATCH] MIFOSX-97: move permissions checking to api and cater for _CHECKER permissions needed. --- .../platform/api/ClientsApiResource.java | 66 +++++++--------- .../platform/api/RolesApiResource.java | 11 +++ .../platform/api/UsersApiResource.java | 10 +++ .../service/ClientReadPlatformService.java | 22 +++--- .../service/ClientWritePlatformService.java | 3 - .../service/ClientCommandHandler.java | 15 +++- .../service/RoleCommandHandler.java | 77 ++++++++++++------- .../service/UserCommandHandler.java | 13 +++- .../mifosng/platform/user/domain/AppUser.java | 24 +++++- .../service/AppUserWritePlatformService.java | 4 - .../service/RoleWritePlatformService.java | 4 - 11 files changed, 153 insertions(+), 96 deletions(-) diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/ClientsApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/ClientsApiResource.java index e3f199015..8fc448abe 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/ClientsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/ClientsApiResource.java @@ -4,7 +4,6 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.HashSet; import java.util.List; import java.util.Set; @@ -229,6 +228,9 @@ public class ClientsApiResource { @Produces({MediaType.APPLICATION_JSON}) public String createClient(final String jsonRequestBody) { + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "CREATE_CLIENT"); + context.authenticatedUser().validateHasPermissionTo("CREATE_CLIENT", allowedPermissions); + final EntityIdentifier result = this.commandsSourceWritePlatformService .logCommandSource("CREATE", "clients", null, jsonRequestBody); @@ -241,6 +243,9 @@ public class ClientsApiResource { @Produces({MediaType.APPLICATION_JSON}) public String updateClient(@PathParam("clientId") final Long clientId, final String jsonRequestBody) { + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "UPDATE_CLIENT"); + context.authenticatedUser().validateHasPermissionTo("UPDATE_CLIENT", allowedPermissions); + final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "clients", clientId, jsonRequestBody); @@ -253,6 +258,9 @@ public class ClientsApiResource { @Produces({MediaType.APPLICATION_JSON}) public String deleteClient(@PathParam("clientId") final Long clientId) { + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "DELETE_CLIENT"); + context.authenticatedUser().validateHasPermissionTo("DELETE_CLIENT", allowedPermissions); + final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE", "clients", clientId, "{}"); return this.apiJsonSerializerService.serializeEntityIdentifier(result); @@ -266,20 +274,10 @@ public class ClientsApiResource { context.authenticatedUser().validateHasReadPermission("CLIENT"); - Set typicalResponseParameters = new HashSet(Arrays.asList("pendingApprovalLoans", "awaitingDisbursalLoans", - "openLoans", "closedLoans", "anyLoanCount", "pendingApprovalLoanCount", "awaitingDisbursalLoanCount", "activeLoanCount", - "closedLoanCount", "pendingApprovalDespositAccountsCount", "pendingApprovalDespositAccounts", - "approvedDespositAccountsCount", "approvedDespositAccounts", "withdrawnByClientDespositAccountsCount", - "withdrawnByClientDespositAccounts", "closedDepositAccountsCount", "closedDepositAccounts", "rejectedDepositAccountsCount", - "rejectedDepositAccounts", "preclosedDepositAccountsCount", "preclosedDepositAccounts")); + final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - - ClientAccountSummaryCollectionData clientAccount = this.clientReadPlatformService.retrieveClientAccountDetails(clientId); + final ClientAccountSummaryCollectionData clientAccount = this.clientReadPlatformService.retrieveClientAccountDetails(clientId); return this.apiJsonSerializerService.serializeClientAccountSummaryCollectionDataToJson(prettyPrint, responseParameters, clientAccount); @@ -293,16 +291,10 @@ public class ClientsApiResource { context.authenticatedUser().validateHasReadPermission("CLIENTNOTE"); - Set typicalResponseParameters = new HashSet(Arrays.asList("id", "clientId", "loanId", "loanTransactionId", - "noteType", "note", "createdById", "createdByUsername", "createdOn", "updatedById", "updatedByUsername", "updatedOn")); + final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - - Collection notes = this.clientReadPlatformService.retrieveAllClientNotes(clientId); + final Collection notes = this.clientReadPlatformService.retrieveAllClientNotes(clientId); return this.apiJsonSerializerService.serializeNoteDataToJson(prettyPrint, responseParameters, notes); } @@ -313,9 +305,9 @@ public class ClientsApiResource { @Produces({MediaType.APPLICATION_JSON}) public Response addNewClientNote(@PathParam("clientId") final Long clientId, final String jsonRequestBody) { - NoteCommand command = this.apiDataConversionService.convertJsonToNoteCommand(null, clientId, jsonRequestBody); + final NoteCommand command = this.apiDataConversionService.convertJsonToNoteCommand(null, clientId, jsonRequestBody); - EntityIdentifier identifier = this.clientWritePlatformService.addClientNote(command); + final EntityIdentifier identifier = this.clientWritePlatformService.addClientNote(command); return Response.ok().entity(identifier).build(); } @@ -329,16 +321,10 @@ public class ClientsApiResource { context.authenticatedUser().validateHasReadPermission("CLIENTNOTE"); - Set typicalResponseParameters = new HashSet(Arrays.asList("id", "clientId", "loanId", "loanTransactionId", - "noteType", "note", "createdById", "createdByUsername", "createdOn", "updatedById", "updatedByUsername", "updatedOn")); + final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - - NoteData note = this.clientReadPlatformService.retrieveClientNote(clientId, noteId); + final NoteData note = this.clientReadPlatformService.retrieveClientNote(clientId, noteId); return this.apiJsonSerializerService.serializeNoteDataToJson(prettyPrint, responseParameters, note); } @@ -350,9 +336,9 @@ public class ClientsApiResource { public Response updateClientNote(@PathParam("clientId") final Long clientId, @PathParam("noteId") final Long noteId, final String jsonRequestBody) { - NoteCommand command = this.apiDataConversionService.convertJsonToNoteCommand(noteId, clientId, jsonRequestBody); + final NoteCommand command = this.apiDataConversionService.convertJsonToNoteCommand(noteId, clientId, jsonRequestBody); - EntityIdentifier identifier = this.clientWritePlatformService.updateNote(command); + final EntityIdentifier identifier = this.clientWritePlatformService.updateNote(command); return Response.ok().entity(identifier).build(); } @@ -375,9 +361,9 @@ public class ClientsApiResource { FileUtils.validateImageMimeType(bodyPart.getMediaType().toString()); FileUtils.validateFileSizeWithinPermissibleRange(fileSize, fileDetails.getFileName(), ApiConstants.MAX_FILE_UPLOAD_SIZE_IN_MB); - logger.debug(bodyPart.getMediaType().toString()); +// logger.debug(bodyPart.getMediaType().toString()); - EntityIdentifier entityIdentifier = this.clientWritePlatformService.saveOrUpdateClientImage(clientId, fileDetails.getFileName(), + final EntityIdentifier entityIdentifier = this.clientWritePlatformService.saveOrUpdateClientImage(clientId, fileDetails.getFileName(), inputStream); return Response.ok().entity(entityIdentifier).build(); @@ -392,9 +378,9 @@ public class ClientsApiResource { @Produces({MediaType.APPLICATION_JSON}) public Response addNewClientImage(@PathParam("clientId") final Long clientId, final String jsonRequestBody) { - Base64EncodedImage base64EncodedImage = FileUtils.extractImageFromDataURL(jsonRequestBody); + final Base64EncodedImage base64EncodedImage = FileUtils.extractImageFromDataURL(jsonRequestBody); - EntityIdentifier entityIdentifier = this.clientWritePlatformService.saveOrUpdateClientImage(clientId, base64EncodedImage); + final EntityIdentifier entityIdentifier = this.clientWritePlatformService.saveOrUpdateClientImage(clientId, base64EncodedImage); return Response.ok().entity(entityIdentifier).build(); } diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/RolesApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/RolesApiResource.java index 0fbea5b86..3f0f04420 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/RolesApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/RolesApiResource.java @@ -1,7 +1,9 @@ package org.mifosng.platform.api; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.List; import java.util.Set; import javax.ws.rs.Consumes; @@ -81,6 +83,9 @@ public class RolesApiResource { @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) public String createRole(final String apiRequestBodyAsJson) { + + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "USER_ADMINISTRATION_SUPER_USER", "CREATE_ROLE"); + context.authenticatedUser().validateHasPermissionTo("CREATE_ROLE", allowedPermissions); final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "roles", null, apiRequestBodyAsJson); @@ -127,6 +132,9 @@ public class RolesApiResource { @Produces({ MediaType.APPLICATION_JSON }) public String updateRole(@PathParam("roleId") final Long roleId, final String apiRequestBodyAsJson) { + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "USER_ADMINISTRATION_SUPER_USER", "UPDATE_ROLE"); + context.authenticatedUser().validateHasPermissionTo("UPDATE_ROLE", allowedPermissions); + final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "roles", roleId, apiRequestBodyAsJson); @@ -184,6 +192,9 @@ public class RolesApiResource { @Produces({ MediaType.APPLICATION_JSON }) public String updateRolePermissions(@PathParam("roleId") final Long roleId, final String apiRequestBodyAsJson) { + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "USER_ADMINISTRATION_SUPER_USER", "PERMISSIONS_ROLE"); + context.authenticatedUser().validateHasPermissionTo("PERMISSIONS_ROLE", allowedPermissions); + final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATEPERMISSIONS", "roles", roleId, apiRequestBodyAsJson); diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/UsersApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/UsersApiResource.java index 51d1ab5f6..30bda3847 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/UsersApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/UsersApiResource.java @@ -1,6 +1,7 @@ package org.mifosng.platform.api; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Set; @@ -109,6 +110,9 @@ public class UsersApiResource { @Produces({MediaType.APPLICATION_JSON}) public String createUser(final String apiRequestBodyAsJson) { + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "USER_ADMINISTRATION_SUPER_USER", "CREATE_USER"); + context.authenticatedUser().validateHasPermissionTo("CREATE_USER", allowedPermissions); + final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "users", null, apiRequestBodyAsJson); return this.apiJsonSerializerService.serializeEntityIdentifier(result); @@ -120,6 +124,9 @@ public class UsersApiResource { @Produces({MediaType.APPLICATION_JSON}) public String deleteUser(@PathParam("userId") final Long userId) { + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "USER_ADMINISTRATION_SUPER_USER", "DELETE_USER"); + context.authenticatedUser().validateHasPermissionTo("DELETE_USER", allowedPermissions); + final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE", "users", userId, "{}"); return this.apiJsonSerializerService.serializeEntityIdentifier(result); @@ -131,6 +138,9 @@ public class UsersApiResource { @Produces({MediaType.APPLICATION_JSON}) public String updateUser(@PathParam("userId") final Long userId, final String apiRequestBodyAsJson) { + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "USER_ADMINISTRATION_SUPER_USER", "UPDATE_USER"); + context.authenticatedUser().validateHasPermissionTo("UPDATE_USER", allowedPermissions); + final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "users", userId, apiRequestBodyAsJson); return this.apiJsonSerializerService.serializeEntityIdentifier(result); diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientReadPlatformService.java index af98be5de..f1fb0ea1e 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientReadPlatformService.java @@ -11,27 +11,27 @@ import org.mifosng.platform.api.data.NoteData; public interface ClientReadPlatformService { - Collection retrieveAllIndividualClients(String extraCriteria); + Collection retrieveAllIndividualClients(String extraCriteria); - ClientData retrieveIndividualClient(Long clientId); + ClientData retrieveIndividualClient(Long clientId); - ClientData retrieveNewClientDetails(); + ClientData retrieveNewClientDetails(); Collection retrieveAllIndividualClientsForLookup(String extraCriteria); Collection retrieveAllIndividualClientsForLookupByOfficeId(Long officeId); - ClientAccountSummaryCollectionData retrieveClientAccountDetails(Long clientId); + ClientAccountSummaryCollectionData retrieveClientAccountDetails(Long clientId); Collection retrieveClientLoanAccountsByLoanOfficerId(Long clientId, Long loanOfficerId); - Collection retrieveAllClientNotes(Long clientId); + Collection retrieveAllClientNotes(Long clientId); - NoteData retrieveClientNote(Long clientId, Long noteId); - - Collection retrieveClientIdentifiers(Long clientId); - - ClientIdentifierData retrieveClientIdentifier(Long clientId,Long clientIdentifierId); + NoteData retrieveClientNote(Long clientId, Long noteId); - ClientData retrieveClientByIdentifier(Long identifierTypeId, String identifierKey); + Collection retrieveClientIdentifiers(Long clientId); + + ClientIdentifierData retrieveClientIdentifier(Long clientId, Long clientIdentifierId); + + ClientData retrieveClientByIdentifier(Long identifierTypeId, String identifierKey); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientWritePlatformService.java index 7f975e2ff..2f0cb44e7 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientWritePlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientWritePlatformService.java @@ -11,13 +11,10 @@ import org.springframework.security.access.prepost.PreAuthorize; public interface ClientWritePlatformService { - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'CREATE_CLIENT')") Long createClient(ClientCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'UPDATE_CLIENT')") EntityIdentifier updateClientDetails(ClientCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'DELETE_CLIENT')") EntityIdentifier deleteClient(ClientCommand command); @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'CREATE_CLIENTIMAGE')") diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/ClientCommandHandler.java b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/ClientCommandHandler.java index 70d2de444..94c69d94d 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/ClientCommandHandler.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/ClientCommandHandler.java @@ -1,5 +1,8 @@ package org.mifosng.platform.makerchecker.service; +import java.util.Arrays; +import java.util.List; + import org.joda.time.LocalDate; import org.mifosng.platform.api.commands.ClientCommand; import org.mifosng.platform.api.data.EntityIdentifier; @@ -93,21 +96,29 @@ public class ClientCommandHandler implements CommandSourceHandler { commandSourceResult.resourceId(), commandSourceResult.json(), true); if (commandSourceResult.isCreate()) { + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "CREATE_CLIENT_CHECKER"); + context.authenticatedUser().validateHasPermissionTo("CREATE_CLIENT_CHECKER", allowedPermissions); + resourceId = this.clientWritePlatformService.createClient(command); + commandSourceResult.updateResourceId(resourceId); commandSourceResult.markAsChecked(checker, new LocalDate()); } else if (commandSourceResult.isUpdate()) { + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "UPDATE_CLIENT_CHECKER"); + context.authenticatedUser().validateHasPermissionTo("UPDATE_CLIENT_CHECKER", allowedPermissions); + EntityIdentifier result = this.clientWritePlatformService.updateClientDetails(command); resourceId = result.getEntityId(); commandSourceResult.markAsChecked(checker, new LocalDate()); } else if (commandSourceResult.isDelete()) { + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "DELETE_CLIENT_CHECKER"); + context.authenticatedUser().validateHasPermissionTo("DELETE_CLIENT_CHECKER", allowedPermissions); + EntityIdentifier result = this.clientWritePlatformService.deleteClient(command); resourceId = result.getEntityId(); commandSourceResult.markAsChecked(checker, new LocalDate()); } } - commandSourceResult.updateResourceId(resourceId); - return commandSourceResult; } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/RoleCommandHandler.java b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/RoleCommandHandler.java index 66529bcde..52a288c79 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/RoleCommandHandler.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/RoleCommandHandler.java @@ -1,5 +1,8 @@ package org.mifosng.platform.makerchecker.service; +import java.util.Arrays; +import java.util.List; + import org.joda.time.LocalDate; import org.mifosng.platform.api.commands.RoleCommand; import org.mifosng.platform.api.commands.RolePermissionCommand; @@ -24,13 +27,12 @@ public class RoleCommandHandler implements CommandSourceHandler { private final PortfolioCommandSerializerService commandSerializerService; private final PortfolioCommandDeserializerService commandDeserializerService; private final RoleWritePlatformService writePlatformService; - + @Autowired public RoleCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService, final PortfolioApiDataConversionService apiDataConversionService, final PortfolioCommandSerializerService commandSerializerService, - final PortfolioCommandDeserializerService commandDeserializerService, - final RoleWritePlatformService writePlatformService) { + final PortfolioCommandDeserializerService commandDeserializerService, final RoleWritePlatformService writePlatformService) { this.context = context; this.changeDetectionService = changeDetectionService; this.apiDataConversionService = apiDataConversionService; @@ -40,9 +42,10 @@ public class RoleCommandHandler implements CommandSourceHandler { } /* - * Used when users with 'create' capability create a command. If 'maker-checker' is not - * enabled for this specific command then the 'creator' is also marked 'as the checker' and command - * automatically is processed and changes state of system. + * Used when users with 'create' capability create a command. If + * 'maker-checker' is not enabled for this specific command then the + * 'creator' is also marked 'as the checker' and command automatically is + * processed and changes state of system. */ public CommandSource handle(final CommandSource commandSource, final String apiRequestBodyInJson) { @@ -56,10 +59,11 @@ public class RoleCommandHandler implements CommandSourceHandler { if (commandSource.isCreate()) { try { - final RoleCommand command = this.apiDataConversionService.convertApiRequestJsonToRoleCommand(resourceId, apiRequestBodyInJson); + final RoleCommand command = this.apiDataConversionService.convertApiRequestJsonToRoleCommand(resourceId, + apiRequestBodyInJson); final String commandSerializedAsJson = this.commandSerializerService.serializeRoleCommandToJson(command); commandSourceResult.updateJsonTo(commandSerializedAsJson); - + newResourceId = this.writePlatformService.createRole(command); commandSourceResult.markAsChecked(maker, asToday); commandSourceResult.updateResourceId(newResourceId); @@ -68,14 +72,17 @@ public class RoleCommandHandler implements CommandSourceHandler { } } else if (commandSource.isUpdate()) { try { - final RoleCommand command = this.apiDataConversionService.convertApiRequestJsonToRoleCommand(resourceId, apiRequestBodyInJson); + final RoleCommand command = this.apiDataConversionService.convertApiRequestJsonToRoleCommand(resourceId, + apiRequestBodyInJson); final String commandSerializedAsJson = this.commandSerializerService.serializeRoleCommandToJson(command); commandSourceResult.updateJsonTo(commandSerializedAsJson); - - final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(), commandSource.resourceId(), commandSerializedAsJson); + + final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(), + commandSource.resourceId(), commandSerializedAsJson); commandSourceResult.updateJsonTo(jsonOfChangesOnly); - final RoleCommand changesOnly = this.commandDeserializerService.deserializeRoleCommand(resourceId, jsonOfChangesOnly, false); + final RoleCommand changesOnly = this.commandDeserializerService + .deserializeRoleCommand(resourceId, jsonOfChangesOnly, false); newResourceId = this.writePlatformService.updateRole(changesOnly); @@ -85,24 +92,25 @@ public class RoleCommandHandler implements CommandSourceHandler { } } else if (commandSource.isUpdateRolePermissions()) { try { - final RolePermissionCommand command = this.apiDataConversionService.convertApiRequestJsonToRolePermissionCommand(resourceId, apiRequestBodyInJson); + final RolePermissionCommand command = this.apiDataConversionService.convertApiRequestJsonToRolePermissionCommand( + resourceId, apiRequestBodyInJson); final String commandSerializedAsJson = this.commandSerializerService.serializeRolePermissionCommandToJson(command); commandSourceResult.updateJsonTo(commandSerializedAsJson); - - final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(), commandSource.resourceId(), commandSerializedAsJson); + + final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(), + commandSource.resourceId(), commandSerializedAsJson); commandSourceResult.updateJsonTo(jsonOfChangesOnly); - final RolePermissionCommand changesOnly = this.commandDeserializerService.deserializeRolePermissionCommand(resourceId, jsonOfChangesOnly, false); + final RolePermissionCommand changesOnly = this.commandDeserializerService.deserializeRolePermissionCommand(resourceId, + jsonOfChangesOnly, false); - newResourceId =this.writePlatformService.updateRolePermissions(changesOnly); + newResourceId = this.writePlatformService.updateRolePermissions(changesOnly); commandSourceResult.markAsChecked(maker, asToday); } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { // swallow this rollback transaction by design } - } else if (commandSource.isDelete()) { - throw new UnsupportedCommandException(commandSource.commandName()); - } + } else if (commandSource.isDelete()) { throw new UnsupportedCommandException(commandSource.commandName()); } return commandSourceResult; } @@ -113,24 +121,37 @@ public class RoleCommandHandler implements CommandSourceHandler { public CommandSource handle(final CommandSource commandSourceResult) { final AppUser checker = context.authenticatedUser(); - + Long resourceId = commandSourceResult.resourceId(); if (commandSourceResult.isRoleResource()) { if (commandSourceResult.isCreate()) { - final RoleCommand command = this.commandDeserializerService.deserializeRoleCommand(resourceId, commandSourceResult.json(), true); + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "USER_ADMINISTRATION_SUPER_USER", + "CREATE_ROLE_CHECKER"); + context.authenticatedUser().validateHasPermissionTo("CREATE_ROLE_CHECKER", allowedPermissions); + + final RoleCommand command = this.commandDeserializerService.deserializeRoleCommand(resourceId, commandSourceResult.json(), + true); resourceId = this.writePlatformService.createRole(command); commandSourceResult.markAsChecked(checker, new LocalDate()); } else if (commandSourceResult.isUpdate()) { - final RoleCommand command = this.commandDeserializerService.deserializeRoleCommand(resourceId, commandSourceResult.json(), true); + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "USER_ADMINISTRATION_SUPER_USER", + "UPDATE_ROLE_CHECKER"); + context.authenticatedUser().validateHasPermissionTo("UPDATE_ROLE_CHECKER", allowedPermissions); + + final RoleCommand command = this.commandDeserializerService.deserializeRoleCommand(resourceId, commandSourceResult.json(), + true); resourceId = this.writePlatformService.updateRole(command); commandSourceResult.markAsChecked(checker, new LocalDate()); } else if (commandSourceResult.isUpdateRolePermissions()) { - final RolePermissionCommand command = this.commandDeserializerService.deserializeRolePermissionCommand(resourceId, commandSourceResult.json(), true); - resourceId =this.writePlatformService.updateRolePermissions(command); + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "USER_ADMINISTRATION_SUPER_USER", + "PERMISSIONS_ROLE_CHECKER"); + context.authenticatedUser().validateHasPermissionTo("PERMISSIONS_ROLE_CHECKER", allowedPermissions); + + final RolePermissionCommand command = this.commandDeserializerService.deserializeRolePermissionCommand(resourceId, + commandSourceResult.json(), true); + resourceId = this.writePlatformService.updateRolePermissions(command); commandSourceResult.markAsChecked(checker, new LocalDate()); - } else if (commandSourceResult.isDelete()) { - throw new UnsupportedCommandException(commandSourceResult.commandName()); - } + } else if (commandSourceResult.isDelete()) { throw new UnsupportedCommandException(commandSourceResult.commandName()); } } commandSourceResult.updateResourceId(resourceId); diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/UserCommandHandler.java b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/UserCommandHandler.java index 443e800d6..d58df011d 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/UserCommandHandler.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/UserCommandHandler.java @@ -1,5 +1,8 @@ package org.mifosng.platform.makerchecker.service; +import java.util.Arrays; +import java.util.List; + import org.joda.time.LocalDate; import org.mifosng.platform.api.commands.UserCommand; import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; @@ -109,13 +112,18 @@ public class UserCommandHandler implements CommandSourceHandler { Long resourceId = commandSourceResult.resourceId(); if (commandSourceResult.isUserResource()) { if (commandSourceResult.isCreate()) { + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "USER_ADMINISTRATION_SUPER_USER", "CREATE_USER_MAKER"); + context.authenticatedUser().validateHasPermissionTo("CREATE_USER_MAKER", allowedPermissions); + final UserCommand command = this.commandDeserializerService.deserializeUserCommand(resourceId, commandSourceResult.json(), true); resourceId = this.writePlatformService.createUser(command); commandSourceResult.updateResourceId(resourceId); commandSourceResult.markAsChecked(checker, new LocalDate()); } else if (commandSourceResult.isUpdate()) { - final UserCommand command = this.commandDeserializerService.deserializeUserCommand(resourceId, commandSourceResult.json(), true); + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "USER_ADMINISTRATION_SUPER_USER", "UPDATE_USER_MAKER"); + context.authenticatedUser().validateHasPermissionTo("UPDATE_USER_MAKER", allowedPermissions); + final UserCommand command = this.commandDeserializerService.deserializeUserCommand(resourceId, commandSourceResult.json(), true); if (checker.hasIdOf(command.getId())) { this.writePlatformService.updateUsersOwnAccountDetails(command); } else { @@ -124,6 +132,9 @@ public class UserCommandHandler implements CommandSourceHandler { commandSourceResult.markAsChecked(checker, new LocalDate()); } else if (commandSourceResult.isDelete()) { + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "USER_ADMINISTRATION_SUPER_USER", "DELETE_USER_MAKER"); + context.authenticatedUser().validateHasPermissionTo("DELETE_USER_MAKER", allowedPermissions); + final UserCommand command = this.commandDeserializerService.deserializeUserCommand(resourceId, commandSourceResult.json(), true); this.writePlatformService.deleteUser(command); commandSourceResult.markAsChecked(checker, new LocalDate()); diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/user/domain/AppUser.java b/mifosng-provider/src/main/java/org/mifosng/platform/user/domain/AppUser.java index b95f663df..b1f587e5d 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/user/domain/AppUser.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/user/domain/AppUser.java @@ -340,7 +340,6 @@ public class AppUser extends AbstractAuditableCustom implements P if (!(higherPermission.equals(""))) { if (hasNotPermissionForAnyOf(higherPermission)) throw new NoAuthorizationException(authorizationMessage); } - } private boolean hasPermissionTo(final String permissionCode) { @@ -351,11 +350,30 @@ public class AppUser extends AbstractAuditableCustom implements P break; } } - return match; } - + public boolean hasIdOf(final Long userId) { return getId().equals(userId); } + + private boolean hasAnyPermission(final List requiredPermissions) { + boolean hasAtLeastOneOf = false; + + for (final String permissionCode : requiredPermissions) { + if (hasPermissionTo(permissionCode)) { + hasAtLeastOneOf = true; + break; + } + } + + return hasAtLeastOneOf; + } + + public void validateHasPermissionTo(final String function, final List allowedPermissions) { + if (hasAnyPermission(allowedPermissions)) { + final String authorizationMessage = "User has no authority to: " + function; + throw new NoAuthorizationException(authorizationMessage); + } + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/user/service/AppUserWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/AppUserWritePlatformService.java index 5f01ba735..2fc0a3c03 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/user/service/AppUserWritePlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/AppUserWritePlatformService.java @@ -1,17 +1,13 @@ package org.mifosng.platform.user.service; import org.mifosng.platform.api.commands.UserCommand; -import org.springframework.security.access.prepost.PreAuthorize; public interface AppUserWritePlatformService { - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'USER_ADMINISTRATION_SUPER_USER', 'CREATE_USER')") Long createUser(UserCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'USER_ADMINISTRATION_SUPER_USER', 'UPDATE_USER')") Long updateUser(UserCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'USER_ADMINISTRATION_SUPER_USER', 'DELETE_USER')") void deleteUser(UserCommand command); // we dont put any permissions on this e.g. a user with no admin rights can diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/user/service/RoleWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/RoleWritePlatformService.java index 934e8b72c..fad662d1e 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/user/service/RoleWritePlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/RoleWritePlatformService.java @@ -2,16 +2,12 @@ package org.mifosng.platform.user.service; import org.mifosng.platform.api.commands.RoleCommand; import org.mifosng.platform.api.commands.RolePermissionCommand; -import org.springframework.security.access.prepost.PreAuthorize; public interface RoleWritePlatformService { - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'USER_ADMINISTRATION_SUPER_USER', 'CREATE_ROLE')") Long createRole(RoleCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'USER_ADMINISTRATION_SUPER_USER', 'UPDATE_ROLE')") Long updateRole(RoleCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'USER_ADMINISTRATION_SUPER_USER', 'PERMISSIONS_ROLE')") Long updateRolePermissions(RolePermissionCommand command); } \ No newline at end of file