diff --git a/app/api/domains/cho.py b/app/api/domains/cho.py index 068277f75..b7ac5b8f1 100644 --- a/app/api/domains/cho.py +++ b/app/api/domains/cho.py @@ -3,6 +3,7 @@ from __future__ import annotations import asyncio +import hashlib import logging import re import struct @@ -759,12 +760,23 @@ async def handle_osu_login_request( # TODO: store adapters individually + # Some disk manufacturers set constant/shared ids for their products. + # In these cases, there's not a whole lot we can do -- we'll allow them thru. + INACTIONABLE_DISK_SIGNATURE_MD5S: list[str] = [ + hashlib.md5(b"0").hexdigest(), # "0" is likely the most common variant + ] + + if login_data["disk_signature_md5"] not in INACTIONABLE_DISK_SIGNATURE_MD5S: + disk_signature_md5 = login_data["disk_signature_md5"] + else: + disk_signature_md5 = None + hw_matches = await client_hashes_repo.fetch_any_hardware_matches_for_user( userid=user_info["id"], running_under_wine=running_under_wine, adapters=login_data["adapters_md5"], uninstall_id=login_data["uninstall_md5"], - disk_serial=login_data["disk_signature_md5"], + disk_serial=disk_signature_md5, ) if hw_matches: diff --git a/app/repositories/client_hashes.py b/app/repositories/client_hashes.py index 67f3494bc..8f7d50c6c 100644 --- a/app/repositories/client_hashes.py +++ b/app/repositories/client_hashes.py @@ -13,6 +13,8 @@ from sqlalchemy import select from sqlalchemy.dialects.mysql import Insert as MysqlInsert from sqlalchemy.dialects.mysql import insert as mysql_insert +from sqlalchemy.sql import ColumnElement +from sqlalchemy.types import Boolean import app.state.services from app.repositories import Base @@ -101,8 +103,8 @@ async def create( async def fetch_any_hardware_matches_for_user( userid: int, running_under_wine: bool, - adapters: str | None = None, - uninstall_id: str | None = None, + adapters: str, + uninstall_id: str, disk_serial: str | None = None, ) -> list[ClientHashWithPlayer]: """\ @@ -119,13 +121,13 @@ async def fetch_any_hardware_matches_for_user( if running_under_wine: select_stmt = select_stmt.where(ClientHashesTable.uninstall_id == uninstall_id) else: - select_stmt = select_stmt.where( - or_( - ClientHashesTable.adapters == adapters, - ClientHashesTable.uninstall_id == uninstall_id, - ClientHashesTable.disk_serial == disk_serial, - ), - ) + # make disk serial optional in the OR + oneof_filters: list[ColumnElement[Boolean]] = [] + oneof_filters.append(ClientHashesTable.adapters == adapters) + oneof_filters.append(ClientHashesTable.uninstall_id == uninstall_id) + if disk_serial is not None: + oneof_filters.append(ClientHashesTable.disk_serial == disk_serial) + select_stmt = select_stmt.where(or_(*oneof_filters)) client_hashes = await app.state.services.database.fetch_all(select_stmt) return cast(list[ClientHashWithPlayer], client_hashes)