keygen_rs/
lib.rs

1use client::Client;
2use errors::Error;
3use license::{License, LicenseResponse, SchemeCode};
4use serde::{Deserialize, Serialize};
5
6pub(crate) mod certificate;
7pub(crate) mod client;
8pub(crate) mod decryptor;
9pub(crate) mod entitlement;
10pub(crate) mod verifier;
11
12pub mod component;
13pub mod config;
14pub mod errors;
15pub mod license;
16pub mod license_file;
17pub mod machine;
18pub mod machine_file;
19pub mod service;
20
21// Management features only available with "token" feature flag
22#[cfg(feature = "token")]
23pub mod policy;
24#[cfg(feature = "token")]
25pub mod product;
26#[cfg(feature = "token")]
27pub mod token;
28#[cfg(feature = "token")]
29pub mod user;
30
31#[derive(Debug, Clone, Serialize, Deserialize)]
32pub(crate) struct KeygenRelationshipData {
33    pub r#type: String,
34    pub id: String,
35}
36
37#[derive(Debug, Clone, Serialize, Deserialize)]
38pub(crate) struct KeygenRelationship {
39    #[serde(default)]
40    pub data: Option<KeygenRelationshipData>,
41    #[serde(default)]
42    pub links: Option<serde_json::Value>,
43}
44
45#[derive(Debug, Clone, Serialize, Deserialize, Default)]
46pub(crate) struct KeygenRelationships {
47    #[serde(default)]
48    pub policy: Option<KeygenRelationship>,
49    #[serde(default)]
50    pub account: Option<KeygenRelationship>,
51    #[serde(default)]
52    pub product: Option<KeygenRelationship>,
53    #[serde(default)]
54    pub group: Option<KeygenRelationship>,
55    #[serde(default)]
56    pub owner: Option<KeygenRelationship>,
57    #[serde(default)]
58    pub users: Option<KeygenRelationship>,
59    #[serde(default)]
60    pub machines: Option<KeygenRelationship>,
61    #[serde(default)]
62    pub environment: Option<KeygenRelationship>,
63    #[serde(default)]
64    pub license: Option<KeygenRelationship>,
65    // Use flatten to capture any other relationship fields we don't explicitly handle
66    #[serde(flatten)]
67    pub other: std::collections::HashMap<String, serde_json::Value>,
68}
69
70#[derive(Debug, Clone, Serialize, Deserialize)]
71pub(crate) struct KeygenResponseData<T> {
72    pub id: String,
73    pub r#type: String,
74    pub attributes: T,
75    pub relationships: KeygenRelationships,
76}
77
78/// Validates a license key
79///
80/// # Exampled
81/// ```
82/// #[tokio::main]
83/// async fn main() -> Result<(), Error> {
84///     dotenv().ok();
85///     config::set_config(KeygenConfig {
86///         api_url: env::var("KEYGEN_API_URL").expect("KEYGEN_API_URL must be set"),
87///         account: env::var("KEYGEN_ACCOUNT").expect("KEYGEN_ACCOUNT must be set"),
88///         product: env::var("KEYGEN_PRODUCT").expect("KEYGEN_PRODUCT must be set"),
89///         license_key: Some(env::var("KEYGEN_LICENSE_KEY").expect("KEYGEN_LICENSE_KEY must be set")),
90///         public_key: Some(env::var("KEYGEN_PUBLIC_KEY").expect("KEYGEN_PUBLIC_KEY must be set")),
91///         ..KeygenConfig::default()
92///     });
93///
94///     let fingerprint = machine_uid::get().unwrap_or("".into());
95///     let license = keygen_rs::validate(&[fingerprint]).await?;
96///     println!("License validated successfully: {:?}", license);
97///     Ok(())
98/// }
99/// ```
100pub async fn validate(fingerprints: &[String], entitlements: &[String]) -> Result<License, Error> {
101    let client = Client::default();
102    let response = client.get("me", None::<&()>).await?;
103    let profile: LicenseResponse<()> = serde_json::from_value(response.body)?;
104    let license = License::from(profile.data);
105    Ok(license.validate_key(fingerprints, entitlements).await?)
106}
107
108/// Verifies a signed key based on a given scheme
109///
110/// Supported schemes are:
111/// - Ed25519Sign
112///
113/// # Exampled
114/// ```
115/// #[tokio::main]
116/// async fn main() {
117///     dotenv().ok();
118///     let (public_key, signed_key) =
119///         generate_signed_license_key("4F5D3B-0FB8B2-6871BC-5D3EB3-4885B7-V3".to_string());
120///     config::set_config(KeygenConfig {
121///         api_url: env::var("KEYGEN_API_URL").expect("KEYGEN_API_URL must be set"),
122///         account: env::var("KEYGEN_ACCOUNT").expect("KEYGEN_ACCOUNT must be set"),
123///         product: env::var("KEYGEN_PRODUCT").expect("KEYGEN_PRODUCT must be set"),
124///         license_key: Some(env::var("KEYGEN_LICENSE_KEY").expect("KEYGEN_LICENSE_KEY must be set")),
125///         public_key: Some(public_key.clone()),
126///         ..KeygenConfig::default()
127///     });
128///
129///     println!("Signed key: {:?}", signed_key);
130///     if let Ok(data) = keygen_rs::verify(SchemeCode::Ed25519Sign, &signed_key) {
131///       println!("License verified: {:?}", String::from_utf8_lossy(&data));
132///     } else {
133///       println!("License verification failed");
134///     }
135/// }
136
137pub fn verify(scheme: SchemeCode, signed_key: &str) -> Result<Vec<u8>, Error> {
138    let license = License::from_signed_key(scheme, signed_key);
139    license.verify()
140}