feat: Add Gitea username integration, refactor password hashing with direct bcrypt, and remove frontend version displays.

This commit is contained in:
vinland100 2026-01-05 13:47:48 +08:00
parent bc1597a41d
commit 4d3761e0e0
9 changed files with 96 additions and 21 deletions

View File

@ -0,0 +1,34 @@
"""add gitea_username to user model
Revision ID: 08a73307418d
Revises: ecc7c0ff0957
Create Date: 2026-01-05 13:36:16.845876
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '08a73307418d'
down_revision = 'ecc7c0ff0957'
branch_labels = None
depends_on = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('users', sa.Column('gitea_username', sa.String(), nullable=True))
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('users', 'gitea_username')
# ### end Alembic commands ###

View File

@ -1,18 +1,10 @@
from datetime import datetime, timedelta, timezone
from typing import Any, Union
from jose import jwt
import bcrypt # Import first
import bcrypt
# MonkeyPatch passlib/bcrypt compatibility (passlib expects __about__)
if not hasattr(bcrypt, "__about__"):
from types import SimpleNamespace
bcrypt.__about__ = SimpleNamespace(__version__=bcrypt.__version__)
from passlib.context import CryptContext
from app.core.config import settings
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
ALGORITHM = settings.ALGORITHM
def create_access_token(
@ -29,10 +21,36 @@ def create_access_token(
return encoded_jwt
def verify_password(plain_password: str, hashed_password: str) -> bool:
return pwd_context.verify(plain_password, hashed_password)
"""
Verify a password against a hash.
Explicitly truncate to 72 bytes to avoid bcrypt ValueError and maintain compatibility.
"""
if not plain_password or not hashed_password:
return False
try:
password_bytes = plain_password.encode("utf-8")
if len(password_bytes) > 72:
password_bytes = password_bytes[:72]
return bcrypt.checkpw(
password_bytes,
hashed_password.encode("utf-8")
)
except Exception:
return False
def get_password_hash(password: str) -> str:
return pwd_context.hash(password)
"""
Generate a bcrypt hash of the password.
Explicitly truncate to 72 bytes for consistency.
"""
password_bytes = password.encode("utf-8")
if len(password_bytes) > 72:
password_bytes = password_bytes[:72]
salt = bcrypt.gensalt()
return bcrypt.hashpw(password_bytes, salt).decode("utf-8")

View File

@ -19,6 +19,7 @@ class User(Base):
role = Column(String, default="member")
github_username = Column(String, nullable=True)
gitlab_username = Column(String, nullable=True)
gitea_username = Column(String, nullable=True)
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())

View File

@ -13,6 +13,7 @@ class UserBase(BaseModel):
role: str = "member"
github_username: Optional[str] = None
gitlab_username: Optional[str] = None
gitea_username: Optional[str] = None
class UserCreate(UserBase):
email: EmailStr

View File

@ -275,8 +275,8 @@ SYSTEM_RULE_SETS = [
"description": "基于 OWASP Top 10 2021 的安全审计规则集",
"language": "all",
"rule_type": "security",
"is_default": True,
"sort_order": 0,
"is_default": False,
"sort_order": 1,
"severity_weights": {"critical": 10, "high": 5, "medium": 2, "low": 1},
"rules": [
{
@ -386,8 +386,8 @@ SYSTEM_RULE_SETS = [
"description": "通用代码质量检查规则集",
"language": "all",
"rule_type": "quality",
"is_default": False,
"sort_order": 1,
"is_default": True,
"sort_order": 0,
"severity_weights": {"critical": 10, "high": 5, "medium": 2, "low": 1},
"rules": [
{
@ -550,6 +550,11 @@ async def init_system_templates(db: AsyncSession) -> None:
)
db.add(template)
logger.info(f"✓ 创建系统提示词模板: {template_data['name']}")
else:
# 更新已存在的系统模板的默认状态和排序
existing.is_default = template_data.get("is_default", False)
existing.sort_order = template_data.get("sort_order", 0)
db.add(existing)
await db.flush()
@ -599,6 +604,11 @@ async def init_system_rule_sets(db: AsyncSession) -> None:
db.add(rule)
logger.info(f"✓ 创建系统规则集: {rule_set_data['name']} ({len(rule_set_data.get('rules', []))} 条规则)")
else:
# 更新已存在的系统规则集的默认状态和排序
existing.is_default = rule_set_data.get("is_default", False)
existing.sort_order = rule_set_data.get("sort_order", 0)
db.add(existing)
await db.flush()

View File

@ -467,7 +467,6 @@ export default function TerminalProgressDialog({
<Terminal className="w-5 h-5 text-primary" />
<div>
<span className="text-lg font-bold uppercase tracking-[0.15em] text-slate-800 dark:text-[#f0e6d3]">AUDIT_TERMINAL</span>
<span className="text-xs text-slate-500 dark:text-[#5a6577] ml-2 tracking-wider">v3.0</span>
</div>
</div>

View File

@ -38,6 +38,7 @@ export default function Account() {
phone: "",
github_username: "",
gitlab_username: "",
gitea_username: "",
});
const [passwordForm, setPasswordForm] = useState({
current_password: "",
@ -60,6 +61,7 @@ export default function Account() {
phone: res.data.phone || "",
github_username: res.data.github_username || "",
gitlab_username: res.data.gitlab_username || "",
gitea_username: res.data.gitea_username || "",
});
} catch (error) {
console.error('Failed to load profile:', error);
@ -288,6 +290,18 @@ export default function Account() {
className="cyber-input"
/>
</div>
<div className="space-y-2">
<Label htmlFor="gitea" className="text-xs font-bold text-muted-foreground uppercase flex items-center gap-2">
<GitBranch className="w-3 h-3" /> Gitea
</Label>
<Input
id="gitea"
value={form.gitea_username}
onChange={(e) => setForm({ ...form, gitea_username: e.target.value })}
placeholder="your-gitea-username"
className="cyber-input"
/>
</div>
</div>
</div>

View File

@ -15,7 +15,7 @@ interface SplashScreenProps {
// Enhanced boot sequence messages with icons
const BOOT_SEQUENCE = [
{ text: "[INIT] Loading DeepAudit Core...", delay: 0, type: 'init' },
{ text: "[SCAN] AI Code Review Engine v3.0", delay: 200, type: 'scan' },
{ text: "[SCAN] AI Code Review Engine", delay: 200, type: 'scan' },
{ text: "[LOAD] Vulnerability Pattern Database", delay: 400, type: 'load' },
{ text: "[SYNC] Agent Orchestration Module", delay: 600, type: 'sync' },
{ text: "[READY] System Online", delay: 800, type: 'ready' },
@ -234,10 +234,7 @@ export function SplashScreen({ onComplete }: SplashScreenProps) {
<AppLogo size="xl" subtitle="AI Code Review Bot" />
</div>
</div>
{/* Version tag */}
<div className="mt-2 text-[10px] font-mono text-primary/50 tracking-widest">
[ v3.0.0 // NEURAL_CORE ]
</div>
{/* Version tag removed */}
</div>
{/* Terminal window - adaptive styling */}

View File

@ -16,6 +16,7 @@ export interface Profile {
role: 'admin' | 'member';
github_username?: string;
gitlab_username?: string;
gitea_username?: string;
created_at: string;
updated_at: string;
}