rbeesoft 2.0.5__py3-none-any.whl → 2.0.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
rbeesoft/app/main.py CHANGED
@@ -1,9 +1,10 @@
1
1
  import sys
2
2
  from PySide6 import QtWidgets, QtCore
3
- from rbeesoft.app.ui.rbeesoftmainwindow import RbeesoftMainWindow
4
- from rbeesoft.app.ui.widgets.pages.page import Page
5
- from rbeesoft.app.ui.processes.process import Process
6
- from rbeesoft.app.ui.processes.processrunner import ProcessRunner
3
+ from rbeesoft.app.ui import RbeesoftMainWindow
4
+ from rbeesoft.app.ui.widgets.pages import Page
5
+ from rbeesoft.app.ui.processes import Process
6
+ from rbeesoft.app.ui.processes import ProcessRunner
7
+ from rbeesoft.common import LicenseManager
7
8
 
8
9
 
9
10
  class MainWindow(RbeesoftMainWindow):
@@ -32,7 +33,10 @@ class HomePage(Page):
32
33
  layout.setAlignment(QtCore.Qt.AlignmentFlag.AlignTop)
33
34
  layout.addWidget(QtWidgets.QLabel(self.title()))
34
35
  layout.addWidget(button)
35
- layout.addWidget(process_button)
36
+ manager = LicenseManager(settings)
37
+ license = manager.license()
38
+ if license.has_all_features('x'):
39
+ layout.addWidget(process_button)
36
40
  self.setLayout(layout)
37
41
 
38
42
  def handle_button(self):
@@ -0,0 +1,2 @@
1
+ from rbeesoft.app.ui.settings import Settings
2
+ from rbeesoft.app.ui.rbeesoftmainwindow import RbeesoftMainWindow
@@ -0,0 +1,2 @@
1
+ from rbeesoft.app.ui.processes.process import Process
2
+ from rbeesoft.app.ui.processes.processrunner import ProcessRunner
@@ -1,4 +1,4 @@
1
- from rbeesoft.common.singleton import singleton
1
+ from rbeesoft.common.decorators import singleton
2
2
  from rbeesoft.common.logmanager import LogManager
3
3
 
4
4
  LOG = LogManager()
@@ -6,7 +6,7 @@ from rbeesoft.app.ui.settings import Settings
6
6
  from rbeesoft.app.ui.widgets.centraldockwidget import CentralDockWidget
7
7
  from rbeesoft.app.ui.widgets.logdockwidget import LogDockWidget
8
8
  from rbeesoft.common.licensemanager import LicenseManager
9
- from rbeesoft.common.licenseexception import LicenseException
9
+ from rbeesoft.common.exceptions.licenseexception import LicenseException
10
10
  from rbeesoft.common.logmanager import LogManager
11
11
 
12
12
  LOG = LogManager()
@@ -87,7 +87,7 @@ class RbeesoftMainWindow(QMainWindow):
87
87
 
88
88
  def license_manager(self):
89
89
  if not self._license_manager:
90
- self._license_manager = LicenseManager(self.settings().get('public_key', None))
90
+ self._license_manager = LicenseManager(self.settings())
91
91
  return self._license_manager
92
92
 
93
93
  def license(self):
@@ -116,7 +116,7 @@ class RbeesoftMainWindow(QMainWindow):
116
116
  file_path = self.settings().get('mainwindow/license_file', None)
117
117
  if file_path:
118
118
  try:
119
- self._license = self.license_manager().verify(file_path)
119
+ self._license = self.license_manager().check_license(file_path)
120
120
  LOG.info(f'License found at {file_path}')
121
121
  LOG.info('License OK')
122
122
  return True
@@ -0,0 +1,2 @@
1
+ from rbeesoft.app.ui.widgets.centraldockwidget import CentralDockWidget
2
+ from rbeesoft.app.ui.widgets.logdockwidget import LogDockWidget
@@ -0,0 +1,2 @@
1
+ from rbeesoft.app.ui.widgets.pages.page import Page
2
+ from rbeesoft.app.ui.widgets.pages.pagerouter import PageRouter
@@ -0,0 +1,4 @@
1
+ from rbeesoft.common.logmanager import LogManager
2
+ from rbeesoft.common.logmanagerlistener import LogManagerListener
3
+ from rbeesoft.common.licensemanager import LicenseManager
4
+ from rbeesoft.common.license import License
@@ -0,0 +1 @@
1
+ from rbeesoft.common.exceptions.licenseexception import LicenseException
@@ -0,0 +1,38 @@
1
+ import time
2
+
3
+
4
+ class License:
5
+ def __init__(self, payload):
6
+ self._payload = payload
7
+
8
+ def customer(self):
9
+ return self._payload['customer']
10
+
11
+ def product(self):
12
+ return self._payload['product']
13
+
14
+ def feature_list(self):
15
+ return self._payload['features']
16
+
17
+ def expiry_days(self):
18
+ return int(self._payload['exp'])
19
+
20
+ def id(self):
21
+ return self._payload['license_id']
22
+
23
+ # CHECKS
24
+
25
+ def is_expired(self):
26
+ now = int(time.time())
27
+ if now > self.expiry_days():
28
+ return True
29
+ return False
30
+
31
+ def is_valid(self):
32
+ return not self.is_expired()
33
+
34
+ def has_all_features(self):
35
+ return 'all' in self.feature_list()
36
+
37
+ def has_feature(self, name):
38
+ return name in self.feature_list()
@@ -3,19 +3,26 @@ import time
3
3
  import base64
4
4
  from pathlib import Path
5
5
  from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
6
- from rbeesoft.common.licenseexception import LicenseException
6
+ from rbeesoft.common.exceptions import LicenseException
7
+ from rbeesoft.common.license import License
8
+ from rbeesoft.common.decorators import singleton
7
9
 
8
10
 
11
+ @singleton
9
12
  class LicenseManager:
10
- def __init__(self, public_key):
13
+ def __init__(self, settings):
11
14
  self._file_path = None
12
- self._public_key = public_key
15
+ self._public_key = settings.get('public_key', None)
16
+ self._license = None
13
17
 
14
18
  def file_path(self):
15
19
  return self._file_path
16
20
 
17
21
  def public_key(self):
18
22
  return self._public_key
23
+
24
+ def license(self):
25
+ return self._license
19
26
 
20
27
  def canonical_json_bytes(self, obj: dict) -> bytes:
21
28
  return json.dumps(
@@ -25,7 +32,7 @@ class LicenseManager:
25
32
  ensure_ascii=False
26
33
  ).encode("utf-8")
27
34
 
28
- def verify(self, file_path):
35
+ def check_license(self, file_path):
29
36
  if isinstance(file_path, str):
30
37
  file_path = Path(file_path)
31
38
  if not file_path.exists():
@@ -44,6 +51,7 @@ class LicenseManager:
44
51
  exp = int(payload["exp"])
45
52
  if now > exp:
46
53
  raise LicenseException('License expired')
47
- return payload
54
+ self._license = License(payload)
55
+ return self._license
48
56
  except Exception as e:
49
57
  raise LicenseException(f'Invalid license: {e}')
@@ -2,7 +2,7 @@ import os
2
2
  import atexit
3
3
  import datetime
4
4
  from pathlib import Path
5
- from rbeesoft.common.singleton import singleton
5
+ from rbeesoft.common.decorators import singleton
6
6
 
7
7
 
8
8
  @singleton
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rbeesoft
3
- Version: 2.0.5
3
+ Version: 2.0.7
4
4
  Summary:
5
5
  Author: Brecheisen
6
6
  Author-email: r.brecheisen@maastrichtuniversity.nl
@@ -0,0 +1,29 @@
1
+ rbeesoft/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ rbeesoft/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ rbeesoft/app/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ rbeesoft/app/main.py,sha256=oPNVGXd310TZBKBbRdJFIxbN-RW-Jrp0aSggCf-Uo0c,3012
5
+ rbeesoft/app/ui/__init__.py,sha256=uDSH_teO12m1hKSf_6ukPnUxIwHg_cvs3ld0UGngTd4,112
6
+ rbeesoft/app/ui/processes/__init__.py,sha256=r08tBoeRxfyMDyuJcUxljGXdxR00yyQRyxHuLp8H1lI,120
7
+ rbeesoft/app/ui/processes/dummyprocess.py,sha256=4r97xwHv7ZaoK85zBxR00zzYnYpoFAxZfBPmxFJYDkM,470
8
+ rbeesoft/app/ui/processes/process.py,sha256=qMrXKvT06oRe1yRSe3DLO9ObhV2qzzZLI5R-PwryOYs,1694
9
+ rbeesoft/app/ui/processes/processrunner.py,sha256=3Jozq_3aPXjCTN3sjL9UmgfssFms73G9LAkXNvdjFxQ,1171
10
+ rbeesoft/app/ui/rbeesoftmainwindow.py,sha256=EIPuCiwrWdYjMochKoDVlp1ebmRY9_jv-_QtkIpPvnQ,5703
11
+ rbeesoft/app/ui/settings.py,sha256=JeUBdQgah9s2XbSqsgEEYzFN2yvUwFMk8L7KFsa55WM,2200
12
+ rbeesoft/app/ui/widgets/__init__.py,sha256=PI6L1-6X9UBEQqiGbZard5Gde2ik7uQTyBATgZ6dvq4,136
13
+ rbeesoft/app/ui/widgets/centraldockwidget.py,sha256=kK0x-Sz4yz7D4icaIepWpAtct7ZQ9BNroi9EccAvABA,1376
14
+ rbeesoft/app/ui/widgets/logdockwidget.py,sha256=DZkQQitarE5B82qvNCSnUWDWXxhWsuTauboULFoh7eI,1810
15
+ rbeesoft/app/ui/widgets/pages/__init__.py,sha256=RfblhaIaT8rGBK6ZCtAw6MOqJ6gQJcWwkj13GOtDlok,116
16
+ rbeesoft/app/ui/widgets/pages/page.py,sha256=huzUrbvyx8qZmeelKRhLimB9RFfuj9bK_EsG_56AK_E,661
17
+ rbeesoft/app/ui/widgets/pages/pagerouter.py,sha256=L5EKEMWVibSI7IpabQBkLsCDw1xBt1wfYY50iR56VZA,1460
18
+ rbeesoft/common/__init__.py,sha256=8o67M0v8JtjuLeECjKW47wttfX8vSQrhdlvlQ7g2DzE,220
19
+ rbeesoft/common/decorators.py,sha256=FV0k_LlOCmFhlWN6gf1c2x7YXWyd8-7DsIMvOKrI6NY,224
20
+ rbeesoft/common/exceptions/__init__.py,sha256=6JA5DLQE467BorgSuAwB2jICgt6YJju40QJjGiIk_aY,72
21
+ rbeesoft/common/exceptions/licenseexception.py,sha256=oapxaf0e9Fbl3iAa5e3c2EYxNhD0e1im1mwJfimsZ3Q,44
22
+ rbeesoft/common/license.py,sha256=Xda7d1TSqDCcernFUThmRbDeJcAti460tDo5NuAqxCI,863
23
+ rbeesoft/common/licensemanager.py,sha256=I3kc5x8yfyCDtLquu4lxNOi6jH7ryBYbEvF-P8VCdJE,1916
24
+ rbeesoft/common/logmanager.py,sha256=Hrn0pmLwh0LQtvucRAO43lAHlGdM2hh1Qc1gA3QC1nk,1392
25
+ rbeesoft/common/logmanagerlistener.py,sha256=Gaig07yjBnyQq9I8sN85olTEeDCDyCFQnEJdwzvmgvc,99
26
+ rbeesoft/webapp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
+ rbeesoft-2.0.7.dist-info/METADATA,sha256=DYs3_KmvF4bvF6jk86jMy_QnGjmE-28q-cXRgwSBF0A,378
28
+ rbeesoft-2.0.7.dist-info/WHEEL,sha256=3ny-bZhpXrU6vSQ1UPG34FoxZBp3lVcvK0LkgUz6VLk,88
29
+ rbeesoft-2.0.7.dist-info/RECORD,,
@@ -1,37 +0,0 @@
1
- import os
2
- import base64
3
- from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
4
- from cryptography.hazmat.primitives import serialization
5
- from pathlib import Path
6
-
7
- # RUN THIS ONLY ONCE!!! You can distribute the public key to clients
8
-
9
-
10
- def main():
11
- output_dir = Path.home() / 'keys'
12
- os.makedirs(output_dir, exist_ok=True)
13
- priv = Ed25519PrivateKey.generate()
14
- pub = priv.public_key()
15
- priv_bytes = priv.private_bytes(
16
- encoding=serialization.Encoding.Raw,
17
- format=serialization.PrivateFormat.Raw,
18
- encryption_algorithm=serialization.NoEncryption(),
19
- )
20
- pub_bytes = pub.public_bytes(
21
- encoding=serialization.Encoding.Raw,
22
- format=serialization.PublicFormat.Raw,
23
- )
24
- priv_file = output_dir / 'ed25519_private.key'
25
- priv_file.write_bytes(priv_bytes)
26
- pub_file = output_dir / 'ed25519_public.key'
27
- pub_file.write_bytes(pub_bytes)
28
- print("Wrote:")
29
- print(" - $HOME/keys/ed25519_private.key (KEEP SECRET)")
30
- print(" - $HOME/keys/ed25519_public.key (embed in app)")
31
- print("\nPublic key (base64) to embed:")
32
- print(base64.b64encode(pub_bytes).decode("ascii"))
33
-
34
-
35
- if __name__ == '__main__':
36
- main()
37
-
rbeesoft/app/license.json DELETED
@@ -1,15 +0,0 @@
1
- {
2
- "payload": {
3
- "customer": "Ralph Example",
4
- "product": "MyPySideApp Pro",
5
- "features": [
6
- "pro",
7
- "export_pdf"
8
- ],
9
- "issued_at": 1770031472,
10
- "exp": 1772623472,
11
- "license_id": "LIC-1770031472"
12
- },
13
- "signature": "2NPw5sb9zeOF3b6Sm5hrxWcne/cX0G0vJwVJ+bG+0i7/WY6SJyCNcmN5v+2eBe7WZjs+E+c33JOA7mX8BLTmBA==",
14
- "alg": "Ed25519"
15
- }
@@ -1,76 +0,0 @@
1
- import base64
2
- import argparse
3
- import json
4
- import time
5
- from pathlib import Path
6
- from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
7
-
8
- def canonical_json_bytes(obj: dict) -> bytes:
9
- # Deterministic JSON -> same bytes everywhere
10
- return json.dumps(
11
- obj,
12
- sort_keys=True,
13
- separators=(",", ":"),
14
- ensure_ascii=False
15
- ).encode("utf-8")
16
-
17
- def load_private_key(path: Path) -> Ed25519PrivateKey:
18
- key_bytes = path.read_bytes()
19
- return Ed25519PrivateKey.from_private_bytes(key_bytes)
20
-
21
- def make_license_payload(
22
- customer: str,
23
- product: str,
24
- expires_days_from_now: int,
25
- features: list[str],
26
- machine_fp: str | None = None,
27
- ) -> dict:
28
- now = int(time.time())
29
- exp = now + expires_days_from_now * 24 * 3600
30
- payload = {
31
- "customer": customer,
32
- "product": product,
33
- "features": features,
34
- "issued_at": now,
35
- "exp": exp,
36
- "license_id": f"LIC-{now}",
37
- }
38
- # Optional machine binding (keep None for portable)
39
- if machine_fp:
40
- payload["machine_fp"] = machine_fp
41
- return payload
42
-
43
- def sign_license(payload: dict, priv: Ed25519PrivateKey) -> dict:
44
- msg = canonical_json_bytes(payload)
45
- sig = priv.sign(msg)
46
- return {
47
- "payload": payload,
48
- "signature": base64.b64encode(sig).decode("ascii"),
49
- "alg": "Ed25519",
50
- }
51
-
52
- def main():
53
- parser = argparse.ArgumentParser()
54
- parser.add_argument('private_key_path', help='Path to private key file')
55
- parser.add_argument('output_dir', help='Path to output directory where license.json is written')
56
- parser.add_argument('product', help='Name of product')
57
- parser.add_argument('expires_days_from_now', help='Number of days to expire', type=int)
58
- parser.add_argument('--features', help='Feature list', default='')
59
- args = parser.parse_args()
60
- priv_path = Path(args.private_key_path) # Path.home() / 'keys/ed25519_private.key'
61
- out_path = Path(args.output_dir) / 'license.json'
62
- priv = load_private_key(priv_path)
63
- payload = make_license_payload(
64
- customer='Default customer',
65
- product=args.product,
66
- expires_days_from_now=args.expires_days_from_now,
67
- features=[x.strip() for x in args.features.split(',')],
68
- machine_fp=None, # set to a fingerprint to bind to a device
69
- )
70
- signed = sign_license(payload, priv)
71
- out_path.write_text(json.dumps(signed, indent=2, ensure_ascii=False), encoding="utf-8")
72
- print(f"Wrote signed license to: {out_path.resolve()}")
73
- print(f"Expires at (unix): {payload['exp']}")
74
-
75
- if __name__ == "__main__":
76
- main()
@@ -1,30 +0,0 @@
1
- rbeesoft/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- rbeesoft/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- rbeesoft/app/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- rbeesoft/app/generatekeys.py,sha256=YVxIhKhyo0JY6HFxCTNZdD5bU_K6Vb1zkRKdsYQ80Ew,1243
5
- rbeesoft/app/license.json,sha256=m8ukgKJdiJ3fU4nsFIrE2fm6Qk_SdIdwoqkapM2MnlI,374
6
- rbeesoft/app/main.py,sha256=AsDayu8MZoLnd9ODZmHL-AA-dqS8exodKv4LcHKw44o,2886
7
- rbeesoft/app/signlicense.py,sha256=Zp5bZOnmtHsFOACgU3iGRwy0Ko0nb4GZ97lB4BKTWMw,2704
8
- rbeesoft/app/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- rbeesoft/app/ui/processes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- rbeesoft/app/ui/processes/dummyprocess.py,sha256=4r97xwHv7ZaoK85zBxR00zzYnYpoFAxZfBPmxFJYDkM,470
11
- rbeesoft/app/ui/processes/process.py,sha256=qMrXKvT06oRe1yRSe3DLO9ObhV2qzzZLI5R-PwryOYs,1694
12
- rbeesoft/app/ui/processes/processrunner.py,sha256=HqDQ3ZMlqCqQkyuEgV5sJCkzD35ENvp58z9D-TtnVdA,1170
13
- rbeesoft/app/ui/rbeesoftmainwindow.py,sha256=Fjy5m5cMzEbs4J_tVphJT7OzBFn32MWppDBOnlcFN1Y,5709
14
- rbeesoft/app/ui/settings.py,sha256=JeUBdQgah9s2XbSqsgEEYzFN2yvUwFMk8L7KFsa55WM,2200
15
- rbeesoft/app/ui/widgets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
- rbeesoft/app/ui/widgets/centraldockwidget.py,sha256=kK0x-Sz4yz7D4icaIepWpAtct7ZQ9BNroi9EccAvABA,1376
17
- rbeesoft/app/ui/widgets/logdockwidget.py,sha256=DZkQQitarE5B82qvNCSnUWDWXxhWsuTauboULFoh7eI,1810
18
- rbeesoft/app/ui/widgets/pages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
- rbeesoft/app/ui/widgets/pages/page.py,sha256=huzUrbvyx8qZmeelKRhLimB9RFfuj9bK_EsG_56AK_E,661
20
- rbeesoft/app/ui/widgets/pages/pagerouter.py,sha256=L5EKEMWVibSI7IpabQBkLsCDw1xBt1wfYY50iR56VZA,1460
21
- rbeesoft/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
- rbeesoft/common/licenseexception.py,sha256=oapxaf0e9Fbl3iAa5e3c2EYxNhD0e1im1mwJfimsZ3Q,44
23
- rbeesoft/common/licensemanager.py,sha256=K-F9fpnBXOG-tjfhO5YAK706gXDk623ZtYQVi12-4Iw,1646
24
- rbeesoft/common/logmanager.py,sha256=K_qCbPjrzoV5le3KSvLOSSXYa-_MWLJ3FdFNTEGYSxg,1391
25
- rbeesoft/common/logmanagerlistener.py,sha256=Gaig07yjBnyQq9I8sN85olTEeDCDyCFQnEJdwzvmgvc,99
26
- rbeesoft/common/singleton.py,sha256=FV0k_LlOCmFhlWN6gf1c2x7YXWyd8-7DsIMvOKrI6NY,224
27
- rbeesoft/webapp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
- rbeesoft-2.0.5.dist-info/METADATA,sha256=MLufddI91YLdHBYByzCtZgb7ZpzKZv0rJqU4Ye6Ymlw,378
29
- rbeesoft-2.0.5.dist-info/WHEEL,sha256=3ny-bZhpXrU6vSQ1UPG34FoxZBp3lVcvK0LkgUz6VLk,88
30
- rbeesoft-2.0.5.dist-info/RECORD,,
File without changes