Skip to content

Commit

Permalink
[MOSIP-35455] Unlimited download support and changing the transaction…
Browse files Browse the repository at this point in the history
…Allowed (Using request param) for share to be created in standalone mode.

Signed-off-by: Ashok Kumar Sharma <[email protected]>
  • Loading branch information
ashok-ksharma committed Oct 3, 2024
1 parent 67a213b commit ac79488
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 37 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Refer to [MOSIP docs](https://docs.mosip.io/1.2.0/modules/datashare).
API documentation is available [here](https://docs.mosip.io/1.2.0/api).

## Durian in standalone mode
Durian application has dependency on the external services such as partner management service for policy verification and key management service for crypto operations such as signature computation, Encryption etc.
Durian application has dependency on other MOSIP module services such as partner management service for policy verification and key management service for crypto operations such as signature computation, Encryption etc.
Durian application can be configured in the standalone mode where it doesn't depend on the external services to perform the operations.
To configure the same, below properties should be used:
1. **mosip.data.share.standalone.mode.enabled:** This property enables application to run in standalone mode. The value for the property should be **true**.
Expand All @@ -22,7 +22,7 @@ To configure the same, below properties should be used:
4. **mosip.data.share.static-policy.subscriber-id:** This property contains the subscriber id which will be used for creating the data share. This property must match with the {subscriberId} received in the **/create** API otherwise error will be thrown.
5. **mosip.data.share.signature.disabled:** This property enables/disables the signature computation for the created data share. This property value must be **true**.

Standalone mode enablement is not advisable because it bypasses the policy verification and signature computation for the created data share. It makes difficult to detect the integrity issue and restricts dynamic policy based data share generation.
Standalone mode enablement is not advisable as part of MOSIP identity platform deployment because it bypasses the policy verification and signature computation for the created data share. It makes difficult to detect the integrity issue and restricts dynamic policy based data share generation.

## License
This project is licensed under the terms of [Mozilla Public License 2.0](LICENSE).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ public class DataShareController {
@ApiResponse(responseCode = "404", description = "Not Found" ,content = @Content(schema = @Schema(hidden = true)))})
public ResponseEntity<Object> createDataShare(@RequestBody MultipartFile file,
@PathVariable("policyId") String policyId, @PathVariable("subscriberId") String subscriberId,
@Parameter(description = "Number of allowed transaction in standalone mode") @RequestParam(required = false, name = "transactionsAllowed") String transactionsAllowed) {
@Parameter(description = "Usage count for standalone mode") @RequestParam(required = false, name = "usageCountForStandaloneMode") String usageCountForStandaloneMode) {


DataShare dataShare = dataShareService.createDataShare(policyId, subscriberId, file, transactionsAllowed);
DataShare dataShare = dataShareService.createDataShare(policyId, subscriberId, file, usageCountForStandaloneMode);
return ResponseEntity.status(HttpStatus.OK)
.body(buildDataShareResponse(dataShare));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ public interface DataShareService {
* @param policyId the policy id
* @param subscriberId the subscriber id
* @param file the file
* @param transactionsAllowed the number of transaction allowed in standalone mode
* @param usageCountForStandaloneMode the usage count for standalone mode
* @return the data share
*/
public DataShare createDataShare(String policyId, String subscriberId,
MultipartFile file, String transactionsAllowed);
MultipartFile file, String usageCountForStandaloneMode);

/**
* Gets the data file.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ public class DataShareServiceImpl implements DataShareService {
/** The Constant DATETIME_PATTERN. */
private static final String DATETIME_PATTERN = "mosip.data.share.datetime.pattern";

/** The constant defines unlimited transaction allowed */
public static final int UNLIMITED_TRANSACTION_ALLOWED = -1;
/** The constant defines unlimited usage count for the created share */
public static final int UNLIMITED_USAGE_COUNT = -1;

/*
* (non-Javadoc)
Expand All @@ -143,7 +143,7 @@ public class DataShareServiceImpl implements DataShareService {
*/
@Override
public DataShare createDataShare(String policyId, String subscriberId, MultipartFile file,
String transactionsAllowed) {
String usageCountForStandaloneMode) {
LOGGER.debug(LoggerFileConstant.SESSIONID.toString(), LoggerFileConstant.POLICYID.toString(), policyId,
"DataShareServiceImpl::createDataShare()::entry");
DataShare dataShare = new DataShare();
Expand All @@ -160,7 +160,7 @@ public DataShare createDataShare(String policyId, String subscriberId, Multipart
dataSharePolicy = policyDetailResponse.getPolicies().getDataSharePolicies();
policyPublishDate = policyDetailResponse.getPublishDate();
} else {
dataSharePolicy = policyUtil.getStaticDataSharePolicy(policyId, subscriberId, transactionsAllowed);
dataSharePolicy = policyUtil.getStaticDataSharePolicy(policyId, subscriberId, usageCountForStandaloneMode);
}
byte[] encryptedData = null;
if (PARTNERBASED.equalsIgnoreCase(dataSharePolicy.getEncryptionType())) {
Expand Down Expand Up @@ -335,8 +335,8 @@ private boolean getAndUpdateMetaData(String randomShareKey, String policyId, Str
LOGGER.info(LoggerFileConstant.SESSIONID.toString(), LoggerFileConstant.POLICYID.toString(), policyId,
"Successfully update the metadata");
}
/* Unlimited transaction is allowed hence not updating the metadata*/
if(transactionAllowed == UNLIMITED_TRANSACTION_ALLOWED) {
/* Unlimited usage is allowed hence not updating the metadata*/
if(transactionAllowed == UNLIMITED_USAGE_COUNT) {
isDataShareAllow = true;
LOGGER.info(LoggerFileConstant.SESSIONID.toString(), LoggerFileConstant.POLICYID.toString(), policyId,
"Unlimited usage of data share is configured hence not updating metadata");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,23 +133,24 @@ public void emptyPartnerPolicyCache() {
* Provides static data share policy for sharing the data.
* @param policyId Policy Id from request
* @param subscriberId Subscriber Id from request
* @param usageCountForStandaloneMode Usage count for standalone mode from request
* @return the DataShareDto object
*/
public DataShareDto getStaticDataSharePolicy(String policyId, String subscriberId, String transactionsAllowed) {
public DataShareDto getStaticDataSharePolicy(String policyId, String subscriberId, String usageCountForStandaloneMode) {
LOGGER.debug(LoggerFileConstant.SESSIONID.toString(), LoggerFileConstant.POLICYID.toString(),
policyId, "PolicyUtil::getStaticDataSharePolicy()::entry");
try {
if (!policyId.equals(staticPolicyId) || !subscriberId.equals(staticSubscriberId))
throw new PolicyException("Either Policy Id or Subscriber Id not matching with configured in system");

DataShareDto dataShareDto = mapper.readValue(staticPolicyJson, DataShareDto.class);
/* transactionAllowed attribute from request will be taken precedence
over the configured in static data share policy */
if(StringUtils.isNotEmpty(transactionsAllowed)) {
validateTransactionAllowed(transactionsAllowed);
/* usageCountForStandaloneMode attribute from request will take precedence
over the transactionAllowed configured in static data share policy in standalone mode */
if(StringUtils.isNotEmpty(usageCountForStandaloneMode)) {
validateUsageCountForStandaloneMode(usageCountForStandaloneMode);
LOGGER.debug(LoggerFileConstant.SESSIONID.toString(), LoggerFileConstant.POLICYID.toString(), policyId,
"Overriding the transactionAllowed configured in static data share policy : " + transactionsAllowed);
dataShareDto.setTransactionsAllowed(transactionsAllowed);
"Overriding the transactionAllowed configured in static data share policy : " + usageCountForStandaloneMode);
dataShareDto.setTransactionsAllowed(usageCountForStandaloneMode);
}
LOGGER.debug(LoggerFileConstant.SESSIONID.toString(), LoggerFileConstant.POLICYID.toString(), policyId,
"PolicyUtil::getStaticDataSharePolicy()::exit");
Expand All @@ -164,14 +165,14 @@ public DataShareDto getStaticDataSharePolicy(String policyId, String subscriberI
}
}

private void validateTransactionAllowed(String transactionsAllowed) {
private void validateUsageCountForStandaloneMode(String usageCountForStandaloneMode) {
try {
int transactions = Integer.parseInt(transactionsAllowed);
if(transactions < DataShareServiceImpl.UNLIMITED_TRANSACTION_ALLOWED)
throw new PolicyException("transactionsAllowed must not be less than " +
DataShareServiceImpl.UNLIMITED_TRANSACTION_ALLOWED);
int usageCount = Integer.parseInt(usageCountForStandaloneMode);
if(usageCount == 0 || usageCount < DataShareServiceImpl.UNLIMITED_USAGE_COUNT)
throw new PolicyException("usageCountForStandaloneMode must not be 0 or less than " +
DataShareServiceImpl.UNLIMITED_USAGE_COUNT);
} catch (NumberFormatException e) {
throw new PolicyException("transactionsAllowed must be number");
throw new PolicyException("usageCountForStandaloneMode must be a number");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,30 +226,37 @@ public void getStaticDateSharePolicyWithTransactionAllowedSuccessTest() throws J
dataShareDto.setValidForInMinutes("30");
Mockito.when(objectMapper.readValue(Mockito.anyString(), Mockito.any(Class.class))).
thenReturn(dataShareDto);
String transactionAllowed = "10";
DataShareDto response = policyUtil.getStaticDataSharePolicy("static-policyid", "static-subscriberid", transactionAllowed);
assertEquals(response.getTransactionsAllowed(), transactionAllowed);
String usageCountForStandaloneMode = "10";
DataShareDto response = policyUtil.getStaticDataSharePolicy("static-policyid", "static-subscriberid", usageCountForStandaloneMode);
assertEquals(response.getTransactionsAllowed(), usageCountForStandaloneMode);
}

@Test(expected = PolicyException.class)
public void validateTransactionAllowedWithInvalidValue() {
String transactionAllowed = "abc";
public void validateUsageCountForStandaloneModeWithInvalidValue() {
String usageCountForStandaloneMode = "abc";
ReflectionTestUtils.invokeMethod(policyUtil,
"validateTransactionAllowed", transactionAllowed);
"validateUsageCountForStandaloneMode", usageCountForStandaloneMode);
}

@Test(expected = PolicyException.class)
public void validateTransactionAllowedWithValueLessThanOne() {
String transactionAllowed = "-2";
public void validateUsageCountForStandaloneModeWithZero() {
String usageCountForStandaloneMode = "0";
ReflectionTestUtils.invokeMethod(policyUtil,
"validateTransactionAllowed", transactionAllowed);
"validateUsageCountForStandaloneMode", usageCountForStandaloneMode);
}

@Test(expected = PolicyException.class)
public void validateUsageCountForStandaloneModeWithValueLessThanOne() {
String usageCountForStandaloneMode = "-2";
ReflectionTestUtils.invokeMethod(policyUtil,
"validateUsageCountForStandaloneMode", usageCountForStandaloneMode);
}

@Test
public void validateTransactionAllowedWithValidValue() {
String transactionAllowed = "10";
public void validateUsageCountForStandaloneModeWithValidValue() {
String usageCountForStandaloneMode = "10";
ReflectionTestUtils.invokeMethod(policyUtil,
"validateTransactionAllowed", transactionAllowed);
"validateUsageCountForStandaloneMode", usageCountForStandaloneMode);
}

}

0 comments on commit ac79488

Please sign in to comment.