diff --git a/src/error_codes.rs b/src/error_codes.rs index dd141bd..6e7bd4c 100644 --- a/src/error_codes.rs +++ b/src/error_codes.rs @@ -141,6 +141,8 @@ pub enum LexActivatorError { LA_E_SERVER = 91, /// Client error. LA_E_CLIENT = 92, + /// Invalid account ID. + LA_E_ACCOUNT_ID = 93, /// The user account has been temporarily locked for 5 mins due to 5 failed attempts. LA_E_LOGIN_TEMPORARILY_LOCKED = 100, /// Invalid authentication ID token. @@ -155,6 +157,14 @@ pub enum LexActivatorError { LA_E_INVALID_PERMISSION_FLAG = 105, /// The free plan has reached its activation limit. LA_E_FREE_PLAN_ACTIVATION_LIMIT_REACHED = 106, + /// Invalid feature entitlements. + LA_E_FEATURE_ENTITLEMENTS_INVALID = 107, + /// The feature entitlement does not exist. + LA_E_FEATURE_ENTITLEMENT_NOT_FOUND = 108, + /// No entitlement set is linked to the license. + LA_E_ENTITLEMENT_SET_NOT_LINKED = 109, + /// The license cannot be activated before its effective date. + LA_E_LICENSE_NOT_EFFECTIVE = 110, } impl From for LexActivatorStatus { @@ -232,6 +242,7 @@ impl From for LexActivatorError { 90 => LexActivatorError::LA_E_RATE_LIMIT, 91 => LexActivatorError::LA_E_SERVER, 92 => LexActivatorError::LA_E_CLIENT, + 93 => LexActivatorError::LA_E_ACCOUNT_ID, 100 => LexActivatorError::LA_E_LOGIN_TEMPORARILY_LOCKED, 101 => LexActivatorError::LA_E_AUTHENTICATION_ID_TOKEN_INVALID, 102 => LexActivatorError::LA_E_OIDC_SSO_NOT_ENABLED, @@ -239,6 +250,10 @@ impl From for LexActivatorError { 104 => LexActivatorError::LA_E_OS_USER, 105 => LexActivatorError::LA_E_INVALID_PERMISSION_FLAG, 106 => LexActivatorError::LA_E_FREE_PLAN_ACTIVATION_LIMIT_REACHED, + 107 => LexActivatorError::LA_E_FEATURE_ENTITLEMENTS_INVALID, + 108 => LexActivatorError::LA_E_FEATURE_ENTITLEMENT_NOT_FOUND, + 109 => LexActivatorError::LA_E_ENTITLEMENT_SET_NOT_LINKED, + 110 => LexActivatorError::LA_E_LICENSE_NOT_EFFECTIVE, _ => todo!(), // Add more mappings as needed } @@ -326,6 +341,11 @@ impl fmt::Display for LexActivatorError { LexActivatorError::LA_E_OS_USER => write!(f, "{} OS user has changed since activation and the license is user-locked.", LexActivatorError::LA_E_OS_USER as i32), LexActivatorError::LA_E_INVALID_PERMISSION_FLAG => write!(f, "{} Invalid permission flag.", LexActivatorError::LA_E_INVALID_PERMISSION_FLAG as i32), LexActivatorError::LA_E_FREE_PLAN_ACTIVATION_LIMIT_REACHED => write!(f, "{} The free plan has reached its activation limit.", LexActivatorError::LA_E_FREE_PLAN_ACTIVATION_LIMIT_REACHED as i32), + LexActivatorError::LA_E_ACCOUNT_ID => write!(f, "{} Invalid account ID.", LexActivatorError::LA_E_ACCOUNT_ID as i32), + LexActivatorError::LA_E_FEATURE_ENTITLEMENTS_INVALID => write!(f, "{} Invalid feature entitlements.", LexActivatorError::LA_E_FEATURE_ENTITLEMENTS_INVALID as i32), + LexActivatorError::LA_E_FEATURE_ENTITLEMENT_NOT_FOUND => write!(f, "{} The feature entitlement does not exist.", LexActivatorError::LA_E_FEATURE_ENTITLEMENT_NOT_FOUND as i32), + LexActivatorError::LA_E_ENTITLEMENT_SET_NOT_LINKED => write!(f, "{} No entitlement set is linked to the license.", LexActivatorError::LA_E_ENTITLEMENT_SET_NOT_LINKED as i32), + LexActivatorError::LA_E_LICENSE_NOT_EFFECTIVE => write!(f, "{} The license cannot be activated before its effective date.", LexActivatorError::LA_E_LICENSE_NOT_EFFECTIVE as i32), } } } @@ -347,7 +367,7 @@ impl LexActivatorCode { pub fn from_i32(code: i32) -> Self { match code { 0..=32 => LexActivatorCode::Status(LexActivatorStatus::from(code)), - 40..=106 => LexActivatorCode::Error(LexActivatorError::from(code)), + 40..=110 => LexActivatorCode::Error(LexActivatorError::from(code)), _ => LexActivatorCode::Error(LexActivatorError::LA_E_CLIENT), // Fallback to a general error } } diff --git a/src/extern_functions.rs b/src/extern_functions.rs index 0f250dc..9cd52e8 100644 --- a/src/extern_functions.rs +++ b/src/extern_functions.rs @@ -79,6 +79,10 @@ extern "C" { pub fn GetLicenseUserMetadata(key: cstrtype!(), value: strtype!(), length: c_uint) -> c_int; pub fn GetLicenseOrganizationName(organizationName: strtype!(), length: c_uint) -> c_int; pub fn GetLicenseOrganizationAddressInternal(organizationAddressJson: strtype!(), length: c_uint) -> c_int; + pub fn GetLicenseEntitlementSetName(name: strtype!(), length: c_uint) -> c_int; + pub fn GetLicenseEntitlementSetDisplayName(displayName: strtype!(), length: c_uint) -> c_int; + pub fn GetFeatureEntitlementsInternal(featureEntitlementsJson: strtype!(), length: c_uint) -> c_int; + pub fn GetFeatureEntitlementInternal(featureName: cstrtype!(), featureEntitlementJson: strtype!(), length: c_uint) -> c_int; pub fn GetUserLicensesInternal(userLicenses: strtype!(), length: c_uint) -> c_int; pub fn GetLicenseType(licenseType: strtype!(), length: c_uint) -> c_int; pub fn GetActivationId(id:strtype!(), length: c_uint) -> c_int; diff --git a/src/lib.rs b/src/lib.rs index dad2100..9ea80de 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -104,6 +104,20 @@ pub struct UserLicense { pub metadata: Vec } +/// Represents a feature entitlement with details about its value. +#[derive(Debug, Deserialize)] +pub struct FeatureEntitlement { + /// The name of the feature. + #[serde(rename = "featureName")] + pub feature_name: String, + /// The display name of the feature. + #[serde(rename = "featureDisplayName")] + pub feature_display_name: String, + /// The value of the feature. + #[serde(rename = "value")] + pub value: String, +} + /// Represents various permission flags. #[repr(u32)] pub enum PermissionFlags { @@ -340,7 +354,10 @@ pub fn set_license_key(license_key: String) -> Result<(), LexActivatorError> { } /// Sets the license user credentials for activation. -/// +/// +/// # Deprecated +/// This function is deprecated. Use [`authenticate_user`] instead. +/// /// # Arguments /// /// * `email` - The email associated with the user. @@ -749,6 +766,9 @@ pub fn get_product_metadata(key: String) -> Result { /// Retrieves the name of the product version. /// +/// # Deprecated +/// This function is deprecated. Use [`get_license_entitlement_set_name`] instead. +/// /// # Returns /// /// Returns `Ok(String)` with the name of the product version if it is retrieved successfully, If an error occurs, an `Err` containing the `LexActivatorError`is returned. @@ -778,30 +798,36 @@ pub fn get_product_version_name() -> Result { /// Retrieves the display name of the product version. /// -/// # Returns +/// # Deprecated +/// This function is deprecated. Use [`get_license_entitlement_set_display_name`] instead. /// -/// Returns `Ok(String)` with the display name of the product version if it is retrieved successfully, If an error occurs, an `Err` containing the `LexActivatorError`is returned. +/// # Returns +/// Returns `Ok(String)` with the display name of the product version if it is retrieved successfully. +/// If an error occurs, an `Err` containing the `LexActivatorError` is returned. pub fn get_product_version_display_name() -> Result { let status: i32; const LENGTH: usize = 256; // Set the appropriate buffer length let product_version_display_name: String; + #[cfg(windows)] { let mut buffer: [u16; LENGTH] = [0; LENGTH]; status = unsafe { GetProductVersionDisplayName(buffer.as_mut_ptr(), LENGTH as c_uint) }; product_version_display_name = utf16_to_string(&buffer); } + #[cfg(not(windows))] { let mut buffer: [c_char; LENGTH] = [0; LENGTH]; status = unsafe { GetProductVersionDisplayName(buffer.as_mut_ptr(), LENGTH as c_uint) }; product_version_display_name = c_char_to_string(&buffer); } + if status == 0 { Ok(product_version_display_name) } else { - return Err(LexActivatorError::from(status)); + Err(LexActivatorError::from(status)) } } @@ -810,6 +836,9 @@ pub fn get_product_version_display_name() -> Result { /// # Arguments /// /// * `name` - The name of the feature flag. +/// +/// # Deprecated +/// This function is deprecated. Use [`get_feature_entitlement`] instead. /// /// # Returns /// @@ -1331,6 +1360,138 @@ pub fn get_user_licenses() -> Result, LexActivatorError> { } } +/// Retrieves the license entitlement set name. +/// +/// # Returns +/// +/// Returns `Ok(String)` with the entitlement set name of the license if it is retrieved successfully, If an error occurs, an `Err` containing the `LexActivatorError`is returned. + +pub fn get_license_entitlement_set_name() -> Result { + let status: i32; + const LENGTH: usize = 256; + let license_entitlement_set_name: String; + #[cfg(windows)] + { + let mut buffer: [u16; LENGTH] = [0; LENGTH]; + status = unsafe { GetLicenseEntitlementSetName(buffer.as_mut_ptr(), LENGTH as c_uint) }; + license_entitlement_set_name = utf16_to_string(&buffer); + } + #[cfg(not(windows))] + { + let mut buffer: [c_char; LENGTH] = [0; LENGTH]; + status = unsafe { GetLicenseEntitlementSetName(buffer.as_mut_ptr(), LENGTH as c_uint) }; + license_entitlement_set_name = c_char_to_string(&buffer); + } + if status == 0 { + Ok(license_entitlement_set_name) + } else { + return Err(LexActivatorError::from(status)); + } +} + +/// Retrieves the license entitlement set display name. +/// +/// # Returns +/// +/// Returns `Ok(String)` with the entitlement set display name of the license if it is retrieved successfully, If an error occurs, an `Err` containing the `LexActivatorError`is returned. + +pub fn get_license_entitlement_set_display_name() -> Result { + let status: i32; + const LENGTH: usize = 256; + let license_entitlement_set_display_name: String; + #[cfg(windows)] + { + let mut buffer: [u16; LENGTH] = [0; LENGTH]; + status = unsafe { GetLicenseEntitlementSetDisplayName(buffer.as_mut_ptr(), LENGTH as c_uint) }; + license_entitlement_set_display_name = utf16_to_string(&buffer); + } + #[cfg(not(windows))] + { + let mut buffer: [c_char; LENGTH] = [0; LENGTH]; + status = unsafe { GetLicenseEntitlementSetDisplayName(buffer.as_mut_ptr(), LENGTH as c_uint) }; + license_entitlement_set_display_name = c_char_to_string(&buffer); + } + if status == 0 { + Ok(license_entitlement_set_display_name) + } else { + return Err(LexActivatorError::from(status)); + } +} + +/// Retrieves the feature entitlements. +/// +/// # Returns +/// +/// Returns `Ok(Vec)` with the feature entitlements of the license if it is retrieved successfully, If an error occurs, an `Err` containing the `LexActivatorError`is returned. +pub fn get_feature_entitlements() -> Result, LexActivatorError> { + let status: i32; + const LENGTH: usize = 4096; + let feature_entitlements_json: String; + + #[cfg(windows)] + { + let mut buffer: [u16; LENGTH] = [0; LENGTH]; + status = unsafe { GetFeatureEntitlementsInternal(buffer.as_mut_ptr(), LENGTH as c_uint) }; + feature_entitlements_json = utf16_to_string(&buffer); + } + + #[cfg(not(windows))] + { + let mut buffer: [c_char; LENGTH] = [0; LENGTH]; + status = unsafe { GetFeatureEntitlementsInternal(buffer.as_mut_ptr(), LENGTH as c_uint) }; + feature_entitlements_json = c_char_to_string(&buffer); + } + + if status == 0 { + if feature_entitlements_json.is_empty() { + Ok(Vec::new()) + } else { + let feature_entitlements: Vec = serde_json::from_str(&feature_entitlements_json).expect("Failed to parse JSON"); + Ok(feature_entitlements) + } + } else { + Err(LexActivatorError::from(status)) + } +} + +/// Retrieves the feature entitlement. +/// +/// # Arguments +/// +/// * `feature_name` - A `string` value representing the name of the feature. +/// +/// # Returns +/// +/// Returns `Ok(FeatureEntitlement)` with the feature entitlement of the license if it is retrieved successfully, If an error occurs, an `Err` containing the `LexActivatorError`is returned. +pub fn get_feature_entitlement(feature_name: String) -> Result { + let status: i32; + const LENGTH: usize = 1024; + let feature_entitlement_json: String; + + #[cfg(windows)] + { + let mut buffer: [u16; LENGTH] = [0; LENGTH]; + let c_name = to_utf16(name); + status = unsafe { GetFeatureEntitlementInternal(c_name.as_ptr(), buffer.as_mut_ptr(), LENGTH as c_uint) }; + feature_entitlement_json = utf16_to_string(&buffer); + } + + #[cfg(not(windows))] + { + let c_name = string_to_cstring(feature_name)?; + let mut buffer: [c_char; LENGTH] = [0; LENGTH]; + status = unsafe { GetFeatureEntitlementInternal(c_name.as_ptr(), buffer.as_mut_ptr(), LENGTH as c_uint) }; + feature_entitlement_json = c_char_to_string(&buffer); + } + + if status == 0 { + let feature_entitlement: FeatureEntitlement = serde_json::from_str(&feature_entitlement_json).expect("Failed to parse JSON"); + Ok(feature_entitlement) + } else { + Err(LexActivatorError::from(status)) + } +} + /// Retrieves the type of the license. /// /// # Returns