Questo è correlato sia a The road to stable, then permanent, for granular_anonymous_and_logged_in_groups_permissions che a Granular group-based permissions for anonymous and logged in users
Nel core, nonché in molti temi e plugin, un pattern come questo è diventato piuttosto comune:
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;
}
Tuttavia, questo non è un modo efficace per verificare i permessi dell’utente. Un utente può essere membro di gruppi che non sono visibili a lui, quindi non vengono serializzati sul client e non possono essere utilizzati in modo coerente o accurato per i controlli di sicurezza.
Per rendere questo aspetto più evidente, rinomineremo currentUser.groups/user.groups in currentUser.visibleGroups/user.visibleGroups nel modello User e deprecheremo la vecchia proprietà. La PR iniziale per farlo è DEV: Deprecate calling user.groups on client directly - Pull Request #42711 - discourse/discourse - GitHub .
Esistono diverse alternative se è necessario verificare il permesso di un utente in base a un elenco di ID di gruppo sul client in JavaScript:
Per i plugin
Estendi il serializzatore current_user con un nuovo attributo e verifica i permessi dell’utente con scope.in_any_groups? lato server, che copre anche i gruppi pseudo come logged_in_users e 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) }
Quindi puoi eseguire this.currentUser.has_some_permission sul client.
Per temi e componenti
Per le impostazioni del tema di tipo list con list_type: group, puoi usare resolve_group_membership: true:
copy_button_allowed_groups:
default: "1|3"
type: list
list_type: group
resolve_group_membership: true
Questo sostituirà settings.copy_button_allowed_groups sul client con settings.user_in_copy_button_allowed_groups (prefissando l’impostazione con user_in_), che è un valore booleano calcolato lato server in base alle appartenenze di gruppo dell’utente.
Questo funziona anche per le impostazioni di oggetto con type: groups . Aggiungi resolve_group_membership: true alla proprietà groups:
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
Quindi l’accesso sarà così:
for (const section of settings.menu_sections) {
if (section.user_in_groups) {
// L'utente appartiene ad almeno un gruppo selezionato per questa sezione.
}
}