1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
//! Network user and session management //! //! `libqaul` is an abstraction over a distributed network of users, //! meaning that it is impossible to tell the underlying device //! configuration. When connecting to other applications on the //! network, this is always done between *users*. use crate::diff::{ItemDiff, SetDiff}; use ratman_identity::Identity; use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, BTreeSet}; /// A random authentication token pub type Token = String; /// Wrapper to encode `User` authentication state /// /// This structure can be aquired by challenging an authentication /// endpoint, such as `User::login` to yield a token. If a session for /// this `Identity` already exists, it will be re-used. #[derive(Serialize, Deserialize, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct UserAuth(pub Identity, pub Token); /// A complete user profile with ID and metadata /// /// This abstraction is used in the Service API (see `api` module), /// but is important beyond the API functions, and as such is not part /// of the API `models` module. /// /// The user profile itself makes no destinction between local, remote /// or self users (the latter being the currently active user in a /// session) #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] pub struct UserProfile { /// A user's network (node) ID pub id: Identity, /// A human readable display-name (like @foobar) pub handle: Option<String>, /// A human's preferred call-sign ("Friends call me foo") pub display_name: Option<String>, /// A key-value list of things the user deems interesting about /// themselves. This could be stuff like "gender", "preferred /// languages" or whatever. pub bio: BTreeMap<String, String>, /// The set of services this user runs (should never be empty!) pub services: BTreeSet<String>, /// A users profile picture (some people like selfies) pub avatar: Option<Vec<u8>>, } impl UserProfile { /// Create a new user profile for a user ID pub fn new(id: Identity) -> Self { Self { id, handle: None, display_name: None, bio: BTreeMap::new(), services: BTreeSet::new(), avatar: None, } } // /// Apply the given UserUpdate to this UserUpdate in-place // pub fn apply(self, update: UserUpdate) -> Self { // let mut new = self; // update.apply_to(&mut new); // new // } /// Do a contains-query on names to facilitate searching /// /// This means that the query string needs to be contained in it's /// entirety in the display or real name strings to return a /// match. pub fn contains_query(&self, query: &str) -> bool { (match &self.display_name { None => false, Some(v) => v.contains(query), }) || (match &self.display_name { None => false, Some(v) => v.contains(query), }) } /// Do a fully fuzzy query on names to facilitate searching pub fn fuzzy_query(&self, _query: &str) -> bool { unimplemented!() } #[doc(hidden)] pub fn generate_updates(&self, new: Self) -> UserUpdate { let mut update = UserUpdate::default(); match (&self.handle, new.handle) { (None, Some(name)) => update.handle = ItemDiff::Set(name), (Some(_), None) => update.handle = ItemDiff::Unset, (_, _) => {} // Ignore is the default } match (&self.display_name, new.display_name) { (None, Some(name)) => update.display_name = ItemDiff::Set(name), (Some(_), None) => update.display_name = ItemDiff::Unset, (_, _) => {} // Ignore is the default } // TODO: implement other user updates update } } /// All the ways a UserData can change, as individual events. #[derive(Serialize, Deserialize, Default, PartialEq, Eq, Debug, Clone)] #[serde(default)] pub struct UserUpdate { /// Set or blank the User's handle pub handle: ItemDiff<String>, /// Set or blank the User's display name pub display_name: ItemDiff<String>, /// Add or update a biography line with the given key to the given value. pub add_to_bio: Vec<(String, String)>, /// Remove a biography line with the given key, or do nothing if it does not exist. pub rm_from_bio: BTreeSet<String>, /// Add a service with the given name. pub services: BTreeSet<SetDiff<String>>, /// Set or blank the User's avatar. pub avi_data: ItemDiff<Vec<u8>>, }