From 5ccecb8bc48e3505f0dbe7b95cbb954f57667e40 Mon Sep 17 00:00:00 2001 From: Keith Woodlock Date: Mon, 14 May 2012 16:01:24 +0100 Subject: [PATCH] switch provider app to 8080, tidy up users resource and clean up export code for reports. --- .../org/mifosng/data/command/UserCommand.java | 6 +- mifosng-db/0001-mifosng-base-schema.sql | 2 +- mifosng-db/latest_demo_dump_2012_05_01.sql | 2 +- mifosng-individual-lending-app/build.gradle | 2 +- .../webapp/WEB-INF/views/admin/orghome.jsp | 10 +- .../webapp/WEB-INF/views/admin/userhome.jsp | 28 +-- mifosng-provider/build.gradle | 2 +- .../platform/UserCommandValidator.java | 71 -------- .../platform/WritePlatformService.java | 13 -- ...WritePlatformServiceJpaRepositoryImpl.java | 121 +------------ .../platform/api/ReportingApiResource.java | 82 +++------ .../platform/api/user/UserApiResource.java | 149 +++++++--------- .../infrastructure/SignupController.java | 4 +- .../service/OfficeWritePlatformService.java | 6 +- ...WritePlatformServiceJpaRepositoryImpl.java | 3 +- .../rest/UserAdmistrationResource.java | 159 +----------------- .../mifosng/platform/user/domain/AppUser.java | 4 +- .../service/AppUserWritePlatformService.java | 12 ++ ...WritePlatformServiceJpaRepositoryImpl.java | 159 ++++++++++++++++++ .../user/service/UserCommandValidator.java | 72 ++++++++ 20 files changed, 367 insertions(+), 540 deletions(-) delete mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/UserCommandValidator.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/user/service/AppUserWritePlatformService.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/user/service/AppUserWritePlatformServiceJpaRepositoryImpl.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/user/service/UserCommandValidator.java diff --git a/mifosng-data/src/main/java/org/mifosng/data/command/UserCommand.java b/mifosng-data/src/main/java/org/mifosng/data/command/UserCommand.java index 6e7b09ce9..a77704ca6 100644 --- a/mifosng-data/src/main/java/org/mifosng/data/command/UserCommand.java +++ b/mifosng-data/src/main/java/org/mifosng/data/command/UserCommand.java @@ -21,7 +21,7 @@ public class UserCommand implements Serializable { private Long officeId; private List notSelectedItems = new ArrayList(); - private List selectedItems = new ArrayList(); + private String[] selectedItems; public UserCommand() { // @@ -95,11 +95,11 @@ public class UserCommand implements Serializable { this.notSelectedItems = notSelectedItems; } - public List getSelectedItems() { + public String[] getSelectedItems() { return selectedItems; } - public void setSelectedItems(List selectedItems) { + public void setSelectedItems(String... selectedItems) { this.selectedItems = selectedItems; } } \ No newline at end of file diff --git a/mifosng-db/0001-mifosng-base-schema.sql b/mifosng-db/0001-mifosng-base-schema.sql index d29aa0a15..00d4b1c5c 100644 --- a/mifosng-db/0001-mifosng-base-schema.sql +++ b/mifosng-db/0001-mifosng-base-schema.sql @@ -333,7 +333,7 @@ CREATE TABLE `admin_appuser` ( `lastmodified_date` datetime DEFAULT NULL, `lastmodifiedby_id` bigint(20) DEFAULT NULL, PRIMARY KEY (`id`), - UNIQUE KEY `org_id` (`org_id`,`username`), + UNIQUE KEY `username_org` (`org_id`,`username`), KEY `FKB3D587CE0DD567A` (`office_id`), KEY `FKB3D587C54DF2770` (`org_id`), CONSTRAINT `FKB3D587C54DF2770` FOREIGN KEY (`org_id`) REFERENCES `org_organisation` (`id`), diff --git a/mifosng-db/latest_demo_dump_2012_05_01.sql b/mifosng-db/latest_demo_dump_2012_05_01.sql index a45b32b06..2cdea8c52 100644 --- a/mifosng-db/latest_demo_dump_2012_05_01.sql +++ b/mifosng-db/latest_demo_dump_2012_05_01.sql @@ -41,7 +41,7 @@ CREATE TABLE `admin_appuser` ( `lastmodified_date` datetime DEFAULT NULL, `lastmodifiedby_id` bigint(20) DEFAULT NULL, PRIMARY KEY (`id`), - UNIQUE KEY `org_id` (`org_id`,`username`), + UNIQUE KEY `username_org` (`org_id`,`username`), KEY `FKB3D587CE0DD567A` (`office_id`), KEY `FKB3D587C54DF2770` (`org_id`), CONSTRAINT `FKB3D587C54DF2770` FOREIGN KEY (`org_id`) REFERENCES `org_organisation` (`id`), diff --git a/mifosng-individual-lending-app/build.gradle b/mifosng-individual-lending-app/build.gradle index e70725180..a832bcfad 100644 --- a/mifosng-individual-lending-app/build.gradle +++ b/mifosng-individual-lending-app/build.gradle @@ -91,6 +91,6 @@ dependencies { } [tomcatRun, tomcatRunWar, tomcatStop]*.with { - httpPort = 8080 + httpPort = 8085 stopPort = 8082 } \ No newline at end of file diff --git a/mifosng-individual-lending-app/src/main/webapp/WEB-INF/views/admin/orghome.jsp b/mifosng-individual-lending-app/src/main/webapp/WEB-INF/views/admin/orghome.jsp index 9a9243810..bfc906b6b 100644 --- a/mifosng-individual-lending-app/src/main/webapp/WEB-INF/views/admin/orghome.jsp +++ b/mifosng-individual-lending-app/src/main/webapp/WEB-INF/views/admin/orghome.jsp @@ -187,7 +187,13 @@ } o[this.name].push(this.value || ''); } else { - o[this.name] = this.value || ''; + + if (this.name === 'selectedItems' || this.name === 'notSelectedItems') { + o[this.name] = new Array(); + o[this.name].push(this.value || ''); + } else { + o[this.name] = this.value || ''; + } } }); return o; @@ -397,7 +403,7 @@ $.each(data.offices, function(i, item) { //alert(item.name); }); - console.log(data); + console.log(data); var officelistParent = new Object(); officelistParent.items = data.offices; diff --git a/mifosng-individual-lending-app/src/main/webapp/WEB-INF/views/admin/userhome.jsp b/mifosng-individual-lending-app/src/main/webapp/WEB-INF/views/admin/userhome.jsp index 47dd581a6..e50188e02 100644 --- a/mifosng-individual-lending-app/src/main/webapp/WEB-INF/views/admin/userhome.jsp +++ b/mifosng-individual-lending-app/src/main/webapp/WEB-INF/views/admin/userhome.jsp @@ -114,9 +114,7 @@ $(document).ready(function() { removeErrors(placeholderDiv); var jsonErrors = JSON.parse(jqXHR.responseText); - console.log(jsonErrors); var valErrors = jsonErrors.errors; - console.log(valErrors); var errorArray = new Array(); var arrayIndex = 0; $.each(valErrors, function() { @@ -133,7 +131,6 @@ $(document).ready(function() { argArray[argArrayIndex] = this.value; argArrayIndex++; }); - console.log(argArray); // hardcoded support for six arguments errorObj.message = jQuery.i18n.prop(this.userMessageGlobalisationCode, argArray[0], argArray[1], argArray[2], argArray[3], argArray[4], argArray[5]); errorObj.value = this.value; @@ -166,7 +163,13 @@ $(document).ready(function() { } o[this.name].push(this.value || ''); } else { - o[this.name] = this.value || ''; + + if (this.name === 'selectedItems' || this.name === 'notSelectedItems') { + o[this.name] = new Array(); + o[this.name].push(this.value || ''); + } else { + o[this.name] = this.value || ''; + } } }); return o; @@ -199,7 +202,6 @@ $(document).ready(function() { $('#selectedItems option').each(function(i) { $(this).attr("selected", "selected"); }); - var newFormData = JSON.stringify($('#entityform').serializeObject()); console.log(newFormData); @@ -322,14 +324,14 @@ $(document).ready(function() { } $('#listusers').click(function(e) { - var listUrl = "http://localhost:8085/mifosng-provider/api/v1/users"; + var listUrl = "http://localhost:8080/mifosng-provider/api/v1/users"; refreshUsersView(); e.preventDefault(); }); $('#adduser').click(function(e) { - var url = 'http://localhost:8085/mifosng-provider/api/v1/users/template'; - var postUrl = "http://localhost:8085/mifosng-provider/api/v1/users"; + var url = 'http://localhost:8080/mifosng-provider/api/v1/users/template'; + var postUrl = "http://localhost:8080/mifosng-provider/api/v1/users"; var templateSelector = "#userFormTemplate"; var width = 1000; var height = 550; @@ -405,10 +407,10 @@ $(document).ready(function() { function refreshUsersView() { - var listUrl = 'http://localhost:8085/mifosng-provider/api/v1/users'; + var listUrl = 'http://localhost:8080/mifosng-provider/api/v1/users'; var templateSelector = "#usersListTemplate"; var displayAreaDivSelector = "#contentplaceholder"; - var singleEntityPrefixUrl = 'http://localhost:8085/mifosng-provider/api/v1/users/'; + var singleEntityPrefixUrl = 'http://localhost:8080/mifosng-provider/api/v1/users/'; var singleEntityTemplateSelector = "#userFormTemplate"; var jqxhr = $.ajax({ @@ -424,8 +426,8 @@ $(document).ready(function() { $("a.edit").click( function(e) { var linkId = this.id; var entityId = linkId.replace("edit", ""); - var getUrl = 'http://localhost:8085/mifosng-provider/api/v1/users/' + entityId; - var putUrl = 'http://localhost:8085/mifosng-provider/api/v1/users/' + entityId; + var getUrl = 'http://localhost:8080/mifosng-provider/api/v1/users/' + entityId; + var putUrl = 'http://localhost:8080/mifosng-provider/api/v1/users/' + entityId; var templateSelector = "#userFormTemplate"; var width = 600; @@ -443,7 +445,7 @@ $(document).ready(function() { $("a.delete").click( function(e) { var linkId = this.id; var entityId = linkId.replace("delete", ""); - var url = 'http://localhost:8085/mifosng-provider/api/v1/users/' + entityId; + var url = 'http://localhost:8080/mifosng-provider/api/v1/users/' + entityId; showNotAvailableDialog('dialog.title.functionality.not.available'); e.preventDefault(); diff --git a/mifosng-provider/build.gradle b/mifosng-provider/build.gradle index a20c8fd2a..e7a6b94ef 100644 --- a/mifosng-provider/build.gradle +++ b/mifosng-provider/build.gradle @@ -123,6 +123,6 @@ dependencies { [tomcatRun, tomcatRunWar, tomcatStop]*.with { configFile = file('src/test/resources/META-INF/context.xml') - httpPort = 8085 + httpPort = 8080 stopPort = 8081 } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/UserCommandValidator.java b/mifosng-provider/src/main/java/org/mifosng/platform/UserCommandValidator.java deleted file mode 100644 index b86e21696..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/UserCommandValidator.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.mifosng.platform; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.commons.lang.StringUtils; -import org.mifosng.data.ErrorResponse; -import org.mifosng.data.command.UserCommand; -import org.mifosng.platform.exceptions.NewDataValidationException; - -public class UserCommandValidator { - - private final UserCommand command; - - public UserCommandValidator(UserCommand command) { - this.command = command; - } - - public void validate() { - - List dataValidationErrors = new ArrayList(); - - validateAccountSettings(dataValidationErrors); - - if (command.getOfficeId() == null || command.getOfficeId().equals(Long.valueOf(-1))) { - ErrorResponse error = new ErrorResponse("validation.msg.user.office.cannot.be.blank", "officeId"); - dataValidationErrors.add(error); - } - - if (command.getSelectedItems() == null) { - ErrorResponse error = new ErrorResponse("validation.msg.user.roles.cannot.be.blank", "selectedItems"); - dataValidationErrors.add(error); - } - - if (!dataValidationErrors.isEmpty()) { - throw new NewDataValidationException(dataValidationErrors, "Data validation errors exist."); - } - } - - public void validateAccountSettingDetails() { - List dataValidationErrors = new ArrayList(); - - validateAccountSettings(dataValidationErrors); - - if (!dataValidationErrors.isEmpty()) { - throw new NewDataValidationException(dataValidationErrors, "Data validation errors exist."); - } - } - - private void validateAccountSettings(List dataValidationErrors) { - if (StringUtils.isBlank(command.getUsername())) { - ErrorResponse error = new ErrorResponse("validation.msg.user.username.cannot.be.blank", "username"); - dataValidationErrors.add(error); - } - - if (StringUtils.isBlank(command.getFirstname())) { - ErrorResponse error = new ErrorResponse("validation.msg.user.firstname.cannot.be.blank", "firstname"); - dataValidationErrors.add(error); - } - - if (StringUtils.isBlank(command.getLastname())) { - ErrorResponse error = new ErrorResponse("validation.msg.user.lastname.cannot.be.blank", "lastname"); - dataValidationErrors.add(error); - } - - if (StringUtils.isBlank(command.getEmail())) { - ErrorResponse error = new ErrorResponse("validation.msg.user.email.cannot.be.blank", "email"); - dataValidationErrors.add(error); - } - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/WritePlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/WritePlatformService.java index 35defe45f..1a2f99079 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/WritePlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/WritePlatformService.java @@ -8,36 +8,23 @@ import org.mifosng.data.command.LoanStateTransitionCommand; import org.mifosng.data.command.LoanTransactionCommand; import org.mifosng.data.command.NoteCommand; import org.mifosng.data.command.RoleCommand; -import org.mifosng.data.command.SignupCommand; import org.mifosng.data.command.SubmitLoanApplicationCommand; import org.mifosng.data.command.UndoLoanApprovalCommand; import org.mifosng.data.command.UndoLoanDisbursalCommand; import org.mifosng.data.command.UpdateUsernamePasswordCommand; import org.mifosng.data.command.UserCommand; -import org.mifosng.platform.exceptions.InvalidSignupException; import org.springframework.security.access.prepost.PreAuthorize; public interface WritePlatformService { - Long createUser(UserCommand command); - - Long updateUser(UserCommand command); - Long updateCurrentUser(UserCommand command); Long updateCurrentUserPassword(ChangePasswordCommand command); - void deleteUser(Long userId); - Long createRole(RoleCommand command); Long updateRole(RoleCommand command); - /** - * @throws InvalidSignupException when sign up fails - */ - Long signup(SignupCommand command); - void updateUsernamePasswordOnFirstTimeLogin(UpdateUsernamePasswordCommand command); @PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_ENROLL_NEW_CLIENT_ROLE')") diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/WritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/WritePlatformServiceJpaRepositoryImpl.java index 0977d4558..37edc0696 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/WritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/WritePlatformServiceJpaRepositoryImpl.java @@ -9,13 +9,10 @@ import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.HashSet; import java.util.List; -import java.util.Set; import org.apache.commons.lang.StringUtils; import org.joda.time.LocalDate; -import org.mifosng.data.ApiParameterError; import org.mifosng.data.EntityIdentifier; import org.mifosng.data.ErrorResponse; import org.mifosng.data.LoanSchedule; @@ -29,7 +26,6 @@ import org.mifosng.data.command.LoanStateTransitionCommand; import org.mifosng.data.command.LoanTransactionCommand; import org.mifosng.data.command.NoteCommand; import org.mifosng.data.command.RoleCommand; -import org.mifosng.data.command.SignupCommand; import org.mifosng.data.command.SubmitLoanApplicationCommand; import org.mifosng.data.command.UndoLoanApprovalCommand; import org.mifosng.data.command.UndoLoanDisbursalCommand; @@ -42,11 +38,7 @@ import org.mifosng.platform.client.domain.NoteRepository; import org.mifosng.platform.currency.domain.MonetaryCurrency; import org.mifosng.platform.currency.domain.Money; import org.mifosng.platform.exceptions.ApplicationDomainRuleException; -import org.mifosng.platform.exceptions.InvalidSignupException; import org.mifosng.platform.exceptions.NoAuthorizationException; -import org.mifosng.platform.exceptions.PlatformApiDataValidationException; -import org.mifosng.platform.exceptions.PlatformDataIntegrityException; -import org.mifosng.platform.exceptions.PlatformResourceNotFoundException; import org.mifosng.platform.exceptions.UnAuthenticatedUserException; import org.mifosng.platform.infrastructure.BasicPasswordEncodablePlatformUser; import org.mifosng.platform.infrastructure.PlatformPasswordEncoder; @@ -71,9 +63,6 @@ import org.mifosng.platform.loan.domain.LoanTransactionRepository; import org.mifosng.platform.loan.domain.PeriodFrequencyType; import org.mifosng.platform.organisation.domain.Office; import org.mifosng.platform.organisation.domain.OfficeRepository; -import org.mifosng.platform.organisation.domain.Organisation; -import org.mifosng.platform.organisation.domain.OrganisationCurrency; -import org.mifosng.platform.organisation.domain.OrganisationRepository; import org.mifosng.platform.user.domain.AppUser; import org.mifosng.platform.user.domain.AppUserRepository; import org.mifosng.platform.user.domain.Permission; @@ -81,7 +70,7 @@ import org.mifosng.platform.user.domain.PermissionRepository; import org.mifosng.platform.user.domain.PlatformUserRepository; import org.mifosng.platform.user.domain.Role; import org.mifosng.platform.user.domain.RoleRepository; -import org.mifosng.platform.user.domain.UserDomainService; +import org.mifosng.platform.user.service.UserCommandValidator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.security.core.Authentication; @@ -93,9 +82,7 @@ import org.springframework.transaction.annotation.Transactional; @Service public class WritePlatformServiceJpaRepositoryImpl implements WritePlatformService { - private final OrganisationRepository organisationRepository; private final OfficeRepository officeRepository; - private final UserDomainService userDomainService; private final PlatformUserRepository platformUserRepository; private final PlatformPasswordEncoder platformPasswordEncoder; private final ClientRepository clientRepository; @@ -111,9 +98,7 @@ public class WritePlatformServiceJpaRepositoryImpl implements WritePlatformServi @Autowired public WritePlatformServiceJpaRepositoryImpl( - final OrganisationRepository organisationRepository, final OfficeRepository officeRepository, - final UserDomainService userDomainService, final PlatformUserRepository platformUserRepository, final PlatformPasswordEncoder platformPasswordEncoder, final ClientRepository clientRepository, @@ -126,9 +111,7 @@ public class WritePlatformServiceJpaRepositoryImpl implements WritePlatformServi final AppUserRepository appUserRepository, final RoleRepository roleRepository, final PermissionRepository permissionRepository) { - this.organisationRepository = organisationRepository; this.officeRepository = officeRepository; - this.userDomainService = userDomainService; this.platformUserRepository = platformUserRepository; this.platformPasswordEncoder = platformPasswordEncoder; this.clientRepository = clientRepository; @@ -143,78 +126,6 @@ public class WritePlatformServiceJpaRepositoryImpl implements WritePlatformServi this.permissionRepository = permissionRepository; } - @Transactional - @Override - public Long createUser(final UserCommand command) { - - try { - AppUser currentUser = extractAuthenticatedUser(); - - UserCommandValidator validator = new UserCommandValidator(command); - validator.validate(); - - Set allRoles = new HashSet(); - for (String roleId : command.getSelectedItems()) { - Role role = this.roleRepository.findOne(Long.valueOf(roleId)); - allRoles.add(role); - } - - Office office = this.officeRepository.findOne(command.getOfficeId()); - - AppUser appUser = AppUser.createNew(currentUser.getOrganisation(), office, - allRoles, command.getUsername(), command.getEmail(), - command.getFirstname(), command.getLastname(), - command.getPassword()); - - this.userDomainService.create(appUser); - return appUser.getId(); - } catch (DataIntegrityViolationException e) { - throw new UsernameAlreadyExistsException(e); - } - } - - @Transactional - @Override - public Long updateUser(UserCommand command) { - - try { - AppUser currentUser = extractAuthenticatedUser(); - - UserCommandValidator validator = new UserCommandValidator(command); - validator.validate(); - - List dataValidationErrors = new ArrayList(); - if (command.getId() == null) { - ApiParameterError error = ApiParameterError.parameterError("validation.msg.user.id.cannot.be.blank", "The parameter id cannot be empty.", "id"); - dataValidationErrors.add(error); - - throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); - } - - Set allRoles = new HashSet(); - for (String roleId : command.getSelectedItems()) { - Role role = this.roleRepository.findOne(Long.valueOf(roleId)); - allRoles.add(role); - } - - Office office = this.officeRepository.findOne(command.getOfficeId()); - if (office == null) { - throw new PlatformResourceNotFoundException("error.msg.office.id.invalid", "Office with identifier {0} does not exist.", command.getOfficeId()); - } - - AppUser userToUpdate = this.appUserRepository.findOne(usersThatMatch(currentUser.getOrganisation(), command.getId())); - if (userToUpdate == null) { - throw new PlatformResourceNotFoundException("error.msg.user.id.invalid", "User with identifier {0} does not exist.", command.getId()); - } - - userToUpdate.update(allRoles, office, command.getUsername(), command.getFirstname(), command.getLastname(), command.getEmail()); - - return userToUpdate.getId(); - } catch (DataIntegrityViolationException e) { - throw new PlatformDataIntegrityException("validation.msg.username.already.exists.in.organisation", "Username already exists.", "username", command.getUsername()); - } - } - @Transactional @Override public Long updateCurrentUser(UserCommand command) { @@ -254,12 +165,6 @@ public class WritePlatformServiceJpaRepositoryImpl implements WritePlatformServi return userToUpdate.getId(); } - @Transactional - @Override - public void deleteUser(Long userId) { - this.appUserRepository.delete(userId); - } - @Transactional @Override public Long createRole(final RoleCommand command) { @@ -320,30 +225,6 @@ public class WritePlatformServiceJpaRepositoryImpl implements WritePlatformServi return role.getId(); } - - @Transactional - @Override - public Long signup(final SignupCommand command) { - - try { - Organisation organisation = new Organisation( - command.getOrganisationName(), command.getOpeningDate(), - command.getContactEmail(), command.getContactName(), - new ArrayList()); - this.organisationRepository.save(organisation); - - String name = command.getOrganisationName() + " Head Office"; - String externalId = null; - Office headOffice = Office.headOffice(organisation, name, command.getOpeningDate(), externalId); - this.officeRepository.save(headOffice); - - this.userDomainService.createDefaultAdminUser(organisation, - headOffice); - return organisation.getId(); - } catch (DataIntegrityViolationException e) { - throw new InvalidSignupException(e); - } - } @Transactional @Override diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/ReportingApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/ReportingApiResource.java index 0f6a8c420..a59447013 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/ReportingApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/ReportingApiResource.java @@ -4,18 +4,14 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; -import javax.servlet.http.HttpServletResponse; import javax.ws.rs.Consumes; import javax.ws.rs.GET; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.OPTIONS; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.ResponseBuilder; import javax.ws.rs.core.StreamingOutput; import javax.ws.rs.core.UriInfo; @@ -38,57 +34,25 @@ public class ReportingApiResource { @Autowired private ReadExtraDataAndReportingService ReadExtraDataAndReportingService; - private String _corsHeaders; - - private Response makeCORS(ResponseBuilder req, String returnMethod) { - ResponseBuilder rb = req.header("Access-Control-Allow-Origin", "*") - .header("Access-Control-Allow-Methods", "GET, POST, OPTIONS"); - - if (!"".equals(returnMethod)) { - rb.header("Access-Control-Allow-Headers", returnMethod); - } - - return rb.build(); - } - - private Response makeCORS(ResponseBuilder req) { - return makeCORS(req, _corsHeaders); - } - - private Response makeCORSExport(ResponseBuilder req, String exportFilename, - String returnMethod) { - ResponseBuilder rb = req - .header("Access-Control-Allow-Origin", "*") - .header("Access-Control-Allow-Methods", "GET, POST, OPTIONS") - .header("Content-Disposition", - "attachment;filename=" + exportFilename); - - if (!"".equals(returnMethod)) { - rb.header("Access-Control-Allow-Headers", returnMethod); - } - - return rb.build(); - } - - private Response makeCORSExport(ResponseBuilder req, String exportFilename) { - return makeCORSExport(req, exportFilename, _corsHeaders); - } - - // This OPTIONS request/response is necessary - // if you consumes other format than text/plain or - // if you use other HTTP verbs than GET and POST - @OPTIONS - public Response corsMyResource( - @HeaderParam("Access-Control-Request-Headers") String requestH) { - _corsHeaders = requestH; - return makeCORS(Response.ok(), requestH); - } +// private Response makeCORSExport(ResponseBuilder req, String exportFilename, +// String returnMethod) { +// ResponseBuilder rb = req +// .header("Access-Control-Allow-Origin", "*") +// .header("Access-Control-Allow-Methods", "GET, POST, OPTIONS") +// .header("Content-Disposition", +// "attachment;filename=" + exportFilename); +// +// if (!"".equals(returnMethod)) { +// rb.header("Access-Control-Allow-Headers", returnMethod); +// } +// +// return rb.build(); +// } @GET @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @Produces({ MediaType.APPLICATION_JSON, "application/x-msdownload" }) - public Response retrieveReport(@Context UriInfo uriInfo, - @Context HttpServletResponse httpServletResponse) { + public Response retrieveReport(@Context UriInfo uriInfo) { MultivaluedMap queryParams = uriInfo .getQueryParameters(); @@ -115,17 +79,15 @@ public class ReportingApiResource { if ((exportCSV == null) || (!(exportCSV.equalsIgnoreCase("true")))) { GenericResultset result = this.ReadExtraDataAndReportingService .retrieveGenericResultset(name, type, extractedQueryParams); - return makeCORS(Response.ok().entity(result)); - } else { - StreamingOutput result = this.ReadExtraDataAndReportingService - .retrieveReportCSV(name, type, extractedQueryParams); - - return makeCORSExport(Response.ok().entity(result), - name.replaceAll(" ", "") + ".csv"); - } + + return Response.ok().entity(result).build(); + } + + StreamingOutput result = this.ReadExtraDataAndReportingService.retrieveReportCSV(name, type, extractedQueryParams); + return Response.ok().entity(result).header("Content-Disposition","attachment;filename=" + name.replaceAll(" ", "") + ".csv").build(); } - + @GET @Path("forceauth") public Response hackToForceAuthentication() { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/user/UserApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/user/UserApiResource.java index 748387b15..f4c9565ab 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/user/UserApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/user/UserApiResource.java @@ -3,7 +3,6 @@ package org.mifosng.platform.api.user; import java.util.Arrays; import java.util.Collection; -import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; @@ -13,7 +12,6 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; @@ -23,20 +21,16 @@ import org.mifosng.data.EntityIdentifier; import org.mifosng.data.ErrorResponse; import org.mifosng.data.ErrorResponseList; import org.mifosng.data.UserList; -import org.mifosng.data.command.ChangePasswordCommand; import org.mifosng.data.command.UserCommand; import org.mifosng.platform.ReadPlatformService; -import org.mifosng.platform.WritePlatformService; import org.mifosng.platform.exceptions.ApplicationDomainRuleException; import org.mifosng.platform.exceptions.NewDataValidationException; import org.mifosng.platform.exceptions.UnAuthenticatedUserException; import org.mifosng.platform.user.domain.AppUser; import org.mifosng.platform.user.domain.AppUserRepository; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.mifosng.platform.user.service.AppUserWritePlatformService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; -import org.springframework.dao.DataIntegrityViolationException; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; @@ -49,13 +43,11 @@ import org.springframework.stereotype.Component; @Scope("singleton") public class UserApiResource { - private final static Logger logger = LoggerFactory.getLogger(UserApiResource.class); - @Autowired private ReadPlatformService readPlatformService; @Autowired - private WritePlatformService writePlatformService; + private AppUserWritePlatformService appUserWritePlatformService; @Autowired private AppUserRepository appUserRepository; @@ -108,32 +100,11 @@ public class UserApiResource { @POST @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) @Produces({ MediaType.APPLICATION_JSON}) - public Response createUser(@Context HttpServletRequest request) { + public Response createUser(UserCommand command) { -// try { - String selectedItems = request.getParameter("selectedItems"); - final UserCommand command = new UserCommand(); -// command.setSelectedItems(Arrays.asList(a)); - hardcodeUserIntoSecurityContext(); - Long userId = this.writePlatformService.createUser(command); + Long userId = this.appUserWritePlatformService.createUser(command); return Response.ok().entity(new EntityIdentifier(userId)).build(); -// } catch (UsernameAlreadyExistsException e) { -// List allErrors = new ArrayList(); -// ErrorResponse err = new ErrorResponse("validation.msg.username.already.exists.in.organisation", "username", command.getUsername()); -// allErrors.add(err); -// -// throw new WebApplicationException(Response -// .status(Status.BAD_REQUEST) -// .entity(new ErrorResponseList(allErrors)).build()); -// } catch (PlatformEmailSendException e) { -// List allErrors = new ArrayList(); -// ErrorResponse err = new ErrorResponse("error.msg.user.email.invalid","email", "Email is invalid."); -// allErrors.add(err); -// throw new WebApplicationException(Response -// .status(Status.BAD_REQUEST) -// .entity(new ErrorResponseList(allErrors)).build()); -// } } @DELETE @@ -143,7 +114,7 @@ public class UserApiResource { public Response deleteUser(@PathParam("userId") final Long userId) { try { - this.writePlatformService.deleteUser(userId); + this.appUserWritePlatformService.deleteUser(userId); return Response.ok().build(); } catch (UnAuthenticatedUserException e) { @@ -167,11 +138,9 @@ public class UserApiResource { hardcodeUserIntoSecurityContext(); -// UserCommand command = new UserCommand(); -// command.setSelectedItems(new ArrayList(commandEile.getSelectedItems())); command.setId(userId); - this.writePlatformService.updateUser(command); + this.appUserWritePlatformService.updateUser(command); return Response.ok().entity(new EntityIdentifier(userId)).build(); } @@ -201,57 +170,57 @@ public class UserApiResource { } } - @POST - @Path("user/current") - @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) - public Response updateCurrentUser(UserCommand command) { - - try { - hardcodeUserIntoSecurityContext(); - - Long userId = this.writePlatformService.updateCurrentUser(command); - - return Response.ok().entity(new EntityIdentifier(userId)).build(); - } catch (UnAuthenticatedUserException e) { - throw new WebApplicationException(Response.status(Status.UNAUTHORIZED).build()); - } catch (AccessDeniedException e) { - ErrorResponse errorResponse = new ErrorResponse("error.msg.no.permission", "id"); - ErrorResponseList list = new ErrorResponseList(Arrays.asList(errorResponse)); - throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(list).build()); - } catch (ApplicationDomainRuleException e) { - throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getErrors())).build()); - } catch (NewDataValidationException e) { - throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getValidationErrors())).build()); - } catch (DataIntegrityViolationException e) { - ErrorResponse errorResponse = new ErrorResponse("error.msg.username.already.exists.in.organisation", "username", command.getUsername()); - ErrorResponseList list = new ErrorResponseList(Arrays.asList(errorResponse)); - throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(list).build()); - } - } - - @POST - @Path("user/current/password") - @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) - public Response updateCurrentUserPassword(ChangePasswordCommand command) { - - try { - hardcodeUserIntoSecurityContext(); - - Long userId = this.writePlatformService.updateCurrentUserPassword(command); - - return Response.ok().entity(new EntityIdentifier(userId)).build(); - } catch (UnAuthenticatedUserException e) { - throw new WebApplicationException(Response.status(Status.UNAUTHORIZED).build()); - } catch (AccessDeniedException e) { - ErrorResponse errorResponse = new ErrorResponse("error.msg.no.permission", "id"); - ErrorResponseList list = new ErrorResponseList(Arrays.asList(errorResponse)); - throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(list).build()); - } catch (ApplicationDomainRuleException e) { - throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getErrors())).build()); - } catch (NewDataValidationException e) { - throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getValidationErrors())).build()); - } - } +// @POST +// @Path("user/current") +// @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) +// @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) +// public Response updateCurrentUser(UserCommand command) { +// +// try { +// hardcodeUserIntoSecurityContext(); +// +// Long userId = this.appUserWritePlatformService.updateCurrentUser(command); +// +// return Response.ok().entity(new EntityIdentifier(userId)).build(); +// } catch (UnAuthenticatedUserException e) { +// throw new WebApplicationException(Response.status(Status.UNAUTHORIZED).build()); +// } catch (AccessDeniedException e) { +// ErrorResponse errorResponse = new ErrorResponse("error.msg.no.permission", "id"); +// ErrorResponseList list = new ErrorResponseList(Arrays.asList(errorResponse)); +// throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(list).build()); +// } catch (ApplicationDomainRuleException e) { +// throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getErrors())).build()); +// } catch (NewDataValidationException e) { +// throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getValidationErrors())).build()); +// } catch (DataIntegrityViolationException e) { +// ErrorResponse errorResponse = new ErrorResponse("error.msg.username.already.exists.in.organisation", "username", command.getUsername()); +// ErrorResponseList list = new ErrorResponseList(Arrays.asList(errorResponse)); +// throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(list).build()); +// } +// } +// +// @POST +// @Path("user/current/password") +// @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) +// @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) +// public Response updateCurrentUserPassword(ChangePasswordCommand command) { +// +// try { +// hardcodeUserIntoSecurityContext(); +// +// Long userId = this.appUserWritePlatformService.updateCurrentUserPassword(command); +// +// return Response.ok().entity(new EntityIdentifier(userId)).build(); +// } catch (UnAuthenticatedUserException e) { +// throw new WebApplicationException(Response.status(Status.UNAUTHORIZED).build()); +// } catch (AccessDeniedException e) { +// ErrorResponse errorResponse = new ErrorResponse("error.msg.no.permission", "id"); +// ErrorResponseList list = new ErrorResponseList(Arrays.asList(errorResponse)); +// throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(list).build()); +// } catch (ApplicationDomainRuleException e) { +// throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getErrors())).build()); +// } catch (NewDataValidationException e) { +// throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getValidationErrors())).build()); +// } +// } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/SignupController.java b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/SignupController.java index c83f79186..f393bebff 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/SignupController.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/SignupController.java @@ -16,6 +16,7 @@ import org.springframework.web.bind.support.SessionStatus; import org.springframework.web.servlet.ModelAndView; /** + * FIXMED - REMOVE DEPRECATED CONTROLLER and related code artifacts * @deprecated - remove signup functionality for now. */ @Deprecated @@ -95,7 +96,8 @@ public class SignupController { ModelAndView mav = null; try { - signupPlatformService.signup(command); + // REMOVED +// signupPlatformService.signup(command); status.setComplete(); mav = new ModelAndView("/tenant/signupsuccess", "signupFormBean", diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeWritePlatformService.java index 8c41deb9b..ef32854ad 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeWritePlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeWritePlatformService.java @@ -4,7 +4,7 @@ import org.mifosng.data.command.OfficeCommand; public interface OfficeWritePlatformService { - Long createOffice(OfficeCommand command); - - Long updateOffice(OfficeCommand command); + Long createOffice(final OfficeCommand command); + + Long updateOffice(final OfficeCommand command); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeWritePlatformServiceJpaRepositoryImpl.java index f858dd73f..5af27656a 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeWritePlatformServiceJpaRepositoryImpl.java @@ -7,6 +7,7 @@ import org.mifosng.platform.exceptions.NoAuthorizationException; import org.mifosng.platform.exceptions.PlatformDataIntegrityException; import org.mifosng.platform.organisation.domain.Office; import org.mifosng.platform.organisation.domain.OfficeRepository; +import org.mifosng.platform.organisation.service.OfficeCommandValidator; import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosng.platform.user.domain.AppUser; import org.slf4j.Logger; @@ -49,7 +50,7 @@ public class OfficeWritePlatformServiceJpaRepositoryImpl implements OfficeWriteP office.generateHierarchy(); - this.officeRepository.save(office); + this.officeRepository.saveAndFlush(office); return office.getId(); } catch (DataIntegrityViolationException dve) { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/rest/UserAdmistrationResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/rest/UserAdmistrationResource.java index e337604cb..df682a21c 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/rest/UserAdmistrationResource.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/rest/UserAdmistrationResource.java @@ -3,10 +3,8 @@ package org.mifosng.platform.rest; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.List; import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; @@ -27,17 +25,14 @@ import org.mifosng.data.PermissionData; import org.mifosng.data.PermissionList; import org.mifosng.data.RoleData; import org.mifosng.data.RoleList; -import org.mifosng.data.UserList; import org.mifosng.data.command.ChangePasswordCommand; import org.mifosng.data.command.RoleCommand; import org.mifosng.data.command.UserCommand; import org.mifosng.platform.ReadPlatformService; import org.mifosng.platform.WritePlatformService; import org.mifosng.platform.exceptions.ApplicationDomainRuleException; -import org.mifosng.platform.exceptions.UnAuthenticatedUserException; import org.mifosng.platform.exceptions.NewDataValidationException; -import org.mifosng.platform.infrastructure.PlatformEmailSendException; -import org.mifosng.platform.infrastructure.UsernameAlreadyExistsException; +import org.mifosng.platform.exceptions.UnAuthenticatedUserException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.dao.DataIntegrityViolationException; @@ -55,158 +50,6 @@ public class UserAdmistrationResource { @Autowired private WritePlatformService writePlatformService; - @GET - @Path("user/all") - @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) - @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) - public Response retrieveUsers() { - - try { - Collection users = this.readPlatformService.retrieveAllUsers(); - - return Response.ok().entity(new UserList(users)).build(); - } catch (UnAuthenticatedUserException e) { - throw new WebApplicationException(Response.status(Status.UNAUTHORIZED).build()); - } catch (AccessDeniedException e) { - ErrorResponse errorResponse = new ErrorResponse("error.msg.no.permission", "id"); - ErrorResponseList list = new ErrorResponseList(Arrays.asList(errorResponse)); - throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(list).build()); - } catch (ApplicationDomainRuleException e) { - throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getErrors())).build()); - } catch (NewDataValidationException e) { - throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getValidationErrors())).build()); - } - } - - @GET - @Path("user/new") - @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) - public Response newUserDetails() { - - try { - AppUserData newUser = this.readPlatformService.retrieveNewUserDetails(); - - return Response.ok().entity(newUser).build(); - } catch (UnAuthenticatedUserException e) { - throw new WebApplicationException(Response.status(Status.UNAUTHORIZED).build()); - } catch (AccessDeniedException e) { - ErrorResponse errorResponse = new ErrorResponse("error.msg.no.permission", "id"); - ErrorResponseList list = new ErrorResponseList(Arrays.asList(errorResponse)); - throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(list).build()); - } catch (ApplicationDomainRuleException e) { - throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getErrors())).build()); - } catch (NewDataValidationException e) { - throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getValidationErrors())).build()); - } - } - - @POST - @Path("user/new") - @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) - public Response createUser(final UserCommand command) { - - try { - Long userId = this.writePlatformService.createUser(command); - return Response.ok().entity(new EntityIdentifier(userId)).build(); - } catch (UsernameAlreadyExistsException e) { - List allErrors = new ArrayList(); - ErrorResponse err = new ErrorResponse("validation.msg.username.already.exists.in.organisation", "username", command.getUsername()); - allErrors.add(err); - - throw new WebApplicationException(Response - .status(Status.BAD_REQUEST) - .entity(new ErrorResponseList(allErrors)).build()); - } catch (PlatformEmailSendException e) { - List allErrors = new ArrayList(); - ErrorResponse err = new ErrorResponse("error.msg.user.email.invalid","email", "Email is invalid."); - allErrors.add(err); - throw new WebApplicationException(Response - .status(Status.BAD_REQUEST) - .entity(new ErrorResponseList(allErrors)).build()); - } catch (UnAuthenticatedUserException e) { - throw new WebApplicationException(Response.status(Status.UNAUTHORIZED).build()); - } catch (AccessDeniedException e) { - ErrorResponse errorResponse = new ErrorResponse("error.msg.no.permission", "id"); - ErrorResponseList list = new ErrorResponseList(Arrays.asList(errorResponse)); - throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(list).build()); - } catch (ApplicationDomainRuleException e) { - throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getErrors())).build()); - } catch (NewDataValidationException e) { - throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getValidationErrors())).build()); - } - } - - @DELETE - @Path("user/{userId}") - @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) - public Response deleteUser(@PathParam("userId") final Long userId) { - - try { - this.writePlatformService.deleteUser(userId); - - return Response.ok().build(); - } catch (UnAuthenticatedUserException e) { - throw new WebApplicationException(Response.status(Status.UNAUTHORIZED).build()); - } catch (AccessDeniedException e) { - ErrorResponse errorResponse = new ErrorResponse("error.msg.no.permission", "id"); - ErrorResponseList list = new ErrorResponseList(Arrays.asList(errorResponse)); - throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(list).build()); - } catch (ApplicationDomainRuleException e) { - throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getErrors())).build()); - } catch (NewDataValidationException e) { - throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getValidationErrors())).build()); - } - } - - @GET - @Path("user/{userId}") - @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) - public Response retrieveUser(@PathParam("userId") final Long userId) { - - try { - AppUserData user = this.readPlatformService.retrieveUser(userId); - - return Response.ok().entity(user).build(); - } catch (UnAuthenticatedUserException e) { - throw new WebApplicationException(Response.status(Status.UNAUTHORIZED).build()); - } catch (AccessDeniedException e) { - ErrorResponse errorResponse = new ErrorResponse("error.msg.no.permission", "id"); - ErrorResponseList list = new ErrorResponseList(Arrays.asList(errorResponse)); - throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(list).build()); - } catch (ApplicationDomainRuleException e) { - throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getErrors())).build()); - } catch (NewDataValidationException e) { - throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getValidationErrors())).build()); - } - } - - @POST - @Path("user/{userId}") - @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) - public Response updateUser(UserCommand command) { - - try { - Long userId = this.writePlatformService.updateUser(command); - - return Response.ok().entity(new EntityIdentifier(userId)).build(); - } catch (UnAuthenticatedUserException e) { - throw new WebApplicationException(Response.status(Status.UNAUTHORIZED).build()); - } catch (AccessDeniedException e) { - ErrorResponse errorResponse = new ErrorResponse("error.msg.no.permission", "id"); - ErrorResponseList list = new ErrorResponseList(Arrays.asList(errorResponse)); - throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(list).build()); - } catch (ApplicationDomainRuleException e) { - throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getErrors())).build()); - } catch (NewDataValidationException e) { - throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getValidationErrors())).build()); - } - } - @GET @Path("user/current") @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) 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 c12fea14e..cac09ee2f 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 @@ -25,7 +25,7 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.User; @Entity -@Table(name = "admin_appuser", uniqueConstraints=@UniqueConstraint(columnNames = {"org_id", "username"})) +@Table(name = "admin_appuser", uniqueConstraints=@UniqueConstraint(columnNames = {"org_id", "username"}, name="username_org")) public class AppUser extends AbstractAuditableCustom implements PlatformUser { @Column(name = "email", nullable=false, length=100) @@ -81,6 +81,8 @@ public class AppUser extends AbstractAuditableCustom implements P boolean userAccountNonLocked = true; Collection authorities = new ArrayList(); + authorities.add(new SimpleGrantedAuthority("DUMMY_ROLE_NOT_USED_OR_PERSISTED_TO_AVOID_EXCEPTION")); + User user = new User(username, password, userEnabled, userAccountNonExpired, userCredentialsNonExpired, userAccountNonLocked, authorities); return new AppUser(organisation, office, user, allRoles, email, firstname, lastname); } 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 new file mode 100644 index 000000000..39106edc8 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/AppUserWritePlatformService.java @@ -0,0 +1,12 @@ +package org.mifosng.platform.user.service; + +import org.mifosng.data.command.UserCommand; + +public interface AppUserWritePlatformService { + + Long createUser(final UserCommand command); + + Long updateUser(final UserCommand command); + + void deleteUser(final Long userId); +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/user/service/AppUserWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/AppUserWritePlatformServiceJpaRepositoryImpl.java new file mode 100644 index 000000000..0cc4755de --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/AppUserWritePlatformServiceJpaRepositoryImpl.java @@ -0,0 +1,159 @@ +package org.mifosng.platform.user.service; + +import static org.mifosng.platform.Specifications.usersThatMatch; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.mifosng.data.ApiParameterError; +import org.mifosng.data.command.UserCommand; +import org.mifosng.platform.exceptions.PlatformApiDataValidationException; +import org.mifosng.platform.exceptions.PlatformDataIntegrityException; +import org.mifosng.platform.exceptions.PlatformResourceNotFoundException; +import org.mifosng.platform.infrastructure.PlatformEmailSendException; +import org.mifosng.platform.organisation.domain.Office; +import org.mifosng.platform.organisation.domain.OfficeRepository; +import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosng.platform.user.domain.AppUser; +import org.mifosng.platform.user.domain.AppUserRepository; +import org.mifosng.platform.user.domain.Role; +import org.mifosng.platform.user.domain.RoleRepository; +import org.mifosng.platform.user.domain.UserDomainService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class AppUserWritePlatformServiceJpaRepositoryImpl implements AppUserWritePlatformService { + + private final static Logger logger = LoggerFactory.getLogger(AppUserWritePlatformServiceJpaRepositoryImpl.class); + + private final PlatformSecurityContext context; + private final AppUserRepository appUserRepository; + private final OfficeRepository officeRepository; + private final RoleRepository roleRepository; + private final UserDomainService userDomainService; + + @Autowired + public AppUserWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final AppUserRepository appUserRepository, final UserDomainService userDomainService, + final OfficeRepository officeRepository, final RoleRepository roleRepository) { + this.context = context; + this.appUserRepository = appUserRepository; + this.userDomainService = userDomainService; + this.officeRepository = officeRepository; + this.roleRepository = roleRepository; + } + + @Transactional + @Override + public Long createUser(final UserCommand command) { + + try { + AppUser currentUser = context.authenticatedUser(); + + UserCommandValidator validator = new UserCommandValidator(command); + validator.validate(); + + Set allRoles = new HashSet(); + for (String roleId : command.getSelectedItems()) { + Role role = this.roleRepository.findOne(Long.valueOf(roleId)); + allRoles.add(role); + } + + Office office = this.officeRepository.findOne(command.getOfficeId()); + + String password = command.getPassword(); + if (StringUtils.isBlank(password)) { + password = "autogenerate"; + } + + AppUser appUser = AppUser.createNew(currentUser.getOrganisation(), office, + allRoles, command.getUsername(), command.getEmail(), + command.getFirstname(), command.getLastname(), + password); + + this.userDomainService.create(appUser); + + return appUser.getId(); + } catch (DataIntegrityViolationException dve) { + handleOfficeDataIntegrityIssues(command, dve); + return Long.valueOf(-1); + } catch (PlatformEmailSendException e) { + List dataValidationErrors = new ArrayList(); + ApiParameterError error = ApiParameterError.parameterError("error.msg.user.email.invalid", "The parameter email is invalid.", "email", command.getEmail()); + dataValidationErrors.add(error); + + throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); + } + } + + @Transactional + @Override + public Long updateUser(UserCommand command) { + + try { + AppUser currentUser = context.authenticatedUser(); + + UserCommandValidator validator = new UserCommandValidator(command); + validator.validate(); + + List dataValidationErrors = new ArrayList(); + if (command.getId() == null) { + ApiParameterError error = ApiParameterError.parameterError("validation.msg.user.id.cannot.be.blank", "The parameter id cannot be empty.", "id"); + dataValidationErrors.add(error); + + throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); + } + + Set allRoles = new HashSet(); + for (String roleId : command.getSelectedItems()) { + Role role = this.roleRepository.findOne(Long.valueOf(roleId)); + allRoles.add(role); + } + + Office office = this.officeRepository.findOne(command.getOfficeId()); + if (office == null) { + throw new PlatformResourceNotFoundException("error.msg.office.id.invalid", "Office with identifier {0} does not exist.", command.getOfficeId()); + } + + AppUser userToUpdate = this.appUserRepository.findOne(usersThatMatch(currentUser.getOrganisation(), command.getId())); + if (userToUpdate == null) { + throw new PlatformResourceNotFoundException("error.msg.user.id.invalid", "User with identifier {0} does not exist.", command.getId()); + } + + userToUpdate.update(allRoles, office, command.getUsername(), command.getFirstname(), command.getLastname(), command.getEmail()); + this.appUserRepository.saveAndFlush(userToUpdate); + + return userToUpdate.getId(); + } catch (DataIntegrityViolationException dve) { + handleOfficeDataIntegrityIssues(command, dve); + return Long.valueOf(-1); + } + } + + @Transactional + @Override + public void deleteUser(Long userId) { + this.appUserRepository.delete(userId); + } + + /* + * Guaranteed to throw an exception no matter what the data integrity issue is. + */ + private void handleOfficeDataIntegrityIssues(final UserCommand command, DataIntegrityViolationException dve) { + + Throwable realCause = dve.getMostSpecificCause(); + if (realCause.getMessage().contains("username_org")) { + throw new PlatformDataIntegrityException("error.msg.user.duplicate.username", "User with username {0} already exists", "username", command.getUsername()); + } + + logger.error(dve.getMessage(), dve); + throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue", "Unknown data integrity issue with resource."); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/user/service/UserCommandValidator.java b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/UserCommandValidator.java new file mode 100644 index 000000000..db14ed96a --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/UserCommandValidator.java @@ -0,0 +1,72 @@ +package org.mifosng.platform.user.service; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.mifosng.data.ApiParameterError; +import org.mifosng.data.command.UserCommand; +import org.mifosng.platform.exceptions.PlatformApiDataValidationException; +import org.springframework.util.ObjectUtils; + +public class UserCommandValidator { + + private final UserCommand command; + + public UserCommandValidator(UserCommand command) { + this.command = command; + } + + public void validate() { + + List dataValidationErrors = new ArrayList(); + + validateAccountSettings(dataValidationErrors); + + if (command.getOfficeId() == null || command.getOfficeId().equals(Long.valueOf(-1))) { + ApiParameterError error = ApiParameterError.parameterError("validation.msg.user.office.cannot.be.blank", "The parameter officeId cannot be blank.", "officeId"); + dataValidationErrors.add(error); + } + + if (ObjectUtils.isEmpty(command.getSelectedItems())) { + ApiParameterError error = ApiParameterError.parameterError("validation.msg.user.roles.cannot.be.blank", "The parameter selectedItems cannot be blank.", "selectedItems"); + dataValidationErrors.add(error); + } + + if (!dataValidationErrors.isEmpty()) { + throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); + } + } + + public void validateAccountSettingDetails() { + List dataValidationErrors = new ArrayList(); + + validateAccountSettings(dataValidationErrors); + + if (!dataValidationErrors.isEmpty()) { + throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); + } + } + + private void validateAccountSettings(List dataValidationErrors) { + if (StringUtils.isBlank(command.getUsername())) { + ApiParameterError error = ApiParameterError.parameterError("validation.msg.user.username.cannot.be.blank", "The parameter username cannot be blank.", "username"); + dataValidationErrors.add(error); + } + + if (StringUtils.isBlank(command.getFirstname())) { + ApiParameterError error = ApiParameterError.parameterError("validation.msg.user.firstname.cannot.be.blank", "The parameter firstname cannot be blank.", "firstname"); + dataValidationErrors.add(error); + } + + if (StringUtils.isBlank(command.getLastname())) { + ApiParameterError error = ApiParameterError.parameterError("validation.msg.user.lastname.cannot.be.blank", "The parameter lastname cannot be blank.", "lastname"); + dataValidationErrors.add(error); + } + + if (StringUtils.isBlank(command.getEmail())) { + ApiParameterError error = ApiParameterError.parameterError("validation.msg.user.email.cannot.be.blank", "The parameter email cannot be blank.", "email"); + dataValidationErrors.add(error); + } + } +} \ No newline at end of file