mirror of
https://github.com/langgenius/dify.git
synced 2026-06-24 13:01:16 +08:00
chore: compatiable old role update (#37804)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
b98ba99b23
commit
db9b899321
@ -183,7 +183,11 @@ class EnterpriseRequest(BaseRequest):
|
||||
if account_id:
|
||||
inner_headers[INNER_ACCOUNT_ID_HEADER] = account_id
|
||||
|
||||
if not cls.base_url.startswith("http") or not cls.base_url.startswith("https") or not cls.base_url:
|
||||
if (
|
||||
not cls.rbac_base_url.startswith("http")
|
||||
or not cls.rbac_base_url.startswith("https")
|
||||
or not cls.rbac_base_url
|
||||
):
|
||||
raise ValueError("ENTERPRISE_RBAC_API_URL is required when RBAC_ENABLED=true")
|
||||
|
||||
url = f"{cls.rbac_base_url}{endpoint}"
|
||||
|
||||
@ -534,6 +534,31 @@ def _legacy_role_permission_keys(role: TenantAccountRole) -> list[str]:
|
||||
)
|
||||
|
||||
|
||||
def _legacy_member_roles_response(
|
||||
tenant_id: str, member_account_id: str, role: TenantAccountRole | str | None
|
||||
) -> MemberRolesResponse:
|
||||
if not role:
|
||||
return MemberRolesResponse(account_id=member_account_id, roles=[])
|
||||
|
||||
tenant_role = TenantAccountRole(role)
|
||||
role_value = tenant_role.value
|
||||
return MemberRolesResponse(
|
||||
account_id=member_account_id,
|
||||
roles=[
|
||||
RBACRole(
|
||||
id=role_value,
|
||||
name=role_value,
|
||||
description="",
|
||||
is_builtin=True,
|
||||
type="",
|
||||
permission_keys=_legacy_role_permission_keys(tenant_role),
|
||||
role_tag="owner" if tenant_role == TenantAccountRole.OWNER else role_value,
|
||||
tenant_id=tenant_id,
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
def _legacy_my_permissions(tenant_id: str, account_id: str | None) -> MyPermissionsResponse:
|
||||
if not account_id:
|
||||
return MyPermissionsResponse()
|
||||
@ -1582,23 +1607,7 @@ class RBACService:
|
||||
TenantAccountJoin.account_id == member_account_id,
|
||||
)
|
||||
)
|
||||
return MemberRolesResponse(
|
||||
account_id=member_account_id,
|
||||
roles=[
|
||||
RBACRole(
|
||||
id=role,
|
||||
name=role,
|
||||
description="",
|
||||
is_builtin=True,
|
||||
type="",
|
||||
permission_keys=_legacy_role_permission_keys(role),
|
||||
role_tag="owner" if role == "owner" else role,
|
||||
tenant_id=tenant_id,
|
||||
)
|
||||
]
|
||||
if role
|
||||
else [],
|
||||
)
|
||||
return _legacy_member_roles_response(tenant_id, member_account_id, role)
|
||||
|
||||
@staticmethod
|
||||
def batch_get(
|
||||
@ -1629,6 +1638,36 @@ class RBACService:
|
||||
member_account_id: str,
|
||||
role_ids: list[str],
|
||||
) -> MemberRolesResponse:
|
||||
if not dify_config.RBAC_ENABLED:
|
||||
if len(role_ids) != 1:
|
||||
raise ValueError("Legacy workspace member role update requires exactly one role.")
|
||||
|
||||
tenant_role = TenantAccountRole(role_ids[0])
|
||||
with session_factory.create_session() as session:
|
||||
target_member_join = session.scalar(
|
||||
select(TenantAccountJoin).where(
|
||||
TenantAccountJoin.tenant_id == tenant_id,
|
||||
TenantAccountJoin.account_id == member_account_id,
|
||||
)
|
||||
)
|
||||
if not target_member_join:
|
||||
raise ValueError("Member not in tenant.")
|
||||
|
||||
if tenant_role == TenantAccountRole.OWNER:
|
||||
current_owner_join = session.scalar(
|
||||
select(TenantAccountJoin).where(
|
||||
TenantAccountJoin.tenant_id == tenant_id,
|
||||
TenantAccountJoin.role == TenantAccountRole.OWNER,
|
||||
)
|
||||
)
|
||||
if current_owner_join and current_owner_join.account_id != member_account_id:
|
||||
current_owner_join.role = TenantAccountRole.ADMIN
|
||||
|
||||
target_member_join.role = tenant_role
|
||||
session.commit()
|
||||
|
||||
return _legacy_member_roles_response(tenant_id, member_account_id, tenant_role)
|
||||
|
||||
data = _inner_call(
|
||||
"PUT",
|
||||
f"{_INNER_PREFIX}/members/rbac-roles",
|
||||
|
||||
@ -745,15 +745,54 @@ class TestMemberRoles:
|
||||
|
||||
def test_replace(self, mock_send: MagicMock):
|
||||
mock_send.return_value = {"account_id": "acct-2", "roles": []}
|
||||
svc.RBACService.MemberRoles.replace(
|
||||
"tenant-1", "acct-1", "acct-2", role_ids=["workspace.owner", "workspace.editor"]
|
||||
)
|
||||
with patch(f"{MODULE}.dify_config.RBAC_ENABLED", True):
|
||||
svc.RBACService.MemberRoles.replace(
|
||||
"tenant-1", "acct-1", "acct-2", role_ids=["workspace.owner", "workspace.editor"]
|
||||
)
|
||||
call = _call_args(mock_send)
|
||||
assert call.method == "PUT"
|
||||
assert call.endpoint == "/rbac/members/rbac-roles"
|
||||
assert call.params == {"account_id": "acct-2"}
|
||||
assert call.json == {"role_ids": ["workspace.owner", "workspace.editor"]}
|
||||
|
||||
def test_replace_updates_legacy_join_role_when_rbac_disabled(self, mock_send: MagicMock):
|
||||
session = MagicMock()
|
||||
session.__enter__.return_value = session
|
||||
target_join = SimpleNamespace(role=svc.TenantAccountRole.NORMAL, account_id="acct-2")
|
||||
session.scalar.return_value = target_join
|
||||
|
||||
with (
|
||||
patch(f"{MODULE}.dify_config.RBAC_ENABLED", False),
|
||||
patch(f"{MODULE}.session_factory.create_session", return_value=session),
|
||||
):
|
||||
out = svc.RBACService.MemberRoles.replace("tenant-1", "acct-1", "acct-2", role_ids=["editor"])
|
||||
|
||||
mock_send.assert_not_called()
|
||||
session.commit.assert_called_once()
|
||||
assert target_join.role == svc.TenantAccountRole.EDITOR
|
||||
assert out.account_id == "acct-2"
|
||||
assert out.roles[0].id == "editor"
|
||||
assert "app.acl.preview" in out.roles[0].permission_keys
|
||||
|
||||
def test_replace_legacy_owner_demotes_current_owner_when_rbac_disabled(self, mock_send: MagicMock):
|
||||
session = MagicMock()
|
||||
session.__enter__.return_value = session
|
||||
target_join = SimpleNamespace(role=svc.TenantAccountRole.NORMAL, account_id="acct-2")
|
||||
owner_join = SimpleNamespace(role=svc.TenantAccountRole.OWNER, account_id="acct-owner")
|
||||
session.scalar.side_effect = [target_join, owner_join]
|
||||
|
||||
with (
|
||||
patch(f"{MODULE}.dify_config.RBAC_ENABLED", False),
|
||||
patch(f"{MODULE}.session_factory.create_session", return_value=session),
|
||||
):
|
||||
out = svc.RBACService.MemberRoles.replace("tenant-1", "acct-1", "acct-2", role_ids=["owner"])
|
||||
|
||||
mock_send.assert_not_called()
|
||||
session.commit.assert_called_once()
|
||||
assert target_join.role == svc.TenantAccountRole.OWNER
|
||||
assert owner_join.role == svc.TenantAccountRole.ADMIN
|
||||
assert out.roles[0].id == "owner"
|
||||
|
||||
def test_batch_get(self, mock_send: MagicMock):
|
||||
mock_send.return_value = {
|
||||
"acct-2": [
|
||||
|
||||
Loading…
Reference in New Issue
Block a user