diff --git a/examples/license-activation.rs b/examples/license-activation.rs index 1fe32c9..4dd9431 100644 --- a/examples/license-activation.rs +++ b/examples/license-activation.rs @@ -2,17 +2,25 @@ use std::io::{self, BufRead}; // for user input (pause) use lexactivator::*; -extern "C" fn license_callback(status: u32) { - if status == LexActivatorStatus::LA_OK as u32 { - println!("License is active!"); - } else if status == LexActivatorStatus::LA_EXPIRED as u32 { - println!("License has expired!"); - } else if status == LexActivatorStatus::LA_SUSPENDED as u32 { - println!("License has been suspended!"); - } else if status == LexActivatorStatus::LA_GRACE_PERIOD_OVER as u32 { - println!("License grace period is over!"); - } else { - println!("License status code: {}", status); +pub type CallbackType = extern "C" fn(LexActivatorCode); + +extern "C" fn license_callback(code: LexActivatorCode) { + match code { + LexActivatorCode::Status(status) => { + match status { + LexActivatorStatus::LA_OK => println!("License is active!"), + LexActivatorStatus::LA_EXPIRED => println!("License has expired!"), + LexActivatorStatus::LA_SUSPENDED => println!("License has been suspended!"), + LexActivatorStatus::LA_GRACE_PERIOD_OVER => println!("License grace period is over!"), + _ => println!("Unknown license status"), + } + } + LexActivatorCode::Error(error) => { + match error { + LexActivatorError::LA_E_ACTIVATION_NOT_FOUND => println!("The license activation was deleted on the server."), + _ => println!("Unknown error"), + } + } } } diff --git a/src/error_codes.rs b/src/error_codes.rs index 4742147..6ca8bb8 100644 --- a/src/error_codes.rs +++ b/src/error_codes.rs @@ -7,15 +7,25 @@ use std::ffi::NulError; #[derive(PartialEq)] #[repr(i32)] pub enum LexActivatorStatus { + /// Success code. LA_OK = 0, + /// Failure code. LA_FAIL = 1, + /// The license has expired or system time has been tampered with. Ensure your date and time settings are correct. LA_EXPIRED = 20, + /// The license has been suspended. LA_SUSPENDED =21, + /// The grace period for server sync is over. LA_GRACE_PERIOD_OVER = 22, + /// The trial has expired or system time has been tampered with. Ensure your date and time settings are correct. LA_TRIAL_EXPIRED = 25, + /// The local trial has expired or system time has been tampered with. Ensure your date and time settings are correct. LA_LOCAL_TRIAL_EXPIRED = 26, + /// A new update is available for the product. This means a new release has been published for the product. LA_RELEASE_UPDATE_AVAILABLE = 30, + /// No new update is available for the product. The current version is latest. LA_RELEASE_UPDATE_NOT_AVAILABLE = 31, + /// The update available is not allowed for this license. LA_RELEASE_UPDATE_AVAILABLE_NOT_ALLOWED = 32, } @@ -23,57 +33,122 @@ pub enum LexActivatorStatus { #[derive(PartialEq)] #[repr(i32)] pub enum LexActivatorError { + /// Failure code. LA_FAIL = 1, + /// Invalid file path. LA_E_FILE_PATH = 40, + /// Invalid or corrupted product file. LA_E_PRODUCT_FILE = 41, + /// Invalid product data. LA_E_PRODUCT_DATA = 42, + /// The product id is incorrect. LA_E_PRODUCT_ID = 43, + /// Insufficient system permissions. Occurs when LA_SYSTEM flag is used but application is not run with admin privileges. LA_E_SYSTEM_PERMISSION = 44, + /// No permission to write to file. LA_E_FILE_PERMISSION = 45, + /// Fingerprint couldn't be generated because Windows Management Instrumentation (WMI) service has been disabled. This error is specific to Windows only. LA_E_WMIC = 46, + /// The difference between the network time and the system time is more than allowed clock offset. LA_E_TIME = 47, + /// Failed to connect to the server due to network error. LA_E_INET = 48, + /// Invalid network proxy. LA_E_NET_PROXY = 49, + /// Invalid Cryptlex host url. LA_E_HOST_URL = 50, + /// The buffer size was smaller than required. LA_E_BUFFER_SIZE = 51, + /// App version length is more than 256 characters. LA_E_APP_VERSION_LENGTH = 52, + /// The license has been revoked. LA_E_REVOKED = 53, + /// Invalid license key. LA_E_LICENSE_KEY = 54, + /// Invalid license type. Make sure floating license is not being used. LA_E_LICENSE_TYPE = 55, + /// Invalid offline activation response file. LA_E_OFFLINE_RESPONSE_FILE = 56, + /// The offline activation response has expired. LA_E_OFFLINE_RESPONSE_FILE_EXPIRED = 57, + /// The license has reached it's allowed activations limit. LA_E_ACTIVATION_LIMIT = 58, + /// The license activation was deleted on the server. LA_E_ACTIVATION_NOT_FOUND = 59, + /// The license has reached it's allowed deactivations limit. LA_E_DEACTIVATION_LIMIT = 60, + /// Trial not allowed for the product. LA_E_TRIAL_NOT_ALLOWED = 61, + /// Your account has reached it's trial activations limit. LA_E_TRIAL_ACTIVATION_LIMIT = 62, + /// Machine fingerprint has changed since activation. LA_E_MACHINE_FINGERPRINT = 63, + /// Metadata key length is more than 256 characters. LA_E_METADATA_KEY_LENGTH = 64, + /// Metadata value length is more than 4096 characters. LA_E_METADATA_VALUE_LENGTH = 65, + /// The license has reached it's metadata fields limit. LA_E_ACTIVATION_METADATA_LIMIT = 66, + /// The trial has reached it's metadata fields limit. LA_E_TRIAL_ACTIVATION_METADATA_LIMIT = 67, + /// The metadata key does not exist. LA_E_METADATA_KEY_NOT_FOUND = 68, + /// The system time has been tampered (backdated). LA_E_TIME_MODIFIED = 69, + /// Invalid version format. LA_E_RELEASE_VERSION_FORMAT = 70, + /// Incorrect email or password. LA_E_AUTHENTICATION_FAILED = 71, + /// The meter attribute does not exist. LA_E_METER_ATTRIBUTE_NOT_FOUND = 72, + /// The meter attribute has reached it's usage limit. LA_E_METER_ATTRIBUTE_USES_LIMIT_REACHED = 73, + /// Custom device fingerprint length is less than 64 characters or more than 256 characters. LA_E_CUSTOM_FINGERPRINT_LENGTH = 74, + /// No product version is linked with the license. LA_E_PRODUCT_VERSION_NOT_LINKED = 75, + /// The product version feature flag does not exist. LA_E_FEATURE_FLAG_NOT_FOUND = 76, + /// The release version is not allowed. LA_E_RELEASE_VERSION_NOT_ALLOWED = 77, + /// Release platform length is more than 256 characters. LA_E_RELEASE_PLATFORM_LENGTH = 78, + /// Release channel length is more than 256 characters. LA_E_RELEASE_CHANNEL_LENGTH = 79, + /// Application is being run inside a virtual machine / hypervisor, and activation has been disallowed in the VM. LA_E_VM = 80, + /// Country is not allowed. LA_E_COUNTRY = 81, + /// IP address is not allowed. LA_E_IP = 82, + /// Application is being run inside a container and activation has been disallowed in the container. LA_E_CONTAINER = 83, + /// Invalid release version. Make sure the release version uses the following formats: x.x, x.x.x, x.x.x.x (where x is a number). LA_E_RELEASE_VERSION = 84, + /// Release platform not set. LA_E_RELEASE_PLATFORM = 85, + /// Release channel not set. LA_E_RELEASE_CHANNEL = 86, + /// The user is not authenticated. + LA_E_USER_NOT_AUTHENTICATED = 87, + /// The two-factor authentication code for the user authentication is missing. + LA_E_TWO_FACTOR_AUTHENTICATION_CODE_MISSING = 88, + /// The two-factor authentication code provided by the user is invalid. + LA_E_TWO_FACTOR_AUTHENTICATION_CODE_INVALID = 89, + /// Rate limit for API has reached, try again later. LA_E_RATE_LIMIT = 90, + /// Server error. LA_E_SERVER = 91, - LA_E_CLIENT = 92 + /// Client error. + LA_E_CLIENT = 92, + /// 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. + LA_E_AUTHENTICATION_ID_TOKEN_INVALID = 101, + /// OIDC SSO is not enabled. + LA_E_OIDC_SSO_NOT_ENABLED = 102, + /// The allowed users for this account has reached its limit. + LA_E_USERS_LIMIT_REACHED = 103, } impl From for LexActivatorStatus { @@ -145,9 +220,16 @@ impl From for LexActivatorError { 84 => LexActivatorError::LA_E_RELEASE_VERSION, 85 => LexActivatorError::LA_E_RELEASE_PLATFORM, 86 => LexActivatorError::LA_E_RELEASE_CHANNEL, + 87 => LexActivatorError::LA_E_USER_NOT_AUTHENTICATED, + 88 => LexActivatorError::LA_E_TWO_FACTOR_AUTHENTICATION_CODE_MISSING, + 89 => LexActivatorError::LA_E_TWO_FACTOR_AUTHENTICATION_CODE_INVALID, 90 => LexActivatorError::LA_E_RATE_LIMIT, 91 => LexActivatorError::LA_E_SERVER, 92 => LexActivatorError::LA_E_CLIENT, + 100 => LexActivatorError::LA_E_LOGIN_TEMPORARILY_LOCKED, + 101 => LexActivatorError::LA_E_AUTHENTICATION_ID_TOKEN_INVALID, + 102 => LexActivatorError::LA_E_OIDC_SSO_NOT_ENABLED, + 103 => LexActivatorError::LA_E_USERS_LIMIT_REACHED, _ => todo!(), // Add more mappings as needed } @@ -222,9 +304,16 @@ impl fmt::Display for LexActivatorError { LexActivatorError::LA_E_RELEASE_VERSION => write!(f, "{} Invalid release version. Make sure the release version uses the following formats: x.x, x.x.x, x.x.x.x (where x is a number).", LexActivatorError::LA_E_RELEASE_VERSION as i32), LexActivatorError::LA_E_RELEASE_PLATFORM => write!(f, "{} Release platform not set.", LexActivatorError::LA_E_RELEASE_PLATFORM as i32), LexActivatorError::LA_E_RELEASE_CHANNEL => write!(f, "{} Release channel not set.", LexActivatorError::LA_E_RELEASE_CHANNEL as i32), + LexActivatorError::LA_E_USER_NOT_AUTHENTICATED => write!(f, "{} The user is not authenticated.", LexActivatorError::LA_E_USER_NOT_AUTHENTICATED as i32), + LexActivatorError::LA_E_TWO_FACTOR_AUTHENTICATION_CODE_MISSING => write!(f, "{} The two-factor authentication code for the user authentication is missing.", LexActivatorError::LA_E_TWO_FACTOR_AUTHENTICATION_CODE_MISSING as i32), + LexActivatorError::LA_E_TWO_FACTOR_AUTHENTICATION_CODE_INVALID => write!(f, "{} he two-factor authentication code provided by the user is invalid.", LexActivatorError::LA_E_TWO_FACTOR_AUTHENTICATION_CODE_INVALID as i32), LexActivatorError::LA_E_RATE_LIMIT => write!(f, "{} Rate limit for API has reached, try again later.", LexActivatorError::LA_E_RATE_LIMIT as i32), LexActivatorError::LA_E_SERVER => write!(f, "{} Server error.", LexActivatorError::LA_E_SERVER as i32), LexActivatorError::LA_E_CLIENT => write!(f, "{} Client error.", LexActivatorError::LA_E_CLIENT as i32), + LexActivatorError::LA_E_LOGIN_TEMPORARILY_LOCKED => write!(f, "{} The user account has been temporarily locked for 5 mins due to 5 failed attempts.", LexActivatorError::LA_E_LOGIN_TEMPORARILY_LOCKED as i32), + LexActivatorError::LA_E_AUTHENTICATION_ID_TOKEN_INVALID => write!(f, "{} Invalid authentication ID token.", LexActivatorError::LA_E_AUTHENTICATION_ID_TOKEN_INVALID as i32), + LexActivatorError::LA_E_OIDC_SSO_NOT_ENABLED => write!(f, "{} OIDC SSO is not enabled.", LexActivatorError::LA_E_OIDC_SSO_NOT_ENABLED as i32), + LexActivatorError::LA_E_USERS_LIMIT_REACHED => write!(f, "{} The allowed users for this account has reached its limit.", LexActivatorError::LA_E_USERS_LIMIT_REACHED as i32), } } } @@ -233,4 +322,11 @@ impl From for LexActivatorError { fn from(_: NulError) -> Self { LexActivatorError::LA_E_CLIENT } +} + +#[derive(Debug)] +#[repr(i32)] +pub enum LexActivatorCode { + Status(LexActivatorStatus), + Error(LexActivatorError), } \ No newline at end of file diff --git a/src/extern_functions.rs b/src/extern_functions.rs index f77be2e..84ffb81 100644 --- a/src/extern_functions.rs +++ b/src/extern_functions.rs @@ -1,5 +1,7 @@ use std::ffi::{c_char, c_int, c_uint}; +use crate::LexActivatorCode; + #[cfg(windows)] macro_rules! cstrtype { () => { @@ -28,13 +30,14 @@ macro_rules! strtype { } } -pub type CallbackType = extern "C" fn(u32); +pub type CallbackType = extern "C" fn(LexActivatorCode); extern "C" { // --------------- Setter Functions --------------- pub fn SetProductData(productData: cstrtype!()) -> c_int; pub fn SetProductId(productId: cstrtype!() , flags: c_uint) -> c_int; pub fn SetDataDirectory(dataDir: cstrtype!()) -> c_int; + pub fn SetDebugMode(enable: c_uint) -> c_uint; pub fn SetCustomDeviceFingerprint(deviceFingerprint: cstrtype!()) -> c_int; pub fn SetLicenseKey(licenseKey: cstrtype!()) -> c_int; pub fn SetLicenseUserCredential(email: cstrtype!(), password: cstrtype!()) -> c_int; @@ -49,6 +52,7 @@ extern "C" { pub fn SetOfflineActivationRequestMeterAttributeUses(name: cstrtype!(), uses: c_uint) -> c_int; pub fn SetNetworkProxy(proxy: cstrtype!()) -> c_int; pub fn SetCryptlexHost(host: cstrtype!()) -> c_int; + pub fn SetTwoFactorAuthenticationCode(twoFactorAuthenticationCode: cstrtype!()) -> c_int; // --------------- Getter Functions --------------- @@ -62,6 +66,8 @@ extern "C" { pub fn GetLicenseAllowedDeactivations(allowedDeactivations: *mut c_uint) -> c_int; pub fn GetLicenseTotalActivations(totalActivations: *mut c_uint) -> c_int; pub fn GetLicenseTotalDeactivations(totalDeactivations: *mut c_uint) -> c_int; + pub fn GetLicenseCreationDate(creationDate: *mut c_uint) -> c_int; + pub fn GetLicenseActivationDate(activationDate: *mut c_uint) -> c_int; pub fn GetLicenseExpiryDate(expiryDate: *mut c_uint) -> c_int; pub fn GetLicenseMaintenanceExpiryDate(maintenanceExpiryDate: *mut c_uint) -> c_int; pub fn GetLicenseMaxAllowedReleaseVersion(maxAllowedReleaseVersion: strtype!(), length: c_uint) -> c_int; @@ -71,7 +77,9 @@ 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 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; pub fn GetActivationMetadata(key: cstrtype!(), value: strtype!(), length: c_uint) -> c_int; pub fn GetActivationMode(initialMode: strtype!(), initialModeLength: c_uint, currentMode: strtype!(), currentModeLength: c_uint) -> c_int; pub fn GetActivationMeterAttributeUses(name: cstrtype!(), uses: *mut c_uint) -> c_int; @@ -85,6 +93,8 @@ extern "C" { // --------------- LexActivator Action Functions --------------- + pub fn AuthenticateUser(email: cstrtype!(), password: cstrtype!()) -> c_int; + pub fn AuthenticateUserWithIdToken(idToken: cstrtype!()) -> c_int; pub fn ActivateLicense() -> c_int; pub fn ActivateLicenseOffline(filePath: cstrtype!()) -> c_int; pub fn GenerateOfflineActivationRequest(filePath: cstrtype!()) -> c_int; diff --git a/src/lib.rs b/src/lib.rs index 8dc6ef1..b1bd500 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -46,7 +46,7 @@ pub struct ActivationMode { } /// Represents an organization address. -#[derive(Debug, Deserialize)] +#[derive(Debug, Deserialize, Default)] pub struct OrganizationAddress { /// The first line of the address. #[serde(rename = "addressLine1")] @@ -65,6 +65,23 @@ pub struct OrganizationAddress { pub postal_code: String } +/// Represents a user license with information about various license parameters. +#[derive(Debug, Deserialize)] +pub struct UserLicense { + /// The allowed activations count of a license. + #[serde(rename = "allowedActivations")] + pub allowed_activations: u32, + /// The allowed deactivations count of a license. + #[serde(rename = "allowedDeactivations")] + pub allowed_deactivations: u32, + /// The license key. + pub key: String, + /// The license type. + #[serde(rename = "type")] + pub license_type: String +} + +/// Represents various permission flags. #[repr(u32)] pub enum PermissionFlags { LA_USER = 1, @@ -179,6 +196,23 @@ pub fn set_data_directory(data_dir: String) -> Result<(), LexActivatorError> { } } +/// Enables network logs. +/// +/// This function should be used for network testing only in case of network errors. By default logging is disabled. +/// +/// This function generates the lexactivator-logs.log file in the same directory where the application is running. +/// +/// # Arguments +/// +/// * `enable` - 0 or 1 to disable or enable logging. +/// +/// Returns `Ok(())` if the debug mode is enabled successfully. + +pub fn set_debug_mode(enable: u32) { + let c_enable: c_uint = enable as c_uint; + unsafe { SetDebugMode(c_enable) }; +} + /// In case you don't want to use the LexActivator's advanced device fingerprinting algorithm, this function can be used to set a custom device fingerprint. /// /// # Arguments @@ -578,6 +612,35 @@ pub fn set_cryptlex_host(host: String) -> Result<(), LexActivatorError> { } } +/// Sets the two-factor authentication code for the user authentication. +/// +/// # Arguments +/// +/// * `two_factor_authentication_code` - The 2FA code. +/// +/// # Returns +/// +/// Returns `Ok(())` if the two_factor_authentication_code is set successfully, If an error occurs, an `Err` containing the `LexActivatorError`is returned. + +pub fn set_two_factor_authentication_code(two_factor_authentication_code: String) -> Result<(), LexActivatorError> { + let status: i32; + #[cfg(windows)] + { + let c_two_factor_authentication_code = to_utf16(two_factor_authentication_code); + status = unsafe { SetTwoFactorAuthenticationCode(c_two_factor_authentication_code.as_ptr()) }; + } + #[cfg(not(windows))] + { + let c_two_factor_authentication_code = string_to_cstring(two_factor_authentication_code)?; + status = unsafe { SetTwoFactorAuthenticationCode(c_two_factor_authentication_code.as_ptr()) }; + } + if status == 0 { + Ok(()) + } else { + return Err(LexActivatorError::from(status)); + } +} + // ------------------- Getter Functions -------------------- pub fn get_product_metadata(key: String) -> Result { @@ -873,6 +936,38 @@ pub fn get_license_total_deactivations() -> Result { } } +/// Retrieves the license creation date timestamp. +/// +/// # Returns +/// +/// Returns `Ok(u32)` with the license creation date timestamp if it is retrieved successfully, If an error occurs, an `Err` containing the `LexActivatorError`is returned. + +pub fn get_license_creation_date() -> Result { + let mut creation_date:c_uint = 0; + let status = unsafe { GetLicenseCreationDate(&mut creation_date) }; + if status == 0 { + Ok(creation_date) + } else { + return Err(LexActivatorError::from(status)); + } +} + +/// Retrieves the license activation date timestamp. +/// +/// # Returns +/// +/// Returns `Ok(u32)` with the license activation date timestamp if it is retrieved successfully, If an error occurs, an `Err` containing the `LexActivatorError`is returned. + +pub fn get_license_activation_date() -> Result { + let mut activation_date:c_uint = 0; + let status = unsafe { GetLicenseActivationDate(&mut activation_date) }; + if status == 0 { + Ok(activation_date) + } else { + return Err(LexActivatorError::from(status)); + } +} + /// Retrieves the expiry date of the license. /// /// # Returns @@ -1107,13 +1202,55 @@ pub fn get_license_organization_address() -> Result)` with the user licenses if retrieved successfully. If an error occurs, an `Err` containing the `LexActivatorError` is returned. + +pub fn get_user_licenses() -> Result, LexActivatorError> { + let status: i32; + const LENGTH: usize = 256; + let user_licenses_json: String; + #[cfg(windows)] + { + let mut buffer: [u16; LENGTH] = [0; LENGTH]; + status = unsafe { GetUserLicensesInternal(buffer.as_mut_ptr(), LENGTH as c_uint) }; + user_licenses_json = utf16_to_string(&buffer); + } + #[cfg(not(windows))] + { + let mut buffer: [c_char; LENGTH] = [0; LENGTH]; + status = unsafe { GetUserLicensesInternal(buffer.as_mut_ptr(), LENGTH as c_uint) }; + user_licenses_json = c_char_to_string(&buffer); + } + if status == 0 { + if user_licenses_json.is_empty() { + Ok(Vec::new()) + } else { + let user_licenses: Vec = serde_json::from_str(&user_licenses_json).expect("Failed to parse JSON"); + Ok(user_licenses) + } + + } else { + Err(LexActivatorError::from(status)) + } } /// Retrieves the type of the license. @@ -1145,6 +1282,35 @@ pub fn get_license_type() -> Result { } } +/// Retrieves the activation id. +/// +/// # Returns +/// +/// Returns `Ok(String)` with the activation id if it is retrieved successfully, If an error occurs, an `Err` containing the `LexActivatorError`is returned. + +pub fn get_activation_id() -> Result { + let status: i32; + const LENGTH: usize = 256; + let activation_id: String; + #[cfg(windows)] + { + let mut buffer: [u16; LENGTH] = [0; LENGTH]; + status = unsafe { GetActivationId(buffer.as_mut_ptr(), LENGTH as c_uint) }; + activation_id = utf16_to_string(&buffer); + } + #[cfg(not(windows))] + { + let mut buffer: [c_char; LENGTH] = [0; LENGTH]; + status = unsafe { GetActivationId(buffer.as_mut_ptr(), LENGTH as c_uint) }; + activation_id = c_char_to_string(&buffer); + } + if status == 0 { + Ok(activation_id) + } else { + return Err(LexActivatorError::from(status)); + } +} + /// Retrieves the metadata value associated with the specified key for the activation. /// /// # Arguments @@ -1394,6 +1560,69 @@ pub fn get_library_version() -> Result { // ------------------ Action Functions ------------------ +/// Authenticates the user. +/// +/// It sends the request to the Cryptlex servers to authenticate the user. +/// +/// # Arguments +/// +/// * `email` - user email address. +/// * `password` - user password. +/// +/// # Returns +/// +/// Returns `Ok(LexActivatorStatus)` with the status code `LexActivatorStatus::LA_OK` if the authentication is successful. If an error occurs, an `Err` containing the `LexActivatorError`is returned. + +pub fn authenticate_user(email: String, password: String) -> Result<(), LexActivatorError> { + let status: i32; + #[cfg(windows)] + { + let c_email = to_utf16(email); + let c_password = to_utf16(password); + status = unsafe { AuthenticateUser(c_email.as_ptr(), c_password.as_ptr()) }; + } + #[cfg(not(windows))] + { + let c_email = string_to_cstring(email)?; + let c_password = string_to_cstring(password)?; + status = unsafe { AuthenticateUser(c_email.as_ptr(), c_password.as_ptr()) }; + } + if status == 0 { + Ok(()) + } else { + return Err(LexActivatorError::from(status)); + } +} + +/// Authenticates the user via OIDC Id token. +/// +/// # Arguments +/// +/// * `id_token` - The id token obtained from the OIDC provider. +/// +/// # Returns +/// +/// Returns `Ok(LexActivatorStatus)` with the status code `LexActivatorStatus::LA_OK` if the authentication is successful. If an error occurs, an `Err` containing the `LexActivatorError`is returned. + +pub fn authenticate_user_with_id_token(id_token: String) -> Result<(), LexActivatorError> { + let status: i32; + #[cfg(windows)] + { + let c_id_token = to_utf16(id_token); + status = unsafe { AuthenticateUserWithIdToken(c_id_token.as_ptr()) }; + } + #[cfg(not(windows))] + { + let c_id_token = string_to_cstring(id_token)?; + status = unsafe { AuthenticateUserWithIdToken(c_id_token.as_ptr()) }; + } + if status == 0 { + Ok(()) + } else { + return Err(LexActivatorError::from(status)); + } +} + /// Activates the license by contacting the Cryptlex servers. /// /// It validates the key and returns with encrypted and digitally signed token which it stores and uses to activate the application.