self service registration

This commit is contained in:
nazeer shaik
2017-07-25 20:22:10 +05:30
parent 0f98cbbed8
commit afdc665b52
18 changed files with 880 additions and 2 deletions
@@ -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;
}
@@ -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<Client, Long>, JpaSpecificationExecutor<Client> {
// 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);
}
@@ -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;
}
}
@@ -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+".");
}
}
@@ -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<String> REGISTRATION_REQUEST_DATA_PARAMETERS = new HashSet<>(Arrays.asList(usernameParamName,
accountNumberParamName, passwordParamName, firstNameParamName, mobileNumberParamName, lastNameParamName, emailParamName,
authenticationModeParamName));
public static final Set<String> CREATE_USER_REQUEST_DATA_PARAMETERS = new HashSet<>(Arrays.asList(requestIdParamName,
authenticationTokenParamName));
public static final Object[] SUPPORTED_AUTHENTICATION_MODE_PARAMETERS = new Object[] {emailModeParamName,
mobileModeParamName};
}
@@ -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<AppUser> toApiJsonSerializer;
@Autowired
public SelfServiceRegistrationApiResource(
final SelfServiceRegistrationWritePlatformService selfServiceRegistrationWritePlatformService,
final DefaultToApiJsonSerializer<AppUser> 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));
}
}
@@ -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);
}
}
@@ -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<Long> {
@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;
}
}
@@ -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<SelfServiceRegistration, Long>,
JpaSpecificationExecutor<SelfServiceRegistration> {
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);
}
@@ -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);
}
}
@@ -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);
}
@@ -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;
}
}
@@ -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);
}
@@ -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<Map<String, Object>>() {}.getType();
final List<ApiParameterError> 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<SmsProviderData> 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<ApiParameterError> 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<Map<String, Object>>() {}.getType();
final List<ApiParameterError> 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<SimpleGrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority("DUMMY_ROLE_NOT_USED_OR_PERSISTED_TO_AVOID_EXCEPTION"));
final Set<Role> allRoles = new HashSet<>();
List<Client> 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.");
}
}
@@ -31,4 +31,6 @@ public interface AppUserReadPlatformService {
AppUserData retrieveNewUserDetails();
AppUserData retrieveUser(Long userId);
boolean isUsernameExist(String username);
}
@@ -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;
}
}
@@ -38,6 +38,10 @@
method="POST" requires-channel="https" />
<intercept-url pattern="/api/*/self/authentication" access="permitAll"
method="POST" requires-channel="https" />
<intercept-url pattern="/api/*/self/registration" access="permitAll"
method="POST" requires-channel="https" />
<intercept-url pattern="/api/*/self/registration/user" access="permitAll"
method="POST" requires-channel="https" />
<intercept-url pattern="/api/**" access="isFullyAuthenticated()"
method="GET" requires-channel="https" />
<intercept-url pattern="/api/**" access="isFullyAuthenticated()"
@@ -0,0 +1,38 @@
--
-- 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.
--
CREATE TABLE `request_audit_table` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`lastname` VARCHAR(100) NOT NULL,
`username` VARCHAR(100) NOT NULL,
`mobile_number` VARCHAR(50) NULL DEFAULT NULL,
`firstname` VARCHAR(100) NOT NULL,
`authentication_token` VARCHAR(100) NULL DEFAULT NULL,
`password` VARCHAR(250) NOT NULL,
`email` VARCHAR(100) NOT NULL,
`client_id` BIGINT(20) NOT NULL,
`created_date` DATE NOT NULL,
`account_number` VARCHAR(100) NOT NULL,
PRIMARY KEY (`id`),
INDEX `FK1_request_audit_table_m_client` (`client_id`),
CONSTRAINT `FK1_request_audit_table_m_client` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;