Deprecazione dell'uso di `user.groups` nel modello `User` in JavaScript

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.
  }
}

Ciao Martin,
Queste modifiche entreranno in vigore al momento del merge della PR, oppure con l’aggiornamento successivo al merge?

Perché è importante? Questo non romperà nulla. Mostrerà semplicemente un avviso nella console del browser, avvisando gli sviluppatori di adeguare il proprio codice.

Ho dei componenti del tema di cui so che dipendono da questo e volevo una chiarificazione. Se si tratta solo di un avviso ma continuerà a funzionare per un po’, sono meno preoccupato.

Di solito, il codice deprecato continua a essere supportato fino al rilascio successivo a supporto esteso. Altrimenti, i forum che lo utilizzano non avrebbero alcuna possibilità di vedere l’avviso prima che qualcosa vada a rotte.

La PR è stata fusa, quindi è deprecata:

Ma sì, come dice Moin, per il momento riceverai solo avvisi di deprecazione nella console del browser :slight_smile: Quando introduciamo per la prima volta una deprecazione, siamo obbligati a correggere tutte le istanze nel core, nei plugin e nei temi ufficiali. Successivamente, lasciamo la deprecazione attiva per un certo periodo, consentendo di correggere gradualmente i temi di terze parti, inclusi i temi dei clienti.

Questa non diventerà una rimozione permanente di user.groups per molto tempo, finché non saremo sicuri di aver individuato tutti i punti di chiamata. E anche in quel caso, inizieremo prima mostrando un avviso all’amministratore per i siti che hanno ancora codice che chiama il vecchio metodo.