2020-03-30 11:46:18 +00:00
|
|
|
use crate::{utils, Database};
|
2020-03-29 22:10:15 +00:00
|
|
|
use ruma_events::collections::all::Event;
|
|
|
|
use ruma_identifiers::{EventId, RoomId, UserId};
|
2020-03-29 19:05:20 +00:00
|
|
|
use std::convert::TryInto;
|
|
|
|
|
2020-03-30 11:46:18 +00:00
|
|
|
pub struct Data {
|
|
|
|
hostname: String,
|
|
|
|
db: Database,
|
|
|
|
}
|
2020-03-28 17:50:02 +00:00
|
|
|
|
|
|
|
impl Data {
|
2020-03-29 19:05:20 +00:00
|
|
|
/// Load an existing database or create a new one.
|
2020-03-30 11:46:18 +00:00
|
|
|
pub fn load_or_create(hostname: &str) -> Self {
|
|
|
|
Self {
|
|
|
|
hostname: hostname.to_owned(),
|
|
|
|
db: Database::load_or_create(hostname),
|
|
|
|
}
|
2020-03-29 19:05:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get the hostname of the server.
|
2020-03-30 11:46:18 +00:00
|
|
|
pub fn hostname(&self) -> &str {
|
|
|
|
&self.hostname
|
2020-03-29 19:05:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Check if a user has an account by looking for an assigned password.
|
2020-03-28 17:50:02 +00:00
|
|
|
pub fn user_exists(&self, user_id: &UserId) -> bool {
|
2020-03-30 11:46:18 +00:00
|
|
|
self.db
|
|
|
|
.userid_password
|
2020-03-28 17:50:02 +00:00
|
|
|
.contains_key(user_id.to_string())
|
|
|
|
.unwrap()
|
|
|
|
}
|
|
|
|
|
2020-03-29 19:05:20 +00:00
|
|
|
/// Create a new user account by assigning them a password.
|
|
|
|
pub fn user_add(&self, user_id: &UserId, password: Option<String>) {
|
2020-03-30 11:46:18 +00:00
|
|
|
self.db
|
|
|
|
.userid_password
|
2020-03-28 17:50:02 +00:00
|
|
|
.insert(user_id.to_string(), &*password.unwrap_or_default())
|
|
|
|
.unwrap();
|
|
|
|
}
|
2020-03-29 11:48:44 +00:00
|
|
|
|
2020-03-29 19:05:20 +00:00
|
|
|
/// Find out which user an access token belongs to.
|
|
|
|
pub fn user_from_token(&self, token: &str) -> Option<UserId> {
|
2020-03-30 11:46:18 +00:00
|
|
|
self.db
|
|
|
|
.token_userid
|
2020-03-29 19:05:20 +00:00
|
|
|
.get(token)
|
|
|
|
.unwrap()
|
2020-03-30 11:46:18 +00:00
|
|
|
.and_then(|bytes| (*utils::string_from_bytes(&bytes)).try_into().ok())
|
2020-03-29 19:05:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Checks if the given password is equal to the one in the database.
|
|
|
|
pub fn password_get(&self, user_id: &UserId) -> Option<String> {
|
2020-03-30 11:46:18 +00:00
|
|
|
self.db
|
|
|
|
.userid_password
|
2020-03-29 19:05:20 +00:00
|
|
|
.get(user_id.to_string())
|
|
|
|
.unwrap()
|
2020-03-30 11:46:18 +00:00
|
|
|
.map(|bytes| utils::string_from_bytes(&bytes))
|
2020-03-29 19:05:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Add a new device to a user.
|
|
|
|
pub fn device_add(&self, user_id: &UserId, device_id: &str) {
|
2020-03-30 11:46:18 +00:00
|
|
|
if self
|
|
|
|
.db
|
|
|
|
.userid_deviceids
|
|
|
|
.get_iter(&user_id.to_string().as_bytes())
|
|
|
|
.filter_map(|item| item.ok())
|
|
|
|
.map(|(_key, value)| value)
|
|
|
|
.all(|device| device != device_id)
|
|
|
|
{
|
|
|
|
self.db
|
|
|
|
.userid_deviceids
|
|
|
|
.add(user_id.to_string().as_bytes(), device_id.into());
|
|
|
|
}
|
2020-03-29 19:05:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Replace the access token of one device.
|
|
|
|
pub fn token_replace(&self, user_id: &UserId, device_id: &String, token: String) {
|
|
|
|
// Make sure the device id belongs to the user
|
|
|
|
debug_assert!(self
|
2020-03-30 11:46:18 +00:00
|
|
|
.db
|
|
|
|
.userid_deviceids
|
|
|
|
.get_iter(&user_id.to_string().as_bytes())
|
|
|
|
.filter_map(|item| item.ok())
|
|
|
|
.map(|(_key, value)| value)
|
|
|
|
.any(|device| device == device_id.as_bytes())); // Does the user have that device?
|
2020-03-29 19:05:20 +00:00
|
|
|
|
|
|
|
// Remove old token
|
2020-03-30 11:46:18 +00:00
|
|
|
if let Some(old_token) = self.db.deviceid_token.get(device_id).unwrap() {
|
|
|
|
self.db.token_userid.remove(old_token).unwrap();
|
|
|
|
// It will be removed from deviceid_token by the insert later
|
2020-03-29 19:05:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Assign token to device_id
|
2020-03-30 11:46:18 +00:00
|
|
|
self.db.deviceid_token.insert(device_id, &*token).unwrap();
|
2020-03-29 19:05:20 +00:00
|
|
|
|
|
|
|
// Assign token to user
|
2020-03-30 11:46:18 +00:00
|
|
|
self.db
|
|
|
|
.token_userid
|
2020-03-29 19:05:20 +00:00
|
|
|
.insert(token, &*user_id.to_string())
|
|
|
|
.unwrap();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create a new room event.
|
2020-03-30 11:46:18 +00:00
|
|
|
pub fn event_add(&self, room_id: &RoomId, event_id: &EventId, event: &Event) {
|
|
|
|
let mut key = room_id.to_string().as_bytes().to_vec();
|
|
|
|
key.extend_from_slice(event_id.to_string().as_bytes());
|
|
|
|
self.db
|
|
|
|
.roomid_eventid_event
|
|
|
|
.insert(&key, &*serde_json::to_string(event).unwrap())
|
|
|
|
.unwrap();
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn debug(&self) {
|
|
|
|
self.db.debug();
|
2020-03-29 19:05:20 +00:00
|
|
|
}
|
2020-03-28 17:50:02 +00:00
|
|
|
}
|