Skip to content
This repository has been archived by the owner on Oct 12, 2023. It is now read-only.

Commit

Permalink
Merge pull request #18 from openpaygo/master
Browse files Browse the repository at this point in the history
Add packaging of OpenPAYGO as PIP module + small fixes
  • Loading branch information
dmohns authored Feb 22, 2023
2 parents a605825 + 035d3fc commit e30b705
Show file tree
Hide file tree
Showing 22 changed files with 95 additions and 50 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ Copyright (c) 2019 Eternum Ltd. UK (trading as Solaris Offgrid)

END OF TERMS AND CONDITIONS

Copyright 2021 Eternum Limited (UK) t/a Solaris Offgrid
Copyright 2009-2022 Eternum Limited (UK) t/a Solaris Offgrid

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
23 changes: 18 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ This project is supported by the EnAccess Foundation (https://enaccess.org/)

Hardware implementation with generic C version + Arduino + schematics: https://github.com/EnAccess/OpenPAYGO-HW

## INSTALLATION

1. Run ```pip install openpaygo-token```
2. That's it, you're ready to go. Check the test scenarios to see how to use the libraries to generate and check tokens.


## GETTING STARTED

Expand All @@ -14,13 +19,13 @@ Hardware implementation with generic C version + Arduino + schematics: https://g
3. The guide for the example, including a quick test to see if you have implemented the code properly into your system: https://github.com/EnAccess/OpenPAYGO/blob/master/documentation/example_implementation_documentation.pdf


## NOTE
If you have pulled or downloaded this implementation before the official OpenPAYGO Token release on the 10th of October 2019,
please make sure to update to the latest version before using in production.


## CHANGELOG

2022-09-05: v2.2.0 release
- Packaged into a PIP package (thanks to the work of @wan5xp)
- Folder structure cleanup
- Tests improvements

2021-06-24: v2.1.5 release
- Added padding of tokens with 0 directly to the generator
- Modified tests to work with recommended settings for unordered token entry
Expand Down Expand Up @@ -63,3 +68,11 @@ please make sure to update to the latest version before using in production.
- First functional pre-release version

**Note:** The v1.0 version was only provided to a few partners for a limited beta test and to gather feedback useful to make the v2.0, it is not published here, is not compatible with the v2.0 and should not be used in production.


## PUBLISHING

(For internal use of Solaris Offgrid)
To publish run:
1. ```python setup.py sdist```
2. ```twine upload dist/*```
Empty file removed __init__.py
Empty file.
4 changes: 4 additions & 0 deletions openpaygo-token/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from .decode_token import OPAYGODecoder
from .encode_token import OPAYGOEncoder
from .shared import OPAYGOShared
from .shared_extended import OPAYGOSharedExtended
16 changes: 8 additions & 8 deletions decode_token.py → openpaygo-token/decode_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ def get_activation_value_count_and_type_from_token(cls, token, starting_code, ke
if restricted_digit_set:
token = OPAYGOShared.convert_from_4_digit_token(token)
valid_older_token = False
token_base = OPAYGOShared.get_token_base(token) # We get the base of the token
current_code = OPAYGOShared.put_base_in_token(starting_code, token_base) # We put it into the starting code
starting_code_base = OPAYGOShared.get_token_base(starting_code) # We get the base of the starting code
token_base = OPAYGOShared.get_token_base(token) # We get the base of the token
current_code = OPAYGOShared.put_base_in_token(starting_code, token_base) # We put it into the starting code
starting_code_base = OPAYGOShared.get_token_base(starting_code) # We get the base of the starting code
value = cls._decode_base(starting_code_base, token_base) # If there is a match we get the value from the token
# We try all combination up until last_count + TOKEN_JUMP, or to the larger jump if syncing counter
# We could start directly the loop at the last count if we kept the token value for the last count
Expand All @@ -26,15 +26,15 @@ def get_activation_value_count_and_type_from_token(cls, token, starting_code, ke
for count in range(0, max_count_try):
masked_token = OPAYGOShared.put_base_in_token(current_code, token_base)
if count % 2:
type = OPAYGOShared.TOKEN_TYPE_SET_TIME
this_type = OPAYGOShared.TOKEN_TYPE_SET_TIME
else:
type = OPAYGOShared.TOKEN_TYPE_ADD_TIME
this_type = OPAYGOShared.TOKEN_TYPE_ADD_TIME
if masked_token == token:
if cls._count_is_valid(count, last_count, value, type, used_counts):
return value, count, type
if cls._count_is_valid(count, last_count, value, this_type, used_counts):
return value, count, this_type
else:
valid_older_token = True
current_code = OPAYGOShared.generate_next_token(current_code, key) # If not we go to the next token
current_code = OPAYGOShared.generate_next_token(current_code, key) # If not we go to the next token
if valid_older_token:
return -2, None, None
return None, None, None
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 2 additions & 0 deletions openpaygo-token/simulators/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .device_simulator import DeviceSimulator
from .server_simulator import SingleDeviceServerSimulator
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@ def _update_device_status_from_token(self, token, show_result=True):
print('TOKEN_INVALID')
self.invalid_token_count += 1
self.token_entry_blocked_until = datetime.now() + timedelta(minutes=2**self.invalid_token_count)
return False
return -1
elif token_value == -2:
if show_result:
print('OLD_TOKEN')
return True
return -2
else:
if show_result:
print('TOKEN_VALID', ' | Value:', token_value)
Expand All @@ -78,7 +78,7 @@ def _update_device_status_from_token(self, token, show_result=True):
self.used_counts = OPAYGODecoder.update_used_counts(self.used_counts, token_value, token_count, token_type)
self.invalid_token_count = 0
self._update_device_status_from_token_value(token_value, token_type)
return True
return 1

def _update_device_status_from_extended_token(self, token):
if self.token_entry_blocked_until > datetime.now() and self.waiting_period_enabled:
Expand Down
14 changes: 14 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[metadata]
name = openpaygo-token
version = 2.2.0
url = https://www.paygops.com/openpaygotoken
description-file=README.md
license_files=LICENSE

[options]
python_requires = >=2.7
packages = find:
include_package_data = true
zip_safe = false
install_requires =
siphash >= 0.0.1
14 changes: 14 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from setuptools import setup, find_packages


setup(
name="openpaygo-token",
packages=find_packages(),
version='2.2.0',
license='Apache 2.0',
author="Solaris Offgrid",
url='https://github.com/openpaygo/OpenPAYGO-Token',
install_requires=[
'siphash',
],
)
10 changes: 10 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# OpenPAYGO-Token Test

To run the test, first, create and activate a virtual environment. Then install the module and run the test:

```
$ cd tests
$ python -m venv env
$ python -m pip install -e ..
$ python ./scenario.py
```
17 changes: 7 additions & 10 deletions tests/full_test_procedure.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import os, sys, inspect
parentdir = os.path.dirname(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))))
sys.path.insert(0, parentdir)
from tests.helpers import ADD_TIME, SET_TIME, DISABLE_VALUE, generate_from_device_data, test_accepted_validator, test_how_many_days_validator, test_name
from simulators.device_simulator import DeviceSimulator
from .helpers import ADD_TIME, SET_TIME, DISABLE_VALUE, generate_from_device_data, test_accepted_validator, test_how_many_days_validator, test_name
from openpaygo-token.simulators import DeviceSimulator
import codecs


Expand All @@ -13,7 +10,7 @@ def run_core_token_tests(device_data, device_simulator):

test = 'We enter an invalid token'
token_g1 = '123 456 789'
test_accepted_validator(device_simulator, 'G1', token_g1, False, description=test)
test_accepted_validator(device_simulator, 'G1', token_g1, -1, description=test)

test = 'We enter a valid token for setting one day'
device_data, token_g2 = generate_from_device_data(device_data, token_type=SET_TIME, value_days=1)
Expand All @@ -24,9 +21,9 @@ def run_core_token_tests(device_data, device_simulator):
test_how_many_days_validator(device_simulator, 'G3', token_g3, 2, description=test)

test = 'We enter the same Add Time token for 1 day, the days should not be added and the device should signal that the token was already used'
test_how_many_days_validator(device_simulator, 'G4A', token_g3, 2, description=test)
test_how_many_days_validator(device_simulator, 'G4A', token_g3, 2, description=test, accepted_but_used=True)
test = 'We enter the older Set Time token for 1 day, the days should not change and the device should signal that the token was already used'
test_how_many_days_validator(device_simulator, 'G4B', token_g2, 2, description=test)
test_how_many_days_validator(device_simulator, 'G4B', token_g2, 2, description=test, accepted_but_used=True)

test = 'We enter a valid token for setting 30 days and ensures it sets and does not add to the existing'
device_data, token_g5 = generate_from_device_data(device_data, token_type=SET_TIME, value_days=30)
Expand Down Expand Up @@ -88,14 +85,14 @@ def run_unordered_entry_tests(device_data, device_simulator):
device_data, token_u2b = generate_from_device_data(device_data, token_type=SET_TIME, value_days=10)
device_data, token_u2c = generate_from_device_data(device_data, token_type=ADD_TIME, value_days=3)
test_how_many_days_validator(device_simulator, 'U2A', token_u2b, 10, description=test)
test_how_many_days_validator(device_simulator, 'U2B', token_u2a, 10)
test_how_many_days_validator(device_simulator, 'U2B', token_u2a, 10, accepted_but_used=True)
test_how_many_days_validator(device_simulator, 'U2C', token_u2c, 13)

test = 'We generate an Add Time token and a Disable PAYG token, we enter the Disable PAYG token and then the Add Time token should be refused'
device_data, token_u3a = generate_from_device_data(device_data, token_type=ADD_TIME, value_days=1)
device_data, token_u3b = generate_from_device_data(device_data, token_type=ADD_TIME, value_raw=DISABLE_VALUE)
test_how_many_days_validator(device_simulator, 'U3A', token_u3b, None, description=test)
test_how_many_days_validator(device_simulator, 'U3B', token_u3a, None)
test_how_many_days_validator(device_simulator, 'U3B', token_u3a, None, accepted_but_used=True)

return device_data

Expand Down
18 changes: 9 additions & 9 deletions tests/helpers.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import os, sys, inspect
parentdir = os.path.dirname(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))))
sys.path.insert(0, parentdir)
from encode_token import OPAYGOEncoder, OPAYGOShared
from decode_token import OPAYGODecoder
from openpaygo-token import OPAYGOEncoder
import codecs


SET_TIME = 1
ADD_TIME = 2
DISABLE_VALUE = 998

START_RED = '\033[91m'
END_RED = '\033[0m'


def generate_from_device_data(device_data, token_type, value_raw=None, value_days=None, token_count=None):
assert (value_days is not None) or (value_raw is not None)
Expand Down Expand Up @@ -42,25 +41,26 @@ def test_accepted(test_name, token, expected, description=''):
print(test_name+','+token+','+expected_string+',"'+description+'"')


def test_how_many_days_validator(device_simulator, test_name, token, value_days=None, value_raw=None, device_data=None, description=''):
def test_how_many_days_validator(device_simulator, test_name, token, value_days=None, value_raw=None, device_data=None, description='', accepted_but_used=False):
if value_days is None:
if value_raw is not None:
value_days = value_raw/device_data['time_divider']
else:
value_days = 'infinite'
if device_simulator.enter_token(token.replace(' ', ''), show_result=False):
result = device_simulator.enter_token(token.replace(' ', ''), show_result=False)
if result == 1 or (accepted_but_used and result == -2):
if device_simulator.get_days_remaining() == value_days:
print(test_name+': Passed')
return
print(test_name+': Failed')
print(START_RED+test_name+': Failed'+END_RED)


def test_accepted_validator(device_simulator, test_name, token, expected, description=''):
if device_simulator.enter_token(token.replace(' ', ''), show_result=False) == expected:
print(test_name+': Passed')
return
else:
print(test_name+': Failed')
print(START_RED+test_name+': Failed'+END_RED)


def test_name(test_base_name, test_number):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from encode_token import OPAYGOEncoder
from shared import OPAYGOShared
from openpaygo-token import OPAYGOEncoder, OPAYGOShared
import codecs

# We know the starting code, and we know 3 tokens with count and value
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from encode_token import OPAYGOEncoder
from shared import OPAYGOShared
from openpaygo-token import OPAYGOEncoder, OPAYGOShared
import codecs

# We know the key, and we know 3 tokens with count and value
Expand Down
8 changes: 2 additions & 6 deletions tests/simple_scenario_test.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import os, sys, inspect
parentdir = os.path.dirname(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))))
sys.path.insert(0, parentdir)
from simulators.device_simulator import DeviceSimulator
from simulators.server_simulator import SingleDeviceServerSimulator, OPAYGOShared
from openpaygo-token.simulators import DeviceSimulator, SingleDeviceServerSimulator
from openpaygo-token import OPAYGOShared
from datetime import datetime, timedelta
import codecs


def assert_time_equals(time1, time2):
Expand Down
5 changes: 1 addition & 4 deletions tests/test_spreadsheet_generator.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import os, sys, inspect
parentdir = os.path.dirname(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))))
sys.path.insert(0, parentdir)
from tests.helpers import ADD_TIME, SET_TIME, DISABLE_VALUE, generate_from_device_data, test_accepted, test_how_many_days, test_name
from .helpers import ADD_TIME, SET_TIME, DISABLE_VALUE, generate_from_device_data, test_accepted, test_how_many_days, test_name


def run_core_token_tests(device_data):
Expand Down

0 comments on commit e30b705

Please sign in to comment.