Align session verification logic with osu-web
Updated session verification method selection to match osu-web's State.php:36 logic, using SUPPORT_TOTP_VERIFICATION_VER for version checks and prioritizing TOTP when available. Added example environment files for osu-web-master to support local, dusk, and testing setups.
This commit is contained in:
@@ -121,12 +121,12 @@ async def get_client_user(
|
||||
verify_method = await LoginSessionService.get_login_method(user.id, token.id, redis)
|
||||
|
||||
if verify_method is None:
|
||||
# 智能选择验证方式(有TOTP优先TOTP)
|
||||
# 智能选择验证方式(参考 osu-web State.php:36)
|
||||
totp_key = await user.awaitable_attrs.totp_key
|
||||
verify_method = "totp" if totp_key is not None and api_version >= SUPPORT_TOTP_VERIFICATION_VER else "mail"
|
||||
|
||||
# 设置选择的验证方法到Redis中,避免重复选择
|
||||
if api_version >= 20250913:
|
||||
if api_version >= SUPPORT_TOTP_VERIFICATION_VER:
|
||||
await LoginSessionService.set_login_method(user.id, token.id, verify_method, redis)
|
||||
|
||||
# 返回符合 osu! API 标准的错误响应
|
||||
|
||||
@@ -338,8 +338,13 @@ async def oauth_token(
|
||||
# 检查是否为新位置登录
|
||||
trusted_device = await LoginSessionService.check_trusted_device(db, user_id, ip_address, user_agent, web_uuid)
|
||||
|
||||
# 根据 osu-web 逻辑确定验证方法:
|
||||
# 1. 如果 API 版本支持 TOTP 且用户启用了 TOTP,则始终要求 TOTP 验证(无论是否为信任设备)
|
||||
# 2. 否则,如果是新设备且启用了邮件验证,则要求邮件验证
|
||||
# 3. 否则,不需要验证或自动验证
|
||||
session_verification_method = None
|
||||
if settings.enable_totp_verification and totp_key is not None and api_version >= SUPPORT_TOTP_VERIFICATION_VER:
|
||||
if api_version >= SUPPORT_TOTP_VERIFICATION_VER and settings.enable_totp_verification and totp_key is not None:
|
||||
# TOTP 验证优先(参考 osu-web State.php:36)
|
||||
session_verification_method = "totp"
|
||||
await LoginLogService.record_login(
|
||||
db=db,
|
||||
|
||||
@@ -88,10 +88,9 @@ async def verify_session(
|
||||
try:
|
||||
totp_key: TotpKeys | None = await current_user.awaitable_attrs.totp_key
|
||||
if verify_method is None:
|
||||
# 智能选择验证方法(参考osu-web实现)
|
||||
# 智能选择验证方法(参考osu-web实现 State.php:36)
|
||||
# API版本较老或用户未设置TOTP时强制使用邮件验证
|
||||
# print(api_version, totp_key)
|
||||
verify_method = "mail" if api_version < 20240101 or totp_key is None else "totp"
|
||||
verify_method = "mail" if api_version < SUPPORT_TOTP_VERIFICATION_VER or totp_key is None else "totp"
|
||||
await LoginSessionService.set_login_method(user_id, token_id, verify_method, redis)
|
||||
login_method = verify_method
|
||||
|
||||
@@ -210,7 +209,9 @@ async def reissue_verification_code(
|
||||
return SessionReissueResponse(success=False, message="当前会话不需要验证")
|
||||
|
||||
verify_method: str | None = (
|
||||
"mail" if api_version < 20250913 else await LoginSessionService.get_login_method(user_id, token_id, redis)
|
||||
"mail"
|
||||
if api_version < SUPPORT_TOTP_VERIFICATION_VER
|
||||
else await LoginSessionService.get_login_method(user_id, token_id, redis)
|
||||
)
|
||||
if verify_method != "mail":
|
||||
return SessionReissueResponse(success=False, message="当前会话不支持重新发送验证码")
|
||||
|
||||
13
osu-web-master/.env.dusk.local.example
Normal file
13
osu-web-master/.env.dusk.local.example
Normal file
@@ -0,0 +1,13 @@
|
||||
APP_KEY=
|
||||
APP_ENV=testing
|
||||
|
||||
APP_URL=http://nginx:8008
|
||||
NOTIFICATION_ENDPOINT=ws://nginx:8008/home/notifications/feed
|
||||
|
||||
DB_DATABASE=osu_test
|
||||
DB_DATABASE_CHAT=osu_chat_test
|
||||
DB_DATABASE_MP=osu_mp_test
|
||||
DB_DATABASE_STORE=osu_store_test
|
||||
DB_DATABASE_UPDATES=osu_updates_test
|
||||
|
||||
ES_INDEX_PREFIX=test_
|
||||
333
osu-web-master/.env.example
Normal file
333
osu-web-master/.env.example
Normal file
@@ -0,0 +1,333 @@
|
||||
# API_THROTTLE_GLOBAL=1200,1,api
|
||||
# API_THROTTLE_SCORES_DOWNLOAD=10,1,api-scores-download
|
||||
|
||||
# default url for vagrant
|
||||
APP_URL=http://localhost:8080
|
||||
APP_ENV=local
|
||||
APP_DEBUG=true
|
||||
APP_KEY=
|
||||
APP_LOG_LEVEL=debug
|
||||
# APP_SENTRY=https://...
|
||||
# APP_SENTRY_ENVIRONMENT=
|
||||
|
||||
# DOCS_URL=
|
||||
|
||||
# clockwork provides local development insights (at /__clockwork/)
|
||||
# adds a slight performance overhead.
|
||||
CLOCKWORK_ENABLE=true
|
||||
|
||||
DB_HOST=localhost
|
||||
DB_DATABASE=osu
|
||||
DB_USERNAME=osuweb
|
||||
# DB_PASSWORD=
|
||||
|
||||
# REDIS_HOST=127.0.0.1
|
||||
# REDIS_PORT=6379
|
||||
# REDIS_DB=0
|
||||
# REDIS_PASSWORD=
|
||||
|
||||
# CACHE_REDIS_HOST=127.0.0.1
|
||||
# CACHE_REDIS_PORT=6379
|
||||
# CACHE_REDIS_DB=0
|
||||
# CACHE_REDIS_PASSWORD=
|
||||
|
||||
# MEMCACHED_PERSISTENT_ID=
|
||||
# MEMCACHED_USERNAME=
|
||||
# MEMCACHED_PASSWORD=
|
||||
# MEMCACHED_HOST=127.0.0.1
|
||||
# MEMCACHED_PORT=11211
|
||||
|
||||
OSU_API_KEY=
|
||||
|
||||
# BROADCAST_DRIVER=redis
|
||||
# CACHE_DRIVER=redis
|
||||
# SESSION_DRIVER=redis
|
||||
# SESSION_DOMAIN=
|
||||
# SESSION_SECURE_COOKIE=false
|
||||
# SESSION_PREFIX=
|
||||
|
||||
# MAIL_DRIVER=log
|
||||
# MAIL_HOST=
|
||||
# MAIL_PORT=
|
||||
# MAIL_ENCRYPTION=
|
||||
# MAIL_USERNAME=
|
||||
# MAIL_PASSWORD=
|
||||
|
||||
SLACK_ENDPOINT=https://myconan.net/null/
|
||||
# SHARED_INTEROP_SECRET=
|
||||
|
||||
# STORE_NOTICE=
|
||||
|
||||
# FILESYSTEM_DISK=local
|
||||
|
||||
# BM_PROCESSOR_MIRRORS=1
|
||||
# BM_PROCESSOR_THUMBNAILER=http://localhost:4001
|
||||
# BM_PROCESSOR_SENTRY=
|
||||
|
||||
# S3_KEY=
|
||||
# S3_SECRET=
|
||||
# S3_REGION=
|
||||
# S3_BUCKET=
|
||||
# S3_BASE_URL=
|
||||
# S3_MINI_URL=
|
||||
|
||||
# S3_ENDPOINT=
|
||||
# S3_USE_PATH_STYLE_ENDPOINT=false
|
||||
|
||||
# S3_CENTRAL_BUCKET_NAME=
|
||||
# S3_CENTRAL_BUCKET_REGION=
|
||||
# S3_SOLO_REPLAY_BUCKET=solo-scores-replays
|
||||
|
||||
# S3_AVATAR_KEY=
|
||||
# S3_AVATAR_SECRET=
|
||||
# S3_AVATAR_REGION=
|
||||
# S3_AVATAR_BUCKET=
|
||||
# S3_AVATAR_BASE_URL=
|
||||
# AVATAR_CACHE_PURGE_PREFIX=
|
||||
# AVATAR_CACHE_PURGE_METHOD=
|
||||
# AVATAR_CACHE_PURGE_AUTHORIZATION_KEY=
|
||||
# DEFAULT_AVATAR=http://localhost/images/layout/avatar-guest@2x.png
|
||||
|
||||
# QUEUE_DRIVER=
|
||||
# CAMO_KEY=
|
||||
# CAMO_PREFIX=
|
||||
|
||||
# ADMIN_FORUM_ID=
|
||||
# FEATURE_FORUM_ID=4
|
||||
# FEATURE_TOPIC_LARGE_STAR_CUTOFF=1000
|
||||
# HELP_FORUM_ID=5
|
||||
# INITIAL_HELP_FORUM_IDS="5 47 85"
|
||||
# ISSUE_FORUM_IDS=
|
||||
# FORUM_POST_MINIMUM_PLAYS=200
|
||||
# BEATMAP_DESCRIPTION_FORUM_ID=6
|
||||
# DOUBLE_POST_ALLOWED_FORUM_IDS="52 68 84 114"
|
||||
|
||||
PUSHER_APP_ID=
|
||||
PUSHER_KEY=
|
||||
PUSHER_SECRET=
|
||||
|
||||
# PASSPORT_KEY_PATH=/secure/osu.ppy.sh/oauth
|
||||
|
||||
# ENCHANT_ID=
|
||||
|
||||
# GITHUB_TOKEN=
|
||||
|
||||
# GitHub client for users to associate their GitHub accounts
|
||||
# Use "<APP_URL>/home/account/github-users/callback" for the "Authorization callback URL" field on GitHub
|
||||
# GITHUB_CLIENT_ID=
|
||||
# GITHUB_CLIENT_SECRET=
|
||||
|
||||
# DATADOG_ENABLED=true
|
||||
# DATADOG_PREFIX=osu.web
|
||||
# DATADOG_API_KEY=
|
||||
# DATADOG_APP_KEY=
|
||||
# DATADOG_HOST=https://app.datadoghq.com
|
||||
# DATADOG_STATSD_HOST=localhost
|
||||
# DATADOG_STATSD_PORT=8125
|
||||
# DATADOG_STATSD_SOCKET=
|
||||
|
||||
# LANDING_VIDEO_URL=
|
||||
|
||||
# FEATURED_UPDATE_STREAM=
|
||||
# UPDATE_STREAMS=
|
||||
# CHANGELOG_CHART_DAYS=
|
||||
# CHANGELOG_BUILD_HISTORY_INTERVAL=
|
||||
# CHANGELOG_GITHUB_TOKEN=
|
||||
|
||||
# SUPER_FRIENDLY='3'
|
||||
|
||||
PAYMENT_SANDBOX=true
|
||||
|
||||
SHOPIFY_DOMAIN=
|
||||
SHOPIFY_STOREFRONT_TOKEN=
|
||||
SHOPIFY_WEBHOOK_KEY=
|
||||
|
||||
STORE_NOTIFICATION_CHANNEL=test
|
||||
STORE_NOTIFICATIONS_QUEUE=store-notifications
|
||||
STORE_STALE_DAYS=
|
||||
|
||||
PAYPAL_CLIENT_ID=
|
||||
PAYPAL_CLIENT_SECRET=
|
||||
PAYPAL_MERCHANT_ID=
|
||||
PAYPAL_NO_SHIPPING_EXPERIENCE_PROFILE_ID=
|
||||
PAYPAL_URL=https://www.sandbox.paypal.com/cgi-bin/webscr
|
||||
|
||||
XSOLLA_API_KEY=
|
||||
XSOLLA_MERCHANT_ID=
|
||||
XSOLLA_PROJECT_ID=
|
||||
XSOLLA_SECRET_KEY=
|
||||
|
||||
OSU_RUNNING_COST=
|
||||
|
||||
CLIENT_CHECK_VERSION=false
|
||||
# CLIENT_USER_AGENT=osu!
|
||||
# DEFAULT_BUILD_ID=0
|
||||
|
||||
# SEARCH_MINIMUM_LENGTH=2
|
||||
|
||||
# BEATMAPS_DIFFICULTY_CACHE_SERVER_URL=http://localhost:5001
|
||||
# BEATMAPS_OWNERS_MAX=10
|
||||
# BEATMAPSET_DISCUSSION_KUDOSU_PER_USER=10
|
||||
# BEATMAPSET_GUEST_ADVANCED_SEARCH=0
|
||||
# BEATMAPSET_MAXIMUM_DISQUALIFIED_RANK_PENALTY_DAYS=7
|
||||
# BEATMAPSET_REQUIRED_HYPE=5
|
||||
# BEATMAPSET_USER_WEEKLY_HYPE=3
|
||||
# BEATMAPSET_USER_DAILY_NOMINATIONS=10
|
||||
# BEATMAPSET_USER_DOWNLOAD_LIMIT_HOURLY=10
|
||||
# BEATMAPSET_USER_DOWNLOAD_LIMIT_HOURLY_SUPPORTER=20
|
||||
# BEATMAPSET_USER_FAVOURITE_LIMIT=100
|
||||
# BEATMAPSET_USER_FAVOURITE_LIMIT_SUPPORTER=1000
|
||||
|
||||
# Nominations required for a Beatmapset to be qualified. For hybrid Beatmapsets this is the nominations required for the main ruleset.
|
||||
# BEATMAPSET_REQUIRED_NOMINATIONS=2
|
||||
|
||||
# BAN_PERSIST_DAYS=28
|
||||
|
||||
# ES_HOST=localhost:9200
|
||||
# ES_SOLO_SCORES_HOST=localhost:9200
|
||||
# ES_INDEX_PREFIX=
|
||||
# ES_CLIENT_TIMEOUT=5
|
||||
# ES_CLIENT_CONNECT_TIMEOUT=0.5
|
||||
# ES_SEARCH_TIMEOUT=5s
|
||||
|
||||
# {prefix}{filename}.png with {filename} the achievement slug as stored in database.
|
||||
# USER_ACHIEVEMENT_ICON_PREFIX=https://assets.ppy.sh/user-achievements/
|
||||
|
||||
## Limits for chat, throttles after a user sends more than CHAT_*_LIMIT messages in CHAT_*_WINDOW seconds
|
||||
# CHAT_CHANNEL_LIMIT=10000
|
||||
# CHAT_PUBLIC_LIMIT=1
|
||||
# CHAT_PUBLIC_WINDOW=1
|
||||
# CHAT_PRIVATE_LIMIT=1
|
||||
# CHAT_PRIVATE_WINDOW=1
|
||||
# CHAT_MESSAGE_LENGTH_LIMIT=450
|
||||
# CHAT_PUBLIC_BACKLOG_LIMIT_HOURS=24
|
||||
|
||||
# ALLOW_REGISTRATION=true
|
||||
# REGISTRATION_MODE_CLIENT=true
|
||||
# REGISTRATION_MODE_WEB=false
|
||||
|
||||
# USER_ALLOW_EMAIL_LOGIN=true
|
||||
# USER_BYPASS_VERIFICATION=false
|
||||
# USER_POST_ACTION_VERIFICATION=true
|
||||
# USER_MAX_LOGIN_ATTEMPTS=10
|
||||
# USER_MIN_PLAYS_FOR_POSTING=10
|
||||
# USER_MIN_PLAYS_ALLOW_VERIFIED_BYPASS=true
|
||||
# space delimited, list of groups (the identifier) which user can be renamed when inactive
|
||||
# USER_ALLOWED_RENAME_GROUPS="default"
|
||||
|
||||
# USER_MAX_FOLLOWS=5000
|
||||
# USER_MAX_FRIENDS=250
|
||||
# USER_MAX_FRIENDS_SUPPORTER=500
|
||||
# USER_MAX_MULTIPLAYER_DURATION=14
|
||||
# USER_MAX_MULTIPLAYER_DURATION_SUPPORTER=63
|
||||
# USER_MAX_MULTIPLAYER_ROOMS=1
|
||||
# USER_MAX_MULTIPLAYER_ROOMS_SUPPORTER=5
|
||||
|
||||
# USER_MAX_SCORE_PINS=10
|
||||
# USER_MAX_SCORE_PINS_SUPPORTER=50
|
||||
|
||||
# the content is in markdown format
|
||||
# USER_PROFILE_SCORES_NOTICE=
|
||||
|
||||
# MULTIPLAYER_MAX_ATTEMPTS_LIMIT=128
|
||||
# MULTIPLAYER_ROOM_CLOSE_GRACE_PERIOD_MINUTES=5
|
||||
|
||||
# NOTIFICATION_QUEUE=notification
|
||||
# NOTIFICATION_REDIS_HOST=127.0.0.1
|
||||
# NOTIFICATION_REDIS_PORT=6379
|
||||
# NOTIFICATION_REDIS_DB=0
|
||||
# NOTIFICATION_REDIS_PASSWORD=
|
||||
# NOTIFICATION_SERVER_LISTEN_HOST=127.0.0.1
|
||||
# NOTIFICATION_SERVER_LISTEN_PORT=3000
|
||||
# NOTIFICATION_ENDPOINT=/home/notifications/feed
|
||||
# NOTIFICATION_CLEANUP_KEEP_DAYS=180
|
||||
# NOTIFICATION_CLEANUP_MAX_DELETE=50000
|
||||
|
||||
# The open source bounty info page/form url
|
||||
# OS_BOUNTY_URL=http://example.com/bounty_form
|
||||
|
||||
# OAUTH_MAX_USER_CLIENTS=1
|
||||
|
||||
# TEAM_CREATE_REQUIRE_SUPPORTER=false
|
||||
# TEAM_MAX_MEMBERS=40
|
||||
|
||||
# USER_REPORT_NOTIFICATION_ENDPOINT_CHEATING=
|
||||
# default if nothing specified for specific type
|
||||
# USER_REPORT_NOTIFICATION_ENDPOINT_MODERATION=
|
||||
|
||||
# USER_REPORT_NOTIFICATION_ENDPOINT_BEATMAPSET=
|
||||
# USER_REPORT_NOTIFICATION_ENDPOINT_BEATMAPSET_DISCUSSION=
|
||||
# USER_REPORT_NOTIFICATION_ENDPOINT_CHAT=
|
||||
# USER_REPORT_NOTIFICATION_ENDPOINT_COMMENT=
|
||||
# USER_REPORT_NOTIFICATION_ENDPOINT_FORUM=
|
||||
# USER_REPORT_NOTIFICATION_ENDPOINT_USER=
|
||||
|
||||
# LOG_CHANNEL=single
|
||||
|
||||
# WIKI_BRANCH=master
|
||||
# WIKI_REPOSITORY=osu-wiki
|
||||
# WIKI_USER=ppy
|
||||
|
||||
# BEATMAPSET_DISCUSSION_REVIEW_MAXIMUM_BLOCKS=1
|
||||
# BEATMAPSET_DISCUSSION_REVIEW_MINIMUM_ISSUES=1
|
||||
|
||||
# PAGINATION_MAX_COUNT=10000
|
||||
|
||||
## Limits for the allowed number of simultaneous beatmapset uploads (displayed on the support page: /home/support)
|
||||
# BEATMAPSET_UPLOAD_ALLOWED=4
|
||||
# BEATMAPSET_UPLOAD_BONUS_PER_RANKED=1
|
||||
# BEATMAPSET_UPLOAD_BONUS_PER_RANKED_MAX=2
|
||||
# BEATMAPSET_UPLOAD_ALLOWED_SUPPORTER=8
|
||||
# BEATMAPSET_UPLOAD_BONUS_PER_RANKED_SUPPORTER=1
|
||||
# BEATMAPSET_UPLOAD_BONUS_PER_RANKED_MAX_SUPPORTER=12
|
||||
|
||||
# CAPTCHA_THRESHOLD=
|
||||
# TURNSTILE_SITE_KEY=
|
||||
# TURNSTILE_SECRET_KEY=
|
||||
|
||||
# TWITCH_CLIENT_ID=
|
||||
# TWITCH_CLIENT_SECRET=
|
||||
|
||||
# SCORES_ES_CACHE_DURATION=
|
||||
# SCORES_PROCESSING_QUEUE=osu-queue:score-statistics
|
||||
# SCORES_SUBMISSION_ENABLED=1
|
||||
# SCORE_INDEX_MAX_ID_DISTANCE=10_000_000
|
||||
|
||||
# BANCHO_BOT_USER_ID=
|
||||
|
||||
# OCTANE_LOCAL_CACHE_EXPIRE_SECOND=60
|
||||
# OCTANE_LOCAL_CACHE_RESET_REQUESTS=100
|
||||
|
||||
# TRUSTED_PROXIES=
|
||||
|
||||
# IS_DEVELOPMENT_DEPLOY=true
|
||||
|
||||
# OSU_URL_LAZER_ANDROID='https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk'
|
||||
# OSU_URL_LAZER_IOS='/home/testflight'
|
||||
# OSU_URL_LAZER_LINUX_X64='https://github.com/ppy/osu/releases/latest/download/osu.AppImage'
|
||||
# OSU_URL_LAZER_MACOS_AS='https://github.com/ppy/osu/releases/latest/download/osu.app.Apple.Silicon.zip'
|
||||
# OSU_URL_LAZER_OTHER='https://github.com/ppy/osu/#running-osu'
|
||||
# OSU_URL_LAZER_WINDOWS_X64='https://github.com/ppy/osu/releases/latest/download/install.exe'
|
||||
# OSU_URL_LAZER_INFO=
|
||||
# OSU_URL_MENU_CONTENT_JSON=https://assets.ppy.sh/menu-content.json
|
||||
# OSU_URL_USER_RESTRICTION=/wiki/Help_centre/Account_restrictions
|
||||
|
||||
# USER_COUNTRY_CHANGE_MAX_MIXED_MONTHS=2
|
||||
# USER_COUNTRY_CHANGE_MIN_MONTHS=6
|
||||
|
||||
# USER_INACTIVE_DAYS_VERIFICATION=180
|
||||
# USER_INACTIVE_FORCE_PASSWORD_RESET=false
|
||||
|
||||
# COUNTRY_PERFORMANCE_USER_COUNT=1000
|
||||
# COUNTRY_PERFORMANCE_WEIGHTING_FACTOR=0.99
|
||||
# TEAM_PERFORMANCE_USER_COUNT=48
|
||||
# TEAM_PERFORMANCE_WEIGHTING_FACTOR=0.96
|
||||
|
||||
# BEATMAP_TAGS_CACHE_DURATION=60
|
||||
# BEATMAP_TAGS_MIN_VOTES_DISPLAY=5
|
||||
# BEATMAP_TAGS_TOP_COUNT=50
|
||||
|
||||
# OSU_SENTRY_MIN_LOG_DURATION_MS=500
|
||||
# SENTRY_TRACES_SAMPLE_RATE=
|
||||
|
||||
# TOTP_ISSUER_NAME=osu!dev
|
||||
12
osu-web-master/.env.testing.example
Normal file
12
osu-web-master/.env.testing.example
Normal file
@@ -0,0 +1,12 @@
|
||||
DB_DATABASE_CHAT=osu_chat_test
|
||||
DB_DATABASE_MP=osu_mp_test
|
||||
DB_DATABASE_STORE=osu_store_test
|
||||
DB_DATABASE_UPDATES=osu_updates_test
|
||||
DB_DATABASE_CHARTS=osu_charts_test
|
||||
|
||||
# match with docker-compose.yml
|
||||
DB_DATABASE=osu_test
|
||||
ES_INDEX_PREFIX=test_
|
||||
SCHEMA=test
|
||||
|
||||
PAYMENT_SANDBOX=true
|
||||
Reference in New Issue
Block a user