Veraltete Verwendung von `user.groups` im `User`-Modell in JavaScript

Dies bezieht sich sowohl auf The road to stable, then permanent, for granular_anonymous_and_logged_in_groups_permissions als auch auf Granular group-based permissions for anonymous and logged in users

Im Kern sowie in vielen Themes und Plugins ist ein Muster wie dieses ziemlich verbreitet:

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

Dies ist jedoch keine effektive Methode, um die Berechtigungen eines Benutzers zu prüfen. Ein Benutzer kann Mitglied von Gruppen sein, die für ihn nicht sichtbar sind, daher werden diese nicht an den Client serialisiert und können nicht konsistent oder genau für Sicherheitsprüfungen verwendet werden.

Um dies deutlicher zu machen, benennen wir currentUser.groups/user.groups im User-Modell in currentUser.visibleGroups/user.visibleGroups um und kennzeichnen die alte Eigenschaft als veraltet. Der erste PR dafür ist DEV: Deprecate calling user.groups on client directly - Pull Request #42711 - discourse/discourse - GitHub .

Es gibt mehrere Alternativen, falls du auf dem Client in JavaScript die Berechtigung eines Benutzers basierend auf einer Liste von Gruppen-IDs prüfen musst:

Für Plugins

Erweitere den current_user-Serializer um ein neues Attribut und prüfe die Berechtigungen des Benutzers serverseitig mit scope.in_any_groups?, was auch Pseudogruppen wie logged_in_users und anonymous_users abdeckt:

add_to_serializer(
  :current_user,
  :has_some_permission,
  include_condition: -> do
    SiteSetting.plugin_enabled
  end,
) { scope.in_any_groups?(SiteSetting.group_list_setting_map) }

Danach kannst du auf dem Client this.currentUser.has_some_permission aufrufen.

Für Themes und Komponenten

Für Theme-Einstellungen vom Typ list mit list_type: group kannst du resolve_group_membership: true verwenden:

copy_button_allowed_groups:
  default: "1|3"
  type: list
  list_type: group
  resolve_group_membership: true

Dies ersetzt settings.copy_button_allowed_groups auf dem Client durch settings.user_in_copy_button_allowed_groups (mit dem Präfix user_in_), was ein boolescher Wert ist, der serverseitig basierend auf den Gruppenmitgliedschaften des Benutzers berechnet wird.

Dies funktioniert auch für Objekteinstellungen mit type: groups. Füge der groups-Eigenschaft resolve_group_membership: true hinzu:

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

Der Zugriff sieht dann so aus:

for (const section of settings.menu_sections) {
  if (section.user_in_groups) {
    // User is in at least one selected group for this section.
  }
}

Hi Martin,

Wann werden diese Änderungen wirksam – beim Mergen des PRs oder mit dem nächsten Update danach?

Warum ist das wichtig? Dadurch bricht nichts ab. Es wird lediglich eine Warnung in der Browser-Konsole angezeigt, die Entwickler darauf hinweist, ihren Code anzupassen.

Ich habe Theme-Komponenten, von denen ich weiß, dass sie sich darauf verlassen, und hätte gerne eine Klärung. Falls es sich nur um eine Warnung handelt und es vorerst noch funktioniert, bin ich weniger besorgt.

In der Regel wird veralteter Code noch bis zur nächsten erweiterten Support-Version unterstützt. Andernfalls hätten Foren, die ihn verwenden, keine Chance, die Warnung zu sehen, bevor etwas kaputtgeht.

Der PR wurde gerade gemerged, daher ist er nun veraltet:

Ja, wie Moin sagt, bekommst du vorerst nur Deprecation-Warnungen in der Browser-Konsole :slight_smile: Wenn wir eine Deprecation zum ersten Mal einführen, müssen wir zunächst alle Instanzen im Core sowie in offiziellen Plugins und Themes beheben. Danach lassen wir die Deprecation für eine Weile aktiv und können so schrittweise entweder selbst oder durch Dritte Third-Party-Themes, einschließlich Kunden-Themes, beheben.

Dies wird nicht so schnell zu einer endgültigen Entfernung von user.groups führen, bis wir sicher sind, dass wir alle Aufrufstellen erfasst haben. Selbst dann zeigen wir zunächst eine Warnung im Admin-Bereich für Sites an, die immer noch Code aufrufen, der die alte Methode verwendet.