Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3339841
D9482.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
6 KB
Referenced Files
None
Subscribers
None
D9482.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D9482: [identity] add user ID to account ownership message
Attached
Detach File
Event Timeline
Log In to Comment