datadir.rs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. //! Describes accessors around a homeserver or client data directory.
  2. use std::fs;
  3. use std::io;
  4. use std::path::PathBuf;
  5. use serde::{Deserialize, Serialize};
  6. use thiserror::Error;
  7. pub const USERDATA_NAME: &str = "user.json";
  8. pub const DEV_AUTH_NAME: &str = "device_signer.json";
  9. pub const DEV_AUTH_TMP_NAME: &str = "device_signer.tmp";
  10. #[derive(Debug, Error)]
  11. pub enum Error {
  12. #[error("missing user data file")]
  13. MissingUserData,
  14. #[error("missing device auth file")]
  15. MissingDeviceAuth,
  16. #[error("tried to create datadir where one already exists")]
  17. DatadirExists,
  18. #[error("codec: {0}")]
  19. Codec(#[from] aspect_codec::CodecError),
  20. #[error("json: {0}")]
  21. SerdeJson(#[from] serde_json::Error),
  22. #[error("io: {0}")]
  23. Io(#[from] io::Error),
  24. }
  25. pub struct Datadir {
  26. base: PathBuf,
  27. }
  28. impl Datadir {
  29. /// Creates a new datadir with the provided initial state.
  30. pub fn create(
  31. base: PathBuf,
  32. userdata: &UserData,
  33. signer: &aspect_ident::IdentSigner,
  34. ) -> Result<Self, Error> {
  35. if base.exists() {
  36. return Err(Error::DatadirExists);
  37. }
  38. // Save user data.
  39. let ud_buf = serde_json::to_vec(userdata)?;
  40. let mut ud_path = base.clone();
  41. ud_path.push("user.json");
  42. fs::write(&ud_path, &ud_buf)?;
  43. let mut dd = Datadir { base };
  44. dd.save_device_auth(signer)?;
  45. Ok(dd)
  46. }
  47. /// Opens a datadir and makes assertions about its contents from the config.
  48. pub fn open(mut base: PathBuf) -> Result<Self, Error> {
  49. // Check the user data file path.
  50. base.push(USERDATA_NAME);
  51. if !base.exists() {
  52. return Err(Error::MissingUserData);
  53. }
  54. base.pop();
  55. // Check the device authorization data path.
  56. base.push(DEV_AUTH_NAME);
  57. if !base.exists() {
  58. return Err(Error::MissingDeviceAuth);
  59. }
  60. base.pop();
  61. Ok(Self { base })
  62. }
  63. pub fn save_device_auth(&mut self, auth: &aspect_ident::IdentSigner) -> Result<(), Error> {
  64. // Write to a temp file.
  65. let mut dkt_path = self.base.clone();
  66. dkt_path.push(DEV_AUTH_TMP_NAME);
  67. let buf = serde_json::to_vec_pretty(auth)?;
  68. fs::write(&dkt_path, buf)?;
  69. // Move it over the real file so that we don't accidentally truncate it.
  70. let mut dk_path = self.base.clone();
  71. dk_path.push(DEV_AUTH_NAME);
  72. fs::rename(dkt_path, dk_path)?;
  73. Ok(())
  74. }
  75. pub fn load_device_auth(&self) -> Result<aspect_ident::IdentSigner, Error> {
  76. let mut dk_path = self.base.clone();
  77. dk_path.push(DEV_AUTH_NAME);
  78. let buf = fs::read(dk_path)?;
  79. Ok(serde_json::from_slice::<aspect_ident::IdentSigner>(&buf)?)
  80. }
  81. pub fn load_user_data(&self) -> Result<UserData, Error> {
  82. let mut ud_path = self.base.clone();
  83. ud_path.push("user.json");
  84. let buf = fs::read(&ud_path)?;
  85. Ok(serde_json::from_slice(&buf)?)
  86. }
  87. }
  88. #[derive(Clone, Debug, Serialize, Deserialize)]
  89. pub struct UserData {
  90. pub username: String,
  91. pub password: String,
  92. pub homeserver_host: String,
  93. pub homeserver_port: u16,
  94. }