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}")
|
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 ====================
|
# ==================== Dashboard ====================
|
||||||
|
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
|
|||||||
@ -122,17 +122,18 @@ class IAMService:
|
|||||||
|
|
||||||
# Get all projects to build explicit deny list
|
# Get all projects to build explicit deny list
|
||||||
from .volcengine_client import get_resource_client
|
from .volcengine_client import get_resource_client
|
||||||
try:
|
res_client = get_resource_client(
|
||||||
res_client = get_resource_client(
|
self.client.ak, self.client.sk
|
||||||
self.client.ak, self.client.sk
|
)
|
||||||
)
|
resp = res_client.call("ListProjects", {"Limit": "100"})
|
||||||
resp = res_client.call("ListProjects", {"Limit": "100"})
|
all_projects = [
|
||||||
all_projects = [
|
p.get("ProjectName", "") for p in
|
||||||
p.get("ProjectName", "") for p in
|
resp.get("Result", {}).get("Projects", [])
|
||||||
resp.get("Result", {}).get("Projects", [])
|
]
|
||||||
]
|
|
||||||
except Exception:
|
if not all_projects:
|
||||||
all_projects = []
|
logger.warning(f"无法获取项目列表,跳过 Deny 策略更新 ({username})")
|
||||||
|
return
|
||||||
|
|
||||||
if not allowed_projects:
|
if not allowed_projects:
|
||||||
# No projects, deny everything
|
# 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:
|
try:
|
||||||
self.client.call("DeletePolicy", {"PolicyName": policy_name})
|
self.client.call("DeletePolicy", {"PolicyName": policy_name})
|
||||||
except VolcengineAPIError:
|
except VolcengineAPIError:
|
||||||
@ -177,12 +183,7 @@ class IAMService:
|
|||||||
"Description": f"AirGate 自动生成:限制 {username} 只能访问授权项目",
|
"Description": f"AirGate 自动生成:限制 {username} 只能访问授权项目",
|
||||||
})
|
})
|
||||||
|
|
||||||
# Ensure it's attached
|
self.attach_user_policy(username, policy_name, "Custom")
|
||||||
try:
|
|
||||||
self.attach_user_policy(username, policy_name, "Custom")
|
|
||||||
except VolcengineAPIError as e:
|
|
||||||
if "PolicyAttachConflict" not in str(e):
|
|
||||||
raise
|
|
||||||
|
|
||||||
def remove_deny_policy(self, username: str):
|
def remove_deny_policy(self, username: str):
|
||||||
"""移除子账号的 Deny 策略"""
|
"""移除子账号的 Deny 策略"""
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user