Page MenuHomePhorge

D8328.1768816588.diff
No OneTemporary

Size
11 KB
Referenced Files
None
Subscribers
None

D8328.1768816588.diff

diff --git a/keyserver/addons/rust-node-addon/rust-binding-types.js b/keyserver/addons/rust-node-addon/rust-binding-types.js
--- a/keyserver/addons/rust-node-addon/rust-binding-types.js
+++ b/keyserver/addons/rust-node-addon/rust-binding-types.js
@@ -21,7 +21,7 @@
password: string,
signedIdentityKeysBlob: SignedIdentityKeysBlob,
) => Promise<boolean>,
- +addReservedUsername: (message: string, signature: string) => Promise<void>,
+ +addReservedUsernames: (message: string, signature: string) => Promise<void>,
+removeReservedUsername: (
message: string,
signature: string,
diff --git a/keyserver/addons/rust-node-addon/src/identity_client/add_reserved_username.rs b/keyserver/addons/rust-node-addon/src/identity_client/add_reserved_usernames.rs
rename from keyserver/addons/rust-node-addon/src/identity_client/add_reserved_username.rs
rename to keyserver/addons/rust-node-addon/src/identity_client/add_reserved_usernames.rs
--- a/keyserver/addons/rust-node-addon/src/identity_client/add_reserved_username.rs
+++ b/keyserver/addons/rust-node-addon/src/identity_client/add_reserved_usernames.rs
@@ -10,11 +10,11 @@
let channel = get_identity_service_channel().await?;
let mut identity_client = IdentityClientServiceClient::new(channel);
- let add_reserved_username_request =
- AddReservedUsernameRequest { message, signature };
+ let add_reserved_usernames_request =
+ AddReservedUsernamesRequest { message, signature };
identity_client
- .add_reserved_username(add_reserved_username_request)
+ .add_reserved_usernames(add_reserved_usernames_request)
.await
.map_err(|e| Error::new(Status::GenericFailure, e.to_string()))?
.into_inner();
diff --git a/keyserver/addons/rust-node-addon/src/identity_client/mod.rs b/keyserver/addons/rust-node-addon/src/identity_client/mod.rs
--- a/keyserver/addons/rust-node-addon/src/identity_client/mod.rs
+++ b/keyserver/addons/rust-node-addon/src/identity_client/mod.rs
@@ -1,4 +1,4 @@
-pub mod add_reserved_username;
+pub mod add_reserved_usernames;
pub mod register_user;
pub mod remove_reserved_username;
pub mod identity_client {
@@ -7,7 +7,7 @@
use identity_client::identity_client_service_client::IdentityClientServiceClient;
use identity_client::{
- AddReservedUsernameRequest, DeviceKeyUpload, IdentityKeyInfo,
+ AddReservedUsernamesRequest, DeviceKeyUpload, IdentityKeyInfo,
RegistrationFinishRequest, RegistrationStartRequest,
RemoveReservedUsernameRequest,
};
diff --git a/services/identity/src/client_service.rs b/services/identity/src/client_service.rs
--- a/services/identity/src/client_service.rs
+++ b/services/identity/src/client_service.rs
@@ -6,14 +6,16 @@
use crate::{
client_service::client_proto::{
- DeleteUserRequest, Empty, GenerateNonceResponse, InboundKeysForUserRequest,
+ AddReservedUsernamesRequest, DeleteUserRequest, Empty,
+ GenerateNonceResponse, InboundKeysForUserRequest,
InboundKeysForUserResponse, OpaqueLoginFinishRequest,
OpaqueLoginFinishResponse, OpaqueLoginStartRequest,
OpaqueLoginStartResponse, OutboundKeysForUserRequest,
OutboundKeysForUserResponse, OutboundKeyserverResponse,
RefreshUserPreKeysRequest, RegistrationFinishRequest,
RegistrationFinishResponse, RegistrationStartRequest,
- RegistrationStartResponse, UpdateUserPasswordFinishRequest,
+ RegistrationStartResponse, RemoveReservedUsernameRequest,
+ ReservedRegistrationStartRequest, UpdateUserPasswordFinishRequest,
UpdateUserPasswordStartRequest, UpdateUserPasswordStartResponse,
UploadOneTimeKeysRequest, VerifyUserAccessTokenRequest,
VerifyUserAccessTokenResponse, WalletLoginRequest, WalletLoginResponse,
@@ -23,7 +25,7 @@
id::generate_uuid,
nonce::generate_nonce_data,
reserved_users::{
- validate_add_reserved_username_message,
+ validate_add_reserved_usernames_message,
validate_remove_reserved_username_message,
validate_signed_account_ownership_message,
},
@@ -41,11 +43,6 @@
use tonic::Response;
use tracing::{debug, error};
-use self::client_proto::{
- AddReservedUsernameRequest, RemoveReservedUsernameRequest,
- ReservedRegistrationStartRequest,
-};
-
#[derive(Clone)]
pub enum WorkflowInProgress {
Registration(UserRegistrationInfo),
@@ -819,20 +816,33 @@
Ok(response)
}
- async fn add_reserved_username(
+ async fn add_reserved_usernames(
&self,
- request: tonic::Request<AddReservedUsernameRequest>,
+ request: tonic::Request<AddReservedUsernamesRequest>,
) -> Result<tonic::Response<Empty>, tonic::Status> {
let message = request.into_inner();
- let username = validate_add_reserved_username_message(
+ let usernames = validate_add_reserved_usernames_message(
&message.message,
&message.signature,
)?;
+ let mut filtered_usernames = Vec::new();
+
+ for username in usernames {
+ if !self
+ .client
+ .username_taken(username.clone())
+ .await
+ .map_err(handle_db_error)?
+ {
+ filtered_usernames.push(username);
+ }
+ }
+
self
.client
- .add_username_to_reserved_usernames_table(username)
+ .add_usernames_to_reserved_usernames_table(filtered_usernames)
.await
.map_err(handle_db_error)?;
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
@@ -5,7 +5,7 @@
use std::sync::Arc;
use aws_config::SdkConfig;
-use aws_sdk_dynamodb::model::AttributeValue;
+use aws_sdk_dynamodb::model::{AttributeValue, PutRequest, WriteRequest};
use aws_sdk_dynamodb::output::{
DeleteItemOutput, GetItemOutput, PutItemOutput, QueryOutput,
};
@@ -665,22 +665,58 @@
.map_err(|e| Error::AwsSdk(e.into()))
}
- pub async fn add_username_to_reserved_usernames_table(
+ pub async fn add_usernames_to_reserved_usernames_table(
&self,
- username: String,
- ) -> Result<PutItemOutput, Error> {
- 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()))
+ usernames: Vec<String>,
+ ) -> Result<(), Error> {
+ let mut write_requests = vec![];
+
+ for username in usernames {
+ let item: HashMap<String, AttributeValue> = vec![(
+ RESERVED_USERNAMES_TABLE_PARTITION_KEY.to_string(),
+ AttributeValue::S(username),
+ )]
+ .into_iter()
+ .collect();
+
+ let write_request = WriteRequest::builder()
+ .put_request(PutRequest::builder().set_item(Some(item)).build())
+ .build();
+
+ write_requests.push(write_request);
+ }
+
+ loop {
+ let output = self
+ .client
+ .batch_write_item()
+ .request_items(RESERVED_USERNAMES_TABLE, write_requests)
+ .send()
+ .await
+ .map_err(|e| Error::AwsSdk(e.into()))?;
+
+ let unprocessed_items_map = match output.unprocessed_items() {
+ Some(map) => map,
+ None => break,
+ };
+
+ let unprocessed_requests =
+ match unprocessed_items_map.get(RESERVED_USERNAMES_TABLE) {
+ Some(requests) => requests,
+ None => break,
+ };
+
+ info!(
+ "{} unprocessed items, retrying...",
+ unprocessed_requests.len()
+ );
+
+ write_requests = unprocessed_requests.to_vec();
+ }
+
+ info!("Batch write item to reserved usernames table succeeded");
+
+ Ok(())
}
pub async fn delete_username_from_reserved_usernames_table(
diff --git a/services/identity/src/reserved_users.rs b/services/identity/src/reserved_users.rs
--- a/services/identity/src/reserved_users.rs
+++ b/services/identity/src/reserved_users.rs
@@ -9,22 +9,25 @@
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
-struct ReservedUsernameMessage {
+struct Message<T> {
statement: String,
- username: String,
+ payload: T,
issued_at: String,
}
-fn validate_message(
+fn validate_and_decode_message<T: serde::de::DeserializeOwned>(
keyserver_message: &str,
keyserver_signature: &str,
- statement: &[u8],
-) -> Result<ReservedUsernameMessage, Status> {
- let deserialized_message: ReservedUsernameMessage =
+ expected_statement: &[u8],
+) -> Result<Message<T>, Status> {
+ let deserialized_message: Message<T> =
serde_json::from_str(keyserver_message)
.map_err(|_| Status::invalid_argument("message format invalid"))?;
- if !constant_time_eq(deserialized_message.statement.as_bytes(), statement) {
+ if !constant_time_eq(
+ deserialized_message.statement.as_bytes(),
+ expected_statement,
+ ) {
return Err(Status::invalid_argument("message invalid"));
}
@@ -69,41 +72,41 @@
keyserver_message: &str,
keyserver_signature: &str,
) -> Result<(), Status> {
- let deserialized_message = validate_message(
+ let deserialized_message = validate_and_decode_message::<String>(
keyserver_message,
keyserver_signature,
b"This user is the owner of the following username",
)?;
- if deserialized_message.username != username {
+ if deserialized_message.payload != username {
return Err(Status::invalid_argument("message invalid"));
}
Ok(())
}
-pub fn validate_add_reserved_username_message(
+pub fn validate_add_reserved_usernames_message(
keyserver_message: &str,
keyserver_signature: &str,
-) -> Result<String, Status> {
- let deserialized_message = validate_message(
+) -> Result<Vec<String>, Status> {
+ let deserialized_message = validate_and_decode_message::<Vec<String>>(
keyserver_message,
keyserver_signature,
- b"Add the following username to reserved list",
+ b"Add the following usernames to reserved list",
)?;
- Ok(deserialized_message.username)
+ Ok(deserialized_message.payload)
}
pub fn validate_remove_reserved_username_message(
keyserver_message: &str,
keyserver_signature: &str,
) -> Result<String, Status> {
- let deserialized_message = validate_message(
+ let deserialized_message = validate_and_decode_message::<String>(
keyserver_message,
keyserver_signature,
b"Remove the following username from reserved list",
)?;
- Ok(deserialized_message.username)
+ Ok(deserialized_message.payload)
}
diff --git a/shared/protos/identity_client.proto b/shared/protos/identity_client.proto
--- a/shared/protos/identity_client.proto
+++ b/shared/protos/identity_client.proto
@@ -71,7 +71,7 @@
// Called by Ashoat's keyserver to add usernames to the Identity service's
// reserved list
- rpc AddReservedUsername(AddReservedUsernameRequest) returns (Empty) {}
+ rpc AddReservedUsernames(AddReservedUsernamesRequest) returns (Empty) {}
// Called by Ashoat's keyserver to remove usernames from the Identity
// service's reserved list
rpc RemoveReservedUsername(RemoveReservedUsernameRequest) returns (Empty) {}
@@ -340,9 +340,9 @@
bool tokenValid = 1;
}
-// AddReservedUsername
+// AddReservedUsernames
-message AddReservedUsernameRequest {
+message AddReservedUsernamesRequest {
// Message from Ashoat's keyserver containing the username to be added
string message = 1;
// Above message signed with Ashoat's keyserver's signing ed25519 key

File Metadata

Mime Type
text/plain
Expires
Mon, Jan 19, 9:56 AM (4 m, 55 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5955722
Default Alt Text
D8328.1768816588.diff (11 KB)

Event Timeline