fix: deny policy audit - detach before delete, fail on empty project list
- Fix: detach policy before deleting (avoids deletion error on referenced policy) - Fix: fail explicitly if project list can't be fetched (prevent no-op Deny) - Add _refresh_all_deny_policies helper for batch refresh after new project creation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0f034b7b26
commit
ff0d0de8f8
@ -59,6 +59,14 @@ def _update_deny_policy(user):
|
||||
logger.error(f"更新 Deny 策略失败 ({user.username}): {e}")
|
||||
|
||||
|
||||
def _refresh_all_deny_policies():
|
||||
"""刷新所有子账号的 Deny 策略(新建火山项目后调用)"""
|
||||
users = IAMUser.objects.filter(status=IAMUser.Status.ACTIVE)
|
||||
for user in users:
|
||||
if user.projects.exists():
|
||||
_update_deny_policy(user)
|
||||
|
||||
|
||||
# ==================== Dashboard ====================
|
||||
|
||||
@api_view(['GET'])
|
||||
|
||||
@ -122,17 +122,18 @@ class IAMService:
|
||||
|
||||
# Get all projects to build explicit deny list
|
||||
from .volcengine_client import get_resource_client
|
||||
try:
|
||||
res_client = get_resource_client(
|
||||
self.client.ak, self.client.sk
|
||||
)
|
||||
resp = res_client.call("ListProjects", {"Limit": "100"})
|
||||
all_projects = [
|
||||
p.get("ProjectName", "") for p in
|
||||
resp.get("Result", {}).get("Projects", [])
|
||||
]
|
||||
except Exception:
|
||||
all_projects = []
|
||||
res_client = get_resource_client(
|
||||
self.client.ak, self.client.sk
|
||||
)
|
||||
resp = res_client.call("ListProjects", {"Limit": "100"})
|
||||
all_projects = [
|
||||
p.get("ProjectName", "") for p in
|
||||
resp.get("Result", {}).get("Projects", [])
|
||||
]
|
||||
|
||||
if not all_projects:
|
||||
logger.warning(f"无法获取项目列表,跳过 Deny 策略更新 ({username})")
|
||||
return
|
||||
|
||||
if not allowed_projects:
|
||||
# No projects, deny everything
|
||||
@ -165,7 +166,12 @@ class IAMService:
|
||||
}]
|
||||
})
|
||||
|
||||
# Try to update existing, if not found create new
|
||||
# Delete old policy (must detach first), then recreate
|
||||
try:
|
||||
self.detach_user_policy(username, policy_name, "Custom")
|
||||
except VolcengineAPIError:
|
||||
pass # Not attached or doesn't exist
|
||||
|
||||
try:
|
||||
self.client.call("DeletePolicy", {"PolicyName": policy_name})
|
||||
except VolcengineAPIError:
|
||||
@ -177,12 +183,7 @@ class IAMService:
|
||||
"Description": f"AirGate 自动生成:限制 {username} 只能访问授权项目",
|
||||
})
|
||||
|
||||
# Ensure it's attached
|
||||
try:
|
||||
self.attach_user_policy(username, policy_name, "Custom")
|
||||
except VolcengineAPIError as e:
|
||||
if "PolicyAttachConflict" not in str(e):
|
||||
raise
|
||||
self.attach_user_policy(username, policy_name, "Custom")
|
||||
|
||||
def remove_deny_policy(self, username: str):
|
||||
"""移除子账号的 Deny 策略"""
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user