Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3400122
D11796.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
D11796.diff
View Options
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
@@ -58,13 +58,15 @@
pub const USERS_TABLE_WALLET_ADDRESS_INDEX: &str = "walletAddress-index";
pub const USERS_TABLE_FARCASTER_ID_INDEX: &str = "farcasterID-index";
-pub const ACCESS_TOKEN_TABLE: &str = "identity-tokens";
-pub const ACCESS_TOKEN_TABLE_PARTITION_KEY: &str = "userID";
-pub const ACCESS_TOKEN_SORT_KEY: &str = "signingPublicKey";
-pub const ACCESS_TOKEN_TABLE_CREATED_ATTRIBUTE: &str = "created";
-pub const ACCESS_TOKEN_TABLE_AUTH_TYPE_ATTRIBUTE: &str = "authType";
-pub const ACCESS_TOKEN_TABLE_VALID_ATTRIBUTE: &str = "valid";
-pub const ACCESS_TOKEN_TABLE_TOKEN_ATTRIBUTE: &str = "token";
+pub mod token_table {
+ pub const NAME: &str = "identity-tokens";
+ pub const PARTITION_KEY: &str = "userID";
+ pub const SORT_KEY: &str = "signingPublicKey";
+ pub const ATTR_CREATED: &str = "created";
+ pub const ATTR_AUTH_TYPE: &str = "authType";
+ pub const ATTR_VALID: &str = "valid";
+ pub const ATTR_TOKEN: &str = "token";
+}
pub const NONCE_TABLE: &str = "identity-nonces";
pub const NONCE_TABLE_PARTITION_KEY: &str = "nonce";
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
@@ -453,6 +453,9 @@
debug!(user_id, "Attempting to delete user's devices");
self.delete_devices_table_rows_for_user(&user_id).await?;
+ debug!(user_id, "Attempting to delete user's access tokens");
+ self.delete_all_tokens_for_user(&user_id).await?;
+
debug!(user_id, "Attempting to delete user");
match self
.client
diff --git a/services/identity/src/database/token.rs b/services/identity/src/database/token.rs
--- a/services/identity/src/database/token.rs
+++ b/services/identity/src/database/token.rs
@@ -4,20 +4,17 @@
use comm_lib::{
aws::ddb::{
operation::{get_item::GetItemOutput, put_item::PutItemOutput},
- types::AttributeValue,
+ types::{AttributeValue, DeleteRequest, WriteRequest},
+ },
+ database::{
+ batch_operations::{batch_write, ExponentialBackoffConfig},
+ DBItemAttributeError, DBItemError, TryFromAttribute,
},
- database::{DBItemAttributeError, DBItemError, TryFromAttribute},
};
use constant_time_eq::constant_time_eq;
use tracing::{error, info};
use crate::{
- constants::{
- ACCESS_TOKEN_SORT_KEY, ACCESS_TOKEN_TABLE,
- ACCESS_TOKEN_TABLE_AUTH_TYPE_ATTRIBUTE,
- ACCESS_TOKEN_TABLE_CREATED_ATTRIBUTE, ACCESS_TOKEN_TABLE_PARTITION_KEY,
- ACCESS_TOKEN_TABLE_TOKEN_ATTRIBUTE, ACCESS_TOKEN_TABLE_VALID_ATTRIBUTE,
- },
error::Error,
token::{AccessTokenData, AuthType},
};
@@ -30,20 +27,16 @@
user_id: String,
signing_public_key: String,
) -> Result<Option<AccessTokenData>, Error> {
+ use crate::constants::token_table::*;
+
let primary_key = create_composite_primary_key(
- (
- ACCESS_TOKEN_TABLE_PARTITION_KEY.to_string(),
- user_id.clone(),
- ),
- (
- ACCESS_TOKEN_SORT_KEY.to_string(),
- signing_public_key.clone(),
- ),
+ (PARTITION_KEY.to_string(), user_id.clone()),
+ (SORT_KEY.to_string(), signing_public_key.clone()),
);
let get_item_result = self
.client
.get_item()
- .table_name(ACCESS_TOKEN_TABLE)
+ .table_name(NAME)
.set_key(Some(primary_key))
.consistent_read(true)
.send()
@@ -54,18 +47,12 @@
..
}) => {
let created = DateTime::<Utc>::try_from_attr(
- ACCESS_TOKEN_TABLE_CREATED_ATTRIBUTE,
- item.remove(ACCESS_TOKEN_TABLE_CREATED_ATTRIBUTE),
- )?;
- let auth_type = parse_auth_type_attribute(
- item.remove(ACCESS_TOKEN_TABLE_AUTH_TYPE_ATTRIBUTE),
- )?;
- let valid = parse_valid_attribute(
- item.remove(ACCESS_TOKEN_TABLE_VALID_ATTRIBUTE),
- )?;
- let access_token = parse_token_attribute(
- item.remove(ACCESS_TOKEN_TABLE_TOKEN_ATTRIBUTE),
+ ATTR_CREATED,
+ item.remove(ATTR_CREATED),
)?;
+ let auth_type = parse_auth_type_attribute(item.remove(ATTR_AUTH_TYPE))?;
+ let valid = parse_valid_attribute(item.remove(ATTR_VALID))?;
+ let access_token = parse_token_attribute(item.remove(ATTR_TOKEN))?;
Ok(Some(AccessTokenData {
user_id,
signing_public_key,
@@ -116,39 +103,41 @@
&self,
access_token_data: AccessTokenData,
) -> Result<PutItemOutput, Error> {
+ use crate::constants::token_table::*;
+
let item = HashMap::from([
(
- ACCESS_TOKEN_TABLE_PARTITION_KEY.to_string(),
+ PARTITION_KEY.to_string(),
AttributeValue::S(access_token_data.user_id),
),
(
- ACCESS_TOKEN_SORT_KEY.to_string(),
+ SORT_KEY.to_string(),
AttributeValue::S(access_token_data.signing_public_key),
),
(
- ACCESS_TOKEN_TABLE_TOKEN_ATTRIBUTE.to_string(),
+ ATTR_TOKEN.to_string(),
AttributeValue::S(access_token_data.access_token),
),
(
- ACCESS_TOKEN_TABLE_CREATED_ATTRIBUTE.to_string(),
+ ATTR_CREATED.to_string(),
AttributeValue::S(access_token_data.created.to_rfc3339()),
),
(
- ACCESS_TOKEN_TABLE_AUTH_TYPE_ATTRIBUTE.to_string(),
+ ATTR_AUTH_TYPE.to_string(),
AttributeValue::S(match access_token_data.auth_type {
AuthType::Password => "password".to_string(),
AuthType::Wallet => "wallet".to_string(),
}),
),
(
- ACCESS_TOKEN_TABLE_VALID_ATTRIBUTE.to_string(),
+ ATTR_VALID.to_string(),
AttributeValue::Bool(access_token_data.valid),
),
]);
self
.client
.put_item()
- .table_name(ACCESS_TOKEN_TABLE)
+ .table_name(NAME)
.set_item(Some(item))
.send()
.await
@@ -160,42 +149,87 @@
user_id: String,
device_id_key: String,
) -> Result<(), Error> {
+ use crate::constants::token_table::*;
+
self
.client
.delete_item()
- .table_name(ACCESS_TOKEN_TABLE)
- .key(
- ACCESS_TOKEN_TABLE_PARTITION_KEY.to_string(),
- AttributeValue::S(user_id),
- )
- .key(
- ACCESS_TOKEN_SORT_KEY.to_string(),
- AttributeValue::S(device_id_key),
- )
+ .table_name(NAME)
+ .key(PARTITION_KEY.to_string(), AttributeValue::S(user_id))
+ .key(SORT_KEY.to_string(), AttributeValue::S(device_id_key))
.send()
.await
.map_err(|e| Error::AwsSdk(e.into()))?;
Ok(())
}
+
+ pub async fn delete_all_tokens_for_user(
+ &self,
+ user_id: &str,
+ ) -> Result<(), Error> {
+ use crate::constants::token_table::*;
+
+ let primary_keys = self
+ .client
+ .query()
+ .table_name(NAME)
+ .projection_expression("#pk, #sk")
+ .key_condition_expression("#pk = :pk")
+ .expression_attribute_names("#pk", PARTITION_KEY)
+ .expression_attribute_names("#sk", SORT_KEY)
+ .expression_attribute_values(
+ ":pk",
+ AttributeValue::S(user_id.to_string()),
+ )
+ .send()
+ .await
+ .map_err(|e| {
+ error!("Failed to list user's items in tokens table: {:?}", e);
+ Error::AwsSdk(e.into())
+ })?
+ .items
+ .unwrap_or_default();
+
+ let delete_requests = primary_keys
+ .into_iter()
+ .map(|item| {
+ let request = DeleteRequest::builder().set_key(Some(item)).build();
+ WriteRequest::builder().delete_request(request).build()
+ })
+ .collect::<Vec<_>>();
+
+ batch_write(
+ &self.client,
+ NAME,
+ delete_requests,
+ ExponentialBackoffConfig::default(),
+ )
+ .await
+ .map_err(Error::from)?;
+
+ Ok(())
+ }
}
fn parse_auth_type_attribute(
attribute: Option<AttributeValue>,
) -> Result<AuthType, DBItemError> {
+ use crate::constants::token_table::ATTR_AUTH_TYPE;
+
if let Some(AttributeValue::S(auth_type)) = &attribute {
match auth_type.as_str() {
"password" => Ok(AuthType::Password),
"wallet" => Ok(AuthType::Wallet),
_ => Err(DBItemError::new(
- ACCESS_TOKEN_TABLE_AUTH_TYPE_ATTRIBUTE.to_string(),
+ ATTR_AUTH_TYPE.to_string(),
attribute.into(),
DBItemAttributeError::IncorrectType,
)),
}
} else {
Err(DBItemError::new(
- ACCESS_TOKEN_TABLE_AUTH_TYPE_ATTRIBUTE.to_string(),
+ ATTR_AUTH_TYPE.to_string(),
attribute.into(),
DBItemAttributeError::Missing,
))
@@ -205,15 +239,17 @@
fn parse_valid_attribute(
attribute: Option<AttributeValue>,
) -> Result<bool, DBItemError> {
+ use crate::constants::token_table::ATTR_VALID;
+
match attribute {
Some(AttributeValue::Bool(valid)) => Ok(valid),
Some(_) => Err(DBItemError::new(
- ACCESS_TOKEN_TABLE_VALID_ATTRIBUTE.to_string(),
+ ATTR_VALID.to_string(),
attribute.into(),
DBItemAttributeError::IncorrectType,
)),
None => Err(DBItemError::new(
- ACCESS_TOKEN_TABLE_VALID_ATTRIBUTE.to_string(),
+ ATTR_VALID.to_string(),
attribute.into(),
DBItemAttributeError::Missing,
)),
@@ -223,15 +259,17 @@
fn parse_token_attribute(
attribute: Option<AttributeValue>,
) -> Result<String, DBItemError> {
+ use crate::constants::token_table::ATTR_TOKEN;
+
match attribute {
Some(AttributeValue::S(token)) => Ok(token),
Some(_) => Err(DBItemError::new(
- ACCESS_TOKEN_TABLE_TOKEN_ATTRIBUTE.to_string(),
+ ATTR_TOKEN.to_string(),
attribute.into(),
DBItemAttributeError::IncorrectType,
)),
None => Err(DBItemError::new(
- ACCESS_TOKEN_TABLE_TOKEN_ATTRIBUTE.to_string(),
+ ATTR_TOKEN.to_string(),
attribute.into(),
DBItemAttributeError::Missing,
)),
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Dec 3, 6:16 AM (21 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2610549
Default Alt Text
D11796.diff (9 KB)
Attached To
Mode
D11796: [identity] delete all token data on user account deletion
Attached
Detach File
Event Timeline
Log In to Comment