Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3356191
D10480.id35179.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
9 KB
Referenced Files
None
Subscribers
None
D10480.id35179.diff
View Options
diff --git a/keyserver/src/creators/account-creator.js b/keyserver/src/creators/account-creator.js
--- a/keyserver/src/creators/account-creator.js
+++ b/keyserver/src/creators/account-creator.js
@@ -13,6 +13,7 @@
RegisterRequest,
} from 'lib/types/account-types.js';
import type {
+ UserDetail,
ReservedUsernameMessage,
SignedIdentityKeysBlob,
} from 'lib/types/crypto-types.js';
@@ -190,7 +191,9 @@
];
ignorePromiseRejections(
- createAndSendReservedUsernameMessage([request.username]),
+ createAndSendReservedUsernameMessage([
+ { username: request.username, userID: id },
+ ]),
);
return {
@@ -290,14 +293,16 @@
await Promise.all([createMessages(viewer, messageDatas)]);
ignorePromiseRejections(
- createAndSendReservedUsernameMessage([request.address]),
+ createAndSendReservedUsernameMessage([
+ { username: request.address, userID: id },
+ ]),
);
return id;
}
async function createAndSendReservedUsernameMessage(
- payload: $ReadOnlyArray<string>,
+ payload: $ReadOnlyArray<UserDetail>,
) {
const issuedAt = new Date().toISOString();
const reservedUsernameMessage: ReservedUsernameMessage = {
diff --git a/keyserver/src/cron/update-identity-reserved-usernames.js b/keyserver/src/cron/update-identity-reserved-usernames.js
--- a/keyserver/src/cron/update-identity-reserved-usernames.js
+++ b/keyserver/src/cron/update-identity-reserved-usernames.js
@@ -4,19 +4,19 @@
import type { ReservedUsernameMessage } from 'lib/types/crypto-types.js';
-import { fetchAllUsernames } from '../fetchers/user-fetchers.js';
+import { fetchAllUserDetails } from '../fetchers/user-fetchers.js';
import { fetchOlmAccount } from '../updaters/olm-account-updater.js';
async function updateIdentityReservedUsernames(): Promise<void> {
- const [usernames, rustAPI, accountInfo] = await Promise.all([
- fetchAllUsernames(),
+ const [userDetails, rustAPI, accountInfo] = await Promise.all([
+ fetchAllUserDetails(),
getRustAPI(),
fetchOlmAccount('content'),
]);
const issuedAt = new Date().toISOString();
const reservedUsernameMessage: ReservedUsernameMessage = {
statement: 'Add the following usernames to reserved list',
- payload: usernames,
+ payload: userDetails,
issuedAt,
};
const stringifiedMessage = JSON.stringify(reservedUsernameMessage);
diff --git a/keyserver/src/fetchers/user-fetchers.js b/keyserver/src/fetchers/user-fetchers.js
--- a/keyserver/src/fetchers/user-fetchers.js
+++ b/keyserver/src/fetchers/user-fetchers.js
@@ -7,6 +7,7 @@
FUTURE_CODE_VERSION,
} from 'lib/shared/version-utils.js';
import type { AvatarDBContent, ClientAvatar } from 'lib/types/avatar-types.js';
+import type { UserDetail } from 'lib/types/crypto-types.js';
import {
undirectedStatus,
directedStatus,
@@ -448,6 +449,16 @@
return result.map(row => row.username);
}
+async function fetchAllUserDetails(): Promise<UserDetail[]> {
+ const query = SQL`SELECT username, id FROM users`;
+ const [result] = await dbQuery(query);
+
+ return result.map(row => ({
+ username: row.username,
+ userID: row.id,
+ }));
+}
+
async function fetchKeyserverAdminID(): Promise<?string> {
const changeRoleExtractString = `$.${threadPermissions.CHANGE_ROLE}`;
const query = SQL`
@@ -490,6 +501,7 @@
fetchAllUserIDs,
fetchUsername,
fetchAllUsernames,
+ fetchAllUserDetails,
fetchKnownUserInfos,
fetchKeyserverAdminID,
fetchUserIDForEthereumAddress,
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
@@ -67,12 +67,17 @@
signature: t.String,
});
+export type UserDetail = {
+ +username: string,
+ +userID: string,
+};
+
// This type should not be changed without making equivalent changes to
// `Message` in Identity service's `reserved_users` module
export type ReservedUsernameMessage =
| {
+statement: 'Add the following usernames to reserved list',
- +payload: $ReadOnlyArray<string>,
+ +payload: $ReadOnlyArray<UserDetail>,
+issuedAt: string,
}
| {
@@ -82,10 +87,7 @@
}
| {
+statement: 'This user is the owner of the following username and user ID',
- +payload: {
- +username: string,
- +userID: string,
- },
+ +payload: UserDetail,
+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
@@ -600,20 +600,20 @@
) -> Result<tonic::Response<Empty>, tonic::Status> {
let message = request.into_inner();
- let usernames = validate_add_reserved_usernames_message(
+ let user_details = validate_add_reserved_usernames_message(
&message.message,
&message.signature,
)?;
- let filtered_usernames = self
+ let filtered_user_details = self
.client
- .filter_out_taken_usernames(usernames)
+ .filter_out_taken_usernames(user_details)
.await
.map_err(handle_db_error)?;
self
.client
- .add_usernames_to_reserved_usernames_table(filtered_usernames)
+ .add_usernames_to_reserved_usernames_table(filtered_user_details)
.await
.map_err(handle_db_error)?;
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
@@ -87,6 +87,7 @@
// 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";
+pub const RESERVED_USERNAMES_TABLE_USER_ID_ATTRIBUTE: &str = "userID";
// One time keys table, which need to exist in their own table to ensure
// atomicity of additions and removals
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
@@ -7,6 +7,7 @@
create_one_time_key_partition_key, into_one_time_put_requests, OlmAccountType,
};
use crate::error::{consume_error, DBItemAttributeError, DBItemError, Error};
+use crate::reserved_users::UserDetail;
use aws_config::SdkConfig;
use aws_sdk_dynamodb::model::{AttributeValue, PutRequest, WriteRequest};
use aws_sdk_dynamodb::output::{
@@ -27,7 +28,8 @@
NONCE_TABLE_CREATED_ATTRIBUTE, NONCE_TABLE_EXPIRATION_TIME_ATTRIBUTE,
NONCE_TABLE_EXPIRATION_TIME_UNIX_ATTRIBUTE, NONCE_TABLE_PARTITION_KEY,
NOTIF_ONE_TIME_KEY, RESERVED_USERNAMES_TABLE,
- RESERVED_USERNAMES_TABLE_PARTITION_KEY, USERS_TABLE,
+ RESERVED_USERNAMES_TABLE_PARTITION_KEY,
+ RESERVED_USERNAMES_TABLE_USER_ID_ATTRIBUTE, USERS_TABLE,
USERS_TABLE_DEVICES_ATTRIBUTE,
USERS_TABLE_DEVICES_MAP_CONTENT_ONE_TIME_KEYS_ATTRIBUTE_NAME,
USERS_TABLE_DEVICES_MAP_CONTENT_PREKEY_ATTRIBUTE_NAME,
@@ -863,19 +865,18 @@
pub async fn filter_out_taken_usernames(
&self,
- usernames: Vec<String>,
- ) -> Result<Vec<String>, Error> {
+ user_details: Vec<UserDetail>,
+ ) -> Result<Vec<UserDetail>, Error> {
let db_usernames = self.get_all_usernames().await?;
let db_usernames_set: HashSet<String> = db_usernames.into_iter().collect();
- let usernames_set: HashSet<String> = usernames.into_iter().collect();
- let available_usernames: Vec<String> = usernames_set
- .difference(&db_usernames_set)
- .cloned()
+ let available_user_details: Vec<UserDetail> = user_details
+ .into_iter()
+ .filter(|user_detail| !db_usernames_set.contains(&user_detail.username))
.collect();
- Ok(available_usernames)
+ Ok(available_user_details)
}
async fn get_user_from_user_info(
@@ -1208,17 +1209,21 @@
pub async fn add_usernames_to_reserved_usernames_table(
&self,
- usernames: Vec<String>,
+ user_details: Vec<UserDetail>,
) -> Result<(), Error> {
// A single call to BatchWriteItem can consist of up to 25 operations
- for usernames_chunk in usernames.chunks(25) {
- let write_requests = usernames_chunk
+ for user_chunk in user_details.chunks(25) {
+ let write_requests = user_chunk
.iter()
- .map(|username| {
+ .map(|user_detail| {
let put_request = PutRequest::builder()
.item(
RESERVED_USERNAMES_TABLE_PARTITION_KEY,
- AttributeValue::S(username.to_string()),
+ AttributeValue::S(user_detail.username.to_string()),
+ )
+ .item(
+ RESERVED_USERNAMES_TABLE_USER_ID_ATTRIBUTE,
+ AttributeValue::S(user_detail.user_id.to_string()),
)
.build();
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
@@ -21,10 +21,10 @@
// `ReservedUsernameMessage` in lib/types/crypto-types.js
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
-struct UsernameAndID {
- username: String,
+pub struct UserDetail {
+ pub username: String,
#[serde(rename = "userID")]
- user_id: String,
+ pub user_id: String,
}
fn validate_and_decode_message<T: serde::de::DeserializeOwned>(
@@ -88,7 +88,7 @@
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>(
+ let deserialized_message = validate_and_decode_message::<UserDetail>(
keyserver_message,
keyserver_signature,
EXPECTED_STATEMENT,
@@ -104,8 +104,8 @@
pub fn validate_add_reserved_usernames_message(
keyserver_message: &str,
keyserver_signature: &str,
-) -> Result<Vec<String>, Status> {
- let deserialized_message = validate_and_decode_message::<Vec<String>>(
+) -> Result<Vec<UserDetail>, Status> {
+ let deserialized_message = validate_and_decode_message::<Vec<UserDetail>>(
keyserver_message,
keyserver_signature,
b"Add the following usernames to reserved list",
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Nov 24, 5:21 PM (20 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2576856
Default Alt Text
D10480.id35179.diff (9 KB)
Attached To
Mode
D10480: [identity] [lib] [keyserver] [7/n] Add userID to reserved_usernames table in DDB
Attached
Detach File
Event Timeline
Log In to Comment