feat(user): support disallowed name

This commit is contained in:
MingxuanGame
2025-08-17 06:14:45 +00:00
parent 8fec2e2fa5
commit 3409e9dc79
7 changed files with 48 additions and 27 deletions

View File

@@ -57,6 +57,7 @@ ENABLE_ALL_BEATMAP_LEADERBOARD=false # 启用所有谱面的排行榜(没有
ENABLE_ALL_BEATMAP_PP=false # 允许任何谱面获得 PP ENABLE_ALL_BEATMAP_PP=false # 允许任何谱面获得 PP
SUSPICIOUS_SCORE_CHECK=true # 是否检查可疑的分数,默认开启 SUSPICIOUS_SCORE_CHECK=true # 是否检查可疑的分数,默认开启
SEASONAL_BACKGROUNDS='[]' # 季节背景图 URL 列表 SEASONAL_BACKGROUNDS='[]' # 季节背景图 URL 列表
BANNED_NAME='["mrekk", "vaxei", "btmc", "cookiezi", "peppy", "saragi", "chocomint"]' # 禁止使用的用户名列表
# 存储服务设置 # 存储服务设置
# 支持的存储类型local本地存储、r2Cloudflare R2、s3AWS S3 # 支持的存储类型local本地存储、r2Cloudflare R2、s3AWS S3

View File

@@ -115,6 +115,7 @@ The Fetcher is used to get data from the official osu! API using OAuth 2.0 authe
| `ENABLE_ALL_BEATMAP_PP` | Allow any beatmap to grant PP | `false` | | `ENABLE_ALL_BEATMAP_PP` | Allow any beatmap to grant PP | `false` |
| `SUSPICIOUS_SCORE_CHECK` | Enable suspicious score check (star>25 & acc<80 or pp>2300) | `true` | | `SUSPICIOUS_SCORE_CHECK` | Enable suspicious score check (star>25 & acc<80 or pp>2300) | `true` |
| `SEASONAL_BACKGROUNDS` | List of seasonal background URLs | `[]` | | `SEASONAL_BACKGROUNDS` | List of seasonal background URLs | `[]` |
| `BANNED_NAME` | List of banned usernames | `["mrekk", "vaxei", "btmc", "cookiezi", "peppy", "saragi", "chocomint"]` |
### Storage Service Settings ### Storage Service Settings

View File

@@ -119,6 +119,7 @@ Fetcher 用于从 osu! 官方 API 获取数据,使用 osu! 官方 API 的 OAut
| `ENABLE_ALL_BEATMAP_PP` | 允许任何谱面获得 PP | `false` | | `ENABLE_ALL_BEATMAP_PP` | 允许任何谱面获得 PP | `false` |
| `SUSPICIOUS_SCORE_CHECK` | 启用可疑分数检查star>25&acc<80 或 pp>2300 | `true` | | `SUSPICIOUS_SCORE_CHECK` | 启用可疑分数检查star>25&acc<80 或 pp>2300 | `true` |
| `SEASONAL_BACKGROUNDS` | 季节背景图 URL 列表 | `[]` | | `SEASONAL_BACKGROUNDS` | 季节背景图 URL 列表 | `[]` |
| `BANNED_NAME` | 禁止使用的用户名列表 | `["mrekk", "vaxei", "btmc", "cookiezi", "peppy", "saragi", "chocomint"]` |
### 存储服务设置 ### 存储服务设置

View File

@@ -2,6 +2,7 @@ from __future__ import annotations
from datetime import datetime, timedelta from datetime import datetime, timedelta
import hashlib import hashlib
import re
import secrets import secrets
import string import string
@@ -26,6 +27,36 @@ pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
bcrypt_cache = {} bcrypt_cache = {}
def validate_username(username: str) -> list[str]:
"""验证用户名"""
errors = []
if not username:
errors.append("Username is required")
return errors
if len(username) < 3:
errors.append("Username must be at least 3 characters long")
if len(username) > 15:
errors.append("Username must be at most 15 characters long")
# 检查用户名格式(只允许字母、数字、下划线、连字符)
if not re.match(r"^[a-zA-Z0-9_-]+$", username):
errors.append(
"Username can only contain letters, numbers, underscores, and hyphens"
)
# 检查是否以数字开头
if username[0].isdigit():
errors.append("Username cannot start with a number")
if username.lower() in settings.banned_name:
errors.append("This username is not allowed")
return errors
def verify_password_legacy(plain_password: str, bcrypt_hash: str) -> bool: def verify_password_legacy(plain_password: str, bcrypt_hash: str) -> bool:
""" """
验证密码 - 使用 osu! 的验证方式 验证密码 - 使用 osu! 的验证方式

View File

@@ -109,6 +109,15 @@ class Settings(BaseSettings):
enable_all_beatmap_pp: bool = False enable_all_beatmap_pp: bool = False
suspicious_score_check: bool = True suspicious_score_check: bool = True
seasonal_backgrounds: list[str] = [] seasonal_backgrounds: list[str] = []
banned_name: list[str] = [
"mrekk",
"vaxei",
"btmc",
"cookiezi",
"peppy",
"saragi",
"chocomint",
]
# 存储设置 # 存储设置
storage_service: StorageServiceType = StorageServiceType.LOCAL storage_service: StorageServiceType = StorageServiceType.LOCAL

View File

@@ -12,6 +12,7 @@ from app.auth import (
get_token_by_refresh_token, get_token_by_refresh_token,
get_user_by_authorization_code, get_user_by_authorization_code,
store_token, store_token,
validate_username,
) )
from app.config import settings from app.config import settings
from app.const import BANCHOBOT_ID from app.const import BANCHOBOT_ID
@@ -46,33 +47,6 @@ def create_oauth_error_response(
return JSONResponse(status_code=status_code, content=error_data.model_dump()) return JSONResponse(status_code=status_code, content=error_data.model_dump())
def validate_username(username: str) -> list[str]:
"""验证用户名"""
errors = []
if not username:
errors.append("Username is required")
return errors
if len(username) < 3:
errors.append("Username must be at least 3 characters long")
if len(username) > 15:
errors.append("Username must be at most 15 characters long")
# 检查用户名格式(只允许字母、数字、下划线、连字符)
if not re.match(r"^[a-zA-Z0-9_-]+$", username):
errors.append(
"Username can only contain letters, numbers, underscores, and hyphens"
)
# 检查是否以数字开头
if username[0].isdigit():
errors.append("Username cannot start with a number")
return errors
def validate_email(email: str) -> list[str]: def validate_email(email: str) -> list[str]:
"""验证邮箱""" """验证邮箱"""
errors = [] errors = []

View File

@@ -2,6 +2,7 @@ from __future__ import annotations
from datetime import UTC, datetime from datetime import UTC, datetime
from app.auth import validate_username
from app.config import settings from app.config import settings
from app.database.events import Event, EventType from app.database.events import Event, EventType
from app.database.lazer_user import User from app.database.lazer_user import User
@@ -41,6 +42,9 @@ async def user_rename(
).first() ).first()
if samename_user: if samename_user:
raise HTTPException(409, "Username Exisits") raise HTTPException(409, "Username Exisits")
errors = validate_username(new_name)
if errors:
raise HTTPException(403, "\n".join(errors))
previous_username = [] previous_username = []
previous_username.extend(current_user.previous_usernames) previous_username.extend(current_user.previous_usernames)
previous_username.append(current_user.username) previous_username.append(current_user.username)