Skip to content

Commit 0340a73

Browse files
committed
Validate tenant creation request data
Fix tenant already exists exception not being thrown
1 parent fe1770e commit 0340a73

File tree

7 files changed

+146
-10
lines changed

7 files changed

+146
-10
lines changed

gradlew

100644100755
File mode changed.

src/main/java/org/fineract/messagegateway/exception/SecurityException.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ private SecurityException(final String msg) {
2424
super(msg);
2525
}
2626

27-
public static SecurityException tenantAlreadyExisits(final String tenant) {
27+
public static SecurityException tenantAlreadyExists(final String tenant) {
2828
return new SecurityException("Tenant Already existing with "+tenant+" identifier");
2929
}
3030
}

src/main/java/org/fineract/messagegateway/service/SecurityService.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public String generateApiKey(final SMSBridge smsBridge) {
7373
public String generateApiKey(final String tenantId) {
7474
Tenant tenant = this.tenantRepository.findByTenantId(tenantId) ;
7575
if(tenant != null) {
76-
org.fineract.messagegateway.exception.SecurityException.tenantAlreadyExisits(tenantId) ;
76+
throw org.fineract.messagegateway.exception.SecurityException.tenantAlreadyExists(tenantId) ;
7777
}
7878

7979
final String randomKey = UUID.randomUUID().toString();

src/main/java/org/fineract/messagegateway/tenants/api/TenantsApiResource.java

+19-4
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,16 @@
1818
*/
1919
package org.fineract.messagegateway.tenants.api;
2020

21-
import org.fineract.messagegateway.tenants.domain.Tenant;
21+
import org.fineract.messagegateway.exception.PlatformApiDataValidationException;
22+
import org.fineract.messagegateway.exception.UnsupportedParameterException;
23+
import org.fineract.messagegateway.helpers.ApiGlobalErrorResponse;
24+
import org.fineract.messagegateway.helpers.PlatformApiDataValidationExceptionMapper;
25+
import org.fineract.messagegateway.helpers.UnsupportedParameterExceptionMapper;
2226
import org.fineract.messagegateway.tenants.service.TenantsService;
2327
import org.springframework.beans.factory.annotation.Autowired;
2428
import org.springframework.http.HttpStatus;
2529
import org.springframework.http.ResponseEntity;
30+
import org.springframework.web.bind.annotation.ExceptionHandler;
2631
import org.springframework.web.bind.annotation.RequestBody;
2732
import org.springframework.web.bind.annotation.RequestMapping;
2833
import org.springframework.web.bind.annotation.RequestMethod;
@@ -40,8 +45,18 @@ public TenantsApiResource(final TenantsService tenantService) {
4045
}
4146

4247
@RequestMapping(method = RequestMethod.POST, consumes = {"application/json"}, produces = {"application/json"})
43-
public ResponseEntity<String> createSMSBridgeConfig(@RequestBody final Tenant tenant) {
44-
String appKey = this.tenantService.createTenant(tenant) ;
45-
return new ResponseEntity<>(appKey, HttpStatus.CREATED);
48+
public ResponseEntity<String> createSMSBridgeConfig(@RequestBody final String requestJson) {
49+
String appKey = this.tenantService.createTenant(requestJson) ;
50+
return new ResponseEntity<>(appKey, HttpStatus.CREATED);
4651
}
52+
53+
@ExceptionHandler({PlatformApiDataValidationException.class})
54+
public ResponseEntity<ApiGlobalErrorResponse> handlePlatformApiDataValidationException(PlatformApiDataValidationException e) {
55+
return PlatformApiDataValidationExceptionMapper.toResponse(e) ;
56+
}
57+
58+
@ExceptionHandler({UnsupportedParameterException.class})
59+
public ResponseEntity<ApiGlobalErrorResponse> handleUnsupportedParameterException(UnsupportedParameterException e) {
60+
return UnsupportedParameterExceptionMapper.toResponse(e) ;
61+
}
4762
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.fineract.messagegateway.tenants.constants;
20+
21+
import java.util.Arrays;
22+
import java.util.HashSet;
23+
import java.util.Set;
24+
25+
import org.fineract.messagegateway.constants.MessageGatewayConstants;
26+
27+
public interface TenantConstants extends MessageGatewayConstants {
28+
29+
String TENANTS_RESOURCE_NAME = "tenants";
30+
31+
String TENANT_ID = "tenantId";
32+
String TENANT_DESCRIPTION = "description";
33+
34+
35+
// list of allowed parameters for tenant creation request
36+
Set<String> CREATE_REQUEST_PARAMETERS = new HashSet<>(Arrays.asList(TENANT_ID, TENANT_DESCRIPTION));
37+
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.fineract.messagegateway.tenants.serialization;
20+
21+
import java.lang.reflect.Type;
22+
import java.util.ArrayList;
23+
import java.util.List;
24+
import java.util.Map;
25+
26+
import org.fineract.messagegateway.exception.PlatformApiDataValidationException;
27+
import org.fineract.messagegateway.helpers.ApiParameterError;
28+
import org.fineract.messagegateway.helpers.DataValidatorBuilder;
29+
import org.fineract.messagegateway.helpers.FromJsonHelper;
30+
import org.fineract.messagegateway.tenants.constants.TenantConstants;
31+
import org.fineract.messagegateway.tenants.domain.Tenant;
32+
import org.springframework.beans.factory.annotation.Autowired;
33+
import org.springframework.stereotype.Component;
34+
35+
import com.google.gson.JsonElement;
36+
import com.google.gson.reflect.TypeToken;
37+
38+
@Component
39+
public class TenantSerializer {
40+
41+
private final FromJsonHelper fromJsonHelper;
42+
43+
@Autowired
44+
public TenantSerializer(FromJsonHelper fromJsonHelper) {
45+
this.fromJsonHelper = fromJsonHelper;
46+
}
47+
48+
public Tenant validateCreateRequest(final String json) {
49+
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
50+
this.fromJsonHelper.checkForUnsupportedParameters(typeOfMap, json,
51+
TenantConstants.CREATE_REQUEST_PARAMETERS);
52+
53+
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
54+
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
55+
.resource(TenantConstants.TENANTS_RESOURCE_NAME);
56+
final JsonElement element = this.fromJsonHelper.parse(json);
57+
58+
59+
final String tenantId = this.fromJsonHelper.extractStringNamed(TenantConstants.TENANT_ID, element);
60+
baseDataValidator.reset().parameter(TenantConstants.TENANT_ID)
61+
.value(tenantId).notBlank().notExceedingLengthOf(32);
62+
63+
String tenantDescription = null;
64+
if(this.fromJsonHelper.parameterExists(TenantConstants.TENANT_DESCRIPTION, element)) {
65+
tenantDescription = this.fromJsonHelper.extractStringNamed(TenantConstants.TENANT_DESCRIPTION,
66+
element);
67+
baseDataValidator.reset().parameter(TenantConstants.TENANT_DESCRIPTION).value(tenantDescription)
68+
.notBlank().notExceedingLengthOf(500);
69+
}
70+
71+
if (!dataValidationErrors.isEmpty()) {
72+
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
73+
"Validation errors exist.", dataValidationErrors);
74+
}
75+
76+
return new Tenant(tenantId, null, tenantDescription);
77+
}
78+
}

src/main/java/org/fineract/messagegateway/tenants/service/TenantsService.java

+9-4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.fineract.messagegateway.tenants.domain.Tenant;
2323
import org.fineract.messagegateway.tenants.exception.TenantNotFoundException;
2424
import org.fineract.messagegateway.tenants.repository.TenantRepository;
25+
import org.fineract.messagegateway.tenants.serialization.TenantSerializer;
2526
import org.springframework.beans.factory.annotation.Autowired;
2627
import org.springframework.stereotype.Service;
2728

@@ -31,15 +32,19 @@ public class TenantsService {
3132
private final TenantRepository tenantRepository ;
3233

3334
private final SecurityService securityService ;
34-
35+
36+
private final TenantSerializer tenantSerializer;
37+
3538
@Autowired
3639
public TenantsService(final TenantRepository tenantRepository,
37-
final SecurityService securityService) {
40+
final SecurityService securityService, TenantSerializer tenantSerializer) {
3841
this.tenantRepository = tenantRepository ;
3942
this.securityService = securityService ;
43+
this.tenantSerializer = tenantSerializer;
4044
}
41-
42-
public String createTenant(final Tenant tenant) {
45+
46+
public String createTenant(final String requestJson) {
47+
Tenant tenant = tenantSerializer.validateCreateRequest(requestJson);
4348
tenant.setTenantAppKey(this.securityService.generateApiKey(tenant.getTenantId()));
4449
this.tenantRepository.save(tenant) ;
4550
return tenant.getTenantAppKey() ;

0 commit comments

Comments
 (0)