Skip to content

Commit

Permalink
[PHEE-554] Auto generate json web test Signature in postman for bulk …
Browse files Browse the repository at this point in the history
…apis (#91)

* basic x-signature util api working

* raw body type inclusive

* add service layer

* cleanup

* get private key in headers, sha3->sha
  • Loading branch information
Anover000 authored Feb 2, 2024
1 parent 6299706 commit 8a50ee1
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 0 deletions.
74 changes: 74 additions & 0 deletions src/main/java/org/apache/fineract/api/UtilityApi.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package org.apache.fineract.api;

import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.fineract.service.UtilityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.stream.Collectors;


@RestController
@SecurityRequirement(name = "auth")
@RequestMapping("/api/v1")
@Tag(name = "Users API")
public class UtilityApi {

@Autowired
UtilityService utilityService;

@PostMapping("/util/x-signature")
public ResponseEntity<String> getXSignature(
@RequestHeader("X-CorrelationID") String correlationId,
@RequestHeader("Platform-TenantId") String tenantId,
@RequestHeader("privateKey") String privateKey,
@RequestParam(required = false) MultipartFile data,
@RequestBody(required = false) String rawData
)throws NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeySpecException, InvalidKeyException, IOException {

String tobeHashed = "";

if(data != null && !data.isEmpty()) {
String fileContent;
try {
fileContent = readInputStreamToString(data.getInputStream());
} catch (IOException e) {
e.printStackTrace();
return new ResponseEntity<>("Failed to read file content", HttpStatus.INTERNAL_SERVER_ERROR);
}
tobeHashed = correlationId+":"+tenantId+":"+fileContent;
}
else if(rawData != null && !rawData.isEmpty()){
tobeHashed = correlationId+":"+tenantId+":"+rawData;
}
else {
return new ResponseEntity<>("No file or raw data provided", HttpStatus.BAD_REQUEST);
}

return new ResponseEntity<>(utilityService.getSignature(tobeHashed, privateKey), HttpStatus.OK);
}

private String readInputStreamToString(InputStream inputStream) throws IOException {
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream))) {
return bufferedReader.lines().collect(Collectors.joining("\n"));
}
}
}
15 changes: 15 additions & 0 deletions src/main/java/org/apache/fineract/service/UtilityService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.apache.fineract.service;

import org.springframework.stereotype.Service;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;

@Service
public interface UtilityService {

String getSignature(String toBeHashed, String privateKeyString)throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException;
}
39 changes: 39 additions & 0 deletions src/main/java/org/apache/fineract/service/UtilityServiceImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.apache.fineract.service;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.stereotype.Service;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.EncodedKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;

@Service
public class UtilityServiceImpl implements UtilityService{
@Override
public String getSignature(String tobeHashed, String privateKeyString)throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException {
String hashData = (new DigestUtils("SHA-256")).digestAsHex(tobeHashed);

Cipher cipher = Cipher.getInstance("RSA");
PrivateKey publicKey = getPrivateKeyFromString(privateKeyString);
cipher.init(1, publicKey);
byte[] cipherText = cipher.doFinal(hashData.getBytes(StandardCharsets.UTF_8));

return Base64.encodeBase64String(cipherText);
}

public static PrivateKey getPrivateKeyFromString(String key) throws NoSuchAlgorithmException, InvalidKeySpecException {
byte[] keyBytes = Base64.decodeBase64(key);
EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(keySpec);
}
}

0 comments on commit 8a50ee1

Please sign in to comment.