Skip to content

Commit d0b904d

Browse files
authored
Merge branch 'borrowing-develop' into muneeb/request-offline-floating-license
2 parents 74bf813 + 467d968 commit d0b904d

File tree

7 files changed

+145
-13
lines changed

7 files changed

+145
-13
lines changed

.github/workflows/python-publish.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ jobs:
2626

2727
- name: Build and publish
2828
env:
29-
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
30-
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
29+
TWINE_USERNAME: __token__
30+
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
3131
run: |
3232
python setup.py sdist bdist_wheel
3333
twine upload dist/*

cryptlex/lexfloatclient/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
from cryptlex.lexfloatclient.lexfloatclient import LexFloatClient, LexFloatStatusCodes, LexFloatClientException
1+
from cryptlex.lexfloatclient.lexfloatclient import LexFloatClient, LexFloatStatusCodes, LexFloatClientException, PermissionFlags

cryptlex/lexfloatclient/lexfloatclient.py

Lines changed: 100 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
import ctypes
2+
import json
23
from cryptlex.lexfloatclient import lexfloatclient_native as LexFloatClientNative
34
from cryptlex.lexfloatclient.lexfloatstatus_codes import LexFloatStatusCodes
45
from cryptlex.lexfloatclient.lexfloatclient_exception import LexFloatClientException
56

67
callback_list = []
78

9+
class PermissionFlags:
10+
LF_USER = 10
11+
LF_ALL_USERS = 11
812

913
class HostLicenseMeterAttribute(object):
1014
def __init__(self, name, allowed_uses, total_uses, gross_uses):
@@ -19,6 +23,11 @@ def __init__(self, name, enabled, data):
1923
self.enabled = enabled
2024
self.data = data
2125

26+
class HostConfig(object):
27+
def __init__(self, max_offline_lease_duration):
28+
self.max_offline_lease_duration = max_offline_lease_duration
29+
30+
2231
class LexFloatClient:
2332
@staticmethod
2433
def SetHostProductId(product_id):
@@ -100,6 +109,30 @@ def SetFloatingClientMetadata(key, value):
100109
cstring_key, cstring_value)
101110
if LexFloatStatusCodes.LF_OK != status:
102111
raise LexFloatClientException(status)
112+
113+
@staticmethod
114+
def SetPermissionFlag(flag):
115+
"""Sets the permission flag.
116+
117+
This function must be called on every start of your program after SetHostProductId()
118+
function in case the application allows borrowing of licenses or system wide activation.
119+
120+
Args:
121+
flags : depending on your application's requirements, choose one of
122+
the following values: LF_USER, LF_ALL_USERS.
123+
124+
LF_USER: This flag indicates that the application does not require
125+
admin or root permissions to run.
126+
127+
LF_ALL_USERS: This flag is specifically designed for Windows and should be used
128+
for system-wide activations.
129+
130+
Raises:
131+
LexFloatClientException
132+
"""
133+
status = LexFloatClientNative.SetPermissionFlag(flag)
134+
if LexFloatStatusCodes.LF_OK != status:
135+
raise LexFloatClientException(status)
103136

104137
@staticmethod
105138
def GetFloatingClientLibraryVersion():
@@ -117,7 +150,30 @@ def GetFloatingClientLibraryVersion():
117150
status = LexFloatClientNative.GetFloatingClientLibraryVersion(buffer,buffer_size)
118151
if status != LexFloatStatusCodes.LF_OK:
119152
raise LexFloatClientException(status)
120-
return LexFloatClientNative.byte_to_string(buffer.value)
153+
return LexFloatClientNative.byte_to_string(buffer.value)
154+
155+
@staticmethod
156+
def GetHostConfig():
157+
"""This function sends a network request to LexFloatServer to get the configuration details.
158+
159+
Raises:
160+
LexFloatClientException
161+
162+
Returns:
163+
HostConfig: host configuration.
164+
"""
165+
buffer_size = 1024
166+
buffer = LexFloatClientNative.get_ctype_string_buffer(buffer_size)
167+
status = LexFloatClientNative.GetHostConfig(buffer, buffer_size)
168+
if status == LexFloatStatusCodes.LF_OK:
169+
host_config_json = LexFloatClientNative.byte_to_string(buffer.value)
170+
if not host_config_json.strip():
171+
return None
172+
else:
173+
host_config = json.loads(host_config_json)
174+
return HostConfig(host_config["maxOfflineLeaseDuration"])
175+
else:
176+
raise LexFloatClientException(status)
121177

122178
@staticmethod
123179
def GetHostProductVersionName():
@@ -244,6 +300,24 @@ def GetHostLicenseExpiryDate():
244300
return expiry_date.value
245301
else:
246302
raise LexFloatClientException(status)
303+
304+
@staticmethod
305+
def GetFloatingClientLeaseExpiryDate():
306+
"""Gets the lease expiry date timestamp of the floating client.
307+
308+
Raises:
309+
LexFloatClientException
310+
311+
Returns:
312+
int: the timestamp
313+
"""
314+
leaseExpiryDate = ctypes.c_uint()
315+
status = LexFloatClientNative.GetFloatingClientLeaseExpiryDate(
316+
ctypes.byref(leaseExpiryDate))
317+
if status == LexFloatStatusCodes.LF_OK:
318+
return leaseExpiryDate.value
319+
else:
320+
raise LexFloatClientException(status)
247321

248322
@staticmethod
249323
def GetFloatingClientMeterAttributeUses(name):
@@ -267,6 +341,28 @@ def GetFloatingClientMeterAttributeUses(name):
267341
else:
268342
raise LexFloatClientException(status)
269343

344+
@staticmethod
345+
def GetFloatingClientMetadata(key):
346+
"""Gets the value of the floating client metadata.
347+
348+
Args:
349+
key (str): metadata key to retrieve the value
350+
351+
Raises:
352+
LexFloatClientException
353+
354+
Returns:
355+
str: value of the floating client metadata
356+
"""
357+
cstring_key = LexFloatClientNative.get_ctype_string(key)
358+
buffer_size = 4096
359+
buffer = LexFloatClientNative.get_ctype_string_buffer(buffer_size)
360+
status = LexFloatClientNative.GetFloatingClientMetadata(
361+
cstring_key, buffer, buffer_size)
362+
if status != LexFloatStatusCodes.LF_OK:
363+
raise LexFloatClientException(status)
364+
return LexFloatClientNative.byte_to_string(buffer.value)
365+
270366
@staticmethod
271367
def RequestFloatingLicense():
272368
"""Sends the request to lease the license from the LexFloatServer.
@@ -291,7 +387,7 @@ def RequestOfflineFloatingLicense(lease_duration):
291387
status = LexFloatClientNative.RequestOfflineFloatingLicense(lease_duration)
292388
if LexFloatStatusCodes.LF_OK != status:
293389
raise LexFloatClientException(status)
294-
390+
295391
@staticmethod
296392
def DropFloatingLicense():
297393
"""Sends the request to the LexFloatServer to free the license.
@@ -320,6 +416,8 @@ def HasFloatingLicense():
320416
return True
321417
elif LexFloatStatusCodes.LF_E_NO_LICENSE == status:
322418
return False
419+
elif LexFloatStatusCodes.LF_FAIL == status:
420+
return False
323421
else:
324422
raise LexFloatClientException(status)
325423

cryptlex/lexfloatclient/lexfloatclient_exception.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,20 @@ def get_error_message(code):
6464
return 'The server license has been suspended.'
6565
if code == LexFloatStatusCodes.LF_E_SERVER_LICENSE_GRACE_PERIOD_OVER:
6666
return 'The grace period for server license is over.'
67+
if code == LexFloatStatusCodes.LF_E_SYSTEM_PERMISSION:
68+
return 'Insufficient system permissions.'
69+
if code == LexFloatStatusCodes.LF_E_INVALID_PERMISSION_FLAG:
70+
return 'Invalid permission flag.'
71+
if code == LexFloatStatusCodes.LF_E_OFFLINE_FLOATING_LICENSE_NOT_ALLOWED:
72+
return 'Offline floating license is not allowed for per-instance leasing strategy.'
73+
if code == LexFloatStatusCodes.LF_E_MAX_OFFLINE_LEASE_DURATION_EXCEEDED:
74+
return 'Maximum offline lease duration exceeded.'
75+
if code == LexFloatStatusCodes.LF_E_ALLOWED_OFFLINE_FLOATING_CLIENTS_LIMIT_REACHED:
76+
return 'Allowed offline floating clients limit reached.'
77+
if code == LexFloatStatusCodes.LF_E_WMIC:
78+
return "Fingerprint couldn't be generated because Windows Management Instrumentation (WMI) service has been disabled. This error is specific to Windows only."
79+
if code == LexFloatStatusCodes.LF_E_MACHINE_FINGERPRINT:
80+
return 'Machine fingerprint has changed since activation.'
81+
if code == LexFloatStatusCodes.LF_E_PROXY_NOT_TRUSTED:
82+
return 'Request blocked due to untrusted proxy.'
6783
return 'Unknown error!'

cryptlex/lexfloatclient/lexfloatclient_native.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,10 @@ def byte_to_string(input):
127127
SetFloatingClientMetadata.argtypes = [CSTRTYPE, CSTRTYPE]
128128
SetFloatingClientMetadata.restype = c_int
129129

130+
SetPermissionFlag = library.SetPermissionFlag
131+
SetPermissionFlag.argtypes = [c_uint32]
132+
SetPermissionFlag.restype = c_int
133+
130134
GetFloatingClientLibraryVersion = library.GetFloatingClientLibraryVersion
131135
GetFloatingClientLibraryVersion.argtypes = [STRTYPE, c_uint32]
132136
GetFloatingClientLibraryVersion.restype = c_int
@@ -143,6 +147,10 @@ def byte_to_string(input):
143147
GetHostProductVersionFeatureFlag.argtypes = [CSTRTYPE, POINTER(c_uint32), STRTYPE, c_uint32]
144148
GetHostProductVersionFeatureFlag.restype = c_int
145149

150+
GetHostConfig = library.GetHostConfigInternal
151+
GetHostConfig.argtypes = [STRTYPE, c_uint32]
152+
GetHostConfig.restype = c_int
153+
146154
GetHostLicenseMetadata = library.GetHostLicenseMetadata
147155
GetHostLicenseMetadata.argtypes = [CSTRTYPE, STRTYPE, c_uint32]
148156
GetHostLicenseMetadata.restype = c_int
@@ -155,10 +163,18 @@ def byte_to_string(input):
155163
GetHostLicenseExpiryDate.argtypes = [POINTER(c_uint32)]
156164
GetHostLicenseExpiryDate.restype = c_int
157165

166+
GetFloatingClientLeaseExpiryDate = library.GetFloatingClientLeaseExpiryDate
167+
GetFloatingClientLeaseExpiryDate.argtypes = [POINTER(c_uint32)]
168+
GetFloatingClientLeaseExpiryDate.restype = c_int
169+
158170
GetFloatingClientMeterAttributeUses = library.GetFloatingClientMeterAttributeUses
159171
GetFloatingClientMeterAttributeUses.argtypes = [CSTRTYPE, POINTER(c_uint32)]
160172
GetFloatingClientMeterAttributeUses.restype = c_int
161173

174+
GetFloatingClientMetadata = library.GetFloatingClientMetadata
175+
GetFloatingClientMetadata.argtypes = [CSTRTYPE, STRTYPE, c_uint32]
176+
GetFloatingClientMetadata.restype = c_int
177+
162178
RequestFloatingLicense = library.RequestFloatingLicense
163179
RequestFloatingLicense.argtypes = []
164180
RequestFloatingLicense.restype = c_int

cryptlex/lexfloatclient/lexfloatstatus_codes.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,25 +39,27 @@ class LexFloatStatusCodes:
3939
LF_E_METER_ATTRIBUTE_USES_LIMIT_REACHED = 56
4040

4141
LF_E_PRODUCT_VERSION_NOT_LINKED = 57
42-
42+
4343
LF_E_FEATURE_FLAG_NOT_FOUND = 58
44-
44+
4545
LF_E_SYSTEM_PERMISSION = 59
4646

4747
LF_E_IP = 60
48-
48+
4949
LF_E_INVALID_PERMISSION_FLAG = 61
50-
50+
5151
LF_E_OFFLINE_FLOATING_LICENSE_NOT_ALLOWED = 62
52-
52+
5353
LF_E_MAX_OFFLINE_LEASE_DURATION_EXCEEDED = 63
54-
54+
5555
LF_E_ALLOWED_OFFLINE_FLOATING_CLIENTS_LIMIT_REACHED = 64
56-
56+
5757
LF_E_WMIC = 65
5858

5959
LF_E_MACHINE_FINGERPRINT = 66
6060

61+
LF_E_PROXY_NOT_TRUSTED = 67
62+
6163
LF_E_CLIENT = 70
6264

6365
LF_E_SERVER = 71

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setuptools.setup(
77
name="cryptlex.lexfloatclient",
8-
version="4.8.1",
8+
version="4.8.2",
99
author="Cryptlex, LLC",
1010
author_email="support@cryptlex.com",
1111
description="LexFloatClient API wrapper for Python",

0 commit comments

Comments
 (0)