Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F33312827
D8328.1768816588.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
D8328.1768816588.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D8328: change AddReservedUsername to AddReservedUsernames
Attached
Detach File
Event Timeline
Log In to Comment