Page MenuHomePhabricator

D9482.diff
No OneTemporary

D9482.diff

diff --git a/keyserver/src/responders/user-responders.js b/keyserver/src/responders/user-responders.js
--- a/keyserver/src/responders/user-responders.js
+++ b/keyserver/src/responders/user-responders.js
@@ -740,8 +740,11 @@
const issuedAt = new Date().toISOString();
const reservedUsernameMessage: ReservedUsernameMessage = {
- statement: 'This user is the owner of the following username',
- payload: username,
+ statement: 'This user is the owner of the following username and user ID',
+ payload: {
+ username,
+ userID: viewer.userID,
+ },
issuedAt,
};
const message = JSON.stringify(reservedUsernameMessage);
diff --git a/lib/types/crypto-types.js b/lib/types/crypto-types.js
--- a/lib/types/crypto-types.js
+++ b/lib/types/crypto-types.js
@@ -61,8 +61,11 @@
+issuedAt: string,
}
| {
- +statement: 'This user is the owner of the following username',
- +payload: string,
+ +statement: 'This user is the owner of the following username and user ID',
+ +payload: {
+ +username: string,
+ +userID: string,
+ },
+issuedAt: string,
};
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
@@ -36,9 +36,9 @@
use crate::id::generate_uuid;
use crate::nonce::generate_nonce_data;
use crate::reserved_users::{
+ validate_account_ownership_message_and_get_user_id,
validate_add_reserved_usernames_message,
validate_remove_reserved_username_message,
- validate_signed_account_ownership_message,
};
use crate::siwe::{is_valid_ethereum_address, parse_and_verify_siwe_message};
use crate::token::{AccessTokenData, AuthType};
@@ -61,6 +61,7 @@
pub struct UserRegistrationInfo {
pub username: String,
pub flattened_device_key_upload: FlattenedDeviceKeyUpload,
+ pub user_id: Option<String>,
}
#[derive(Clone)]
@@ -173,6 +174,7 @@
device_type: DeviceType::try_from(DBDeviceTypeInt(device_type))
.map_err(handle_db_error)?,
},
+ user_id: None,
};
let session_id = generate_uuid();
self
@@ -217,16 +219,16 @@
.username_in_reserved_usernames_table(&message.username)
.await
.map_err(handle_db_error)?;
- if username_in_reserved_usernames_table {
- validate_signed_account_ownership_message(
- &message.username,
- &message.keyserver_message,
- &message.keyserver_signature,
- )?;
- } else {
+ if !username_in_reserved_usernames_table {
return Err(tonic::Status::permission_denied("username not reserved"));
}
+ let user_id = validate_account_ownership_message_and_get_user_id(
+ &message.username,
+ &message.keyserver_message,
+ &message.keyserver_signature,
+ )?;
+
if let client_proto::ReservedRegistrationStartRequest {
opaque_registration_request: register_message,
username,
@@ -276,6 +278,7 @@
device_type: DeviceType::try_from(DBDeviceTypeInt(device_type))
.map_err(handle_db_error)?,
},
+ user_id: Some(user_id),
};
let session_id = generate_uuid();
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
@@ -144,6 +144,7 @@
Some((registration_state.username, Blob::new(password_file))),
None,
None,
+ registration_state.user_id,
)
.await
}
@@ -160,6 +161,7 @@
None,
Some(wallet_address),
Some(social_proof),
+ None,
)
.await
}
@@ -170,8 +172,9 @@
username_and_password_file: Option<(String, Blob)>,
wallet_address: Option<String>,
social_proof: Option<String>,
+ user_id: Option<String>,
) -> Result<String, Error> {
- let user_id = generate_uuid();
+ let user_id = user_id.unwrap_or_else(generate_uuid);
let device_info =
create_device_info(flattened_device_key_upload.clone(), social_proof);
let devices = HashMap::from([(
@@ -212,6 +215,9 @@
.put_item()
.table_name(USERS_TABLE)
.set_item(Some(user))
+ // make sure we don't accidentaly overwrite existing row
+ .condition_expression("attribute_not_exists(#pk)")
+ .expression_attribute_names("#pk", USERS_TABLE_PARTITION_KEY)
.send()
.await
.map_err(|e| Error::AwsSdk(e.into()))?;
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
@@ -17,6 +17,16 @@
issued_at: String,
}
+// This type should not be changed without making equivalent changes to
+// `ReservedUsernameMessage` in lib/types/crypto-types.js
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+struct UsernameAndID {
+ username: String,
+ #[serde(rename = "userID")]
+ user_id: String,
+}
+
fn validate_and_decode_message<T: serde::de::DeserializeOwned>(
keyserver_message: &str,
keyserver_signature: &str,
@@ -69,22 +79,25 @@
Ok(deserialized_message)
}
-pub fn validate_signed_account_ownership_message(
+pub fn validate_account_ownership_message_and_get_user_id(
username: &str,
keyserver_message: &str,
keyserver_signature: &str,
-) -> Result<(), Status> {
- let deserialized_message = validate_and_decode_message::<String>(
+) -> Result<String, Status> {
+ const EXPECTED_STATEMENT: &[u8; 60] =
+ b"This user is the owner of the following username and user ID";
+
+ let deserialized_message = validate_and_decode_message::<UsernameAndID>(
keyserver_message,
keyserver_signature,
- b"This user is the owner of the following username",
+ EXPECTED_STATEMENT,
)?;
- if deserialized_message.payload != username {
+ if deserialized_message.payload.username != username {
return Err(Status::invalid_argument("message invalid"));
}
- Ok(())
+ Ok(deserialized_message.payload.user_id)
}
pub fn validate_add_reserved_usernames_message(

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 22, 8:41 PM (17 h, 6 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2564856
Default Alt Text
D9482.diff (6 KB)

Event Timeline