MIFOSX-97: move permissions checking to api and cater for _CHECKER permissions needed.

This commit is contained in:
Keith Woodlock
2012-11-26 21:32:53 +00:00
parent 02617ce7f6
commit 0549858dea
11 changed files with 153 additions and 96 deletions
@@ -4,7 +4,6 @@ import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@@ -229,6 +228,9 @@ public class ClientsApiResource {
@Produces({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON})
public String createClient(final String jsonRequestBody) { public String createClient(final String jsonRequestBody) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "CREATE_CLIENT");
context.authenticatedUser().validateHasPermissionTo("CREATE_CLIENT", allowedPermissions);
final EntityIdentifier result = this.commandsSourceWritePlatformService final EntityIdentifier result = this.commandsSourceWritePlatformService
.logCommandSource("CREATE", "clients", null, jsonRequestBody); .logCommandSource("CREATE", "clients", null, jsonRequestBody);
@@ -241,6 +243,9 @@ public class ClientsApiResource {
@Produces({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON})
public String updateClient(@PathParam("clientId") final Long clientId, final String jsonRequestBody) { public String updateClient(@PathParam("clientId") final Long clientId, final String jsonRequestBody) {
final List<String> 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, final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "clients", clientId,
jsonRequestBody); jsonRequestBody);
@@ -253,6 +258,9 @@ public class ClientsApiResource {
@Produces({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON})
public String deleteClient(@PathParam("clientId") final Long clientId) { public String deleteClient(@PathParam("clientId") final Long clientId) {
final List<String> 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, "{}"); final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE", "clients", clientId, "{}");
return this.apiJsonSerializerService.serializeEntityIdentifier(result); return this.apiJsonSerializerService.serializeEntityIdentifier(result);
@@ -266,20 +274,10 @@ public class ClientsApiResource {
context.authenticatedUser().validateHasReadPermission("CLIENT"); context.authenticatedUser().validateHasReadPermission("CLIENT");
Set<String> typicalResponseParameters = new HashSet<String>(Arrays.asList("pendingApprovalLoans", "awaitingDisbursalLoans", final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
"openLoans", "closedLoans", "anyLoanCount", "pendingApprovalLoanCount", "awaitingDisbursalLoanCount", "activeLoanCount", final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
"closedLoanCount", "pendingApprovalDespositAccountsCount", "pendingApprovalDespositAccounts",
"approvedDespositAccountsCount", "approvedDespositAccounts", "withdrawnByClientDespositAccountsCount",
"withdrawnByClientDespositAccounts", "closedDepositAccountsCount", "closedDepositAccounts", "rejectedDepositAccountsCount",
"rejectedDepositAccounts", "preclosedDepositAccountsCount", "preclosedDepositAccounts"));
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); final ClientAccountSummaryCollectionData clientAccount = this.clientReadPlatformService.retrieveClientAccountDetails(clientId);
if (responseParameters.isEmpty()) {
responseParameters.addAll(typicalResponseParameters);
}
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
ClientAccountSummaryCollectionData clientAccount = this.clientReadPlatformService.retrieveClientAccountDetails(clientId);
return this.apiJsonSerializerService.serializeClientAccountSummaryCollectionDataToJson(prettyPrint, responseParameters, return this.apiJsonSerializerService.serializeClientAccountSummaryCollectionDataToJson(prettyPrint, responseParameters,
clientAccount); clientAccount);
@@ -293,16 +291,10 @@ public class ClientsApiResource {
context.authenticatedUser().validateHasReadPermission("CLIENTNOTE"); context.authenticatedUser().validateHasReadPermission("CLIENTNOTE");
Set<String> typicalResponseParameters = new HashSet<String>(Arrays.asList("id", "clientId", "loanId", "loanTransactionId", final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
"noteType", "note", "createdById", "createdByUsername", "createdOn", "updatedById", "updatedByUsername", "updatedOn")); final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); final Collection<NoteData> notes = this.clientReadPlatformService.retrieveAllClientNotes(clientId);
if (responseParameters.isEmpty()) {
responseParameters.addAll(typicalResponseParameters);
}
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
Collection<NoteData> notes = this.clientReadPlatformService.retrieveAllClientNotes(clientId);
return this.apiJsonSerializerService.serializeNoteDataToJson(prettyPrint, responseParameters, notes); return this.apiJsonSerializerService.serializeNoteDataToJson(prettyPrint, responseParameters, notes);
} }
@@ -313,9 +305,9 @@ public class ClientsApiResource {
@Produces({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON})
public Response addNewClientNote(@PathParam("clientId") final Long clientId, final String jsonRequestBody) { 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(); return Response.ok().entity(identifier).build();
} }
@@ -329,16 +321,10 @@ public class ClientsApiResource {
context.authenticatedUser().validateHasReadPermission("CLIENTNOTE"); context.authenticatedUser().validateHasReadPermission("CLIENTNOTE");
Set<String> typicalResponseParameters = new HashSet<String>(Arrays.asList("id", "clientId", "loanId", "loanTransactionId", final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
"noteType", "note", "createdById", "createdByUsername", "createdOn", "updatedById", "updatedByUsername", "updatedOn")); final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); final NoteData note = this.clientReadPlatformService.retrieveClientNote(clientId, noteId);
if (responseParameters.isEmpty()) {
responseParameters.addAll(typicalResponseParameters);
}
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
NoteData note = this.clientReadPlatformService.retrieveClientNote(clientId, noteId);
return this.apiJsonSerializerService.serializeNoteDataToJson(prettyPrint, responseParameters, note); 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, public Response updateClientNote(@PathParam("clientId") final Long clientId, @PathParam("noteId") final Long noteId,
final String jsonRequestBody) { 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(); return Response.ok().entity(identifier).build();
} }
@@ -375,9 +361,9 @@ public class ClientsApiResource {
FileUtils.validateImageMimeType(bodyPart.getMediaType().toString()); FileUtils.validateImageMimeType(bodyPart.getMediaType().toString());
FileUtils.validateFileSizeWithinPermissibleRange(fileSize, fileDetails.getFileName(), ApiConstants.MAX_FILE_UPLOAD_SIZE_IN_MB); 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); inputStream);
return Response.ok().entity(entityIdentifier).build(); return Response.ok().entity(entityIdentifier).build();
@@ -392,9 +378,9 @@ public class ClientsApiResource {
@Produces({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON})
public Response addNewClientImage(@PathParam("clientId") final Long clientId, final String jsonRequestBody) { 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(); return Response.ok().entity(entityIdentifier).build();
} }
@@ -1,7 +1,9 @@
package org.mifosng.platform.api; package org.mifosng.platform.api;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.Set; import java.util.Set;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
@@ -82,6 +84,9 @@ public class RolesApiResource {
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String createRole(final String apiRequestBodyAsJson) { public String createRole(final String apiRequestBodyAsJson) {
final List<String> 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, final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "roles", null,
apiRequestBodyAsJson); apiRequestBodyAsJson);
@@ -127,6 +132,9 @@ public class RolesApiResource {
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String updateRole(@PathParam("roleId") final Long roleId, final String apiRequestBodyAsJson) { public String updateRole(@PathParam("roleId") final Long roleId, final String apiRequestBodyAsJson) {
final List<String> 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, final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "roles", roleId,
apiRequestBodyAsJson); apiRequestBodyAsJson);
@@ -184,6 +192,9 @@ public class RolesApiResource {
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String updateRolePermissions(@PathParam("roleId") final Long roleId, final String apiRequestBodyAsJson) { public String updateRolePermissions(@PathParam("roleId") final Long roleId, final String apiRequestBodyAsJson) {
final List<String> 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, final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATEPERMISSIONS", "roles", roleId,
apiRequestBodyAsJson); apiRequestBodyAsJson);
@@ -1,6 +1,7 @@
package org.mifosng.platform.api; package org.mifosng.platform.api;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@@ -109,6 +110,9 @@ public class UsersApiResource {
@Produces({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON})
public String createUser(final String apiRequestBodyAsJson) { public String createUser(final String apiRequestBodyAsJson) {
final List<String> 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); final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "users", null, apiRequestBodyAsJson);
return this.apiJsonSerializerService.serializeEntityIdentifier(result); return this.apiJsonSerializerService.serializeEntityIdentifier(result);
@@ -120,6 +124,9 @@ public class UsersApiResource {
@Produces({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON})
public String deleteUser(@PathParam("userId") final Long userId) { public String deleteUser(@PathParam("userId") final Long userId) {
final List<String> 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, "{}"); final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE", "users", userId, "{}");
return this.apiJsonSerializerService.serializeEntityIdentifier(result); return this.apiJsonSerializerService.serializeEntityIdentifier(result);
@@ -131,6 +138,9 @@ public class UsersApiResource {
@Produces({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON})
public String updateUser(@PathParam("userId") final Long userId, final String apiRequestBodyAsJson) { public String updateUser(@PathParam("userId") final Long userId, final String apiRequestBodyAsJson) {
final List<String> 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); final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "users", userId, apiRequestBodyAsJson);
return this.apiJsonSerializerService.serializeEntityIdentifier(result); return this.apiJsonSerializerService.serializeEntityIdentifier(result);
@@ -11,27 +11,27 @@ import org.mifosng.platform.api.data.NoteData;
public interface ClientReadPlatformService { public interface ClientReadPlatformService {
Collection<ClientData> retrieveAllIndividualClients(String extraCriteria); Collection<ClientData> retrieveAllIndividualClients(String extraCriteria);
ClientData retrieveIndividualClient(Long clientId); ClientData retrieveIndividualClient(Long clientId);
ClientData retrieveNewClientDetails(); ClientData retrieveNewClientDetails();
Collection<ClientLookup> retrieveAllIndividualClientsForLookup(String extraCriteria); Collection<ClientLookup> retrieveAllIndividualClientsForLookup(String extraCriteria);
Collection<ClientLookup> retrieveAllIndividualClientsForLookupByOfficeId(Long officeId); Collection<ClientLookup> retrieveAllIndividualClientsForLookupByOfficeId(Long officeId);
ClientAccountSummaryCollectionData retrieveClientAccountDetails(Long clientId); ClientAccountSummaryCollectionData retrieveClientAccountDetails(Long clientId);
Collection<ClientAccountSummaryData> retrieveClientLoanAccountsByLoanOfficerId(Long clientId, Long loanOfficerId); Collection<ClientAccountSummaryData> retrieveClientLoanAccountsByLoanOfficerId(Long clientId, Long loanOfficerId);
Collection<NoteData> retrieveAllClientNotes(Long clientId); Collection<NoteData> retrieveAllClientNotes(Long clientId);
NoteData retrieveClientNote(Long clientId, Long noteId); NoteData retrieveClientNote(Long clientId, Long noteId);
Collection<ClientIdentifierData> retrieveClientIdentifiers(Long clientId); Collection<ClientIdentifierData> retrieveClientIdentifiers(Long clientId);
ClientIdentifierData retrieveClientIdentifier(Long clientId,Long clientIdentifierId); ClientIdentifierData retrieveClientIdentifier(Long clientId, Long clientIdentifierId);
ClientData retrieveClientByIdentifier(Long identifierTypeId, String identifierKey); ClientData retrieveClientByIdentifier(Long identifierTypeId, String identifierKey);
} }
@@ -11,13 +11,10 @@ import org.springframework.security.access.prepost.PreAuthorize;
public interface ClientWritePlatformService { public interface ClientWritePlatformService {
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'CREATE_CLIENT')")
Long createClient(ClientCommand command); Long createClient(ClientCommand command);
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'UPDATE_CLIENT')")
EntityIdentifier updateClientDetails(ClientCommand command); EntityIdentifier updateClientDetails(ClientCommand command);
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'DELETE_CLIENT')")
EntityIdentifier deleteClient(ClientCommand command); EntityIdentifier deleteClient(ClientCommand command);
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'CREATE_CLIENTIMAGE')") @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'CREATE_CLIENTIMAGE')")
@@ -1,5 +1,8 @@
package org.mifosng.platform.makerchecker.service; package org.mifosng.platform.makerchecker.service;
import java.util.Arrays;
import java.util.List;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosng.platform.api.commands.ClientCommand; import org.mifosng.platform.api.commands.ClientCommand;
import org.mifosng.platform.api.data.EntityIdentifier; import org.mifosng.platform.api.data.EntityIdentifier;
@@ -93,21 +96,29 @@ public class ClientCommandHandler implements CommandSourceHandler {
commandSourceResult.resourceId(), commandSourceResult.json(), true); commandSourceResult.resourceId(), commandSourceResult.json(), true);
if (commandSourceResult.isCreate()) { if (commandSourceResult.isCreate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "CREATE_CLIENT_CHECKER");
context.authenticatedUser().validateHasPermissionTo("CREATE_CLIENT_CHECKER", allowedPermissions);
resourceId = this.clientWritePlatformService.createClient(command); resourceId = this.clientWritePlatformService.createClient(command);
commandSourceResult.updateResourceId(resourceId);
commandSourceResult.markAsChecked(checker, new LocalDate()); commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isUpdate()) { } else if (commandSourceResult.isUpdate()) {
final List<String> 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); EntityIdentifier result = this.clientWritePlatformService.updateClientDetails(command);
resourceId = result.getEntityId(); resourceId = result.getEntityId();
commandSourceResult.markAsChecked(checker, new LocalDate()); commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isDelete()) { } else if (commandSourceResult.isDelete()) {
final List<String> 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); EntityIdentifier result = this.clientWritePlatformService.deleteClient(command);
resourceId = result.getEntityId(); resourceId = result.getEntityId();
commandSourceResult.markAsChecked(checker, new LocalDate()); commandSourceResult.markAsChecked(checker, new LocalDate());
} }
} }
commandSourceResult.updateResourceId(resourceId);
return commandSourceResult; return commandSourceResult;
} }
} }
@@ -1,5 +1,8 @@
package org.mifosng.platform.makerchecker.service; package org.mifosng.platform.makerchecker.service;
import java.util.Arrays;
import java.util.List;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosng.platform.api.commands.RoleCommand; import org.mifosng.platform.api.commands.RoleCommand;
import org.mifosng.platform.api.commands.RolePermissionCommand; import org.mifosng.platform.api.commands.RolePermissionCommand;
@@ -29,8 +32,7 @@ public class RoleCommandHandler implements CommandSourceHandler {
public RoleCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService, public RoleCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService,
final PortfolioApiDataConversionService apiDataConversionService, final PortfolioApiDataConversionService apiDataConversionService,
final PortfolioCommandSerializerService commandSerializerService, final PortfolioCommandSerializerService commandSerializerService,
final PortfolioCommandDeserializerService commandDeserializerService, final PortfolioCommandDeserializerService commandDeserializerService, final RoleWritePlatformService writePlatformService) {
final RoleWritePlatformService writePlatformService) {
this.context = context; this.context = context;
this.changeDetectionService = changeDetectionService; this.changeDetectionService = changeDetectionService;
this.apiDataConversionService = apiDataConversionService; 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 * Used when users with 'create' capability create a command. If
* enabled for this specific command then the 'creator' is also marked 'as the checker' and command * 'maker-checker' is not enabled for this specific command then the
* automatically is processed and changes state of system. * '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) { public CommandSource handle(final CommandSource commandSource, final String apiRequestBodyInJson) {
@@ -56,7 +59,8 @@ public class RoleCommandHandler implements CommandSourceHandler {
if (commandSource.isCreate()) { if (commandSource.isCreate()) {
try { try {
final RoleCommand command = this.apiDataConversionService.convertApiRequestJsonToRoleCommand(resourceId, apiRequestBodyInJson); final RoleCommand command = this.apiDataConversionService.convertApiRequestJsonToRoleCommand(resourceId,
apiRequestBodyInJson);
final String commandSerializedAsJson = this.commandSerializerService.serializeRoleCommandToJson(command); final String commandSerializedAsJson = this.commandSerializerService.serializeRoleCommandToJson(command);
commandSourceResult.updateJsonTo(commandSerializedAsJson); commandSourceResult.updateJsonTo(commandSerializedAsJson);
@@ -68,14 +72,17 @@ public class RoleCommandHandler implements CommandSourceHandler {
} }
} else if (commandSource.isUpdate()) { } else if (commandSource.isUpdate()) {
try { try {
final RoleCommand command = this.apiDataConversionService.convertApiRequestJsonToRoleCommand(resourceId, apiRequestBodyInJson); final RoleCommand command = this.apiDataConversionService.convertApiRequestJsonToRoleCommand(resourceId,
apiRequestBodyInJson);
final String commandSerializedAsJson = this.commandSerializerService.serializeRoleCommandToJson(command); final String commandSerializedAsJson = this.commandSerializerService.serializeRoleCommandToJson(command);
commandSourceResult.updateJsonTo(commandSerializedAsJson); 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); 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); newResourceId = this.writePlatformService.updateRole(changesOnly);
@@ -85,24 +92,25 @@ public class RoleCommandHandler implements CommandSourceHandler {
} }
} else if (commandSource.isUpdateRolePermissions()) { } else if (commandSource.isUpdateRolePermissions()) {
try { try {
final RolePermissionCommand command = this.apiDataConversionService.convertApiRequestJsonToRolePermissionCommand(resourceId, apiRequestBodyInJson); final RolePermissionCommand command = this.apiDataConversionService.convertApiRequestJsonToRolePermissionCommand(
resourceId, apiRequestBodyInJson);
final String commandSerializedAsJson = this.commandSerializerService.serializeRolePermissionCommandToJson(command); final String commandSerializedAsJson = this.commandSerializerService.serializeRolePermissionCommandToJson(command);
commandSourceResult.updateJsonTo(commandSerializedAsJson); 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); 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); commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design // swallow this rollback transaction by design
} }
} else if (commandSource.isDelete()) { } else if (commandSource.isDelete()) { throw new UnsupportedCommandException(commandSource.commandName()); }
throw new UnsupportedCommandException(commandSource.commandName());
}
return commandSourceResult; return commandSourceResult;
} }
@@ -117,20 +125,33 @@ public class RoleCommandHandler implements CommandSourceHandler {
Long resourceId = commandSourceResult.resourceId(); Long resourceId = commandSourceResult.resourceId();
if (commandSourceResult.isRoleResource()) { if (commandSourceResult.isRoleResource()) {
if (commandSourceResult.isCreate()) { if (commandSourceResult.isCreate()) {
final RoleCommand command = this.commandDeserializerService.deserializeRoleCommand(resourceId, commandSourceResult.json(), true); final List<String> 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); resourceId = this.writePlatformService.createRole(command);
commandSourceResult.markAsChecked(checker, new LocalDate()); commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isUpdate()) { } else if (commandSourceResult.isUpdate()) {
final RoleCommand command = this.commandDeserializerService.deserializeRoleCommand(resourceId, commandSourceResult.json(), true); final List<String> 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); resourceId = this.writePlatformService.updateRole(command);
commandSourceResult.markAsChecked(checker, new LocalDate()); commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isUpdateRolePermissions()) { } else if (commandSourceResult.isUpdateRolePermissions()) {
final RolePermissionCommand command = this.commandDeserializerService.deserializeRolePermissionCommand(resourceId, commandSourceResult.json(), true); final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "USER_ADMINISTRATION_SUPER_USER",
resourceId =this.writePlatformService.updateRolePermissions(command); "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()); commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isDelete()) { } else if (commandSourceResult.isDelete()) { throw new UnsupportedCommandException(commandSourceResult.commandName()); }
throw new UnsupportedCommandException(commandSourceResult.commandName());
}
} }
commandSourceResult.updateResourceId(resourceId); commandSourceResult.updateResourceId(resourceId);
@@ -1,5 +1,8 @@
package org.mifosng.platform.makerchecker.service; package org.mifosng.platform.makerchecker.service;
import java.util.Arrays;
import java.util.List;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosng.platform.api.commands.UserCommand; import org.mifosng.platform.api.commands.UserCommand;
import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService;
@@ -109,13 +112,18 @@ public class UserCommandHandler implements CommandSourceHandler {
Long resourceId = commandSourceResult.resourceId(); Long resourceId = commandSourceResult.resourceId();
if (commandSourceResult.isUserResource()) { if (commandSourceResult.isUserResource()) {
if (commandSourceResult.isCreate()) { if (commandSourceResult.isCreate()) {
final List<String> 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); final UserCommand command = this.commandDeserializerService.deserializeUserCommand(resourceId, commandSourceResult.json(), true);
resourceId = this.writePlatformService.createUser(command); resourceId = this.writePlatformService.createUser(command);
commandSourceResult.updateResourceId(resourceId); commandSourceResult.updateResourceId(resourceId);
commandSourceResult.markAsChecked(checker, new LocalDate()); commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isUpdate()) { } else if (commandSourceResult.isUpdate()) {
final UserCommand command = this.commandDeserializerService.deserializeUserCommand(resourceId, commandSourceResult.json(), true); final List<String> 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())) { if (checker.hasIdOf(command.getId())) {
this.writePlatformService.updateUsersOwnAccountDetails(command); this.writePlatformService.updateUsersOwnAccountDetails(command);
} else { } else {
@@ -124,6 +132,9 @@ public class UserCommandHandler implements CommandSourceHandler {
commandSourceResult.markAsChecked(checker, new LocalDate()); commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isDelete()) { } else if (commandSourceResult.isDelete()) {
final List<String> 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); final UserCommand command = this.commandDeserializerService.deserializeUserCommand(resourceId, commandSourceResult.json(), true);
this.writePlatformService.deleteUser(command); this.writePlatformService.deleteUser(command);
commandSourceResult.markAsChecked(checker, new LocalDate()); commandSourceResult.markAsChecked(checker, new LocalDate());
@@ -340,7 +340,6 @@ public class AppUser extends AbstractAuditableCustom<AppUser, Long> implements P
if (!(higherPermission.equals(""))) { if (!(higherPermission.equals(""))) {
if (hasNotPermissionForAnyOf(higherPermission)) throw new NoAuthorizationException(authorizationMessage); if (hasNotPermissionForAnyOf(higherPermission)) throw new NoAuthorizationException(authorizationMessage);
} }
} }
private boolean hasPermissionTo(final String permissionCode) { private boolean hasPermissionTo(final String permissionCode) {
@@ -351,11 +350,30 @@ public class AppUser extends AbstractAuditableCustom<AppUser, Long> implements P
break; break;
} }
} }
return match; return match;
} }
public boolean hasIdOf(final Long userId) { public boolean hasIdOf(final Long userId) {
return getId().equals(userId); return getId().equals(userId);
} }
private boolean hasAnyPermission(final List<String> 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<String> allowedPermissions) {
if (hasAnyPermission(allowedPermissions)) {
final String authorizationMessage = "User has no authority to: " + function;
throw new NoAuthorizationException(authorizationMessage);
}
}
} }
@@ -1,17 +1,13 @@
package org.mifosng.platform.user.service; package org.mifosng.platform.user.service;
import org.mifosng.platform.api.commands.UserCommand; import org.mifosng.platform.api.commands.UserCommand;
import org.springframework.security.access.prepost.PreAuthorize;
public interface AppUserWritePlatformService { public interface AppUserWritePlatformService {
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'USER_ADMINISTRATION_SUPER_USER', 'CREATE_USER')")
Long createUser(UserCommand command); Long createUser(UserCommand command);
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'USER_ADMINISTRATION_SUPER_USER', 'UPDATE_USER')")
Long updateUser(UserCommand command); Long updateUser(UserCommand command);
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'USER_ADMINISTRATION_SUPER_USER', 'DELETE_USER')")
void deleteUser(UserCommand command); void deleteUser(UserCommand command);
// we dont put any permissions on this e.g. a user with no admin rights can // we dont put any permissions on this e.g. a user with no admin rights can
@@ -2,16 +2,12 @@ package org.mifosng.platform.user.service;
import org.mifosng.platform.api.commands.RoleCommand; import org.mifosng.platform.api.commands.RoleCommand;
import org.mifosng.platform.api.commands.RolePermissionCommand; import org.mifosng.platform.api.commands.RolePermissionCommand;
import org.springframework.security.access.prepost.PreAuthorize;
public interface RoleWritePlatformService { public interface RoleWritePlatformService {
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'USER_ADMINISTRATION_SUPER_USER', 'CREATE_ROLE')")
Long createRole(RoleCommand command); Long createRole(RoleCommand command);
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'USER_ADMINISTRATION_SUPER_USER', 'UPDATE_ROLE')")
Long updateRole(RoleCommand command); Long updateRole(RoleCommand command);
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'USER_ADMINISTRATION_SUPER_USER', 'PERMISSIONS_ROLE')")
Long updateRolePermissions(RolePermissionCommand command); Long updateRolePermissions(RolePermissionCommand command);
} }