これは The road to stable, then permanent, for granular_anonymous_and_logged_in_groups_permissions および Granular group-based permissions for anonymous and logged in users の両方に関連しています。
コアだけでなく、多くのテーマやプラグインでも、次のようなパターンがかなり一般的になっています:
const groupIds = this.currentUser.groups.map((g) => g.id);
const allowedGroupIds = this.siteSettings.some_group_setting.split("|").map((groupId) => parseInt(groupId, 10));
const hasPermission = allowedGroups.some((groupId) =>
userGroupIds.includes(groupId)
);
if (!hasPermission) {
return;
}
しかし、これではユーザーの権限を確認する効果的な方法ではありません。ユーザーは、自分自身に表示されないグループのメンバーである可能性があります。そのため、それらはクライアントにシリアライズされず、セキュリティチェックに一貫性や正確性をもって使用できません。
これをより明確にするため、User モデルにおいて currentUser.groups/user.groups を currentUser.visibleGroups/user.visibleGroups にリネームし、旧プロパティを非推奨とします。これを行うための最初のPRは DEV: Deprecate calling user.groups on client directly - Pull Request #42711 - discourse/discourse - GitHub です。
クライアント側でJavaScriptを使用して、グループIDのリストに基づいてユーザーの権限を確認する必要がある場合、いくつかの代替手段があります:
プラグインの場合
current_user シリアライザーに新しい属性を追加し、サーバーサイドで scope.in_any_groups? を使用してユーザーの権限を確認してください。これにより、logged_in_users や anonymous_users などの疑似グループもカバーされます:
add_to_serializer(
:current_user,
:has_some_permission,
include_condition: -> do
SiteSetting.plugin_enabled
end,
) { scope.in_any_groups?(SiteSetting.group_list_setting_map) }
その後、クライアント側で this.currentUser.has_some_permission を使用できます。
テーマとコンポーネントの場合
list_type: group を持つ list タイプのテーマ設定では、resolve_group_membership: true を使用できます:
copy_button_allowed_groups:
default: "1|3"
type: list
list_type: group
resolve_group_membership: true
これにより、クライアント上の settings.copy_button_allowed_groups は settings.user_in_copy_button_allowed_groups に置き換えられます(設定に user_in_ というプレフィックスが付与されます)。これは、ユーザーのグループメンバーシップに基づいてサーバーサイドで計算されるブール値です。
これは type: groups を持つオブジェクト設定にも適用できます。groups プロパティに resolve_group_membership: true を追加します:
menu_sections:
type: objects
default:
- name: section 1
groups:
- 1
- 3
schema:
name: menu section
properties:
name:
type: string
groups:
type: groups
resolve_group_membership: true
その場合、アクセスは次のようになります:
for (const section of settings.menu_sections) {
if (section.user_in_groups) {
// ユーザーはこのセクションで選択されたグループの少なくとも1つに属しています。
}
}