Skip to content

Commit

Permalink
Merge pull request #113 from smswithoutborders/feature/grpc_api
Browse files Browse the repository at this point in the history
feat: add phone number, country code, and add password validations.
  • Loading branch information
PromiseFru authored Jul 6, 2024
2 parents 3631a4c + 6811720 commit 8436045
Show file tree
Hide file tree
Showing 11 changed files with 277 additions and 138 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,4 @@ dmypy.json
!vault.proto

# Platforms info
supported_platforms.json
platforms.json
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ COPY . .
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf

RUN pip install -U pip && \
pip install --no-cache-dir wheel && \
pip install -U setuptools wheel && \
pip install --no-cache-dir --force-reinstall -r requirements.txt && \
usermod -u 1000 www-data && \
usermod -G root www-data
Expand Down
12 changes: 6 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
python=python3
SUPPORTED_PLATFORMS_URL="https://raw.githubusercontent.com/smswithoutborders/SMSWithoutBorders-Publisher/feature/grpc-api/supported_platforms.json"
SUPPORTED_PLATFORMS_URL="https://raw.githubusercontent.com/smswithoutborders/SMSWithoutBorders-Publisher/feature/grpc-api/platforms.json"

define log_message
@echo "[$(shell date +'%Y-%m-%d %H:%M:%S')] - $1"
Expand Down Expand Up @@ -73,13 +73,13 @@ grpc-internal-server-start:
@$(python) -u grpc_internal_server.py
$(call log_message,INFO - gRPC internal server started successfully.)

update-supported-platforms:
$(call log_message,INFO - Starting download of supported platforms JSON file ...)
@curl -o supported_platforms.json -L "${SUPPORTED_PLATFORMS_URL}"
$(call log_message,INFO - Supported platforms JSON file downloaded successfully.)
download-platforms:
$(call log_message,INFO - Starting download of platforms JSON file ...)
@curl -o platforms.json -L "${SUPPORTED_PLATFORMS_URL}"
$(call log_message,INFO - Platforms JSON file downloaded successfully.)

rest-server-setup: dummy-user-inject start
$(call log_message,INFO - REST server setup completed.)

grpc-server-setup: update-supported-platforms grpc-compile grpc-server-start
grpc-server-setup: download-platforms grpc-compile grpc-server-start
$(call log_message,INFO - gRPC server setup completed.)
57 changes: 46 additions & 11 deletions docs/grpc.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,13 @@ creation process.
> The table lists only the required fields for this step. Other fields will be
> ignored.
| Field | Type | Description |
| ------------ | ------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| phone_number | string | The phone number associated with the entity. It should be in [E164 format](https://en.wikipedia.org/wiki/E.164). e.g., +237123456789. |
| Field | Type | Description |
| ------------------------ | ------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| phone_number | string | The phone number associated with the entity. It should be in [E164 format](https://en.wikipedia.org/wiki/E.164). e.g., +237123456789. |
| country_code | string | The [ISO 3166-1 alpha-2 code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) associated with the phone number. e.g., `CM` for Cameroon. |
| password | string | A secure password for the entity. |
| client_publish_pub_key | string | An `X25519` public key for publishing, `base64 encoded`. |
| client_device_id_pub_key | string | An `X25519` public key for device ID, `base64 encoded`. |

---

Expand Down Expand Up @@ -172,9 +176,23 @@ creation process.

```bash
grpcurl -plaintext \
-d '{"phone_number": "+237123456789"}' \
-d @ \
-proto protos/v1/vault.proto \
localhost:6000 vault.v1.Entity/CreateEntity
localhost:6000 vault.v1.Entity/CreateEntity <payload.json
```

---

**Sample payload.json**

```json
{
"country_code": "CM",
"phone_number": "+237123456789",
"password": "Password@123",
"client_publish_pub_key": "x25519 client publish public key",
"client_device_id_pub_key": "x25519 client device_id public key"
}
```

---
Expand Down Expand Up @@ -317,10 +335,12 @@ of ownership for the phone number.
> The table lists only the required fields for this step. Other fields will be
> ignored.
| Field | Type | Description |
| ------------ | ------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| phone_number | string | The phone number associated with the entity. It should be in [E164 format](https://en.wikipedia.org/wiki/E.164). e.g., +237123456789. |
| password | string | A secure password for the entity. |
| Field | Type | Description |
| ------------------------ | ------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| phone_number | string | The phone number associated with the entity. It should be in [E164 format](https://en.wikipedia.org/wiki/E.164). e.g., +237123456789. |
| password | string | A secure password for the entity. |
| client_publish_pub_key | string | An `X25519` public key for publishing, `base64 encoded`. |
| client_device_id_pub_key | string | An `X25519` public key for device ID, `base64 encoded`. |

---

Expand Down Expand Up @@ -365,9 +385,22 @@ of ownership for the phone number.

```bash
grpcurl -plaintext \
-d '{"phone_number": "+237123456789", "password": "Password@123"}' \
-d @ \
-proto protos/v1/vault.proto \
localhost:6000 vault.v1.Entity/AuthenticateEntity
localhost:6000 vault.v1.Entity/AuthenticateEntity <payload.json
```

---

**Sample payload.json**

```json
{
"phone_number": "+237123456789",
"password": "Password@123",
"client_publish_pub_key": "x25519 client publish public key",
"client_device_id_pub_key": "x25519 client device_id public key"
}
```

---
Expand Down Expand Up @@ -406,6 +439,7 @@ localhost:6000 vault.v1.Entity/AuthenticateEntity
| Field | Type | Description |
| ------------------------ | ------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| phone_number | string | The phone number associated with the entity. It should be in [E164 format](https://en.wikipedia.org/wiki/E.164). e.g., +237123456789. |
| password | string | A secure password for the entity. |
| ownership_proof_response | string | The proof response from the previous step. |
| client_publish_pub_key | string | An `X25519` public key for publishing, `base64 encoded`. |
| client_device_id_pub_key | string | An `X25519` public key for device ID, `base64 encoded`. |
Expand Down Expand Up @@ -466,6 +500,7 @@ localhost:6000 vault.v1.Entity/AuthenticateEntity <payload.json
```json
{
"phone_number": "+237123456789",
"password": "Password@123",
"client_publish_pub_key": "x25519 client publish public key",
"client_device_id_pub_key": "x25519 client device_id public key",
"ownership_proof_response": "123456"
Expand Down
31 changes: 31 additions & 0 deletions example.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
HOST=localhost
PORT=9000
GRPC_HOST=localhost
GRPC_PORT=8000
GRPC_SSL_PORT=8001
GRPC_INTERNAL_PORT=8443
GRPC_INTERNAL_SSL_PORT=8444
SSL_SERVER_NAME=localhost
SSL_PORT=9001
SSL_CERTIFICATE=
SSL_KEY=
SSL_PEM=
SHARED_KEY=
HASHING_SALT=
BROADCAST_WHITELIST=
MYSQL_HOST=127.0.0.1
MYSQL_USER=
MYSQL_PASSWORD=
MYSQL_DATABASE=smswithoutborders_vault
TWILIO_ACCOUNT_SID=
TWILIO_AUTH_TOKEN=
TWILIO_SERVICE_SID=
MOCK_OTP=false
RECAPTCHA_SECRET_KEY=
ENABLE_RECAPTCHA=
ORIGINS=
GMAIL_CREDENTIALS=
TWITTER_CREDENTIALS=
TELEGRAM_CREDENTIALS=
TELEGRAM_RECORDS=
KEYSTORE_PATH=
19 changes: 14 additions & 5 deletions grpc_internal_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import logging
import os
from concurrent import futures
from datetime import datetime

import grpc
from grpc_interceptor import ServerInterceptor
Expand All @@ -28,6 +29,7 @@ def __init__(self):
Initialize the LoggingInterceptor.
"""
self.logger = logger
self.server_protocol = "HTTP/2.0"

def intercept(self, method, request_or_iterator, context, method_name):
"""
Expand All @@ -36,14 +38,21 @@ def intercept(self, method, request_or_iterator, context, method_name):
response = method(request_or_iterator, context)
if context.details():
self.logger.error(
"[RESPONSE] -- %s - %s - %s",
str(context.code()).split(".")[1],
method_name,
'%s - - [%s] "%s %s" %s -',
context.peer(),
datetime.now().strftime("%B %d, %Y %H:%M:%S"),
method_name,
self.server_protocol,
str(context.code()).split(".")[1],
)
else:
self.logger.info(
"[RESPONSE] -- %s - %s - %s", "OK", method_name, context.peer()
self.logger.error(
'%s - - [%s] "%s %s" %s -',
context.peer(),
datetime.now().strftime("%B %d, %Y %H:%M:%S"),
method_name,
self.server_protocol,
"OK",
)
return response

Expand Down
19 changes: 14 additions & 5 deletions grpc_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import logging
import os
from concurrent import futures
from datetime import datetime

import grpc
from grpc_interceptor import ServerInterceptor
Expand All @@ -28,6 +29,7 @@ def __init__(self):
Initialize the LoggingInterceptor.
"""
self.logger = logger
self.server_protocol = "HTTP/2.0"

def intercept(self, method, request_or_iterator, context, method_name):
"""
Expand All @@ -36,14 +38,21 @@ def intercept(self, method, request_or_iterator, context, method_name):
response = method(request_or_iterator, context)
if context.details():
self.logger.error(
"[RESPONSE] -- %s - %s - %s",
str(context.code()).split(".")[1],
method_name,
'%s - - [%s] "%s %s" %s -',
context.peer(),
datetime.now().strftime("%B %d, %Y %H:%M:%S"),
method_name,
self.server_protocol,
str(context.code()).split(".")[1],
)
else:
self.logger.info(
"[RESPONSE] -- %s - %s - %s", "OK", method_name, context.peer()
self.logger.error(
'%s - - [%s] "%s %s" %s -',
context.peer(),
datetime.now().strftime("%B %d, %Y %H:%M:%S"),
method_name,
self.server_protocol,
"OK",
)
return response

Expand Down
20 changes: 0 additions & 20 deletions src/grpc_entity_internal_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
load_key,
get_configs,
encrypt_and_encode,
is_valid_x25519_public_key,
decrypt_and_decode,
load_keypair_object,
get_supported_platforms,
Expand Down Expand Up @@ -98,25 +97,6 @@ def validate_request_fields(context, request, response, required_fields):
grpc.StatusCode.INVALID_ARGUMENT,
)

x25519_fields = [
"client_publish_pub_key",
"client_device_id_pub_key",
]
invalid_fields = {}

for field in set(x25519_fields) & set(required_fields):
is_valid, error = is_valid_x25519_public_key(getattr(request, field))
if not is_valid:
invalid_fields[field] = error

if invalid_fields:
return error_response(
context,
response,
f"Invalid fields: {invalid_fields}",
grpc.StatusCode.INVALID_ARGUMENT,
)

return None


Expand Down
Loading

0 comments on commit 8436045

Please sign in to comment.