base: Sanitize the room id for the path of the state store.

This closes: #71.
master
Damir Jelić 2020-07-16 12:44:07 +02:00
parent 2d955027e1
commit c1ffed4fc9
1 changed files with 37 additions and 13 deletions

View File

@ -39,6 +39,36 @@ impl JsonStore {
user_path_set: AtomicBool::new(false),
})
}
/// Build a path for a file where the Room state to be stored in.
async fn build_room_path(&self, room_state: &str, room_id: &RoomId) -> PathBuf {
let mut path = self.path.read().await.clone();
path.push("rooms");
path.push(room_state);
path.push(JsonStore::sanitize_room_id(room_id));
path.set_extension("json");
path
}
/// Build a path for the file where the Client state to be stored in.
async fn build_client_path(&self) -> PathBuf {
let mut path = self.path.read().await.clone();
path.push("client");
path.set_extension("json");
path
}
/// Replace common characters that can't be used in a file name with an
/// underscore.
fn sanitize_room_id(room_id: &RoomId) -> String {
room_id.as_str().replace(
&['.', ':', '<', '>', '"', '/', '\\', '|', '?', '*'][..],
"_",
)
}
}
impl fmt::Debug for JsonStore {
@ -57,8 +87,7 @@ impl StateStore for JsonStore {
self.path.write().await.push(sess.user_id.localpart())
}
let mut path = self.path.read().await.clone();
path.push("client.json");
let path = self.build_client_path().await;
let json = async_fs::read_to_string(path)
.await
@ -114,8 +143,7 @@ impl StateStore for JsonStore {
}
async fn store_client_state(&self, state: ClientState) -> Result<()> {
let mut path = self.path.read().await.clone();
path.push("client.json");
let path = self.build_client_path().await;
if !path.exists() {
let mut dir = path.clone();
@ -146,9 +174,7 @@ impl StateStore for JsonStore {
self.path.write().await.push(room.own_user_id.localpart())
}
let mut path = self.path.read().await.clone();
path.push("rooms");
path.push(&format!("{}/{}.json", room_state, room.room_id));
let path = self.build_room_path(room_state, &room.room_id).await;
if !path.exists() {
let mut dir = path.clone();
@ -178,15 +204,13 @@ impl StateStore for JsonStore {
return Err(Error::StateStore("path for JsonStore not set".into()));
}
let mut to_del = self.path.read().await.clone();
to_del.push("rooms");
to_del.push(&format!("{}/{}.json", room_state, room_id));
let path = self.build_room_path(room_state, room_id).await;
if !to_del.exists() {
return Err(Error::StateStore(format!("file {:?} not found", to_del)));
if !path.exists() {
return Err(Error::StateStore(format!("file {:?} not found", path)));
}
tokio::fs::remove_file(to_del).await.map_err(Error::from)
tokio::fs::remove_file(path).await.map_err(Error::from)
}
}