过期时间
This commit is contained in:
parent
35f91a7d03
commit
a22211da32
@ -196,9 +196,9 @@ async def check_bot_access(bot_id: str, user_id: str, required_permission: str)
|
||||
if await cursor.fetchone():
|
||||
return True
|
||||
|
||||
# 检查是否在分享列表中
|
||||
# 检查是否在分享列表中(同<EFBFBD><EFBFBD>检查过期时间)
|
||||
await cursor.execute("""
|
||||
SELECT role FROM bot_shares
|
||||
SELECT role, expires_at FROM bot_shares
|
||||
WHERE bot_id = %s AND user_id = %s
|
||||
""", (bot_id, user_id))
|
||||
row = await cursor.fetchone()
|
||||
@ -206,7 +206,16 @@ async def check_bot_access(bot_id: str, user_id: str, required_permission: str)
|
||||
if not row:
|
||||
return False
|
||||
|
||||
role = row[0]
|
||||
role, expires_at = row
|
||||
|
||||
# 检查是否已过期
|
||||
if expires_at is not None:
|
||||
# 获取当前时间(考虑时区)
|
||||
from datetime import datetime, timezone
|
||||
now = datetime.now(timezone.utc)
|
||||
if expires_at < now:
|
||||
# 分享已过期,拒绝访问
|
||||
return False
|
||||
|
||||
# 权限矩阵
|
||||
permissions = {
|
||||
@ -401,6 +410,7 @@ class BotResponse(BaseModel):
|
||||
owner: Optional[dict] = None # {id, username}
|
||||
role: Optional[str] = None # 'viewer', 'editor', None for owner
|
||||
shared_at: Optional[str] = None
|
||||
expires_at: Optional[str] = None # 分享过期时间
|
||||
description: Optional[str] = None # 从 settings 中提取
|
||||
avatar_url: Optional[str] = None # 从 settings 中提取
|
||||
created_at: str
|
||||
@ -502,6 +512,7 @@ class BotShareCreate(BaseModel):
|
||||
"""创建分享请求"""
|
||||
user_ids: List[str]
|
||||
role: str = "viewer" # 'viewer' or 'editor'
|
||||
expires_at: Optional[str] = None # ISO 8601 格式的过期时间,None 表示永不过期
|
||||
|
||||
|
||||
class BotShareResponse(BaseModel):
|
||||
@ -514,6 +525,7 @@ class BotShareResponse(BaseModel):
|
||||
role: str
|
||||
shared_at: str
|
||||
shared_by: Optional[str] = None
|
||||
expires_at: Optional[str] = None # 过期时间
|
||||
|
||||
|
||||
class BotSharesListResponse(BaseModel):
|
||||
@ -609,6 +621,7 @@ async def migrate_bot_owner_and_shares():
|
||||
shared_by UUID NOT NULL REFERENCES agent_user(id) ON DELETE SET NULL,
|
||||
role VARCHAR(50) DEFAULT 'viewer' CHECK (role IN ('viewer', 'editor')),
|
||||
shared_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
expires_at TIMESTAMP WITH TIME ZONE,
|
||||
UNIQUE(bot_id, user_id)
|
||||
)
|
||||
""")
|
||||
@ -618,6 +631,21 @@ async def migrate_bot_owner_and_shares():
|
||||
await cursor.execute("CREATE INDEX idx_bot_shares_shared_by ON bot_shares(shared_by)")
|
||||
|
||||
logger.info("bot_shares table created successfully")
|
||||
else:
|
||||
# 为已存在的表添加 expires_at 字段
|
||||
await cursor.execute("""
|
||||
SELECT column_name
|
||||
FROM information_schema.columns
|
||||
WHERE table_name = 'bot_shares' AND column_name = 'expires_at'
|
||||
""")
|
||||
has_expires_column = await cursor.fetchone()
|
||||
if not has_expires_column:
|
||||
logger.info("Adding expires_at column to bot_shares table")
|
||||
await cursor.execute("""
|
||||
ALTER TABLE bot_shares
|
||||
ADD COLUMN expires_at TIMESTAMP WITH TIME ZONE
|
||||
""")
|
||||
logger.info("expires_at column added successfully")
|
||||
|
||||
# 4. 创建 agent_user_tokens 表
|
||||
await cursor.execute("""
|
||||
@ -1235,15 +1263,16 @@ async def get_bots(authorization: Optional[str] = Header(None)):
|
||||
for row in rows
|
||||
]
|
||||
else:
|
||||
# 用户只能看到拥有的 Bot 和分享给自己的 Bot
|
||||
# 用户只能看到拥有的 Bot 和分享给自己的 Bot(且未过期)
|
||||
await cursor.execute("""
|
||||
SELECT b.id, b.name, b.bot_id, b.created_at, b.updated_at, b.settings,
|
||||
u.id as owner_id, u.username as owner_username,
|
||||
s.role, s.shared_at
|
||||
s.role, s.shared_at, s.expires_at
|
||||
FROM agent_bots b
|
||||
LEFT JOIN agent_user u ON b.owner_id = u.id
|
||||
LEFT JOIN bot_shares s ON b.id = s.bot_id AND s.user_id = %s
|
||||
WHERE b.owner_id = %s OR s.user_id = %s
|
||||
WHERE b.owner_id = %s
|
||||
OR (s.user_id = %s AND (s.expires_at IS NULL OR s.expires_at > NOW()))
|
||||
ORDER BY b.created_at DESC
|
||||
""", (user_id, user_id, user_id))
|
||||
rows = await cursor.fetchall()
|
||||
@ -1258,6 +1287,7 @@ async def get_bots(authorization: Optional[str] = Header(None)):
|
||||
owner={"id": str(row[6]), "username": row[7]} if row[6] else None,
|
||||
role=row[8] if row[8] else None,
|
||||
shared_at=datetime_to_str(row[9]) if row[9] else None,
|
||||
expires_at=row[10].isoformat() if row[10] else None,
|
||||
description=row[5].get('description') if row[5] else None,
|
||||
avatar_url=row[5].get('avatar_url') if row[5] else None,
|
||||
created_at=datetime_to_str(row[3]),
|
||||
@ -2823,7 +2853,7 @@ async def get_bot_shares(
|
||||
async with pool.connection() as conn:
|
||||
async with conn.cursor() as cursor:
|
||||
await cursor.execute("""
|
||||
SELECT s.id, s.bot_id, s.user_id, u.username, u.email, s.role, s.shared_at, su.username
|
||||
SELECT s.id, s.bot_id, s.user_id, u.username, u.email, s.role, s.shared_at, s.expires_at, su.username
|
||||
FROM bot_shares s
|
||||
JOIN agent_user u ON s.user_id = u.id
|
||||
LEFT JOIN agent_user su ON s.shared_by = su.id
|
||||
@ -2841,7 +2871,8 @@ async def get_bot_shares(
|
||||
email=row[4],
|
||||
role=row[5],
|
||||
shared_at=row[6].isoformat() if row[6] else "",
|
||||
shared_by=row[7] if row[7] is None else str(row[7])
|
||||
expires_at=row[7].isoformat() if row[7] else None,
|
||||
shared_by=row[8] if row[8] is None else str(row[8])
|
||||
)
|
||||
for row in rows
|
||||
]
|
||||
@ -2904,12 +2935,13 @@ async def add_bot_share(
|
||||
for target_user_id in request.user_ids:
|
||||
try:
|
||||
await cursor.execute("""
|
||||
INSERT INTO bot_shares (bot_id, user_id, shared_by, role)
|
||||
VALUES (%s, %s, %s, %s)
|
||||
INSERT INTO bot_shares (bot_id, user_id, shared_by, role, expires_at)
|
||||
VALUES (%s, %s, %s, %s, %s)
|
||||
ON CONFLICT (bot_id, user_id) DO UPDATE SET
|
||||
role = EXCLUDED.role,
|
||||
shared_by = EXCLUDED.shared_by
|
||||
""", (bot_uuid, target_user_id, user_id, request.role))
|
||||
shared_by = EXCLUDED.shared_by,
|
||||
expires_at = EXCLUDED.expires_at
|
||||
""", (bot_uuid, target_user_id, user_id, request.role, request.expires_at))
|
||||
added_count += 1
|
||||
except Exception:
|
||||
pass # 忽略重复的
|
||||
|
||||
Loading…
Reference in New Issue
Block a user