commit f802df1af62524e260528eee1203e6d7fad83c6e Author: Catty Steve <4795515+Catty2014@user.noreply.gitee.com> Date: Fri Nov 7 21:34:30 2025 +0800 initial commit: add workshop-deviceid crate diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eb5a316 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +target diff --git a/workshop-builder-native/Cargo.lock b/workshop-builder-native/Cargo.lock new file mode 100644 index 0000000..8299c3e --- /dev/null +++ b/workshop-builder-native/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "workshop-builder-native" +version = "0.1.0" diff --git a/workshop-builder-native/Cargo.toml b/workshop-builder-native/Cargo.toml new file mode 100644 index 0000000..10b6550 --- /dev/null +++ b/workshop-builder-native/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "workshop-builder-native" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/workshop-builder-native/src/error.rs b/workshop-builder-native/src/error.rs new file mode 100644 index 0000000..e9d3c33 --- /dev/null +++ b/workshop-builder-native/src/error.rs @@ -0,0 +1,36 @@ +// src/executors/error.rs +use std::io; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum ExecutionError { + #[error("I/O error: {0}")] + IoError(String), + + #[error("YAML parse error: {0}")] + YamlParseError(String), + + #[error("Command execution error: {0}")] + CommandExecutionError(String), + + #[error("Unsupported platform: {0}")] + UnsupportedPlatform(String), + + #[error("Template error: {0}")] + TemplateError(#[from] crate::services::template_engine::TemplateError), + + #[error("Environment error: {0}")] + EnvironmentError(#[from] crate::services::environment_manager::EnvironmentError), +} + +impl From for ExecutionError { + fn from(error: io::Error) -> Self { + ExecutionError::IoError(error.to_string()) + } +} + +impl From for ExecutionError { + fn from(error: serde_yaml::Error) -> Self { + ExecutionError::YamlParseError(error.to_string()) + } +} diff --git a/workshop-builder-native/src/main.rs b/workshop-builder-native/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/workshop-builder-native/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/workshop-config-manager/.gitignore b/workshop-config-manager/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/workshop-config-manager/.gitignore @@ -0,0 +1 @@ +/target diff --git a/workshop-config-manager/Cargo.lock b/workshop-config-manager/Cargo.lock new file mode 100644 index 0000000..82ec7b6 --- /dev/null +++ b/workshop-config-manager/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "workshop-config-manager" +version = "0.1.0" diff --git a/workshop-config-manager/Cargo.toml b/workshop-config-manager/Cargo.toml new file mode 100644 index 0000000..0566da7 --- /dev/null +++ b/workshop-config-manager/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "workshop-config-manager" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/workshop-config-manager/src/main.rs b/workshop-config-manager/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/workshop-config-manager/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/workshop-deviceid/.gitignore b/workshop-deviceid/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/workshop-deviceid/.gitignore @@ -0,0 +1 @@ +/target diff --git a/workshop-deviceid/Cargo.lock b/workshop-deviceid/Cargo.lock new file mode 100644 index 0000000..ac32190 --- /dev/null +++ b/workshop-deviceid/Cargo.lock @@ -0,0 +1,587 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "bitflags" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[package]] +name = "cc" +version = "1.2.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37521ac7aabe3d13122dc382493e20c9416f299d2ccd5b3a5340a2570cdeb0f3" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "chrono" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-link 0.2.1", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" + +[[package]] +name = "generic-array" +version = "0.14.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "js-sys" +version = "0.3.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.177" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" + +[[package]] +name = "libredox" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" +dependencies = [ + "bitflags", + "libc", + "redox_syscall", +] + +[[package]] +name = "log" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" + +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "ntapi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +dependencies = [ + "winapi", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" +dependencies = [ + "bitflags", +] + +[[package]] +name = "objc2-io-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33fafba39597d6dc1fb709123dfa8289d39406734be322956a69f0931c73bb15" +dependencies = [ + "libc", + "objc2-core-foundation", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "proc-macro2" +version = "1.0.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "raw-cpuid" +version = "11.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "syn" +version = "2.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f17c7e013e88258aa9543dcbe81aca68a667a9ac37cd69c9fbc07858bfe0e2f" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sysinfo" +version = "0.37.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16607d5caffd1c07ce073528f9ed972d88db15dd44023fa57142963be3feb11f" +dependencies = [ + "libc", + "memchr", + "ntapi", + "objc2-core-foundation", + "objc2-io-kit", + "windows", +] + +[[package]] +name = "typenum" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" + +[[package]] +name = "unicode-ident" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "whoami" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d" +dependencies = [ + "libredox", + "wasite", + "web-sys", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.61.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" +dependencies = [ + "windows-collections", + "windows-core", + "windows-future", + "windows-link 0.1.3", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" +dependencies = [ + "windows-core", +] + +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link 0.1.3", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-future" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" +dependencies = [ + "windows-core", + "windows-link 0.1.3", + "windows-threading", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-numerics" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" +dependencies = [ + "windows-core", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows-threading" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "workshop-token" +version = "0.1.0" +dependencies = [ + "chrono", + "lazy_static", + "raw-cpuid", + "serde", + "sha2", + "sysinfo", + "whoami", +] diff --git a/workshop-deviceid/Cargo.toml b/workshop-deviceid/Cargo.toml new file mode 100644 index 0000000..b41eab9 --- /dev/null +++ b/workshop-deviceid/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "workshop-deviceid" +version = "0.1.0" +edition = "2024" + +[dependencies] +chrono = "0.4.42" +lazy_static = "1.5.0" +raw-cpuid = "11.6.0" +serde = { version = "1.0.228", features = ["derive"] } +sha2 = "0.10.9" +sysinfo = "0.37.2" +whoami = "1.6.1" diff --git a/workshop-deviceid/examples/device_id_example.rs b/workshop-deviceid/examples/device_id_example.rs new file mode 100644 index 0000000..c24cc5e --- /dev/null +++ b/workshop-deviceid/examples/device_id_example.rs @@ -0,0 +1,33 @@ +extern crate workshop_token; +use workshop_token::DeviceIdGenerator; + +// server/src/auth/device_id_example.rs + +// 主要使用示例 +fn main() -> Result<(), ()> { + println!("=== 设备ID生成器 ==="); + + // 生成标准设备ID + let device_id = DeviceIdGenerator::generate_device_id()?; + println!("设备ID: {}", device_id); + + // 生成短设备ID + let short_id = DeviceIdGenerator::generate_short_device_id()?; + println!("短设备ID: {}", short_id); + + // 生成详细报告 + let report = DeviceIdGenerator::generate_device_report()?; + println!("\n=== 设备详细信息 ==="); + println!("用户名: {}", report.device_info.username); + println!("主机名: {}", report.device_info.hostname); + println!("操作系统: {} {}", report.device_info.os_name, report.device_info.os_version); + println!("架构: {}", report.device_info.architecture); + println!("CPU: {} {}", report.device_info.cpu_info.vendor_id, report.device_info.cpu_info.brand); + println!("CPU特性: {}", report.device_info.cpu_info.features.join(", ")); + + // 验证设备ID + let is_valid = DeviceIdGenerator::verify_device_id(&device_id)?; + println!("\n设备ID验证: {}", if is_valid { "通过" } else { "失败" }); + + Ok(()) +} diff --git a/workshop-deviceid/src/device_info.rs b/workshop-deviceid/src/device_info.rs new file mode 100644 index 0000000..5e290a2 --- /dev/null +++ b/workshop-deviceid/src/device_info.rs @@ -0,0 +1,139 @@ +// device_info.rs +use raw_cpuid::{CpuId, CpuIdReaderNative}; +use serde::{Serialize, Deserialize}; +use std::collections::HashMap; +use sysinfo::{System}; +use whoami::{username}; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct DeviceInfo { + pub username: String, + pub hostname: String, + pub os_name: String, + pub os_version: String, + pub architecture: String, + pub cpu_info: CpuInfo, + pub system_metadata: HashMap, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct CpuInfo { + pub vendor_id: String, + pub brand: String, + pub family: u8, + pub model: u8, + pub stepping: u8, + pub features: Vec, + pub cache_size: Option, +} + +pub struct DeviceInfoCollector; + +impl DeviceInfoCollector { + pub fn collect_device_info() -> Result { + let mut system = System::new(); + system.refresh_all(); + + Ok(DeviceInfo { + username: Self::get_username(), + hostname: Self::get_hostname(), + os_name: Self::get_os_name(), + os_version: Self::get_os_version(), + architecture: Self::get_architecture(), + cpu_info: Self::get_cpu_info(), + system_metadata: Self::get_system_metadata(&system), + }) + } + + fn get_username() -> String { + // 使用 whoami 库获取用户名 + username() + } + + fn get_hostname() -> String { + // 使用 whoami 库获取主机名 + whoami::fallible::hostname().unwrap_or_else(|_| "unknown".to_string()) + } + + fn get_os_name() -> String { + // 获取操作系统名称 + System::name() + .unwrap_or_else(|| "unknown".to_string()) + } + + fn get_os_version() -> String { + // 获取操作系统版本 + System::os_version() + .unwrap_or_else(|| "unknown".to_string()) + } + + fn get_architecture() -> String { + // 获取系统架构 + std::env::consts::ARCH.to_string() + } + + fn get_cpu_info() -> CpuInfo { + // 使用 cpuid 库获取详细的CPU信息 + let cpuid = CpuId::new(); + let vendor_id = cpuid.get_vendor_info() + .map(|v| v.as_str().to_string()) + .unwrap_or_else(|| "unknown".to_string()); + + let brand = cpuid.get_processor_brand_string() + .map(|b| b.as_str().to_string()) + .unwrap_or_else(|| "unknown".to_string()); + + let (family, model, stepping) = cpuid.get_feature_info() + .map(|f| (f.family_id(), f.model_id(), f.stepping_id())) + .unwrap_or((0, 0, 0)); + + // 获取CPU特性 + let features = Self::get_cpu_features(&cpuid); + + // 获取缓存信息 + let cache_size = Self::get_cache_size(&cpuid); + + CpuInfo { + vendor_id, + brand, + family, + model, + stepping, + features, + cache_size, + } + } + + fn get_cpu_features(cpuid: &CpuId) -> Vec { + let mut features = Vec::new(); + + if let Some(extended_features) = cpuid.get_extended_feature_info() { + if extended_features.has_avx2() { + features.push("avx2".to_string()); + } + if extended_features.has_avx512f() { + features.push("avx512f".to_string()); + } + } + + features + } + + fn get_cache_size(_cpuid: &raw_cpuid::CpuId) -> Option { + // 尝试获取L2或L3缓存大小 + // if let Some(cache_info) = cpuid.get_cache_info() { + // for cache in cache_info { + // if cache.level() == 2 || cache.level() == 3 { + // return Some(cache.size() as u32); + // } + // } + // } + Some(0) + } + + fn get_system_metadata(_system: &System) -> HashMap { + let metadata = HashMap::new(); + + metadata + } +} diff --git a/workshop-deviceid/src/lib.rs b/workshop-deviceid/src/lib.rs new file mode 100644 index 0000000..caf4f8e --- /dev/null +++ b/workshop-deviceid/src/lib.rs @@ -0,0 +1,164 @@ +// server/src/auth/device_id_generator.rs +use serde::Serialize; +mod device_info; +use crate::device_info::{DeviceInfo, DeviceInfoCollector}; +use sha2::{Sha256, Digest}; +use std::collections::HashMap; + +pub struct DeviceIdGenerator; + +impl DeviceIdGenerator { + /// 生成设备ID - 主要方法 + pub fn generate_device_id() -> Result { + let device_info = DeviceInfoCollector::collect_device_info()?; + Self::calculate_device_hash(&device_info) + } + + /// 生成设备ID - 带自定义元数据 + pub fn generate_device_id_with_metadata( + additional_metadata: &HashMap + ) -> Result { + let mut device_info = DeviceInfoCollector::collect_device_info()?; + + // 合并额外的元数据 + for (key, value) in additional_metadata { + device_info.system_metadata.insert(key.clone(), value.clone()); + } + + Self::calculate_device_hash(&device_info) + } + + /// 计算设备信息的SHA256哈希 + fn calculate_device_hash(device_info: &DeviceInfo) -> Result { + let data_string = Self::serialize_device_info(device_info); + let hash = Self::calculate_sha256(&data_string); + + Ok(hash) + } + + /// 将设备信息序列化为字符串用于哈希计算 + fn serialize_device_info(device_info: &DeviceInfo) -> String { + // 按照固定顺序拼接关键信息,确保一致性 + let mut components = Vec::new(); + + // 基础标识信息 + components.push(format!("username:{}", device_info.username)); + components.push(format!("hostname:{}", device_info.hostname)); + components.push(format!("os_name:{}", device_info.os_name)); + components.push(format!("os_version:{}", device_info.os_version)); + components.push(format!("architecture:{}", device_info.architecture)); + + // CPU标识信息 - 这些是相对稳定的 + components.push(format!("cpu_vendor:{}", device_info.cpu_info.vendor_id)); + components.push(format!("cpu_brand:{}", device_info.cpu_info.brand)); + components.push(format!("cpu_family:{}", device_info.cpu_info.family)); + components.push(format!("cpu_model:{}", device_info.cpu_info.model)); + components.push(format!("cpu_stepping:{}", device_info.cpu_info.stepping)); + + // 按字母顺序添加CPU特性,确保一致性 + let mut sorted_features = device_info.cpu_info.features.clone(); + sorted_features.sort(); + components.push(format!("cpu_features:{}", sorted_features.join(","))); + + if let Some(cache_size) = device_info.cpu_info.cache_size { + components.push(format!("cpu_cache:{}", cache_size)); + } + + // 按字母顺序添加系统元数据,确保一致性 + let mut sorted_metadata: Vec<_> = device_info.system_metadata.iter().collect(); + sorted_metadata.sort_by_key(|(k, _)| *k); + + for (key, value) in sorted_metadata { + components.push(format!("{}:{}", key, value)); + } + + components.join("|") + } + + /// 计算SHA256哈希值 + fn calculate_sha256(data: &str) -> String { + let mut hasher = Sha256::new(); + hasher.update(data.as_bytes()); + let result = hasher.finalize(); + + // 转换为十六进制字符串 + result.iter() + .map(|byte| format!("{:02x}", byte)) + .collect() + } + + /// 验证设备ID是否匹配当前设备 + pub fn verify_device_id(device_id: &str) -> Result { + let current_device_id = Self::generate_device_id()?; + Ok(current_device_id == device_id) + } + + /// 获取设备ID的短版本(前16字符) + pub fn generate_short_device_id() -> Result { + let full_id = Self::generate_device_id()?; + Ok(full_id[..16].to_string()) + } + + /// 获取设备信息的详细报告 + pub fn generate_device_report() -> Result { + let device_info = DeviceInfoCollector::collect_device_info()?; + let device_id = Self::calculate_device_hash(&device_info)?; + + Ok(DeviceReport { + device_id, + device_info, + generated_at: chrono::Utc::now().to_string(), + }) + } +} + +#[derive(Debug, Clone, Serialize)] +pub struct DeviceReport { + pub device_id: String, + pub device_info: DeviceInfo, + pub generated_at: String, +} + +#[cfg(test)] +mod tests { + use DeviceIdGenerator; + + use super::*; + + #[test] + fn test_device_id_generation() { + let device_id = DeviceIdGenerator::generate_device_id().unwrap(); + assert_eq!(device_id.len(), 64); // SHA256应该是64字符 + + // 验证设备ID一致性 + let device_id2 = DeviceIdGenerator::generate_device_id().unwrap(); + assert_eq!(device_id, device_id2); + } + + #[test] + fn test_device_verification() { + let device_id = DeviceIdGenerator::generate_device_id().unwrap(); + let is_valid = DeviceIdGenerator::verify_device_id(&device_id).unwrap(); + assert!(is_valid); + + // 验证错误的设备ID + let fake_id = "a".repeat(64); + let is_valid = DeviceIdGenerator::verify_device_id(&fake_id).unwrap(); + assert!(!is_valid); + } + + #[test] + fn test_device_report() { + let report = DeviceIdGenerator::generate_device_report().unwrap(); + + println!("Device ID: {}", report.device_id); + println!("Username: {}", report.device_info.username); + println!("Hostname: {}", report.device_info.hostname); + println!("OS: {} {}", report.device_info.os_name, report.device_info.os_version); + println!("CPU: {} {}", report.device_info.cpu_info.vendor_id, report.device_info.cpu_info.brand); + + assert!(!report.device_id.is_empty()); + assert!(!report.device_info.username.is_empty()); + assert!(!report.device_info.hostname.is_empty()); + } +}