Skip to content

Commit 8005ae2

Browse files
committed
feat: implement machine-id provider for windows
1 parent 8f44cb6 commit 8005ae2

File tree

8 files changed

+114
-68
lines changed

8 files changed

+114
-68
lines changed

Cargo.lock

Lines changed: 41 additions & 35 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

THIRD_PARTY_NOTICES.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2473,13 +2473,6 @@ Distributed under the following license(s):
24732473
* MIT
24742474
* Apache-2.0
24752475

2476-
## wasm-bindgen-backend <https://crates.io/crates/wasm-bindgen-backend>
2477-
2478-
Distributed under the following license(s):
2479-
2480-
* MIT
2481-
* Apache-2.0
2482-
24832476
## wasm-bindgen-futures <https://crates.io/crates/wasm-bindgen-futures>
24842477

24852478
Distributed under the following license(s):
@@ -2646,6 +2639,12 @@ Distributed under the following license(s):
26462639

26472640
* MIT
26482641

2642+
## winreg <https://crates.io/crates/winreg>
2643+
2644+
Distributed under the following license(s):
2645+
2646+
* MIT
2647+
26492648
## wit-bindgen <https://crates.io/crates/wit-bindgen>
26502649

26512650
Distributed under the following license(s):

resource-detection/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ serde_json = { workspace = true }
1717
http = { workspace = true }
1818
fs = { path = "../fs" }
1919
konst = { workspace = true }
20+
21+
[target.'cfg(windows)'.dependencies]
2022
windows-link = "0.2.1"
23+
winreg = "0.55"
2124

2225
[dev-dependencies]
2326
assert_matches = { workspace = true }

resource-detection/src/system.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
pub mod detector;
33
/// hostname retriever
44
pub mod hostname;
5-
mod identifier_machine_id_unix;
5+
mod machine_identifier;
66

77
/// HOSTNAME_KEY represents the hostname key attribute
88
pub const HOSTNAME_KEY: &str = "hostname";

resource-detection/src/system/detector.rs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
//! System resource detector implementation
2-
use super::{
3-
HOSTNAME_KEY, MACHINE_ID_KEY, identifier_machine_id_unix::IdentifierProviderMachineId,
4-
};
2+
use super::{HOSTNAME_KEY, MACHINE_ID_KEY};
53
use crate::system::hostname::get_hostname;
4+
use crate::system::machine_identifier::MachineIdentityProvider;
65
use crate::{DetectError, Detector, Key, Resource, Value};
7-
use fs::LocalFile;
86
use tracing::{error, instrument};
97

108
/// An enumeration of potential errors related to the system detector.
@@ -19,19 +17,15 @@ pub enum SystemDetectorError {
1917
}
2018

2119
/// The `SystemDetector` struct encapsulates system detection functionality.
22-
///
23-
/// # Fields:
24-
/// - `hostname_getter`: An instance of the `HostnameGetter` struct for retrieving system hostname.
25-
/// - `machine_id_provider`: An instance of the `IdentifierProviderMachineId` struct for retrieving machine ID.
2620
pub struct SystemDetector {
27-
machine_id_provider: IdentifierProviderMachineId<LocalFile>,
21+
machine_id_provider: MachineIdentityProvider,
2822
}
2923

3024
/// Default implementation for `SystemDetector` struct.
3125
impl Default for SystemDetector {
3226
fn default() -> Self {
3327
Self {
34-
machine_id_provider: IdentifierProviderMachineId::default(),
28+
machine_id_provider: MachineIdentityProvider::default(),
3529
}
3630
}
3731
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#[cfg(unix)]
2+
mod unix;
3+
#[cfg(windows)]
4+
mod windows;
5+
6+
#[cfg(unix)]
7+
pub(crate) use unix::MachineIdentityProvider;
8+
#[cfg(windows)]
9+
pub(crate) use windows::MachineIdentityProvider;

resource-detection/src/system/identifier_machine_id_unix.rs renamed to resource-detection/src/system/machine_identifier/unix.rs

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
use std::path::{Path, PathBuf};
22

3-
use fs::{
4-
LocalFile,
5-
file_reader::{FileReader, FileReaderError},
6-
};
3+
use fs::LocalFile;
4+
use fs::file_reader::{FileReader, FileReaderError};
75

8-
use super::detector::SystemDetectorError;
6+
use crate::system::detector::SystemDetectorError;
97

108
const MACHINE_ID_PATH: &str =
119
konst::option::unwrap_or!(option_env!("TEST_MACHINE_ID_PATH"), "/etc/machine-id");
@@ -15,29 +13,29 @@ const DBUS_MACHINE_ID_PATH: &str = konst::option::unwrap_or!(
1513
"/var/lib/dbus/machine-id"
1614
);
1715

18-
pub(super) struct IdentifierProviderMachineId<F> {
16+
pub struct MachineIdentityProvider<F = LocalFile> {
1917
machine_id_path: PathBuf,
2018
dbus_machine_id_path: PathBuf,
2119
file_reader: F,
2220
}
2321

24-
impl<F> IdentifierProviderMachineId<F>
22+
impl<F> MachineIdentityProvider<F>
2523
where
2624
F: FileReader,
2725
{
2826
fn read_content(&self, file_path: &Path) -> Result<String, FileReaderError> {
2927
self.file_reader.read(file_path)
3028
}
3129

32-
pub(super) fn provide(&self) -> Result<String, SystemDetectorError> {
30+
pub fn provide(&self) -> Result<String, SystemDetectorError> {
3331
self.read_content(self.machine_id_path.as_path())
3432
.or_else(|_| self.read_content(self.dbus_machine_id_path.as_path()))
3533
.map(|s: String| s.trim().to_string())
3634
.map_err(|e| SystemDetectorError::MachineIDError(e.to_string()))
3735
}
3836
}
3937

40-
impl Default for IdentifierProviderMachineId<LocalFile> {
38+
impl Default for MachineIdentityProvider<LocalFile> {
4139
fn default() -> Self {
4240
Self {
4341
machine_id_path: PathBuf::from(MACHINE_ID_PATH),
@@ -56,7 +54,7 @@ mod tests {
5654
type MachineIDPath = Path;
5755
type DBusMachineIDPath = Path;
5856

59-
impl<F> IdentifierProviderMachineId<F>
57+
impl<F> MachineIdentityProvider<F>
6058
where
6159
F: FileReader,
6260
{
@@ -82,8 +80,7 @@ mod tests {
8280

8381
file_reader.should_read(path.as_path(), expected_machine_id.clone());
8482

85-
let provider =
86-
IdentifierProviderMachineId::new(path.as_path(), path.as_path(), file_reader);
83+
let provider = MachineIdentityProvider::new(path.as_path(), path.as_path(), file_reader);
8784

8885
let machine_id = provider.provide().unwrap();
8986
assert_eq!(expected_machine_id, machine_id);
@@ -103,7 +100,7 @@ mod tests {
103100
);
104101
file_reader.should_read(dbus_machine_id_path.as_path(), expected_machine_id.clone());
105102

106-
let provider = IdentifierProviderMachineId::new(
103+
let provider = MachineIdentityProvider::new(
107104
machine_id_path.as_path(),
108105
dbus_machine_id_path.as_path(),
109106
file_reader,
@@ -124,8 +121,7 @@ mod tests {
124121
file_reader
125122
.should_not_read_file_not_found(path.as_path(), String::from("some error message"));
126123

127-
let provider =
128-
IdentifierProviderMachineId::new(path.as_path(), path.as_path(), file_reader);
124+
let provider = MachineIdentityProvider::new(path.as_path(), path.as_path(), file_reader);
129125

130126
let result = provider.provide();
131127
assert!(result.is_err());
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
use crate::system::detector::SystemDetectorError;
2+
use winreg::{
3+
RegKey,
4+
enums::{HKEY_LOCAL_MACHINE, KEY_READ},
5+
};
6+
7+
const CRYPTOGRAPHY_KEY_PATH: &str = "SOFTWARE\\Microsoft\\Cryptography";
8+
const MACHINE_GUID_KEY_NAME: &str = "MachineGuid";
9+
10+
#[derive(Default)]
11+
pub struct MachineIdentityProvider {}
12+
13+
impl MachineIdentityProvider {
14+
/// Reads the _MachineGuid_ from the Windows registry using [winreg].
15+
pub fn provide(&self) -> Result<String, SystemDetectorError> {
16+
let hklm = RegKey::predef(HKEY_LOCAL_MACHINE); // Open the local machine root key.
17+
// Open the Cryptography reg key with read permissions
18+
let cryptography_key = hklm
19+
.open_subkey_with_flags(CRYPTOGRAPHY_KEY_PATH, KEY_READ)
20+
.map_err(|err| SystemDetectorError::MachineIDError(err.to_string()))?;
21+
// Get the value from the registry
22+
cryptography_key
23+
.get_value(MACHINE_GUID_KEY_NAME)
24+
.map_err(|err| SystemDetectorError::MachineIDError(err.to_string()))
25+
}
26+
}
27+
28+
#[cfg(test)]
29+
mod tests {
30+
use super::*;
31+
32+
#[test]
33+
fn test_windows_machine_guid() {
34+
let machine_guid = MachineIdentityProvider::default()
35+
.provide()
36+
.unwrap_or_else(|err| panic!("Unexpected error obtaining Windows MachineGuid: {err}"));
37+
assert!(!machine_guid.is_empty())
38+
}
39+
}

0 commit comments

Comments
 (0)