Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion agrirouter/auth/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,14 @@ def verify(self, public_key) -> None:
encoded_data = self._state + self._token
unquoted_signature = unquote(self._signature)
encoded_signature = base64.b64decode(unquoted_signature.encode("utf-8"))
self._was_verified = True

try:
verify_signature(encoded_data, encoded_signature, public_key)
except InvalidSignature:
print("Response is invalid: invalid signature.")
self._is_valid = False
finally:
self._was_verified = True

self._is_valid = True

Expand Down
5 changes: 3 additions & 2 deletions agrirouter/messaging/certification.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
import tempfile


from agrirouter.onboarding.response import BaseOnboardingResonse
from agrirouter.onboarding.response import SoftwareOnboardingResponse


def create_certificate_file(onboard_response: BaseOnboardingResonse):
def create_certificate_file_from_pen(onboard_response: SoftwareOnboardingResponse):

dir_ = tempfile.mkdtemp()
prefix = onboard_response.get_sensor_alternate_id()
data = onboard_response.get_authentication().get_certificate()
Expand Down
58 changes: 52 additions & 6 deletions agrirouter/messaging/clients/http.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,62 @@
import http.client
import json
import os
import ssl

from agrirouter.messaging.certification import create_certificate_file_from_pen
from agrirouter.onboarding.dto import ConnectionCriteria
from agrirouter.onboarding.response import SoftwareOnboardingResponse


class HttpClient:

headers = {"Content-Type": "application/json"}

def __init__(self,
on_message_callback: callable,
timeout=20
):
def __init__(
self,
on_message_callback: callable,
timeout=20
):
self.on_message_callback = on_message_callback
self.timeout = timeout

def publish(self):
pass
@staticmethod
def make_connection(certificate_file_path: str, onboard_response: SoftwareOnboardingResponse):
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
context.load_cert_chain(
certfile=certificate_file_path,
keyfile=certificate_file_path,
password=onboard_response.get_authentication().get_secret(),
)
connection = http.client.HTTPSConnection(
host=onboard_response.connection_criteria.get_host(),
port=onboard_response.connection_criteria.get_port(),
context=context
)
return connection

def send(self, method: str, onboard_response: SoftwareOnboardingResponse, request_body=None):
certificate_file_path = create_certificate_file_from_pen(onboard_response)
try:
connection = self.make_connection(certificate_file_path, onboard_response)
if request_body is not None:
connection.request(
method=method,
url=onboard_response.get_connection_criteria().get_measures(),
headers=self.headers,
body=json.dumps(request_body)
)
else:
connection.request(
method=method,
url=onboard_response.get_connection_criteria().get_measures(),
headers=self.headers,
)
response = connection.getresponse()
finally:
os.remove(certificate_file_path)

return response

def subscribe(self):
pass
Expand Down
22 changes: 9 additions & 13 deletions agrirouter/messaging/services/commons.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import requests

from agrirouter.messaging.certification import create_certificate_file
from agrirouter.messaging.clients.http import HttpClient
from agrirouter.messaging.clients.mqtt import MqttClient
from agrirouter.messaging.messages import Message
from agrirouter.messaging.request import MessageRequest
Expand Down Expand Up @@ -32,21 +33,16 @@ def send(self, parameters):

class HttpMessagingService(AbstractMessagingClient):

def __init__(self, on_message_callback, timeout):
self.client = HttpClient(on_message_callback=on_message_callback, timeout=timeout)

def send(self, parameters) -> MessagingResult:
request = self.create_message_request(parameters)
cert_file_path = create_certificate_file(parameters.get_onboarding_response())
try:
response = requests.post(
url=parameters.get_onboarding_response().get_connection_criteria().get_measures(),
headers={"Content-type": "application/json"},
data=request.json_serialize(),
cert=(
cert_file_path,
parameters.get_onboarding_response().get_authentication().get_secret()
),
)
finally:
os.remove(cert_file_path)
response = self.client.send(
"POST",
parameters.get_onboarding_response(),
request
)
result = MessagingResult([parameters.get_message_id()])
return result

Expand Down
23 changes: 10 additions & 13 deletions agrirouter/messaging/services/http/outbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,23 @@

import requests

from agrirouter.messaging.clients.http import HttpClient
from agrirouter.messaging.result import OutboxResponse

from agrirouter.messaging.certification import create_certificate_file
from agrirouter.messaging.certification import create_certificate_file_from_pen


class OutboxService:

def __init__(self, on_message_callback, timeout):
self.client = HttpClient(on_message_callback=on_message_callback, timeout=timeout)

def fetch(self, onboarding_response) -> OutboxResponse:
cert_file_path = create_certificate_file(onboarding_response)
try:
response = requests.get(
url=onboarding_response.get_connection_criteria().get_commands(),
headers={"Content-type": "application/json"},
cert=(
cert_file_path,
onboarding_response.get_authentication().get_secret()
),
)
finally:
os.remove(cert_file_path)
response = self.client.send(
"GET",
onboarding_response,
None
)

outbox_response = OutboxResponse(status_code=response.status_code)
outbox_response.json_deserialize(response.json()["contents"])
Expand Down
Loading