From f44635cb0dd8ec6b7cf7106804b8cae7a64e05e2 Mon Sep 17 00:00:00 2001 From: Ahmad Kemsan Date: Tue, 15 Apr 2025 10:07:14 +0530 Subject: [PATCH] feat: added feature entitlement functions --- cryptlex/lexfloatclient/lexfloatclient.py | 93 +++++++++++++++++++ .../lexfloatclient_exception.py | 4 + .../lexfloatclient/lexfloatclient_native.py | 16 ++++ .../lexfloatclient/lexfloatstatus_codes.py | 4 + 4 files changed, 117 insertions(+) diff --git a/cryptlex/lexfloatclient/lexfloatclient.py b/cryptlex/lexfloatclient/lexfloatclient.py index d30603e..37197fa 100644 --- a/cryptlex/lexfloatclient/lexfloatclient.py +++ b/cryptlex/lexfloatclient/lexfloatclient.py @@ -23,6 +23,12 @@ def __init__(self, name, enabled, data): self.enabled = enabled self.data = data +class HostFeatureEntitlement(object): + def __init__(self, host_feature_entitlement_dict): + self.feature_name = host_feature_entitlement_dict.get("featureName") + self.value = host_feature_entitlement_dict.get("value") + + class HostConfig(object): def __init__(self, max_offline_lease_duration): self.max_offline_lease_duration = max_offline_lease_duration @@ -234,6 +240,93 @@ def GetHostProductVersionFeatureFlag(name): return HostProductVersionFeatureFlag(name, isEnabled, LexFloatClientNative.byte_to_string(buffer.value)) else: raise LexFloatClientException(status) + + @staticmethod + def GetHostLicenseEntitlementSetName(): + """Gets the name of the entitlement set associated with the LexFloatServer license. + + Raises: + LexFloatClientException + + Returns: + str: host license entitlement set name + """ + buffer_size = 256 + buffer = LexFloatClientNative.get_ctype_string_buffer(buffer_size) + status = LexFloatClientNative.GetHostLicenseEntitlementSetName(buffer, buffer_size) + if status != LexFloatStatusCodes.LF_OK: + raise LexFloatClientException(status) + return LexFloatClientNative.byte_to_string(buffer.value) + + @staticmethod + def GetHostLicenseEntitlementSetDisplayName(): + """Gets the display name of the entitlement set associated with the LexFloatServer license. + + Raises: + LexFloatClientException + + Returns: + str: host license entitlement set display name + """ + buffer_size = 256 + buffer = LexFloatClientNative.get_ctype_string_buffer(buffer_size) + status = LexFloatClientNative.GetHostLicenseEntitlementSetDisplayName(buffer, buffer_size) + if status != LexFloatStatusCodes.LF_OK: + raise LexFloatClientException(status) + return LexFloatClientNative.byte_to_string(buffer.value) + + @staticmethod + def GetHostFeatureEntitlements(): + """Gets the feature entitlements associated with the LexFloatServer license. + + Feature entitlements can be linked directly to a license (license feature entitlements) + or via entitlement sets. If a feature entitlement is defined in both, the value from + the license feature entitlement takes precedence, overriding the entitlement set value. + + Raises: + LexFloatClientException + + Returns: + HostFeatureEntitlements[]: list of host feature entitlements + """ + buffer_size = 4096 + buffer = LexFloatClientNative.get_ctype_string_buffer(buffer_size) + status = LexFloatClientNative.GetHostFeatureEntitlements(buffer, buffer_size) + if status == LexFloatStatusCodes.LF_OK: + host_feature_entitlements_json = LexFloatClientNative.byte_to_string(buffer.value) + if not host_feature_entitlements_json.strip(): + return [] + else: + host_feature_entitlements = json.loads(host_feature_entitlements_json) + host_feature_entitlements_list = [HostFeatureEntitlement(feature_detail) for feature_detail in host_feature_entitlements] + return host_feature_entitlements_list + else: + raise LexFloatClientException(status) + + @staticmethod + def GetHostFeatureEntitlement(feature_name): + """Gets the feature entitlement associated with the LexFloatServer license. + + Feature entitlements can be linked directly to a license (license feature entitlements) + or via entitlement sets. If a feature entitlement is defined in both, the value from + the license feature entitlement takes precedence, overriding the entitlement set value. + + Raises: + LexFloatClientException + + Returns: + HostFeatureEntitlement: host feature entitlement + """ + cstring_feature_name = LexFloatClientNative.get_ctype_string(feature_name) + buffer_size = 1024 + buffer = LexFloatClientNative.get_ctype_string_buffer(buffer_size) + status = LexFloatClientNative.GetHostFeatureEntitlement(cstring_feature_name, buffer, buffer_size) + if status == LexFloatStatusCodes.LF_OK: + host_feature_entitlement_json = LexFloatClientNative.byte_to_string(buffer.value) + host_feature_entitlement = json.loads(host_feature_entitlement_json) + return HostFeatureEntitlement(host_feature_entitlement) + else: + raise LexFloatClientException(status) @staticmethod def GetHostLicenseMetadata(key): diff --git a/cryptlex/lexfloatclient/lexfloatclient_exception.py b/cryptlex/lexfloatclient/lexfloatclient_exception.py index 4c15166..83c7931 100644 --- a/cryptlex/lexfloatclient/lexfloatclient_exception.py +++ b/cryptlex/lexfloatclient/lexfloatclient_exception.py @@ -80,4 +80,8 @@ def get_error_message(code): return 'Machine fingerprint has changed since activation.' if code == LexFloatStatusCodes.LF_E_PROXY_NOT_TRUSTED: return 'Request blocked due to untrusted proxy.' + if code == LexFloatStatusCodes.LF_E_ENTITLEMENT_SET_NOT_LINKED: + return 'No entitlement set is linked to the license.' + if code == LexFloatStatusCodes.LF_E_FEATURE_ENTITLEMENT_NOT_FOUND: + return 'The feature entitlement does not exist.' return 'Unknown error!' diff --git a/cryptlex/lexfloatclient/lexfloatclient_native.py b/cryptlex/lexfloatclient/lexfloatclient_native.py index 920c75e..4ffa915 100644 --- a/cryptlex/lexfloatclient/lexfloatclient_native.py +++ b/cryptlex/lexfloatclient/lexfloatclient_native.py @@ -155,6 +155,22 @@ def byte_to_string(input): GetHostConfig.argtypes = [STRTYPE, c_uint32] GetHostConfig.restype = c_int +GetHostLicenseEntitlementSetName = library.GetHostLicenseEntitlementSetName +GetHostLicenseEntitlementSetName.argtypes = [STRTYPE, c_uint32] +GetHostLicenseEntitlementSetName.restype = c_int + +GetHostLicenseEntitlementSetDisplayName = library.GetHostLicenseEntitlementSetDisplayName +GetHostLicenseEntitlementSetDisplayName.argtypes = [STRTYPE, c_uint32] +GetHostLicenseEntitlementSetDisplayName.restype = c_int + +GetHostFeatureEntitlements = library.GetHostFeatureEntitlementsInternal +GetHostFeatureEntitlements.argtypes = [STRTYPE, c_uint32] +GetHostFeatureEntitlements.restype = c_int + +GetHostFeatureEntitlement = library.GetHostFeatureEntitlementInternal +GetHostFeatureEntitlement.argtypes = [CSTRTYPE, STRTYPE, c_uint32] +GetHostFeatureEntitlement.restype = c_int + GetHostLicenseMetadata = library.GetHostLicenseMetadata GetHostLicenseMetadata.argtypes = [CSTRTYPE, STRTYPE, c_uint32] GetHostLicenseMetadata.restype = c_int diff --git a/cryptlex/lexfloatclient/lexfloatstatus_codes.py b/cryptlex/lexfloatclient/lexfloatstatus_codes.py index a30a4da..3f33b35 100644 --- a/cryptlex/lexfloatclient/lexfloatstatus_codes.py +++ b/cryptlex/lexfloatclient/lexfloatstatus_codes.py @@ -60,6 +60,10 @@ class LexFloatStatusCodes: LF_E_PROXY_NOT_TRUSTED = 67 + LF_E_ENTITLEMENT_SET_NOT_LINKED = 68 + + LF_E_FEATURE_ENTITLEMENT_NOT_FOUND = 69 + LF_E_CLIENT = 70 LF_E_SERVER = 71