-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #403 from ase-101/release-1.1.0
ES-842 Added readme, testcases and updated docker compose file
- Loading branch information
Showing
11 changed files
with
382 additions
and
93 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,70 @@ | ||
## Usage of [stomp_websocket.py](stomp_websocket.py) | ||
## Usage of [ws_client.py](ws_client.py) | ||
|
||
eKYC verification process is carried out through WebSocket connection and as postman currently does not support export of WS | ||
collections, we have created [ws_client.py](ws_client.py) script. | ||
|
||
TODO | ||
This script is a simple Python WebSocket client that connects to a specified WebSocket server, subscribes to a topic using | ||
the STOMP protocol, and allows the user to send messages to that topic. | ||
|
||
## Overview of the Script | ||
User Input: | ||
|
||
The script starts by asking the user for the WebSocket server URL, slot ID, and cookie value. | ||
|
||
If you are running eSignet signup service in local, then the url will be "ws://localhost:8089/v1/signup/ws" | ||
Slot ID and IDV_SLOT_ALOTTED cookie value should be taken from 'http://localhost:8088/v1/signup/identity-verification/slot' endpoint response. | ||
|
||
## WebSocket Callbacks: | ||
|
||
Several callback functions handle different events during the WebSocket connection lifecycle: | ||
on_message: Called when a message is received from the server. | ||
on_error: Called when an error occurs during the WebSocket operation. | ||
on_close: Called when the WebSocket connection is closed. | ||
on_open: Called when the WebSocket connection is successfully established. | ||
|
||
## STOMP Protocol Frames: | ||
|
||
The script uses the STOMP protocol to communicate with the WebSocket server, sending: | ||
A CONNECT frame to initiate the STOMP connection. | ||
A SUBSCRIBE frame to listen for messages on a specified topic (based on the user-provided slot_id). | ||
A SEND frame to send messages from the user input to the specified destination. | ||
|
||
## Threading for User Input: | ||
|
||
The send_user_input function runs in a separate thread, allowing the main thread to continue processing incoming messages while waiting for user input. | ||
The user can enter messages to send to the server or type "exit" to close the connection. | ||
|
||
## WebSocket Connection Management: | ||
|
||
The start_ws_client function sets up the WebSocket connection using the websocket-client library, specifying the URI and headers (including cookies). | ||
The connection is established with ws.run_forever(), which keeps the connection alive and processes incoming messages. | ||
|
||
|
||
## How to use the script? | ||
1. Install Required Library: Ensure you have the websocket-client library installed. You can install it using: | ||
|
||
`pip install websocket-client` | ||
|
||
2. Run the Script: Execute the script in your terminal or command prompt: | ||
|
||
`python ws_client.py` | ||
|
||
3. Provide Input: When prompted, enter the base URL (WebSocket server address), slot ID, and cookie value. | ||
|
||
4. Sending Messages: When prompted, to enter message to send, type the message as below, there are 3 different messages | ||
|
||
START step message -> `{"slotId":"slotId","stepCode":"START","frames":[{"frame":"","order":"0"}]}` | ||
|
||
Other step messages -> `{"slotId":"slotId","stepCode":"<step_name as in the received messages>","frames":[{"frame":"","order":"0"}]}` | ||
|
||
END step message -> `{"slotId":"slotId","stepCode":"END","frames":[{"frame":"","order":"0"}]}` | ||
|
||
5. Receiving Messages: Any messages sent from the server to the subscribed topic will be printed to the console as they are received. | ||
|
||
|
||
## Example interaction | ||
|
||
|
||
![img.png](interaction_1.png) | ||
|
||
![img_1.png](interaction_2.png) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import websocket | ||
import threading | ||
import sys | ||
|
||
base_url=input("Enter the base URL (ws://localhost:8089/v1/signup/ws): ") | ||
slot_id=input("Enter the slotId: ") | ||
cookie=input("Enter the cookie value: ") | ||
|
||
def on_message(ws, message): | ||
print("===================") | ||
print(f"Received {message}") | ||
print("===================") | ||
|
||
def on_error(ws, error): | ||
print("Error:", error) | ||
|
||
def on_close(ws, close_status_code, close_msg): | ||
print("Connection closed:", close_status_code, close_msg) | ||
|
||
def on_open(ws): | ||
# Send STOMP CONNECT frame | ||
connect_frame = "CONNECT\naccept-version:1.2\n\n\x00" | ||
ws.send(connect_frame) | ||
print(f"{connect_frame}") | ||
|
||
# Subscribe to the /topic/slotId destination | ||
subscribe_frame = f"SUBSCRIBE\nid:sub-0\ndestination:/topic/{slot_id}\n\n\x00" | ||
ws.send(subscribe_frame) | ||
print(f"{subscribe_frame}") | ||
|
||
# Start a new thread to take user input and send messages to the WebSocket | ||
threading.Thread(target=send_user_input, args=(ws,)).start() | ||
|
||
def send_user_input(ws): | ||
try: | ||
while True: | ||
user_input = input("Enter a message to send: ") | ||
if user_input.lower() == "exit": | ||
print("Closing connection...") | ||
ws.close() | ||
break | ||
|
||
# Send user input as a message to the WebSocket | ||
send_frame = f"SEND\ndestination:/v1/signup/ws/process-frame\ncontent-type:application/json\n\n{user_input}\x00" | ||
ws.send(send_frame) | ||
print(f"{send_frame}") | ||
|
||
except Exception as e: | ||
print("Error sending message:", e) | ||
|
||
# WebSocket connection | ||
def start_ws_client(): | ||
uri = f"{base_url}?slotId={slot_id}" # Replace with your WebSocket server's URI | ||
headers = {"Cookie": f"IDV_SLOT_ALLOTTED={cookie}"} # Replace with any necessary headers | ||
|
||
ws = websocket.WebSocketApp( | ||
uri, | ||
header=headers, | ||
on_open=on_open, | ||
on_message=on_message, | ||
on_error=on_error, | ||
on_close=on_close | ||
) | ||
|
||
# Run the WebSocket with a blocking loop | ||
ws.run_forever() | ||
|
||
# Run the subscribe function | ||
if __name__ == "__main__": | ||
start_ws_client() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
77 changes: 77 additions & 0 deletions
77
signup-service/src/test/java/io/mosip/signup/helper/CryptoHelperTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package io.mosip.signup.helper; | ||
|
||
import io.mosip.esignet.core.util.IdentityProviderUtil; | ||
import io.mosip.signup.services.CacheUtilService; | ||
import org.junit.Before; | ||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
import org.mockito.InjectMocks; | ||
import org.mockito.Mock; | ||
import org.mockito.Mockito; | ||
import org.mockito.junit.MockitoJUnitRunner; | ||
import org.springframework.test.util.ReflectionTestUtils; | ||
|
||
import javax.crypto.Cipher; | ||
import javax.crypto.KeyGenerator; | ||
import javax.crypto.SecretKey; | ||
import javax.crypto.spec.IvParameterSpec; | ||
import java.nio.charset.StandardCharsets; | ||
import java.security.NoSuchAlgorithmException; | ||
import java.util.Base64; | ||
|
||
import static org.junit.Assert.*; | ||
import static org.mockito.Mockito.*; | ||
|
||
@RunWith(MockitoJUnitRunner.class) | ||
public class CryptoHelperTest { | ||
|
||
@InjectMocks | ||
private CryptoHelper cryptoHelper; | ||
|
||
@Mock | ||
private CacheUtilService cacheUtilService; | ||
|
||
private static String symmetricAlgorithm = "AES/CFB/PKCS5Padding"; | ||
private static String symmetricKeyAlgorithm = "AES"; | ||
private static int symmetricKeySize = 256; | ||
|
||
String keyAlias = "aced6829-63bb-5b28-8898-64efd90a70fa"; | ||
private static String secretKey; | ||
|
||
static { | ||
KeyGenerator keyGenerator = null; | ||
try { | ||
keyGenerator = KeyGenerator.getInstance(symmetricKeyAlgorithm); | ||
} catch (NoSuchAlgorithmException e) { | ||
throw new RuntimeException(e); | ||
} | ||
keyGenerator.init(symmetricKeySize); | ||
secretKey = IdentityProviderUtil.b64Encode(keyGenerator.generateKey().getEncoded()); | ||
} | ||
|
||
@Before | ||
public void setUp() { | ||
when(cacheUtilService.getSecretKey(Mockito.anyString())).thenReturn(secretKey).thenReturn(secretKey); | ||
|
||
ReflectionTestUtils.setField(cryptoHelper, "symmetricAlgorithm", symmetricAlgorithm); | ||
ReflectionTestUtils.setField(cryptoHelper, "symmetricKeyAlgorithm", symmetricKeyAlgorithm); | ||
ReflectionTestUtils.setField(cryptoHelper, "symmetricKeySize", symmetricKeySize); | ||
} | ||
|
||
@Test | ||
public void symmetricEncrypt_withValidInput_thenPass() { | ||
String data = "test data test fatata"; | ||
String encryptedData = cryptoHelper.symmetricEncrypt(data); | ||
|
||
assertNotNull(encryptedData); | ||
verify(cacheUtilService, times(1)).getActiveKeyAlias(); | ||
verify(cacheUtilService, times(1)).getSecretKey(keyAlias); | ||
|
||
String decryptedData = cryptoHelper.symmetricDecrypt(encryptedData); | ||
assertNotNull(decryptedData); | ||
assertEquals(data, decryptedData); | ||
verify(cacheUtilService, times(1)).getActiveKeyAlias(); | ||
verify(cacheUtilService, times(2)).getSecretKey(keyAlias); | ||
} | ||
} | ||
|
Oops, something went wrong.