util.rs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. use std::process::{Command, Stdio};
  2. use aes_gcm::{aead::Aead, AeadCore, Aes256Gcm, KeyInit};
  3. use axum::{
  4. body::Body,
  5. response::{IntoResponse, Response},
  6. };
  7. use rand::rngs::OsRng;
  8. use serde::Serialize;
  9. use sha2::{Digest, Sha256};
  10. use crate::global::NONCE;
  11. pub fn generate_auth_key_hash(auth_key: &str) -> String {
  12. let hash = Sha256::digest(auth_key.as_bytes());
  13. base16::encode_lower(&hash[..3])
  14. }
  15. pub fn open_link(link: &str) -> Option<()> {
  16. let null = Stdio::null();
  17. #[cfg(target_os = "windows")]
  18. {
  19. Command::new("rundll32")
  20. .args(["url.dll,FileProtocolHandler", link])
  21. .stdout(null)
  22. .spawn()
  23. .ok()
  24. .map(|_| ())
  25. }
  26. #[cfg(target_os = "macos")]
  27. {
  28. Command::new("open")
  29. .arg(link)
  30. .stdout(null)
  31. .spawn()
  32. .ok()
  33. .map(|_| ())
  34. }
  35. #[cfg(target_os = "linux")]
  36. {
  37. Command::new("xdg-open")
  38. .arg(link)
  39. .stdout(null)
  40. .spawn()
  41. .ok()
  42. .map(|_| ())
  43. }
  44. #[cfg(not(any(target_os = "windows", target_os = "macos", target_os = "linux")))]
  45. {
  46. None
  47. }
  48. }
  49. #[derive(Debug)]
  50. pub struct EncryptedJson<T: Serialize> {
  51. pub key_b16: String,
  52. pub data: T,
  53. }
  54. impl<T> IntoResponse for EncryptedJson<T>
  55. where
  56. T: Serialize,
  57. {
  58. fn into_response(self) -> Response {
  59. let serialized_response = serde_json::to_vec(&self.data)
  60. .expect("Failed serializing response to vec for encryption");
  61. let key: [u8; 32] = base16::decode(&self.key_b16).unwrap()[0..32]
  62. .try_into()
  63. .unwrap();
  64. let cipher = Aes256Gcm::new(&key.into());
  65. let nonce = Aes256Gcm::generate_nonce(&mut OsRng);
  66. let nonce_b16 = base16::encode_lower(&nonce);
  67. let encrypted_response = cipher
  68. .encrypt(&nonce, serialized_response.as_slice())
  69. .expect("Failed encrypting response");
  70. let mut response = Response::new(Body::from(encrypted_response));
  71. let response_headers = response.headers_mut();
  72. response_headers.insert("Content-Type", "application/octet-stream".parse().unwrap());
  73. response_headers.insert(NONCE, nonce_b16.parse().unwrap());
  74. response
  75. }
  76. }