pluto/handler/lib/antifraud.py

114 lines
4.2 KiB
Python

# Project imports
import db
import util
class AntiFraud(util.Base):
def add_bank_sender(self, platform, platform_buyer, bank_sender):
"""
Add the bank senders into Redis.
:param platform: name of the platform - freeform
:param platform_buyer: the username of the buyer on the platform
:param bank_sender: the sender name from the bank
"""
key = f"namemap.{platform}.{platform_buyer}"
db.r.sadd(key, bank_sender)
def get_previous_senders(self, platform, platform_buyer):
"""
Get all the previous bank sender names for the given buyer on the platform.
:param platform: name of the platform - freeform
:param platform_buyer: the username of the buyer on the platform
:return: set of previous buyers
:rtype: set
"""
key = f"namemap.{platform}.{platform_buyer}"
senders = db.r.smembers(key)
if not senders:
return None
senders = util.convert(senders)
return senders
def check_valid_sender(self, reference, platform, bank_sender, platform_buyer):
"""
Check that either:
* The platform buyer has never had a recognised transaction before
* The bank sender name matches a previous transaction from the platform buyer
:param reference: the trade reference
:param platform: name of the platform - freeform
:param bank_sender: the sender of the bank transaction
:param platform_buyer: the username of the buyer on the platform
:return: whether the sender is valid
:rtype: bool
"""
senders = self.get_previous_senders(platform, platform_buyer)
if senders is None: # no senders yet, assume it's valid
return True
if platform_buyer in senders:
return True
self.ux.notify.notify_sender_name_mismatch(
reference, platform_buyer, bank_sender
)
return False
def check_tx_sender(self, tx, reference):
"""
Check whether the sender of a given transaction is authorised based on the previous
transactions of the username that originated the trade reference.
:param tx: the transaction ID
:param reference: the trade reference
"""
stored_trade = db.get_ref(reference)
if not stored_trade:
return None
stored_tx = db.get_tx(tx)
if not stored_tx:
return None
bank_sender = stored_tx["sender"]
platform_buyer = stored_trade["buyer"]
platform = stored_trade["subclass"]
is_allowed = self.check_valid_sender(
reference, platform, bank_sender, platform_buyer
)
if is_allowed is True:
return True
return False
def update_trade_tx(self, reference, txid):
"""
Update a trade to point to a given transaction ID.
Return False if the trade already has a mapped transaction.
"""
existing_tx = db.r.hget(f"trade.{reference}", "tx")
if existing_tx is None:
return None
elif existing_tx == b"":
db.r.hset(f"trade.{reference}", "tx", txid)
return True
else: # Already a mapped transaction
return False
def user_verification_successful(self, uid):
"""
A user has successfully completed verification.
"""
self.log.info(f"User has completed verification: {uid}")
trade_list = self.markets.find_trades_by_uid(uid)
for platform, trade_id, reference, currency in trade_list:
self.markets.send_bank_details(platform, currency, trade_id)
self.markets.send_reference(platform, trade_id, reference)
def send_verification_url(self, platform, uid, trade_id):
send_setting, post_message = self.markets.get_send_settings(platform)
if send_setting == "1":
auth_url = self.ux.verify.create_applicant_and_get_link(uid)
if platform == "lbtc":
auth_url = auth_url.replace("https://", "") # hack
post_message(
trade_id,
f"Hi! To continue the trade, please complete the verification form: {auth_url}",
)
antifraud = AntiFraud()