Skip to content

Commit

Permalink
RCF-214, RCF-212 and RCF-216 (#261)
Browse files Browse the repository at this point in the history
* added mavel native code

Signed-off-by: Sachin S P <sachin.sp@cyberpwn.com>

* changed the new code error

Signed-off-by: Sachin S P <sachin.sp@cyberpwn.com>

* fixed the ui break issue

Signed-off-by: Sachin S P <sachin.sp@cyberpwn.com>

* document upload screen based on mavel script and application doc type

Signed-off-by: Sachin S P <sachin.sp@cyberpwn.com>

* document upload screen validation

Signed-off-by: Sachin S P <sachin.sp@cyberpwn.com>

* document upload screen exception proof function

Signed-off-by: Sachin S P <sachin.sp@cyberpwn.com>

* exception proof validation

Signed-off-by: Sachin S P <sachin.sp@cyberpwn.com>

* made some merge changes

Signed-off-by: Sachin S P <sachin.sp@cyberpwn.com>

---------

Signed-off-by: Sachin S P <sachin.sp@cyberpwn.com>
Co-authored-by: Sachin S P <sachin.sp@cyberpwn.com>
  • Loading branch information
SachinPremkumar and Sachin S P authored Feb 8, 2024
1 parent 516caba commit 40bfdf2
Show file tree
Hide file tree
Showing 32 changed files with 603 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import dagger.Module;
import dagger.Provides;
import io.mosip.registration.clientmanager.dao.FileSignatureDao;
import io.mosip.registration.clientmanager.repository.GlobalParamRepository;
import io.mosip.registration.clientmanager.repository.IdentitySchemaRepository;
import io.mosip.registration.clientmanager.repository.RegistrationCenterRepository;
Expand All @@ -42,13 +43,16 @@
import io.mosip.registration.clientmanager.repository.UserDetailRepository;
import io.mosip.registration.clientmanager.service.MasterDataServiceImpl;
import io.mosip.registration.clientmanager.spi.JobManagerService;
import io.mosip.registration.keymanager.service.CertificateManagerServiceImpl;
import io.mosip.registration.keymanager.spi.CertificateManagerService;
import io.mosip.registration.keymanager.spi.ClientCryptoManagerService;
import io.mosip.registration.keymanager.spi.CryptoManagerService;
import io.mosip.registration_client.api_services.AuditDetailsApi;
import io.mosip.registration_client.api_services.AuthenticationApi;
import io.mosip.registration_client.api_services.BiometricsDetailsApi;
import io.mosip.registration_client.api_services.CommonDetailsApi;
import io.mosip.registration_client.api_services.DemographicsDetailsApi;
import io.mosip.registration_client.api_services.DocumentCategoryApi;
import io.mosip.registration_client.api_services.DocumentDetailsApi;

import io.mosip.registration_client.api_services.DynamicDetailsApi;
Expand Down Expand Up @@ -181,7 +185,8 @@ MasterDataSyncApi getSyncResponseApi(
SyncJobDefRepository syncJobDefRepository,
LanguageRepository languageRepository,
JobManagerService jobManagerService,
AuditManagerService auditManagerService) {
AuditManagerService auditManagerService,
MasterDataService masterDataService) {
return new MasterDataSyncApi( clientCryptoManagerService,
machineRepository, registrationCenterRepository,
syncRestService, certificateManagerService,
Expand All @@ -191,7 +196,7 @@ MasterDataSyncApi getSyncResponseApi(
templateRepository, dynamicFieldRepository,
locationRepository, blocklistedWordRepository,
syncJobDefRepository, languageRepository,jobManagerService,
auditManagerService
auditManagerService,masterDataService
);
}

Expand All @@ -200,5 +205,11 @@ MasterDataSyncApi getSyncResponseApi(
AuditDetailsApi getAuditDetailsApi(AuditManagerService auditManagerService) {
return new AuditDetailsApi(auditManagerService);
}

@Provides
@Singleton
DocumentCategoryApi getDocumentCategoryApi(RegistrationService registrationService, FileSignatureDao fileSignatureRepository, GlobalParamRepository globalParamRepository, MasterDataService masterDataService, CertificateManagerService certificateManagerService, CryptoManagerService cryptoManagerServiceImpl, ClientCryptoManagerService clientCryptoManagerService) {
return new DocumentCategoryApi(registrationService,fileSignatureRepository,globalParamRepository,masterDataService,certificateManagerService,cryptoManagerServiceImpl,clientCryptoManagerService,appContext);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
import io.mosip.registration_client.api_services.BiometricsDetailsApi;
import io.mosip.registration_client.api_services.CommonDetailsApi;
import io.mosip.registration_client.api_services.DemographicsDetailsApi;
import io.mosip.registration_client.api_services.DocumentCategoryApi;
import io.mosip.registration_client.api_services.DocumentDetailsApi;
import io.mosip.registration_client.api_services.DynamicDetailsApi;
import io.mosip.registration_client.api_services.MachineDetailsApi;
Expand All @@ -87,6 +88,7 @@
import io.mosip.registration_client.model.BiometricsPigeon;
import io.mosip.registration_client.model.CommonDetailsPigeon;
import io.mosip.registration_client.model.DemographicsDataPigeon;
import io.mosip.registration_client.model.DocumentCategoryPigeon;
import io.mosip.registration_client.model.DynamicResponsePigeon;
import io.mosip.registration_client.model.MachinePigeon;
import io.mosip.registration_client.model.PacketAuthPigeon;
Expand Down Expand Up @@ -177,6 +179,9 @@ public class MainActivity extends FlutterActivity {
@Inject
GlobalParamDao globalParamDao;

@Inject
DocumentCategoryApi documentCategoryApi;

private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Expand Down Expand Up @@ -352,6 +357,7 @@ public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
DynamicResponsePigeon.DynamicResponseApi.setup(flutterEngine.getDartExecutor().getBinaryMessenger(), dynamicDetailsApi);
MasterDataSyncPigeon.SyncApi.setup(flutterEngine.getDartExecutor().getBinaryMessenger(), masterDataSyncApi);
AuditResponsePigeon.AuditResponseApi.setup(flutterEngine.getDartExecutor().getBinaryMessenger(), auditDetailsApi);
DocumentCategoryPigeon.DocumentCategoryApi.setup(flutterEngine.getDartExecutor().getBinaryMessenger(), documentCategoryApi);

new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), REG_CLIENT_CHANNEL)
.setMethodCallHandler(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
package io.mosip.registration_client.api_services;

import android.content.Context;
import android.util.Log;

import androidx.annotation.NonNull;

import org.apache.commons.io.FileUtils;
import org.json.JSONObject;
import org.mvel2.MVEL;

import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import javax.inject.Inject;
import javax.inject.Singleton;

import io.mosip.registration.clientmanager.dao.FileSignatureDao;
import io.mosip.registration.clientmanager.entity.FileSignature;
import io.mosip.registration.clientmanager.repository.GlobalParamRepository;
import io.mosip.registration.clientmanager.spi.MasterDataService;
import io.mosip.registration.clientmanager.spi.RegistrationService;
import io.mosip.registration.keymanager.dto.CryptoRequestDto;
import io.mosip.registration.keymanager.dto.CryptoResponseDto;
import io.mosip.registration.keymanager.dto.JWTSignatureVerifyRequestDto;
import io.mosip.registration.keymanager.dto.JWTSignatureVerifyResponseDto;
import io.mosip.registration.keymanager.service.LocalClientCryptoServiceImpl;
import io.mosip.registration.keymanager.spi.CertificateManagerService;
import io.mosip.registration.keymanager.spi.ClientCryptoManagerService;
import io.mosip.registration.keymanager.spi.CryptoManagerService;
import io.mosip.registration.keymanager.util.CryptoUtil;
import io.mosip.registration.packetmanager.util.HMACUtils2;
import io.mosip.registration_client.model.DocumentCategoryPigeon;

@Singleton
public class DocumentCategoryApi implements DocumentCategoryPigeon.DocumentCategoryApi {

MasterDataService masterDataService;

private final RegistrationService registrationService;

private static final Map<String, String> SCRIPT_CACHE = new HashMap<>();

private Map<String, Object> applicationMap;

private Context context;

FileSignatureDao fileSignatureRepository;

GlobalParamRepository globalParamRepository;

CertificateManagerService certificateManagerService;

LocalClientCryptoServiceImpl clientCryptoFacade;

CryptoManagerService cryptoManagerServiceImpl;

ClientCryptoManagerService clientCryptoManagerService;



@Inject
public DocumentCategoryApi(RegistrationService registrationService,FileSignatureDao fileSignatureRepository,GlobalParamRepository globalParamRepository,MasterDataService masterDataService,CertificateManagerService certificateManagerService,CryptoManagerService cryptoManagerServiceImpl,ClientCryptoManagerService clientCryptoManagerService,Context context) {
this.registrationService = registrationService;
this.context = context;
this.fileSignatureRepository = fileSignatureRepository;
this.applicationMap = new HashMap<>();
this.globalParamRepository = globalParamRepository;
this.masterDataService = masterDataService;
this.certificateManagerService = certificateManagerService;
this.cryptoManagerServiceImpl = cryptoManagerServiceImpl;
this.clientCryptoManagerService = clientCryptoManagerService;
}
@Override
public void getDocumentCategories(@NonNull String categoryCode, @NonNull String langCode, @NonNull DocumentCategoryPigeon.Result<List<String>> result) {
List<String> documentCategory = new ArrayList<>();
try {
Map<String, Object> dataContext = this.registrationService.getRegistrationDto().getMVELDataContext();
String applicantTypeCode = this.evaluateMvelScript((String) this.globalParamRepository.getCachedStringMAVELScript(), dataContext);
documentCategory = this.masterDataService.getDocumentTypes(categoryCode, applicantTypeCode, langCode);
} catch (Exception e) {
Log.e(getClass().getSimpleName(), "Fetch document values: " + Arrays.toString(e.getStackTrace()));
}
result.success(documentCategory);
}


public String evaluateMvelScript(String scriptName, Map<String, Object> dataContext) {
try {
Map<String, String> ageGroups = new HashMap<String, String>();
JSONObject ageGroupConfig = new JSONObject((String) this.globalParamRepository.getCachedStringAgeGroup());
for (Iterator<String> it = ageGroupConfig.keys(); it.hasNext(); ) {
String key = it.next();
ageGroups.put(key, ageGroupConfig.getString(key));
}

Map context = new HashMap();
MVEL.eval(getScript(scriptName), context);
context.put("identity", dataContext);
context.put("ageGroups", ageGroups);
return MVEL.eval("return getApplicantType();", context, String.class);
} catch (Exception e) {
Log.e(getClass().getSimpleName(),"Failed to evaluate mvel script", e);
}
return null;
}

private String getScript(String scriptName) {
if(SCRIPT_CACHE.containsKey(scriptName) && SCRIPT_CACHE.get(scriptName) != null)
return SCRIPT_CACHE.get(scriptName);

try {
Optional<FileSignature> fileSignature = this.fileSignatureRepository.findByFileName(scriptName);
if(!fileSignature.isPresent()) {
Log.e("File signature not found : {}", scriptName);
return null;
}

Path path = Paths.get(context.getFilesDir().getAbsolutePath(), scriptName);
byte[] bytes;
if(fileSignature.get().getEncrypted()) {
CryptoRequestDto cryptoRequestDto = new CryptoRequestDto();
cryptoRequestDto.setValue(FileUtils.readFileToString(path.toFile(), StandardCharsets.UTF_8));
CryptoResponseDto cryptoResponseDto = clientCryptoFacade.decrypt(cryptoRequestDto);
bytes = CryptoUtil.base64decoder.decode(cryptoResponseDto.getValue());
} else {
bytes = FileUtils.readFileToByteArray(path.toFile());
}
String actualData = String.format("{\"hash\":\"%s\"}", HMACUtils2.digestAsPlainText(bytes));
if(!validateScriptSignature(fileSignature.get().getSignature(), actualData)) {
Log.e("File signature validation failed : {}", scriptName);
return null;
}
SCRIPT_CACHE.put(scriptName, new String(bytes));

} catch (Exception e) {
Log.e(getClass().getSimpleName(),"Failed to get mvel script", e);
}
return SCRIPT_CACHE.get(scriptName);
}


private boolean validateScriptSignature(String signature, String actualData) throws Exception {

String certificateData = this.certificateManagerService.getCertificate("SERVER-RESPONSE", "SIGN-VERIFY");

JWTSignatureVerifyRequestDto jwtSignatureVerifyRequestDto = new JWTSignatureVerifyRequestDto();
jwtSignatureVerifyRequestDto.setJwtSignatureData(signature);
jwtSignatureVerifyRequestDto.setActualData(CryptoUtil.encodeToURLSafeBase64(actualData.getBytes(StandardCharsets.UTF_8)));
jwtSignatureVerifyRequestDto.setCertificateData(certificateData);

JWTSignatureVerifyResponseDto verifyResponseDto = this.clientCryptoManagerService.jwtVerify(jwtSignatureVerifyRequestDto);

return verifyResponseDto.isSignatureValid();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ public void hasDocument(@NonNull String fieldId, @NonNull DocumentDataPigeon.Res

@Override
public void removeDocumentField(@NonNull String fieldId, @NonNull DocumentDataPigeon.Result<Void> result) {

try {
this.registrationService.getRegistrationDto().removeDocumentField(fieldId);
} catch (Exception e) {
Log.e(getClass().getSimpleName(), "Remove Document failed!" + Arrays.toString(e.getStackTrace()));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,16 @@ public DynamicDetailsApi(MasterDataService masterDataService, AuditManagerServic


@Override
public void getFieldValues(@NonNull String fieldName, @NonNull String langCode, @NonNull DynamicResponsePigeon.Result<List<String>> result) {
List<String> response = new ArrayList<>();
public void getFieldValues(@NonNull String fieldName, @NonNull String langCode, @NonNull DynamicResponsePigeon.Result<List<DynamicResponsePigeon.DynamicFieldData>> result) {
List<DynamicResponsePigeon.DynamicFieldData> response = new ArrayList<>();
try {
List<GenericValueDto> genericValueDtoList = this.masterDataService.getFieldValues(fieldName, langCode);
genericValueDtoList.forEach((dto) -> {
response.add(dto.getName());
DynamicResponsePigeon.DynamicFieldData data = new DynamicResponsePigeon.DynamicFieldData.Builder()
.setCode(dto.getCode())
.setName(dto.getName())
.build();
response.add(data);
});
} catch (Exception e) {
Log.e(getClass().getSimpleName(), "Fetch field values: " + Arrays.toString(e.getStackTrace()));
Expand Down
Loading

0 comments on commit 40bfdf2

Please sign in to comment.