Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
937bb12
Create EnvironmentService class. Move exceptions file from auth to en…
dastier Sep 27, 2021
95d6083
Fix exceptions in auth
dastier Sep 27, 2021
cb6191b
Change message of InvalidEnvironmentSetup
dastier Sep 27, 2021
c0569f0
Implement Onboarding
dastier Sep 28, 2021
e039b75
Fix import bug in onboarding/onboarding.py
dastier Sep 28, 2021
eaaacc4
Fix bug in OnboardingParameter.get_body_params() method
dastier Sep 28, 2021
db3f2e0
Fix OnboardingParameter.create_request(), OnboardingParameter.create_…
dastier Sep 28, 2021
ad16fc5
Fix revoking
dastier Sep 28, 2021
9372b54
Implement request signing in onboarding
dastier Sep 28, 2021
810cb18
Implement request signing in revoking
dastier Sep 28, 2021
0fd281e
Implement request signing in auth
dastier Sep 28, 2021
65f5662
Refactor RequestNotSigned exception
dastier Sep 29, 2021
d96a4f3
Create requeirements.txt
dastier Sep 29, 2021
bae3e4a
Merge pull request #1 from DKE-Data/Implement_Onboarding
dastier Sep 29, 2021
bc5cc97
Move files to common agrirouter directory
Oct 4, 2021
cfe5fb2
Merge pull request #2 from DKE-Data/Refactor_structure
dastier Oct 4, 2021
aa3ba7d
Add package config files (#3)
dastier Oct 5, 2021
8d35ed2
Add initial documentation (#4)
dastier Oct 5, 2021
686eff3
Clean up the README (#5)
dastier Oct 6, 2021
45e7654
Implement messaging (#8)
dastier Oct 13, 2021
65e1a75
Add onboarding dto (#11)
dastier Oct 15, 2021
f6e7db4
Fix onboarding signing (#14)
dastier Oct 21, 2021
4d398bc
Add unittests (#13)
dastier Oct 21, 2021
bdaef39
Fix message sending
dastier Oct 21, 2021
c52a9b6
Fix revoking
dastier Oct 21, 2021
e0b69e8
Fix MqttMessagingService
dastier Oct 21, 2021
81bae13
Update examples.txt
dastier Oct 25, 2021
0ad04c9
Fix messaging in examples
dastier Oct 25, 2021
9abf794
Refactor Mqtt client
dastier Oct 25, 2021
c90ba11
Update examples
dastier Oct 25, 2021
f944e84
add test script
dastier Oct 25, 2021
68674df
Update example
dastier Oct 25, 2021
210aba9
Merge remote-tracking branch 'origin/Refactor_Project' into Refactor_…
dastier Oct 25, 2021
005c7ca
remove odd prints
dastier Oct 25, 2021
5a4aed5
Merge remote-tracking branch 'origin/Refactor_Project' into Refactor_…
dastier Oct 25, 2021
2cc7707
Refactor http client
dastier Oct 26, 2021
f6b8fb1
Merge remote-tracking branch 'origin/Refactor_Project' into Refactor_…
dastier Oct 26, 2021
a44be3d
Fix examples
dastier Oct 26, 2021
a1362f7
Add subscription to examples
dastier Oct 26, 2021
f0bc39f
Refactor SubscriptionParameters
dastier Oct 26, 2021
0c47fb8
Fix Http Client
dastier Oct 26, 2021
738db91
Fix revoking test
dastier Oct 27, 2021
6b389f1
Fix outbox
dastier Oct 27, 2021
4c9e6d1
Fix TypeUrl
dastier Oct 27, 2021
0a3afaa
Fix OutboxMessage
dastier Oct 27, 2021
2c9c247
Fix OutboxMessage
dastier Oct 27, 2021
565c69a
Implement SubscriptionItemBuilder, CapabilityBuilder
dastier Oct 27, 2021
26d8971
Refactor encode_header method
dastier Oct 28, 2021
f01f841
Fix CapabilityService
dastier Oct 28, 2021
ddacb85
Refactor CapabilityParameters
dastier Oct 28, 2021
6f62a2b
Refactor Parameters
dastier Oct 28, 2021
c711db3
Remove redundant methods in HttpMessagingService
dastier Oct 28, 2021
ba81a1c
Move AuthorizationResultUrl, AuthorizationToken, AuthorizationResult …
dastier Oct 28, 2021
8c29477
Create helper method let_agrirouter_process_the_message
dastier Oct 28, 2021
4c4927b
Remove redundant CU-classes in onboarding
dastier Oct 28, 2021
4ce5468
Refactor BaseEnvieonment
dastier Oct 28, 2021
819c60c
Refactor Authorization.__init__
dastier Oct 28, 2021
4aac735
Refactor auth
dastier Oct 28, 2021
8005b50
Refactor SoftwareOnboardingResponse
dastier Oct 28, 2021
55ecf8f
Refactor SoftwareOnboardingParameter
dastier Oct 28, 2021
3658d11
Implement tests for
dastier Oct 28, 2021
a11821b
Refactor messaging test
dastier Oct 28, 2021
b6152c5
Refactor project (#16)
dastier Nov 2, 2021
5707874
Refactor Dtos
dastier Nov 9, 2021
9a4edb4
[WIP] Fix MqttClient
dastier Nov 9, 2021
344f735
Fix SoftwareOnboardingResponse
dastier Nov 11, 2021
dbdeb6f
Fix MqttClient.__init__ method
dastier Nov 11, 2021
4373604
Merge branch 'develop' into Fix_MqttClient
dastier Nov 11, 2021
8558c45
Remove redundant files
dastier Nov 11, 2021
0c6da94
Fix SoftwareOnboardingResponse.json_deserialize method
dastier Nov 11, 2021
869b774
Fix let_agrirouter_process_the_message method
dastier Nov 12, 2021
9915d36
Refactor MqttMessagingService
dastier Nov 12, 2021
972ccdb
Implement __str__ and __repr__ magic methods for dtos
dastier Nov 12, 2021
9067872
Refactor MqttClient
dastier Nov 12, 2021
2d06436
Remove redundant prints
dastier Nov 12, 2021
8de531a
Refactor SoftwareOnboardingResponse
dastier Nov 13, 2021
8e1d24e
Update examp,es script
dastier Nov 13, 2021
65a8c8c
Add example functions for QueryHeaderService to example_script
dastier Nov 13, 2021
368689d
Fix example_script
dastier Nov 13, 2021
88d78ba
Refactor example_script
dastier Nov 15, 2021
1181acb
Fix ConnectionCriteria dto
dastier Nov 15, 2021
ab4f189
Add __str__ and __repr__ methods for SoftwareOnboardingResponse
dastier Nov 15, 2021
f51039d
Fix mqtt client (#17)
dastier Nov 15, 2021
dd7dba4
Merge branch 'master' into develop
dastier Nov 15, 2021
e6f35c3
Fix flake8 warnings
dastier Nov 15, 2021
f472191
Merge branch 'Fix_MqttClient' into develop
dastier Nov 15, 2021
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
9 changes: 4 additions & 5 deletions agrirouter/auth/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ class Authorization(EnvironmentalService):
TOKEN_KEY = "token"
ERROR_KEY = "error"

def __init__(self, *args, **kwargs):
self._public_key = kwargs.pop("public_key")
self._private_key = kwargs.pop("private_key")
super(Authorization, self).__init__(*args, **kwargs)
def __init__(self, env, public_key, private_key):
self._public_key = public_key
self._private_key = private_key
super(Authorization, self).__init__(env)

def get_auth_request_url(self, parameters: AuthUrlParameter) -> str:
auth_parameters = parameters.get_parameters()
Expand All @@ -34,4 +34,3 @@ def verify_auth_response(self, response, public_key=None):
def _extract_query_params(query_params: str) -> dict:
qp_pairs = parse_qs(query_params)
return {k: v[0] for k, v in qp_pairs.items()}

118 changes: 118 additions & 0 deletions agrirouter/auth/dto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import json
from typing import Union

from agrirouter.messaging.exceptions import WrongFieldError


class AuthorizationToken:
ACCOUNT = 'account'
REGISTRATION_CODE = 'regcode'
EXPIRES = 'expires'

def __init__(self,
*,
account: str = None,
regcode: str = None,
expires: str = None
):
self.account = account
self.regcode = regcode
self.expires = expires

def json_deserialize(self, data: Union[str, dict]) -> None:
data = data if type(data) == dict else json.loads(data)
for key, value in data.items():
if key == self.ACCOUNT:
self.account = value
elif key == self.REGISTRATION_CODE:
self.regcode = value
elif key == self.EXPIRES:
self.expires = value
else:
raise WrongFieldError(f"Unknown field {key} for AuthorizationToken class")

def get_account(self) -> str:
return self.account

def set_account(self, account: str) -> None:
self.account = account

def get_regcode(self) -> str:
return self.regcode

def set_regcode(self, regcode: str) -> None:
self.regcode = regcode

def get_expires(self) -> str:
return self.expires

def set_expires(self, expires: str) -> None:
self.expires = expires


class AuthorizationResultUrl:
def __init__(self,
*,
state: str = None,
signature: str = None,
token: str = None,
decoded_token: AuthorizationToken = None,
error: str = None
):
self.state = state
self.signature = signature
self.token = token
self.decoded_token = decoded_token
self.error = error

def get_state(self) -> str:
return self.state

def set_state(self, state: str) -> None:
self.state = state

def get_signature(self) -> str:
return self.signature

def set_signature(self, signature: str) -> None:
self.signature = signature

def get_token(self) -> str:
return self.token

def set_token(self, token: str) -> None:
self.token = token

def get_error(self) -> str:
return self.error

def set_error(self, error: str) -> None:
self.error = error

def get_decoded_token(self) -> AuthorizationToken:
return self.decoded_token

def set_decoded_token(self, decoded_token: AuthorizationToken) -> None:
self.decoded_token = decoded_token


class AuthorizationResult:
def __init__(self,
*,
authorization_url: str = None,
state: str = None,
):
self.authorization_url = authorization_url
self.state = state

def get_authorization_url(self) -> str:
return self.authorization_url

def set_authorization_url(self, authorization_url: str) -> None:
self.authorization_url = authorization_url

def get_state(self) -> str:
return self.state

def set_state(self, state: str) -> None:
self.state = state
66 changes: 45 additions & 21 deletions agrirouter/auth/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from cryptography.exceptions import InvalidSignature

from agrirouter.auth.dto import AuthorizationToken, AuthorizationResultUrl
from agrirouter.onboarding.signature import verify_signature


Expand All @@ -17,11 +18,11 @@ class AuthResponse:
CRED_KEY = "credentials"

def __init__(self, query_params):
self._state = query_params.get(self.STATE_KEY, None)
self._signature = query_params.get(self.SIGNATURE_KEY, None)
self._token = query_params.get(self.TOKEN_KEY, None)
self._error = query_params.get(self.ERROR_KEY, None)
self.is_successful = not bool(self._error)
self.state = query_params.get(self.STATE_KEY, None)
self.signature = query_params.get(self.SIGNATURE_KEY, None)
self.token = query_params.get(self.TOKEN_KEY, None)
self.error = query_params.get(self.ERROR_KEY, None)
self.is_successful = not bool(self.error)
self._was_verified = False
self._is_valid = False

Expand All @@ -43,33 +44,56 @@ def verify(self, public_key) -> None:

:return:
"""
encoded_data = self._state + self._token
unquoted_signature = unquote(self._signature)
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

@staticmethod
def decode_token(token: Union[str, bytes]) -> dict:
def decode_token(token: Union[str, bytes]) -> AuthorizationToken:
if type(token) == str:
token = token.encode("utf-8")
base_64_decoded_token = base64.b64decode(token)
decoded_token = base_64_decoded_token.decode("utf-8")
return json.loads(decoded_token)

def get_auth_result(self) -> dict:
if not self.is_successful:
return {self.ERROR_KEY: self._error}
decoded_token = self.decode_token(self._token)
return {
self.SIGNATURE_KEY: self._signature,
self.STATE_KEY: self._state,
self.TOKEN_KEY: self._token,
self.CRED_KEY: decoded_token
}

auth_token = AuthorizationToken()
auth_token.json_deserialize(json.loads(decoded_token))
return auth_token

def get_auth_result(self) -> AuthorizationResultUrl:
decoded_token = self.decode_token(self.token)

return AuthorizationResultUrl(
signature=self.signature,
state=self.state,
token=self.token,
decoded_token=decoded_token,
error=self.error
)

def get_signature(self):
return self.signature

def set_signature(self, signature):
self.signature = signature

def get_state(self):
return self.state

def set_state(self, state):
self.state = state

def get_token(self):
return self.token

def set_token(self, token):
self.token = token
10 changes: 5 additions & 5 deletions agrirouter/environments/environments.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class BaseEnvironment:
_MQTT_URL_TEMPLATE = "ssl://{host}:{port}"
_SECURED_ONBOARDING_AUTHORIZATION_LINK_TEMPLATE = \
"/application/{application_id}/authorize" \
"?response_type={response_type}&state={state}&redirect_uri={redirect_uri}"
"?response_type={response_type}&state={state}"

_ENV_BASE_URL = ""
_API_PREFIX = ""
Expand Down Expand Up @@ -38,13 +38,13 @@ def get_revoke_url(self) -> str:
def get_agrirouter_login_url(self) -> str:
return self.get_base_url() + self._AGRIROUTER_LOGIN_URL

def get_secured_onboarding_authorization_url(self, application_id, response_type, state, redirect_uri) -> str:
return self.get_base_url() + self._SECURED_ONBOARDING_AUTHORIZATION_LINK_TEMPLATE.format(
def get_secured_onboarding_authorization_url(self, application_id, response_type, state, redirect_uri=None) -> str:
auth_url = self.get_base_url() + self._SECURED_ONBOARDING_AUTHORIZATION_LINK_TEMPLATE.format(
application_id=application_id,
response_type=response_type,
state=state,
redirect_uri=redirect_uri
state=state
)
return auth_url + f"&redirect_uri={redirect_uri}" if redirect_uri is not None else auth_url

def get_mqtt_server_url(self, host, port) -> str:
return self._MQTT_URL_TEMPLATE.format(host=host, port=port)
Expand Down
Loading