fix: fix permission key format and fix role return format

This commit is contained in:
fatelei 2026-05-11 14:08:17 +08:00
parent 3dcea78e10
commit d90825fd8a
No known key found for this signature in database
GPG Key ID: 2F91DA05646F4EED
7 changed files with 54 additions and 94 deletions

View File

@ -73,11 +73,11 @@ register_enum_models(console_ns, TenantAccountRole)
register_schema_models(console_ns, AccountWithRole, AccountWithRoleList) register_schema_models(console_ns, AccountWithRole, AccountWithRoleList)
def _serialize_member_roles(current_role: str | None, member_role_ids: list[str]) -> list[str]: def _serialize_member_roles(current_role: str | None, member_roles: list[enterprise_rbac_service.MemberRoleSummary]) -> list[dict[str, str]]:
if member_role_ids: if member_roles:
return member_role_ids return [{"id": role.id, "name": role.name} for role in member_roles]
if current_role: if current_role:
return [current_role] return [{"id": current_role, "name": current_role}]
return [] return []
@ -106,7 +106,7 @@ class MemberListApi(Resource):
current_user.id, current_user.id,
member_ids, member_ids,
) )
roles_map = {item.account_id: [role.id for role in item.roles] for item in member_roles} roles_map = {item.account_id: item.roles for item in member_roles}
else: else:
roles_map = {} roles_map = {}

View File

@ -16,34 +16,24 @@ from services.enterprise import rbac_service as svc
_LEGACY_WORKSPACE_PERMISSION_KEYS: list[str] = [ _LEGACY_WORKSPACE_PERMISSION_KEYS: list[str] = [
"inviteMembers", # These keys are copied from the enterprise RBAC catalog examples in
"removeMembers", # `dify-rbac.md` so the legacy workspace roles stay in the same key format
"assignRoles", # as the enterprise RBAC surface.
"workspaceSettings", "workspace.member.manage",
"manageBilling", "workspace.role.manage",
"transferOwnership",
] ]
_LEGACY_APP_PERMISSION_KEYS: list[str] = [ _LEGACY_APP_PERMISSION_KEYS: list[str] = [
"createApps", "app.acl.view_layout",
"editApps", "app.acl.test_and_run",
"useApps", "app.acl.edit",
"app.acl.access_config",
] ]
_LEGACY_DATASET_PERMISSION_KEYS: list[str] = [ _LEGACY_DATASET_PERMISSION_KEYS: list[str] = [
"createDatasets", "dataset.acl.readonly",
"editDatasets",
"manageDatasets",
]
_LEGACY_ENTERPRISE_PERMISSION_KEYS: list[str] = [
"workspace.member.manage",
"workspace.settings.manage",
"workspace.billing.manage",
"workspace.owner.transfer",
"app.acl.edit",
"app.acl.test_and_run",
"dataset.acl.edit", "dataset.acl.edit",
"dataset.acl.use",
] ]
_LEGACY_ROLE_PERMISSION_KEYS: dict[str, list[str]] = { _LEGACY_ROLE_PERMISSION_KEYS: dict[str, list[str]] = {
@ -55,45 +45,22 @@ _LEGACY_ROLE_PERMISSION_KEYS: dict[str, list[str]] = {
*_LEGACY_WORKSPACE_PERMISSION_KEYS, *_LEGACY_WORKSPACE_PERMISSION_KEYS,
*_LEGACY_APP_PERMISSION_KEYS, *_LEGACY_APP_PERMISSION_KEYS,
*_LEGACY_DATASET_PERMISSION_KEYS, *_LEGACY_DATASET_PERMISSION_KEYS,
*_LEGACY_ENTERPRISE_PERMISSION_KEYS,
], ],
"admin": [ "admin": [
"inviteMembers", *_LEGACY_WORKSPACE_PERMISSION_KEYS,
"removeMembers", *_LEGACY_APP_PERMISSION_KEYS,
"assignRoles", *_LEGACY_DATASET_PERMISSION_KEYS,
"workspaceSettings",
"manageBilling",
"workspace.member.manage",
"workspace.settings.manage",
"workspace.billing.manage",
"app.acl.edit",
"app.acl.test_and_run",
"dataset.acl.edit",
"createApps",
"editApps",
"useApps",
"createDatasets",
"editDatasets",
"manageDatasets",
], ],
"editor": [ "editor": [
"createApps", *_LEGACY_APP_PERMISSION_KEYS,
"editApps", *_LEGACY_DATASET_PERMISSION_KEYS,
"useApps",
"createDatasets",
"editDatasets",
"workspace.member.manage",
"app.acl.edit",
"app.acl.test_and_run",
"dataset.acl.edit",
], ],
"normal": [ "normal": [
"useApps", "app.acl.view_layout",
"app.acl.test_and_run", "app.acl.test_and_run",
], ],
"dataset_operator": [ "dataset_operator": [
"manageDatasets", *_LEGACY_DATASET_PERMISSION_KEYS,
"dataset.acl.edit",
], ],
} }

View File

@ -70,7 +70,7 @@ class AccountWithRole(_AccountAvatar):
last_active_at: int | None = None last_active_at: int | None = None
created_at: int | None = None created_at: int | None = None
role: str role: str
roles: list[str] = Field(default_factory=list) roles: list[dict[str, str]] = Field(default_factory=list)
status: str status: str
@field_validator("last_login_at", "last_active_at", "created_at", mode="before") @field_validator("last_login_at", "last_active_at", "created_at", mode="before")

View File

@ -74,6 +74,11 @@ class RBACRole(_RBACModel):
return value return value
class MemberRoleSummary(_RBACModel):
id: str
name: str
class AccessPolicy(_RBACModel): class AccessPolicy(_RBACModel):
id: str id: str
tenant_id: str = "" tenant_id: str = ""
@ -146,7 +151,7 @@ class MemberBindingsResponse(_RBACModel):
class MemberRolesResponse(_RBACModel): class MemberRolesResponse(_RBACModel):
account_id: str account_id: str
roles: list[RBACRole] = Field(default_factory=list) roles: list[MemberRoleSummary] = Field(default_factory=list)
class MemberRolesBatchResponse(_RBACModel): class MemberRolesBatchResponse(_RBACModel):

View File

@ -60,7 +60,7 @@ class TestMemberListApi:
assert status == 200 assert status == 200
assert len(result["accounts"]) == 1 assert len(result["accounts"]) == 1
assert result["accounts"][0]["role"] == "admin" assert result["accounts"][0]["role"] == "admin"
assert result["accounts"][0]["roles"] == ["admin"] assert result["accounts"][0]["roles"] == [{"id": "admin", "name": "admin"}]
def test_get_with_rbac_enabled_fetches_roles_in_batch(self, app): def test_get_with_rbac_enabled_fetches_roles_in_batch(self, app):
api = MemberListApi() api = MemberListApi()
@ -81,7 +81,10 @@ class TestMemberListApi:
) )
role_item = SimpleNamespace( role_item = SimpleNamespace(
account_id="m1", account_id="m1",
roles=[SimpleNamespace(id="workspace.owner"), SimpleNamespace(id="workspace.editor")], roles=[
SimpleNamespace(id="workspace.owner", name="Owner"),
SimpleNamespace(id="workspace.editor", name="Editor"),
],
) )
with ( with (
@ -98,7 +101,10 @@ class TestMemberListApi:
assert status == 200 assert status == 200
assert result["accounts"][0]["role"] == "editor" assert result["accounts"][0]["role"] == "editor"
assert result["accounts"][0]["roles"] == ["workspace.owner", "workspace.editor"] assert result["accounts"][0]["roles"] == [
{"id": "workspace.owner", "name": "Owner"},
{"id": "workspace.editor", "name": "Editor"},
]
mock_batch_get.assert_called_once_with("tenant-1", "acct-1", ["m1"]) mock_batch_get.assert_called_once_with("tenant-1", "acct-1", ["m1"])
def test_get_no_tenant(self, app): def test_get_no_tenant(self, app):

View File

@ -137,25 +137,15 @@ class TestPaginationMapping:
"description": "", "description": "",
"is_builtin": True, "is_builtin": True,
"permission_keys": [ "permission_keys": [
"inviteMembers",
"removeMembers",
"assignRoles",
"workspaceSettings",
"manageBilling",
"transferOwnership",
"createApps",
"editApps",
"useApps",
"createDatasets",
"editDatasets",
"manageDatasets",
"workspace.member.manage", "workspace.member.manage",
"workspace.settings.manage", "workspace.role.manage",
"workspace.billing.manage", "app.acl.view_layout",
"workspace.owner.transfer",
"app.acl.edit",
"app.acl.test_and_run", "app.acl.test_and_run",
"app.acl.edit",
"app.acl.access_config",
"dataset.acl.readonly",
"dataset.acl.edit", "dataset.acl.edit",
"dataset.acl.use",
], ],
}, },
{ {
@ -167,23 +157,15 @@ class TestPaginationMapping:
"description": "", "description": "",
"is_builtin": True, "is_builtin": True,
"permission_keys": [ "permission_keys": [
"inviteMembers",
"removeMembers",
"assignRoles",
"workspaceSettings",
"manageBilling",
"workspace.member.manage", "workspace.member.manage",
"workspace.settings.manage", "workspace.role.manage",
"workspace.billing.manage", "app.acl.view_layout",
"app.acl.edit",
"app.acl.test_and_run", "app.acl.test_and_run",
"app.acl.edit",
"app.acl.access_config",
"dataset.acl.readonly",
"dataset.acl.edit", "dataset.acl.edit",
"createApps", "dataset.acl.use",
"editApps",
"useApps",
"createDatasets",
"editDatasets",
"manageDatasets",
], ],
}, },
] ]

View File

@ -312,7 +312,7 @@ class TestMyPermissions:
def test_get_without_payload_uses_get(self, mock_send: MagicMock): def test_get_without_payload_uses_get(self, mock_send: MagicMock):
mock_send.return_value = { mock_send.return_value = {
"workspace": {"permission_keys": ["workspace.member.manage"]}, "workspace": {"permission_keys": ["workspace.member.manage"]},
"app": {"default_permission_keys": ["app.acl.test_and_run"], "overrides": []}, "app": {"default_permission_keys": ["app.acl.view_layout", "app.acl.test_and_run"], "overrides": []},
"dataset": {"default_permission_keys": [], "overrides": []}, "dataset": {"default_permission_keys": [], "overrides": []},
} }
@ -378,8 +378,8 @@ class TestMemberRoles:
{ {
"account_id": "acct-2", "account_id": "acct-2",
"roles": [ "roles": [
{"id": "role-1", "type": "workspace", "name": "Admin"}, {"id": "role-1", "name": "Admin"},
{"id": "role-2", "type": "workspace", "name": "Editor"}, {"id": "role-2", "name": "Editor"},
], ],
}, },
{ {