Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 7A5E6200CD3 for ; Fri, 28 Jul 2017 16:28:38 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 78AA916C0EF; Fri, 28 Jul 2017 14:28:38 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 76E5316C0BC for ; Fri, 28 Jul 2017 16:28:36 +0200 (CEST) Received: (qmail 79495 invoked by uid 500); 28 Jul 2017 14:28:35 -0000 Mailing-List: contact commits-help@fineract.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@fineract.apache.org Delivered-To: mailing list commits@fineract.apache.org Received: (qmail 79486 invoked by uid 99); 28 Jul 2017 14:28:35 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 28 Jul 2017 14:28:35 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 059DCE112D; Fri, 28 Jul 2017 14:28:35 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: nazeer1100126@apache.org To: commits@fineract.apache.org Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: fineract git commit: self service registration Date: Fri, 28 Jul 2017 14:28:35 +0000 (UTC) archived-at: Fri, 28 Jul 2017 14:28:38 -0000 Repository: fineract Updated Branches: refs/heads/develop 0f98cbbed -> afdc665b5 self service registration Project: http://git-wip-us.apache.org/repos/asf/fineract/repo Commit: http://git-wip-us.apache.org/repos/asf/fineract/commit/afdc665b Tree: http://git-wip-us.apache.org/repos/asf/fineract/tree/afdc665b Diff: http://git-wip-us.apache.org/repos/asf/fineract/diff/afdc665b Branch: refs/heads/develop Commit: afdc665b52e599e7aa2c3f238c7e77528a63451b Parents: 0f98cbb Author: nazeer shaik Authored: Tue Jul 25 20:22:10 2017 +0530 Committer: nazeer shaik Committed: Tue Jul 25 20:22:10 2017 +0530 ---------------------------------------------------------------------- .../infrastructure/core/api/JsonCommand.java | 23 ++ .../client/domain/ClientRepository.java | 8 +- .../client/domain/ClientRepositoryWrapper.java | 9 +- .../exception/ClientNotFoundException.java | 8 + .../registration/SelfServiceApiConstants.java | 48 +++ .../api/SelfServiceRegistrationApiResource.java | 68 +++++ .../data/SelfServiceRegistrationData.java | 70 +++++ .../domain/SelfServiceRegistration.java | 131 +++++++++ .../SelfServiceRegistrationRepository.java | 36 +++ ...elfServiceRegistrationNotFoundException.java | 30 ++ ...fServiceRegistrationReadPlatformService.java | 26 ++ ...viceRegistrationReadPlatformServiceImpl.java | 50 ++++ ...ServiceRegistrationWritePlatformService.java | 29 ++ ...iceRegistrationWritePlatformServiceImpl.java | 293 +++++++++++++++++++ .../service/AppUserReadPlatformService.java | 2 + .../service/AppUserReadPlatformServiceImpl.java | 9 + .../META-INF/spring/securityContext.xml | 4 + .../V332__self_service_registration_schema.sql | 38 +++ 18 files changed, 880 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/fineract/blob/afdc665b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/api/JsonCommand.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/api/JsonCommand.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/api/JsonCommand.java index 9b8356d..76f30c6 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/api/JsonCommand.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/api/JsonCommand.java @@ -122,6 +122,29 @@ public final class JsonCommand { this.organisationCreditBureauId=organisationCreditBureauId; } + public static JsonCommand fromJsonElement(final Long resourceId, final JsonElement parsedCommand) { + return new JsonCommand(resourceId, parsedCommand); + } + + public JsonCommand(final Long resourceId, final JsonElement parsedCommand) { + this.parsedCommand = parsedCommand; + this.resourceId = resourceId; + this.commandId = null; + this.jsonCommand = null; + this.fromApiJsonHelper = null; + this.entityName = null; + this.subresourceId = null; + this.groupId = null; + this.clientId = null; + this.loanId = null; + this.savingsId = null; + this.transactionId = null; + this.url = null; + this.productId = null; + this.creditBureauId=null; + this.organisationCreditBureauId=null; + } + public Long getOrganisationCreditBureauId() { return this.organisationCreditBureauId; } http://git-wip-us.apache.org/repos/asf/fineract/blob/afdc665b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientRepository.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientRepository.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientRepository.java index e718265..eb2714c 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientRepository.java @@ -20,7 +20,13 @@ package org.apache.fineract.portfolio.client.domain; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; abstract interface ClientRepository extends JpaRepository, JpaSpecificationExecutor { - // no added behaviour + + public static final String FIND_CLIENT_BY_ACCOUNT_NUMBER = "select client from Client client where client.accountNumber = :accountNumber"; + + @Query(FIND_CLIENT_BY_ACCOUNT_NUMBER) + Client getClientByAccountNumber(@Param("accountNumber") String accountNumber); } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/fineract/blob/afdc665b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientRepositoryWrapper.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientRepositoryWrapper.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientRepositoryWrapper.java index f4231d1..b3e8e9e 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientRepositoryWrapper.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientRepositoryWrapper.java @@ -85,5 +85,12 @@ public class ClientRepositoryWrapper { this.context.validateAccessRights(client.getOffice().getHierarchy()); return client; } - + + public Client getClientByAccountNumber(String accountNumber){ + Client client = this.repository.getClientByAccountNumber(accountNumber); + if(client==null){ + throw new ClientNotFoundException(accountNumber); + } + return client; + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/fineract/blob/afdc665b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/exception/ClientNotFoundException.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/exception/ClientNotFoundException.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/exception/ClientNotFoundException.java index 7a6f034..1c182d4 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/exception/ClientNotFoundException.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/exception/ClientNotFoundException.java @@ -28,4 +28,12 @@ public class ClientNotFoundException extends AbstractPlatformResourceNotFoundExc public ClientNotFoundException(final Long id) { super("error.msg.client.id.invalid", "Client with identifier " + id + " does not exist", id); } + + public ClientNotFoundException() { + super("error.msg.client.not.found.with.basic.details", "Client not found with basic details."); + } + + public ClientNotFoundException(String accountNumber) { + super("error.msg.client.not.found.with.account.number", "Client not found with account number "+accountNumber+"."); + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/fineract/blob/afdc665b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/SelfServiceApiConstants.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/SelfServiceApiConstants.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/SelfServiceApiConstants.java new file mode 100644 index 0000000..2362523 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/SelfServiceApiConstants.java @@ -0,0 +1,48 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.portfolio.self.registration; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +public class SelfServiceApiConstants { + + public static final String accountNumberParamName = "accountNumber"; + public static final String passwordParamName = "password"; + public static final String firstNameParamName = "firstName"; + public static final String mobileNumberParamName = "mobileNumber"; + public static final String lastNameParamName = "lastName"; + public static final String emailParamName = "email"; + public static final String usernameParamName = "username"; + public static final String authenticationTokenParamName = "authenticationToken"; + public static final String authenticationModeParamName = "authenticationMode"; + public static final String emailModeParamName = "email"; + public static final String mobileModeParamName = "mobile"; + public static final String requestIdParamName = "requestId"; + public static final String createRequestSuccessMessage = "Self service request created."; + public static final Set REGISTRATION_REQUEST_DATA_PARAMETERS = new HashSet<>(Arrays.asList(usernameParamName, + accountNumberParamName, passwordParamName, firstNameParamName, mobileNumberParamName, lastNameParamName, emailParamName, + authenticationModeParamName)); + public static final Set CREATE_USER_REQUEST_DATA_PARAMETERS = new HashSet<>(Arrays.asList(requestIdParamName, + authenticationTokenParamName)); + public static final Object[] SUPPORTED_AUTHENTICATION_MODE_PARAMETERS = new Object[] {emailModeParamName, + mobileModeParamName}; + +} http://git-wip-us.apache.org/repos/asf/fineract/blob/afdc665b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/api/SelfServiceRegistrationApiResource.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/api/SelfServiceRegistrationApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/api/SelfServiceRegistrationApiResource.java new file mode 100644 index 0000000..64dcfa9 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/api/SelfServiceRegistrationApiResource.java @@ -0,0 +1,68 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.fineract.portfolio.self.registration.api; + +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; +import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer; +import org.apache.fineract.portfolio.note.data.NoteData; +import org.apache.fineract.portfolio.self.registration.SelfServiceApiConstants; +import org.apache.fineract.portfolio.self.registration.service.SelfServiceRegistrationWritePlatformService; +import org.apache.fineract.useradministration.domain.AppUser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +@Path("/self/registration") +@Component +@Scope("singleton") +public class SelfServiceRegistrationApiResource { + + private final SelfServiceRegistrationWritePlatformService selfServiceRegistrationWritePlatformService; + private final DefaultToApiJsonSerializer toApiJsonSerializer; + + @Autowired + public SelfServiceRegistrationApiResource( + final SelfServiceRegistrationWritePlatformService selfServiceRegistrationWritePlatformService, + final DefaultToApiJsonSerializer toApiJsonSerializer) { + this.selfServiceRegistrationWritePlatformService = selfServiceRegistrationWritePlatformService; + this.toApiJsonSerializer = toApiJsonSerializer; + } + + @POST + @Produces({ MediaType.APPLICATION_JSON }) + public String createSelfServiceRegistrationRequest(final String apiRequestBodyAsJson) { + this.selfServiceRegistrationWritePlatformService.createRegistrationRequest(apiRequestBodyAsJson); + return SelfServiceApiConstants.createRequestSuccessMessage; + } + + @POST + @Path("user") + @Produces({ MediaType.APPLICATION_JSON }) + public String createSelfServiceUser(final String apiRequestBodyAsJson) { + AppUser user = this.selfServiceRegistrationWritePlatformService.createUser(apiRequestBodyAsJson); + return this.toApiJsonSerializer.serialize(CommandProcessingResult.resourceResult(user.getId(), null)); + } + +} http://git-wip-us.apache.org/repos/asf/fineract/blob/afdc665b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/data/SelfServiceRegistrationData.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/data/SelfServiceRegistrationData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/data/SelfServiceRegistrationData.java new file mode 100644 index 0000000..9f62500 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/data/SelfServiceRegistrationData.java @@ -0,0 +1,70 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.portfolio.self.registration.data; + +import org.apache.fineract.portfolio.client.domain.Client; +import org.joda.time.LocalDate; + +public class SelfServiceRegistrationData { + + @SuppressWarnings("unused") + private final Long id; + @SuppressWarnings("unused") + private Client client; + @SuppressWarnings("unused") + private String firstName; + @SuppressWarnings("unused") + private String lastName; + @SuppressWarnings("unused") + private String mobileNumber; + @SuppressWarnings("unused") + private String email; + @SuppressWarnings("unused") + private String authenticationToken; + @SuppressWarnings("unused") + private String username; + @SuppressWarnings("unused") + private String password; + @SuppressWarnings("unused") + private LocalDate createdDate; + + public SelfServiceRegistrationData(final Long id, final Client client, final String firstName, final String lastName, + final String mobileNumber, final String email, final String authenticationToken, final String username, final String password, + final LocalDate createdDate) { + this.id = id; + this.client = client; + this.firstName = firstName; + this.lastName = lastName; + this.mobileNumber = mobileNumber; + this.email = email; + this.authenticationToken = authenticationToken; + this.username = username; + this.password = password; + this.createdDate = createdDate; + } + + public static SelfServiceRegistrationData getData(final Long id, final Client client, final String firstName, final String lastName, + final String mobileNumber, final String email, final String authenticationToken, final String username, final String password, + final LocalDate createdDate) { + return new SelfServiceRegistrationData(id, client, firstName, lastName, mobileNumber, email, authenticationToken, username, + password, createdDate); + + } + +} http://git-wip-us.apache.org/repos/asf/fineract/blob/afdc665b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/domain/SelfServiceRegistration.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/domain/SelfServiceRegistration.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/domain/SelfServiceRegistration.java new file mode 100644 index 0000000..7c226c5 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/domain/SelfServiceRegistration.java @@ -0,0 +1,131 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.portfolio.self.registration.domain; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; +import org.apache.fineract.portfolio.client.domain.Client; + +@Entity +@Table(name = "request_audit_table") +public class SelfServiceRegistration extends AbstractPersistableCustom { + + @ManyToOne + @JoinColumn(name = "client_id", nullable = false) + private Client client; + + @Column(name = "account_number", length = 100, nullable = false) + private String accountNumber; + + @Column(name = "firstname", length = 100, nullable = false) + private String firstName; + + @Column(name = "lastname", length = 100, nullable = false) + private String lastName; + + @Column(name = "mobile_number", length = 50, nullable = true) + private String mobileNumber; + + @Column(name = "email", length = 100, nullable = false) + private String email; + + @Column(name = "authentication_token", length = 100, nullable = true) + private String authenticationToken; + + @Column(name = "username", length = 100, nullable = false) + private String username; + + @Column(name = "password", length = 100, nullable = false) + private String password; + + @Column(name = "created_date", nullable = false) + @Temporal(TemporalType.DATE) + private Date createdDate; + + public SelfServiceRegistration(final Client client, String accountNumber, final String firstName, final String lastName, + final String mobileNumber, final String email, final String authenticationToken, final String username, final String password) { + this.client = client; + this.accountNumber = accountNumber; + this.firstName = firstName; + this.lastName = lastName; + this.mobileNumber = mobileNumber; + this.email = email; + this.authenticationToken = authenticationToken; + this.username = username; + this.password = password; + this.createdDate = new Date(); + } + + public static SelfServiceRegistration instance(final Client client, final String accountNumber, final String firstname, + final String lastName, final String mobileNumber, final String email, final String authenticationToken, final String username, + final String password) { + return new SelfServiceRegistration(client, accountNumber, firstname, lastName, mobileNumber, email, authenticationToken, username, + password); + } + + public Client getClient() { + return this.client; + } + + public String getFirstName() { + return this.firstName; + } + + public String getLastName() { + return this.lastName; + } + + public String getMobileNumber() { + return this.mobileNumber; + } + + public String getEmail() { + return this.email; + } + + public String getAuthenticationToken() { + return this.authenticationToken; + } + + public Date getCreatedDate() { + return this.createdDate; + } + + public String getUsername() { + return this.username; + } + + public String getPassword() { + return this.password; + } + + public String getAccountNumber() { + return this.accountNumber; + } + +} http://git-wip-us.apache.org/repos/asf/fineract/blob/afdc665b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/domain/SelfServiceRegistrationRepository.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/domain/SelfServiceRegistrationRepository.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/domain/SelfServiceRegistrationRepository.java new file mode 100644 index 0000000..2f93482 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/domain/SelfServiceRegistrationRepository.java @@ -0,0 +1,36 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.portfolio.self.registration.domain; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +public interface SelfServiceRegistrationRepository extends JpaRepository, + JpaSpecificationExecutor { + + public static final String FIND_BY_REQUEST_AND_AUTHENTICATION_TOKEN = "select request from SelfServiceRegistration request where request.id = :id and " + + "request.authenticationToken = :authenticationToken"; + + @Query(FIND_BY_REQUEST_AND_AUTHENTICATION_TOKEN) + SelfServiceRegistration getRequestByIdAndAuthenticationToken(@Param("id") Long id, + @Param("authenticationToken") String authenticationToken); + +} http://git-wip-us.apache.org/repos/asf/fineract/blob/afdc665b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/exception/SelfServiceRegistrationNotFoundException.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/exception/SelfServiceRegistrationNotFoundException.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/exception/SelfServiceRegistrationNotFoundException.java new file mode 100644 index 0000000..888a827 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/exception/SelfServiceRegistrationNotFoundException.java @@ -0,0 +1,30 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.portfolio.self.registration.exception; + +import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException; + +public class SelfServiceRegistrationNotFoundException extends AbstractPlatformResourceNotFoundException { + + public SelfServiceRegistrationNotFoundException(Long requestId, String authenticationToken) { + super("error.msg.self.service.registration.not.found", "Self service registration not found with request id : " + requestId + + " and authentication token :" + authenticationToken); + } + +} http://git-wip-us.apache.org/repos/asf/fineract/blob/afdc665b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/service/SelfServiceRegistrationReadPlatformService.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/service/SelfServiceRegistrationReadPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/service/SelfServiceRegistrationReadPlatformService.java new file mode 100644 index 0000000..9ff45b4 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/service/SelfServiceRegistrationReadPlatformService.java @@ -0,0 +1,26 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.portfolio.self.registration.service; + +public interface SelfServiceRegistrationReadPlatformService { + + public boolean isClientExist(String accountNumber, String firstName, String lastName, String mobileNumber, + boolean isEmailAuthenticationMode); + +} http://git-wip-us.apache.org/repos/asf/fineract/blob/afdc665b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/service/SelfServiceRegistrationReadPlatformServiceImpl.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/service/SelfServiceRegistrationReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/service/SelfServiceRegistrationReadPlatformServiceImpl.java new file mode 100644 index 0000000..ce265e6 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/service/SelfServiceRegistrationReadPlatformServiceImpl.java @@ -0,0 +1,50 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.portfolio.self.registration.service; + +import org.apache.fineract.infrastructure.core.service.RoutingDataSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +@Service +public class SelfServiceRegistrationReadPlatformServiceImpl implements SelfServiceRegistrationReadPlatformService { + + private final JdbcTemplate jdbcTemplate; + + @Autowired + public SelfServiceRegistrationReadPlatformServiceImpl(final RoutingDataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + @Override + public boolean isClientExist(String accountNumber, String firstName, String lastName, String mobileNumber, + boolean isEmailAuthenticationMode) { + String sql = "select count(*) from m_client where account_no = ? and firstname = ? and lastname = ?"; + Object[] params = new Object[] { accountNumber, firstName, lastName }; + if (!isEmailAuthenticationMode) { + sql = sql + " and mobile_no = ?"; + params = new Object[] { accountNumber, firstName, lastName, mobileNumber }; + } + Integer count = this.jdbcTemplate.queryForObject(sql, params, Integer.class); + if (count == 0) { return false; } + return true; + } + +} http://git-wip-us.apache.org/repos/asf/fineract/blob/afdc665b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/service/SelfServiceRegistrationWritePlatformService.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/service/SelfServiceRegistrationWritePlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/service/SelfServiceRegistrationWritePlatformService.java new file mode 100644 index 0000000..7827c44 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/service/SelfServiceRegistrationWritePlatformService.java @@ -0,0 +1,29 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.portfolio.self.registration.service; + +import org.apache.fineract.portfolio.self.registration.domain.SelfServiceRegistration; +import org.apache.fineract.useradministration.domain.AppUser; + +public interface SelfServiceRegistrationWritePlatformService { + + public SelfServiceRegistration createRegistrationRequest(String apiRequestBodyAsJson); + + public AppUser createUser(String apiRequestBodyAsJson); +} http://git-wip-us.apache.org/repos/asf/fineract/blob/afdc665b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/service/SelfServiceRegistrationWritePlatformServiceImpl.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/service/SelfServiceRegistrationWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/service/SelfServiceRegistrationWritePlatformServiceImpl.java new file mode 100644 index 0000000..7797b2f --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/service/SelfServiceRegistrationWritePlatformServiceImpl.java @@ -0,0 +1,293 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.portfolio.self.registration.service; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.persistence.PersistenceException; + +import org.apache.commons.lang.exception.ExceptionUtils; +import org.apache.fineract.infrastructure.campaigns.sms.data.SmsProviderData; +import org.apache.fineract.infrastructure.campaigns.sms.domain.SmsCampaign; +import org.apache.fineract.infrastructure.campaigns.sms.service.SmsCampaignDropdownReadPlatformService; +import org.apache.fineract.infrastructure.core.api.JsonCommand; +import org.apache.fineract.infrastructure.core.data.ApiParameterError; +import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder; +import org.apache.fineract.infrastructure.core.domain.EmailDetail; +import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException; +import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException; +import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper; +import org.apache.fineract.infrastructure.core.service.GmailBackedPlatformEmailService; +import org.apache.fineract.infrastructure.sms.domain.SmsMessage; +import org.apache.fineract.infrastructure.sms.domain.SmsMessageRepository; +import org.apache.fineract.infrastructure.sms.domain.SmsMessageStatusType; +import org.apache.fineract.infrastructure.sms.scheduler.SmsMessageScheduledJobService; +import org.apache.fineract.organisation.staff.domain.Staff; +import org.apache.fineract.portfolio.client.domain.Client; +import org.apache.fineract.portfolio.client.domain.ClientRepositoryWrapper; +import org.apache.fineract.portfolio.client.exception.ClientNotFoundException; +import org.apache.fineract.portfolio.group.domain.Group; +import org.apache.fineract.portfolio.self.registration.SelfServiceApiConstants; +import org.apache.fineract.portfolio.self.registration.domain.SelfServiceRegistration; +import org.apache.fineract.portfolio.self.registration.domain.SelfServiceRegistrationRepository; +import org.apache.fineract.portfolio.self.registration.exception.SelfServiceRegistrationNotFoundException; +import org.apache.fineract.useradministration.domain.AppUser; +import org.apache.fineract.useradministration.domain.PasswordValidationPolicy; +import org.apache.fineract.useradministration.domain.PasswordValidationPolicyRepository; +import org.apache.fineract.useradministration.domain.Role; +import org.apache.fineract.useradministration.domain.UserDomainService; +import org.apache.fineract.useradministration.service.AppUserReadPlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.security.authentication.AuthenticationServiceException; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.User; +import org.springframework.stereotype.Service; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.reflect.TypeToken; + +@Service +public class SelfServiceRegistrationWritePlatformServiceImpl implements SelfServiceRegistrationWritePlatformService { + + private final SelfServiceRegistrationRepository selfServiceRegistrationRepository; + private final FromJsonHelper fromApiJsonHelper; + private final SelfServiceRegistrationReadPlatformService selfServiceRegistrationReadPlatformService; + private final ClientRepositoryWrapper clientRepository; + private final PasswordValidationPolicyRepository passwordValidationPolicy; + private final UserDomainService userDomainService; + private final GmailBackedPlatformEmailService gmailBackedPlatformEmailService; + private final SmsMessageRepository smsMessageRepository; + private SmsMessageScheduledJobService smsMessageScheduledJobService; + private final SmsCampaignDropdownReadPlatformService smsCampaignDropdownReadPlatformService; + private final AppUserReadPlatformService appUserReadPlatformService; + + @Autowired + public SelfServiceRegistrationWritePlatformServiceImpl(final SelfServiceRegistrationRepository selfServiceRegistrationRepository, + final FromJsonHelper fromApiJsonHelper, + final SelfServiceRegistrationReadPlatformService selfServiceRegistrationReadPlatformService, + final ClientRepositoryWrapper clientRepository, final PasswordValidationPolicyRepository passwordValidationPolicy, + final UserDomainService userDomainService, final GmailBackedPlatformEmailService gmailBackedPlatformEmailService, + final SmsMessageRepository smsMessageRepository, SmsMessageScheduledJobService smsMessageScheduledJobService, + final SmsCampaignDropdownReadPlatformService smsCampaignDropdownReadPlatformService, + final AppUserReadPlatformService appUserReadPlatformService) { + this.selfServiceRegistrationRepository = selfServiceRegistrationRepository; + this.fromApiJsonHelper = fromApiJsonHelper; + this.selfServiceRegistrationReadPlatformService = selfServiceRegistrationReadPlatformService; + this.clientRepository = clientRepository; + this.passwordValidationPolicy = passwordValidationPolicy; + this.userDomainService = userDomainService; + this.gmailBackedPlatformEmailService = gmailBackedPlatformEmailService; + this.smsMessageRepository = smsMessageRepository; + this.smsMessageScheduledJobService = smsMessageScheduledJobService; + this.smsCampaignDropdownReadPlatformService = smsCampaignDropdownReadPlatformService; + this.appUserReadPlatformService = appUserReadPlatformService; + } + + @Override + public SelfServiceRegistration createRegistrationRequest(String apiRequestBodyAsJson) { + Gson gson = new Gson(); + final Type typeOfMap = new TypeToken>() {}.getType(); + final List dataValidationErrors = new ArrayList<>(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("user"); + this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, apiRequestBodyAsJson, + SelfServiceApiConstants.REGISTRATION_REQUEST_DATA_PARAMETERS); + JsonElement element = gson.fromJson(apiRequestBodyAsJson.toString(), JsonElement.class); + + String accountNumber = this.fromApiJsonHelper.extractStringNamed(SelfServiceApiConstants.accountNumberParamName, element); + baseDataValidator.reset().parameter(SelfServiceApiConstants.accountNumberParamName).value(accountNumber).notNull().notBlank() + .notExceedingLengthOf(100); + + String firstName = this.fromApiJsonHelper.extractStringNamed(SelfServiceApiConstants.firstNameParamName, element); + baseDataValidator.reset().parameter(SelfServiceApiConstants.firstNameParamName).value(firstName).notBlank() + .notExceedingLengthOf(100); + + String lastName = this.fromApiJsonHelper.extractStringNamed(SelfServiceApiConstants.lastNameParamName, element); + baseDataValidator.reset().parameter(SelfServiceApiConstants.lastNameParamName).value(lastName).notBlank().notExceedingLengthOf(100); + + String username = this.fromApiJsonHelper.extractStringNamed(SelfServiceApiConstants.usernameParamName, element); + baseDataValidator.reset().parameter(SelfServiceApiConstants.usernameParamName).value(username).notBlank().notExceedingLengthOf(100); + + // validate password policy + String password = this.fromApiJsonHelper.extractStringNamed(SelfServiceApiConstants.passwordParamName, element); + final PasswordValidationPolicy validationPolicy = this.passwordValidationPolicy.findActivePasswordValidationPolicy(); + final String regex = validationPolicy.getRegex(); + final String description = validationPolicy.getDescription(); + baseDataValidator.reset().parameter(SelfServiceApiConstants.passwordParamName).value(password) + .matchesRegularExpression(regex, description).notExceedingLengthOf(100); + + String authenticationMode = this.fromApiJsonHelper.extractStringNamed(SelfServiceApiConstants.authenticationModeParamName, element); + baseDataValidator.reset().parameter(SelfServiceApiConstants.authenticationModeParamName).value(authenticationMode).notBlank() + .isOneOfTheseStringValues(SelfServiceApiConstants.emailModeParamName, SelfServiceApiConstants.mobileModeParamName); + + String email = this.fromApiJsonHelper.extractStringNamed(SelfServiceApiConstants.emailParamName, element); + baseDataValidator.reset().parameter(SelfServiceApiConstants.emailParamName).value(email).notNull().notBlank() + .notExceedingLengthOf(100); + + boolean isEmailAuthenticationMode = authenticationMode.equalsIgnoreCase(SelfServiceApiConstants.emailModeParamName); + String mobileNumber = null; + if (!isEmailAuthenticationMode) { + mobileNumber = this.fromApiJsonHelper.extractStringNamed(SelfServiceApiConstants.mobileNumberParamName, element); + baseDataValidator.reset().parameter(SelfServiceApiConstants.mobileNumberParamName).value(mobileNumber).notNull() + .validatePhoneNumber(); + } + validateForDuplicateUsername(username); + + throwExceptionIfValidationError(dataValidationErrors, accountNumber, firstName, lastName, mobileNumber, isEmailAuthenticationMode); + + String authenticationToken = randomAuthorizationTokenGeneration(); + Client client = this.clientRepository.getClientByAccountNumber(accountNumber); + SelfServiceRegistration selfServiceRegistration = SelfServiceRegistration.instance(client, accountNumber, firstName, lastName, + mobileNumber, email, authenticationToken, username, password); + this.selfServiceRegistrationRepository.saveAndFlush(selfServiceRegistration); + sendAuthorizationToken(selfServiceRegistration, isEmailAuthenticationMode); + return selfServiceRegistration; + + } + + public void validateForDuplicateUsername(String username) { + boolean isDuplicateUserName = this.appUserReadPlatformService.isUsernameExist(username); + if (isDuplicateUserName) { + final StringBuilder defaultMessageBuilder = new StringBuilder("User with username ").append(username) + .append(" already exists."); + throw new PlatformDataIntegrityException("error.msg.user.duplicate.username", defaultMessageBuilder.toString(), + SelfServiceApiConstants.usernameParamName, username); + } + } + + public void sendAuthorizationToken(SelfServiceRegistration selfServiceRegistration, Boolean isEmailAuthenticationMode) { + if (isEmailAuthenticationMode) { + sendAuthorizationMail(selfServiceRegistration); + } else { + sendAuthorizationMessage(selfServiceRegistration); + } + } + + private void sendAuthorizationMessage(SelfServiceRegistration selfServiceRegistration) { + Collection smsProviders = this.smsCampaignDropdownReadPlatformService.retrieveSmsProviders(); + if (smsProviders.isEmpty()) { throw new PlatformDataIntegrityException("error.msg.mobile.service.provider.not.available", + "Mobile service provider not available."); } + Long providerId = (new ArrayList<>(smsProviders)).get(0).getId(); + final String message = "Hi " + selfServiceRegistration.getFirstName() + "," + "\n" + + "To create user, please use following details \n" + "Request Id : " + selfServiceRegistration.getId() + + "\n Authentication Token : " + selfServiceRegistration.getAuthenticationToken(); + String externalId = null; + Group group = null; + Staff staff = null; + SmsCampaign smsCampaign = null; + SmsMessage smsMessage = SmsMessage.instance(externalId, group, selfServiceRegistration.getClient(), staff, + SmsMessageStatusType.PENDING, message, selfServiceRegistration.getMobileNumber(), smsCampaign); + this.smsMessageRepository.save(smsMessage); + this.smsMessageScheduledJobService.sendTriggeredMessage(new ArrayList<>(Arrays.asList(smsMessage)), providerId); + } + + private void sendAuthorizationMail(SelfServiceRegistration selfServiceRegistration) { + final String subject = "Authorization token "; + final String body = "Hi " + selfServiceRegistration.getFirstName() + "," + "\n" + "To create user, please use following details\n" + + "Request Id : " + selfServiceRegistration.getId() + "\n Authentication Token : " + + selfServiceRegistration.getAuthenticationToken(); + + final EmailDetail emailDetail = new EmailDetail(subject, body, selfServiceRegistration.getEmail(), + selfServiceRegistration.getFirstName()); + this.gmailBackedPlatformEmailService.sendDefinedEmail(emailDetail); + } + + private void throwExceptionIfValidationError(final List dataValidationErrors, String accountNumber, + String firstName, String lastName, String mobileNumber, boolean isEmailAuthenticationMode) { + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); } + boolean isClientExist = this.selfServiceRegistrationReadPlatformService.isClientExist(accountNumber, firstName, lastName, + mobileNumber, isEmailAuthenticationMode); + if (!isClientExist) { throw new ClientNotFoundException(); } + } + + public static String randomAuthorizationTokenGeneration() { + Integer randomPIN = (int) (Math.random() * 9000) + 1000; + return randomPIN.toString(); + } + + @Override + public AppUser createUser(String apiRequestBodyAsJson) { + JsonCommand command = null; + String username = null; + try { + Gson gson = new Gson(); + final Type typeOfMap = new TypeToken>() {}.getType(); + final List dataValidationErrors = new ArrayList<>(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("user"); + this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, apiRequestBodyAsJson, + SelfServiceApiConstants.CREATE_USER_REQUEST_DATA_PARAMETERS); + JsonElement element = gson.fromJson(apiRequestBodyAsJson.toString(), JsonElement.class); + + Long id = this.fromApiJsonHelper.extractLongNamed(SelfServiceApiConstants.requestIdParamName, element); + baseDataValidator.reset().parameter(SelfServiceApiConstants.requestIdParamName).value(id).notNull().integerGreaterThanZero(); + command = JsonCommand.fromJsonElement(id, element); + String authenticationToken = this.fromApiJsonHelper.extractStringNamed(SelfServiceApiConstants.authenticationTokenParamName, + element); + baseDataValidator.reset().parameter(SelfServiceApiConstants.authenticationTokenParamName).value(authenticationToken).notBlank() + .notNull().notExceedingLengthOf(100); + + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); } + + SelfServiceRegistration selfServiceRegistration = this.selfServiceRegistrationRepository.getRequestByIdAndAuthenticationToken( + id, authenticationToken); + if (selfServiceRegistration == null) { throw new SelfServiceRegistrationNotFoundException(id, authenticationToken); } + username = selfServiceRegistration.getUsername(); + Client client = selfServiceRegistration.getClient(); + final boolean passwordNeverExpire = true; + final boolean isSelfServiceUser = true; + final Collection authorities = new ArrayList<>(); + authorities.add(new SimpleGrantedAuthority("DUMMY_ROLE_NOT_USED_OR_PERSISTED_TO_AVOID_EXCEPTION")); + final Set allRoles = new HashSet<>(); + List clients = new ArrayList<>(Arrays.asList(client)); + User user = new User(selfServiceRegistration.getUsername(), selfServiceRegistration.getPassword(), authorities); + AppUser appUser = new AppUser(client.getOffice(), user, allRoles, selfServiceRegistration.getEmail(), client.getFirstname(), + client.getLastname(), null, passwordNeverExpire, isSelfServiceUser, clients); + this.userDomainService.create(appUser, true); + return appUser; + + } catch (final DataIntegrityViolationException dve) { + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve, username); + return null; + } catch (final PersistenceException | AuthenticationServiceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()); + handleDataIntegrityIssues(command, throwable, dve, username); + return null; + } + + } + + private void handleDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve, String username) { + if (realCause.getMessage().contains("'username_org'")) { + final StringBuilder defaultMessageBuilder = new StringBuilder("User with username ").append(username) + .append(" already exists."); + throw new PlatformDataIntegrityException("error.msg.user.duplicate.username", defaultMessageBuilder.toString(), "username", + username); + } + throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue", "Unknown data integrity issue with resource."); + } + +} http://git-wip-us.apache.org/repos/asf/fineract/blob/afdc665b/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/AppUserReadPlatformService.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/AppUserReadPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/AppUserReadPlatformService.java index 067c725..b17f6a1 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/AppUserReadPlatformService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/AppUserReadPlatformService.java @@ -31,4 +31,6 @@ public interface AppUserReadPlatformService { AppUserData retrieveNewUserDetails(); AppUserData retrieveUser(Long userId); + + boolean isUsernameExist(String username); } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/fineract/blob/afdc665b/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/AppUserReadPlatformServiceImpl.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/AppUserReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/AppUserReadPlatformServiceImpl.java index 21e064f..13cbbd8 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/AppUserReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/AppUserReadPlatformServiceImpl.java @@ -212,4 +212,13 @@ public class AppUserReadPlatformServiceImpl implements AppUserReadPlatformServic + " join m_office o on o.id = u.office_id where o.hierarchy like ? and u.is_deleted=0 order by u.username"; } } + + @Override + public boolean isUsernameExist(String username) { + String sql = "select count(*) from m_appuser where username = ?"; + Object[] params = new Object[] { username }; + Integer count = this.jdbcTemplate.queryForObject(sql, params, Integer.class); + if (count == 0) { return false; } + return true; + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/fineract/blob/afdc665b/fineract-provider/src/main/resources/META-INF/spring/securityContext.xml ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/resources/META-INF/spring/securityContext.xml b/fineract-provider/src/main/resources/META-INF/spring/securityContext.xml index ee4fb6d..f03220f 100644 --- a/fineract-provider/src/main/resources/META-INF/spring/securityContext.xml +++ b/fineract-provider/src/main/resources/META-INF/spring/securityContext.xml @@ -38,6 +38,10 @@ method="POST" requires-channel="https" /> + +