123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- //! Describes accessors around a homeserver or client data directory.
- use std::fs;
- use std::io;
- use std::path::PathBuf;
- use serde::{Deserialize, Serialize};
- use thiserror::Error;
- pub const USERDATA_NAME: &str = "user.json";
- pub const DEV_AUTH_NAME: &str = "device_signer.json";
- pub const DEV_AUTH_TMP_NAME: &str = "device_signer.tmp";
- #[derive(Debug, Error)]
- pub enum Error {
- #[error("missing user data file")]
- MissingUserData,
- #[error("missing device auth file")]
- MissingDeviceAuth,
- #[error("tried to create datadir where one already exists")]
- DatadirExists,
- #[error("codec: {0}")]
- Codec(#[from] aspect_codec::CodecError),
- #[error("json: {0}")]
- SerdeJson(#[from] serde_json::Error),
- #[error("io: {0}")]
- Io(#[from] io::Error),
- }
- pub struct Datadir {
- base: PathBuf,
- }
- impl Datadir {
- /// Creates a new datadir with the provided initial state.
- pub fn create(
- base: PathBuf,
- userdata: &UserData,
- signer: &aspect_ident::IdentSigner,
- ) -> Result<Self, Error> {
- if base.exists() {
- return Err(Error::DatadirExists);
- }
- // Save user data.
- let ud_buf = serde_json::to_vec(userdata)?;
- let mut ud_path = base.clone();
- ud_path.push("user.json");
- fs::write(&ud_path, &ud_buf)?;
- let mut dd = Datadir { base };
- dd.save_device_auth(signer)?;
- Ok(dd)
- }
- /// Opens a datadir and makes assertions about its contents from the config.
- pub fn open(mut base: PathBuf) -> Result<Self, Error> {
- // Check the user data file path.
- base.push(USERDATA_NAME);
- if !base.exists() {
- return Err(Error::MissingUserData);
- }
- base.pop();
- // Check the device authorization data path.
- base.push(DEV_AUTH_NAME);
- if !base.exists() {
- return Err(Error::MissingDeviceAuth);
- }
- base.pop();
- Ok(Self { base })
- }
- pub fn save_device_auth(&mut self, auth: &aspect_ident::IdentSigner) -> Result<(), Error> {
- // Write to a temp file.
- let mut dkt_path = self.base.clone();
- dkt_path.push(DEV_AUTH_TMP_NAME);
- let buf = serde_json::to_vec_pretty(auth)?;
- fs::write(&dkt_path, buf)?;
- // Move it over the real file so that we don't accidentally truncate it.
- let mut dk_path = self.base.clone();
- dk_path.push(DEV_AUTH_NAME);
- fs::rename(dkt_path, dk_path)?;
- Ok(())
- }
- pub fn load_device_auth(&self) -> Result<aspect_ident::IdentSigner, Error> {
- let mut dk_path = self.base.clone();
- dk_path.push(DEV_AUTH_NAME);
- let buf = fs::read(dk_path)?;
- Ok(serde_json::from_slice::<aspect_ident::IdentSigner>(&buf)?)
- }
- pub fn load_user_data(&self) -> Result<UserData, Error> {
- let mut ud_path = self.base.clone();
- ud_path.push("user.json");
- let buf = fs::read(&ud_path)?;
- Ok(serde_json::from_slice(&buf)?)
- }
- }
- #[derive(Clone, Debug, Serialize, Deserialize)]
- pub struct UserData {
- pub username: String,
- pub password: String,
- pub homeserver_host: String,
- pub homeserver_port: u16,
- }
|