diff --git a/services/identity/src/constants.rs b/services/identity/src/constants.rs --- a/services/identity/src/constants.rs +++ b/services/identity/src/constants.rs @@ -83,6 +83,10 @@ pub const NONCE_TABLE_PARTITION_KEY: &str = "nonce"; pub const NONCE_TABLE_CREATED_ATTRIBUTE: &str = "created"; +// Usernames reserved because they exist in Ashoat's keyserver already +pub const RESERVED_USERNAMES_TABLE: &str = "identity-reserved-usernames"; +pub const RESERVED_USERNAMES_TABLE_PARTITION_KEY: &str = "username"; + // Tokio pub const MPSC_CHANNEL_BUFFER_CAPACITY: usize = 1; diff --git a/services/identity/src/database.rs b/services/identity/src/database.rs --- a/services/identity/src/database.rs +++ b/services/identity/src/database.rs @@ -22,8 +22,9 @@ ACCESS_TOKEN_TABLE_AUTH_TYPE_ATTRIBUTE, ACCESS_TOKEN_TABLE_CREATED_ATTRIBUTE, ACCESS_TOKEN_TABLE_PARTITION_KEY, ACCESS_TOKEN_TABLE_TOKEN_ATTRIBUTE, ACCESS_TOKEN_TABLE_VALID_ATTRIBUTE, NONCE_TABLE, - NONCE_TABLE_CREATED_ATTRIBUTE, NONCE_TABLE_PARTITION_KEY, USERS_TABLE, - USERS_TABLE_DEVICES_ATTRIBUTE, + NONCE_TABLE_CREATED_ATTRIBUTE, NONCE_TABLE_PARTITION_KEY, + RESERVED_USERNAMES_TABLE, RESERVED_USERNAMES_TABLE_PARTITION_KEY, + USERS_TABLE, USERS_TABLE_DEVICES_ATTRIBUTE, USERS_TABLE_DEVICES_MAP_CONTENT_ONETIME_KEYS_ATTRIBUTE_NAME, USERS_TABLE_DEVICES_MAP_CONTENT_PREKEY_ATTRIBUTE_NAME, USERS_TABLE_DEVICES_MAP_CONTENT_PREKEY_SIGNATURE_ATTRIBUTE_NAME, @@ -598,6 +599,80 @@ .await .map_err(|e| Error::AwsSdk(e.into())) } + + pub async fn add_username_to_reserved_usernames_table( + &self, + username: String, + ) -> Result { + let item = HashMap::from([( + RESERVED_USERNAMES_TABLE_PARTITION_KEY.to_string(), + AttributeValue::S(username), + )]); + self + .client + .put_item() + .table_name(RESERVED_USERNAMES_TABLE) + .set_item(Some(item)) + .send() + .await + .map_err(|e| Error::AwsSdk(e.into())) + } + + pub async fn delete_username_from_reserved_usernames_table( + &self, + username: String, + ) -> Result { + debug!( + "Attempting to delete username {} from reserved usernames table", + username + ); + + match self + .client + .delete_item() + .table_name(RESERVED_USERNAMES_TABLE) + .key( + RESERVED_USERNAMES_TABLE_PARTITION_KEY, + AttributeValue::S(username.clone()), + ) + .send() + .await + { + Ok(out) => { + info!( + "Username {} has been deleted from reserved usernames table", + username + ); + Ok(out) + } + Err(e) => { + error!("DynamoDB client failed to delete username {} from reserved usernames table", username); + Err(Error::AwsSdk(e.into())) + } + } + } + + pub async fn username_in_reserved_usernames_table( + &self, + username: &str, + ) -> Result { + match self + .client + .get_item() + .table_name(RESERVED_USERNAMES_TABLE) + .key( + RESERVED_USERNAMES_TABLE_PARTITION_KEY.to_string(), + AttributeValue::S(username.to_string()), + ) + .consistent_read(true) + .send() + .await + { + Ok(GetItemOutput { item: Some(_), .. }) => Ok(true), + Ok(_) => Ok(false), + Err(e) => Err(Error::AwsSdk(e.into())), + } + } } #[derive(