Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@
"message": "Connecting Audius protocol dashboard wallet 0x09439dc8d52396c29e4414664C84f36Cf9A8d500 at 1686252024",
},
},
{
"wallet": "0xe05aC1EfC30cE2F7615186802E2B14CC8759616F",
# 0634902d1af06d2da2ac9badd6718e210b028d753b89b93aaeba8e4438bad4ae
"user_id": 2,
"wallet_signature": {
"signature": "5e38c49b2a0d8157a672d5ccd10abb54758967833efd69c25fbe530e339b00d16d665e1d21688ab629db292d401d53e95cb5701420eaa5fb2cfffbe959cb72f51c",
"message": "Connecting Audius user @user_2 at 1686252024",
},
},
]


Expand Down Expand Up @@ -144,6 +153,20 @@ def test_index_dashboard_wallet_user(app, mocker):
)
},
],
"CreateDashboardWalletUserTx5": [
{
"args": AttributeDict(
{
"_entityId": 0,
"_entityType": EntityType.DASHBOARD_WALLET_USER,
"_userId": new_dashboard_wallet_users_data[4]["user_id"],
"_action": Action.CREATE,
"_metadata": f"""{{"wallet": "{new_dashboard_wallet_users_data[4]["wallet"]}", "wallet_signature": {{"signature": "{new_dashboard_wallet_users_data[4]["wallet_signature"]["signature"]}", "message": "{new_dashboard_wallet_users_data[4]["wallet_signature"]["message"]}"}}}}""",
"_signer": "user2wallet",
}
)
},
],
}

entity_manager_txs = [
Expand All @@ -165,6 +188,7 @@ def get_events_side_effect(_, tx_receipt: TxReceipt):
{
"user_id": user_id,
"wallet": user_wallets.get(user_id, None) or f"user{user_id}wallet",
"handle": f"User_{user_id}",
}
for user_id in range(1, 6)
],
Expand All @@ -190,7 +214,7 @@ def get_events_side_effect(_, tx_receipt: TxReceipt):

# validate db records
all_dwus: List[DashboardWalletUser] = session.query(DashboardWalletUser).all()
assert len(all_dwus) == 5
assert len(all_dwus) == 6
for expected_item in new_dashboard_wallet_users_data:
found_matches = [
item
Expand Down Expand Up @@ -430,6 +454,51 @@ def get_events_side_effect(_, tx_receipt: TxReceipt):
)
},
],
"CreateDashboardWalletUserInvalidTx16": [
{
# Handle in wallet signature incorrect
"args": AttributeDict(
{
"_entityId": 0,
"_entityType": EntityType.DASHBOARD_WALLET_USER,
"_userId": 4,
"_action": Action.CREATE,
"_metadata": """{"wallet": "0x5B905C04b15e3BD152224E9738dA726DF6d103B6", "wallet_signature": {"signature": "d4421fbf7e0275fd9caa20cd65a347f2dcab339490918862463caf1bc68459984641640d76cde8ecae7b9fce045e3d975351176fca61b28450279a78ca1489961b", "message": "Connecting Audius user @beep at 1686252026"}}""",
"_signer": "user4wallet",
}
)
},
],
"CreateDashboardWalletUserInvalidTx17": [
{
# Wallet signature message has extra words (handle format)
"args": AttributeDict(
{
"_entityId": 0,
"_entityType": EntityType.DASHBOARD_WALLET_USER,
"_userId": 4,
"_action": Action.CREATE,
"_metadata": """{"wallet": "0x5B905C04b15e3BD152224E9738dA726DF6d103B6", "wallet_signature": {"signature": "a1e77d57b020b5ba9d0025fe827e24ad271f52bca1d4c0a7640fc825bc651f8564cf72aae2d42f9e3688fd4686ff57671413d01b1c2d66e626ca62d0546c1ab81c", "message": "Connecting Audius user @User_4 Kangaroo at 1686252026"}}""",
"_signer": "user4wallet",
}
)
},
],
"CreateDashboardWalletUserInvalidTx18": [
{
# Wallet signature message has extra words (user id format)
"args": AttributeDict(
{
"_entityId": 0,
"_entityType": EntityType.DASHBOARD_WALLET_USER,
"_userId": 4,
"_action": Action.CREATE,
"_metadata": """{"wallet": "0x5B905C04b15e3BD152224E9738dA726DF6d103B6", "wallet_signature": {"signature": "50d65bdc7f3c6b364258f5fac4f74d570b2b74a8e6547cc1495a339803b6decb13d7420789bc2c9679eda4aabb72d028c1f0857bfce755c1ace6213ea2f9add51c", "message": "Connecting Audius user id 4 Kangaroo at 1686252026"}}""",
"_signer": "user4wallet",
}
)
},
],
}

entity_manager_txs = [
Expand All @@ -451,7 +520,7 @@ def get_events_side_effect(_, tx_receipt: TxReceipt):
# validate db records
all_dwus: List[DashboardWalletUser] = session.query(DashboardWalletUser).all()
# make sure no new rows were added
assert len(all_dwus) == 5
assert len(all_dwus) == 6

# # Test invalid delete txs
tx_receipts = {
Expand Down Expand Up @@ -521,7 +590,7 @@ def get_events_side_effect(_, tx_receipt: TxReceipt):
# validate db records
all_dwus: List[DashboardWalletUser] = session.query(DashboardWalletUser).all()
# make sure no new rows were added or deleted
assert len(all_dwus) == 5
assert len(all_dwus) == 6

expected_deleted_items = [
new_dashboard_wallet_users_data[0],
Expand Down Expand Up @@ -579,7 +648,7 @@ def get_events_side_effect(_, tx_receipt: TxReceipt):
)
# validate db records
all_dwus: List[DashboardWalletUser] = session.query(DashboardWalletUser).all()
assert len(all_dwus) == 5
assert len(all_dwus) == 6

for expected_item in expected_deleted_items:
found_matches = [
Expand Down Expand Up @@ -634,7 +703,7 @@ def get_events_side_effect(_, tx_receipt: TxReceipt):

# validate db records
all_dwus: List[DashboardWalletUser] = session.query(DashboardWalletUser).all()
assert len(all_dwus) == 5
assert len(all_dwus) == 6
for expected_item in second_set_new_dashboard_wallet_users_data:
found_matches = [
item
Expand Down
11 changes: 0 additions & 11 deletions packages/discovery-provider/src/api/v1/models/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,6 @@
},
)

tx_signature = ns.model(
"tx_signature",
{
"message": fields.String(required=True),
"signature": fields.String(required=True),
},
)

decoded_user_token = ns.model(
"decoded_user_token",
{
Expand All @@ -154,9 +146,6 @@
),
"sub": fields.String(required=True),
"iat": fields.String(required=True),
"txSignature": fields.Nested(
tx_signature, required=False, allow_null=True, skip_none=True
),
},
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,42 @@ def matches_user_id(hash_or_int_id, int_id):
return hash_or_int_id == str(int_id) or decode_string_id(hash_or_int_id) == int_id


def verify_dashboard_wallet_signature(dashboard_wallet, user_id, wallet_signature):
def has_valid_user_id_message(wallet_signature, user_id):
wallet_signature_split = wallet_signature.get("message", "").split()
return (
wallet_signature.get("message", "").startswith("Connecting Audius user id")
and matches_user_id(wallet_signature_split[-3], user_id)
and len(wallet_signature_split) == 7
)


def has_valid_user_handle_message(wallet_signature, user_handle):
wallet_signature_split = wallet_signature.get("message", "").split()
return (
wallet_signature.get("message", "").startswith("Connecting Audius user @")
and wallet_signature_split[3].lower() == f"@{user_handle.lower()}"
and len(wallet_signature_split) == 6
)


def verify_dashboard_wallet_signature(
dashboard_wallet, user_id, user_handle, wallet_signature
):
if not isinstance(wallet_signature, dict):
raise IndexingValidationError(
"Invalid Create Dashboard Wallet Transaction, wallet signature malformatted"
)
wallet_signature_split = wallet_signature.get("message", "").split()
if (
# Expect wallet_signature message to be "Connecting Audius user id {user hash id} at {timestamp}"
# OR "Connecting Audius user @{handle} at {timestamp}"
not isinstance(wallet_signature, dict)
or not wallet_signature.get("message", "").startswith(
"Connecting Audius user id"
)
or not matches_user_id(
(wallet_signature.get("message", "").split()[-3]), user_id
or (
not has_valid_user_id_message(wallet_signature, user_id)
and not has_valid_user_handle_message(wallet_signature, user_handle)
)
or not is_within_5_minutes((wallet_signature.get("message", "").split())[-1])
or not wallet_signature_split[-2] == "at"
or not is_within_5_minutes((wallet_signature_split)[-1])
):
raise IndexingValidationError(
"Invalid Create Dashboard Wallet Transaction, wallet signature provided does not have correct message"
Expand Down Expand Up @@ -171,6 +196,7 @@ def validate_dashboard_wallet_user_tx(params: ManageEntityParameters, metadata):
)

user_wallet = params.existing_records["User"][user_id].wallet
user_handle = params.existing_records["User"][user_id].handle
user_matches_signer = user_wallet and user_wallet.lower() == params.signer.lower()
dashboard_wallet_matches_signer = dashboard_wallet == params.signer.lower()
if params.action == Action.DELETE:
Expand Down Expand Up @@ -213,7 +239,7 @@ def validate_dashboard_wallet_user_tx(params: ManageEntityParameters, metadata):
)
if user_matches_signer:
verify_dashboard_wallet_signature(
dashboard_wallet, user_id, metadata["wallet_signature"]
dashboard_wallet, user_id, user_handle, metadata["wallet_signature"]
)
else:
verify_user_signature(
Expand Down
2 changes: 1 addition & 1 deletion packages/libs/src/sdk/api/dashboard-wallet-users/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const CreateDashboardWalletUser = z
userId: HashId,
walletSignature: z
.object({
/** Message should be of the form: "Connecting Audius user id a93jl at 39823489" */
/** Message should be of the form: "Connecting Audius user id a93jl at 39823489" OR "Connecting Audius user @jill1990 at 39823489" */
message: z.string(),
signature: z.string()
})
Expand Down