Skip to content

Commit 791dcc4

Browse files
author
Inbal Tako
committed
Add utils
1 parent 8258b01 commit 791dcc4

10 files changed

Lines changed: 98 additions & 96 deletions

File tree

securenative/context/context_builder.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
from securenative.context.securenative_context import SecureNativeContext
2+
from securenative.utils.request_utils import RequestUtils
3+
from securenative.utils.utils import Utils
24

35

46
class ContextBuilder(object):
@@ -38,8 +40,22 @@ def with_body(self, body):
3840
def default_context_builder():
3941
return ContextBuilder()
4042

41-
def from_http_request(self, request): # TODO!
42-
pass
43+
@staticmethod
44+
def from_http_request(request):
45+
headers = request.headers
46+
47+
client_token = request.cookies[RequestUtils.SECURENATIVE_COOKIE]
48+
if Utils.is_null_or_empty(client_token):
49+
client_token = RequestUtils.get_secure_header_from_request(headers)
50+
51+
return ContextBuilder()\
52+
.with_url(request.url)\
53+
.with_method(request.method)\
54+
.with_headers(headers)\
55+
.with_client_token(client_token)\
56+
.with_ip(RequestUtils.get_client_ip_from_request(request))\
57+
.with_remote_ip(RequestUtils.get_remote_ip_from_request(request))\
58+
.with_body(None)
4359

4460
def build(self):
4561
return self.context

securenative/sdk_options.py

Lines changed: 0 additions & 15 deletions
This file was deleted.

securenative/utils/ip_utils.py

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,39 @@
1-
class IpUtils(object): # TODO!
1+
import socket
2+
import re
3+
import ipaddress
4+
5+
6+
class IpUtils(object):
7+
VALID_IPV4_PATTERN = re.compile("(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])")
8+
VALID_IPV6_PATTERN = re.compile("([0-9a-f]{1,4}:){7}([0-9a-f]){1,4}")
29

310
@staticmethod
4-
def is_ip_address():
5-
pass
11+
def is_ip_address(ip_address):
12+
if IpUtils.VALID_IPV4_PATTERN.match(ip_address):
13+
return True
14+
if IpUtils.VALID_IPV6_PATTERN.match(ip_address):
15+
return True
16+
return False
617

718
@staticmethod
8-
def is_valid_public_ip():
9-
pass
19+
def is_valid_public_ip(ip_address):
20+
try:
21+
socket.inet_aton(ip_address)
22+
except socket.error:
23+
return False
24+
25+
ip = ipaddress.IPv4Address(ip_address)
26+
if ip.is_loopback \
27+
or ip.is_global \
28+
or ip.is_private \
29+
or ip.is_link_local \
30+
or ip.is_multicast \
31+
or ip.is_multicast \
32+
or ip.is_reserved \
33+
or ip.is_unspecified:
34+
return False
35+
return True
1036

1137
@staticmethod
12-
def is_loop_back():
13-
pass
38+
def is_loop_back(ip_address):
39+
return ipaddress.IPv4Address(ip_address).is_loopback
Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,20 @@
1-
class RequestUtils(object): # TODO!
1+
class RequestUtils(object):
2+
SECURENATIVE_COOKIE = "_sn"
3+
SECURENATIVE_HEADER = "x-securenative"
24

35
@staticmethod
4-
def get_headers_from_request():
5-
pass
6+
def get_secure_header_from_request(headers):
7+
return headers[RequestUtils.SECURENATIVE_HEADER]
68

79
@staticmethod
8-
def get_secure_header_from_request():
9-
pass
10+
def get_client_ip_from_request(request):
11+
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
12+
if x_forwarded_for:
13+
ip = x_forwarded_for.split(',')[-1].strip()
14+
else:
15+
ip = request.META.get('REMOTE_ADDR')
16+
return ip
1017

1118
@staticmethod
12-
def get_value_from_request():
13-
pass
14-
15-
@staticmethod
16-
def get_client_ip_from_request():
17-
pass
18-
19-
@staticmethod
20-
def get_cookie_value_from_request():
21-
pass
22-
23-
@staticmethod
24-
def get_remote_ip_from_request():
25-
pass
19+
def get_remote_ip_from_request(request):
20+
return request.raw._original_response.fp.raw._sock.getpeername()[0]
Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
1-
class SignatureUtils(object): # TODO!
1+
import hmac
2+
import hashlib
3+
4+
5+
class SignatureUtils(object):
26

37
@staticmethod
4-
def is_valid_signature():
5-
pass
8+
def is_valid_signature(api_key, payload, header_signature):
9+
try:
10+
key = api_key.encode('utf-8')
11+
body = payload.encode('utf-8')
12+
comparison_signature = hmac.new(key, body, hashlib.sha512).hexdigest()
13+
return hmac.compare_digest(comparison_signature, header_signature)
14+
except Exception:
15+
return False

securenative/utils/utils.py

Lines changed: 6 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,7 @@
1-
import base64
2-
import json
3-
import hmac
4-
import hashlib
1+
class Utils(object):
52

6-
7-
def _parse_cookie(cookie_value=None):
8-
fp = u''
9-
cid = u''
10-
11-
if cookie_value is None:
12-
return cid, fp
13-
14-
try:
15-
base64_decoded = base64.b64decode(cookie_value)
16-
if base64_decoded is None:
17-
base64_decoded = u'{}'
18-
19-
json_obj = json.loads(base64_decoded)
20-
21-
if u'fp' in json_obj:
22-
fp = json_obj['fp']
23-
24-
if u'cid' in json_obj:
25-
cid = json_obj['cid']
26-
except Exception as ex:
27-
pass
28-
29-
return cid, fp
30-
31-
32-
def verify_signature(secret, text_body, header_signature):
33-
try:
34-
key = secret.encode('utf-8')
35-
body = text_body.encode('utf-8')
36-
comparison_signature = hmac.new(key, body, hashlib.sha512).hexdigest()
37-
return hmac.compare_digest(comparison_signature, header_signature)
38-
except Exception as ex:
39-
return False
3+
@staticmethod
4+
def is_null_or_empty(string):
5+
if not string or len(string) is 0:
6+
return False
7+
return True
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
class VersionUtils(object):
22

33
@staticmethod
4-
def get_version(): # TODO!
5-
pass
4+
def get_version():
5+
return "0.1.8"

setup.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
from setuptools import setup, Extension
1+
from setuptools import setup
22

3-
from securenative.config import sdk_version
3+
from securenative.utils.version_utils import VersionUtils
44

55
with open("README.md", "r") as fh:
66
long_description = fh.read()
77

88
setup(
99
name='securenative',
1010
packages=['securenative'],
11-
version=sdk_version,
11+
version=VersionUtils.get_version(),
1212
license='MIT',
1313
description='Secure Native SDK for python',
1414
author='Secure Native',

tests/http_client_test.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
import json
22
import unittest
33

4-
from securenative.config import sdk_version
5-
from securenative.http.http_client import HttpClient
4+
5+
from securenative.http.securenative_http_client import SecureNativeHttpClient
6+
7+
from securenative.utils.version_utils import VersionUtils
68

79

810
class HttpClientTests(unittest.TestCase):
911
def test_post(self):
10-
client = HttpClient()
12+
client = SecureNativeHttpClient()
1113
api_key = u'ABC'
1214
request_body = {"key": "test1", "value": "test2"}
13-
response = client.post(url=u'https://httpbin.org/post', api_key=api_key, body=json.dumps(request_body))
15+
response = client.post(path=u"https://httpbin.org/post", body=json.dumps(request_body))
1416

1517
self.assertEqual(response.status_code, 200)
1618
json_body = json.loads(response.text)
1719
self.assertEqual(json_body['headers']['Content-Type'], 'application/json')
1820
self.assertEqual(json_body['headers']['User-Agent'], 'SecureNative-python')
19-
self.assertEqual(json_body['headers']['Sn-Version'], sdk_version)
21+
self.assertEqual(json_body['headers']['Sn-Version'], VersionUtils.get_version())
2022
self.assertEqual(json_body['headers']['Authorization'], api_key)
2123
self.assertEqual(json_body['json'], request_body)

tests/sn_crypto_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import unittest
22

3-
from securenative.utils.sn_crypto import encrypt, decrypt
3+
from securenative.utils.encryption_utils import EncryptionUtils
44

55

66
class CryptoTests(unittest.TestCase):
77
def test_encrypt_decrypt(self):
88
api_key = '6EA4915349C0AAC6F6572DA4F6B00C42'
99
data = '{"cid":"198a41ff-a10f-4cda-a2f3-a9ca80c0703b","fp":"6d8cabd95987f8318b1fe01593d5c2a5.24700f9f1986800ab4fcc880530dd0ed"}'
10-
self.assertEqual(data, decrypt(encrypt(data, api_key), api_key))
10+
self.assertEqual(data, EncryptionUtils.decrypt(EncryptionUtils.encrypt(data, api_key), api_key))

0 commit comments

Comments
 (0)