Benutzerrechte für Teil eines Seitenbaumes


(Jörg Käseberg) #1

Hallo.

leider finden wir keine Lösung, um folgende Aufgabenstellung umzusetzen. Vielleicht hat jemand einen Tipp.

  • root
    • Seite 1
    • Seite 2
      • Seite 2.1
      • Seite 2.2
    • Seite 3

Wir benötigen einen Benutzer, der nach der Anmeldung nur ‘Seite 2’ und Unterseiten sieht und bearbeiten kann.

Mit TYPO3 wäre das eine Sache von 5 Minuten. Bei einer Suche hier im Forum trifft man schon auf die Fragestellung, aber dort wird nur auf die Doku verwiesen. Damit haben wir aber auch schon alles probiert.

Eine Beispielkonfiguration für diesen “kleinen” Anwendungsfall wäre super.

Vielen Dank schon mal im voraus.

Jörg


(Niklas Droste) #2

Hallo Jörg,

das sollte eigentlich gar kein Problem sein. Ich hab hier mal ein kleines Snippet für deine Policy.yaml:

privilegeTargets:
  'Neos\Neos\Security\Authorization\Privilege\NodeTreePrivilege':
    'Vendor.Project:AccessSite2':
      matcher: 'isDescendantNodeOf("3f0bc644-4a48-11e9-8646-d663bd873d93")'

roles:
  'Vendor.Project:AccessSite2':
    privileges:
      -
        privilegeTarget: 'Vendor.Project:AccessSite2'
        permission: GRANT

Die UUID (3f0bc644-4a48-11e9-8646-d663bd873d93) ersetzt du dabei mit dem Identifier deiner Site2.
Anschließend sollte bei einem Editor ohne die neue Rolle “Seite 2” nicht mehr angezeigt werden.


(Jörg Käseberg) #3

Hallo Niklas,

vielen Dank für die schnelle Antwort.

Scheinbar verstehe ich das Grundprinzip nicht richtig: Dann müsste ich ja für diese Rolle alle anderen Seiten ausschließen, oder verstehe ich das falsch?

Jörg


(Niklas Droste) #4

Für ein Grundsätzliches Vertändnis, kannst du dir das hier einmal durchlesen: https://neos.readthedocs.io/en/stable/CreatingASite/Security.html

Ohne weiteres Setup sollten die Regeln schon grundsätzlich greifen. Sobald das privilegeTarget konfiguriert ist, sollte Neos ohne exaktes GRANT oder DENY auf ABSTAIN zurück fallen und die Node nicht anzeigen.

Hast du des mal mit dem Code versucht?


(Jörg Käseberg) #5

Ich habe es mit deinem Code versucht und folgendes Ergebnis:

Editor mit der neuen Rolle sieht alle Seiten:
root
Seite 1
Seite 2
Seite 2.1
Seite 2.2
Seite 3
Alle anderen Benutzer sehen alle Seiten außer Seite 2 und Unterseiten:

root
    Seite 1
    Seite 3

(Niklas Droste) #6

Wenn ich dich richtig verstehe, ist es doch das was du wolltest. Oder?


(Jörg Käseberg) #7

Nein, genau das möchte ich nicht.
Der Benutzer mit der neuen Rolle soll nur die Seite 2 mit allen Untersteiten sehen und bearbeiten können. Genauso hatte ich es auch schon in meinem initialen Post beschrieben.
Alle anderen Benutzer (insbesondere der Admin) soll immer alle Seiten sehen.

Vielen Dank für deine Geduld!

Jörg


(Sebastian Kurfuerst) #8

Hallo zusammen,

das Policy-Framework von Neos und Flow ist leider manchmal schwer zu verwenden - auch für mich :wink: Ich versuche hier mal, nicht einfach ne Lösung hinzuschreiben, sondern etwas detaillierter zu erklären wie es sich verhält.

tl;dr: Die gesamte Lösung ist im Beispiel für Regel 4 enthalten.

Regel 1: Alle Nodes, die NICHT von einem PrivilegeTarget gematcht werden, sind erlaubt

Beispiel: Ich darf alle Methoden aufrufen, wo es kein MethodPrivilege gibt, welches den Zugriff einschränkt.

Bei Method Privileges (Rechten auf Methodenaufrufe) lässt sich dies durch die Implementierung erklären: Für alle Methoden, welche von einem MethodPrivilege “erreicht” werden, generiert Flow Code à la:

public function myProtectedFunction() {
     checkUserIsAllowedToCallThisMethod();
     return parent::myProtectedFunction(); // call original function
}

Für alle anderen Methoden (wo es kein Privilege Target gibt), wird kein Proxy-Code generiert, das heißt die sind normal erlaubt.

Bei Nodes verhält es sich analog. Bezogen auf Nodes heißt das: Wenn ein Node von KEINEM Node Privilege Target gematcht wird, ist der Zugriff erlaubt.

Regel 2: Alle Nodes, die von einem Privilege Target gematcht werden, sind verboten

Wenn wir jetzt anfangen, ein Privilege Target zu definieren, dann ändern wir quasi den Default von “Erlauben”, auf “Verbieten”, es sei denn der Nutzer hat die entsprechende Rolle.

Als Beispiel:

privilegeTargets:
  'Neos\Neos\Security\Authorization\Privilege\EditNodePrivilege':
    'Vendor.Project:AllNodes':
      matcher: 'TRUE'

Nur durch dieses PrivilegeTarget (ohne Rollenzuweisung) wird dafür gesorgt, dass KEIN node im System editiert werden kann.

Regel 3: Immer mit GRANT arbeiten

Wenn ich bspw. nun dafür sorgen will, dass mein Administrator weiterhin alle Nodes bearbeiten kann, muss ich ihm das AllNodes privilege target zuweisen:

roles:
  'Vendor.Project:AccessSite2':
    privileges:
      -
        privilegeTarget: 'Vendor.Project:AllNodes'
        permission: GRANT

Hierbei eine Empfehlung: Bitte nicht mit DENY arbeiten, sondern immer nur mit GRANT.

Exkurs: Grant vs. Deny

Grant ist composable, d.h. wenn ich zwei PrivilegeTargets mit Grant erlaube, dann darf ich exakt das, was Privilege Target 1 erlaubt, plus das, was Privilege Target 2 erlaubt.

Wenn ich nun anfange, deny zu verwenden, kann ich aus meinem Set von erlaubten Privilege Targets wieder etwas “ausschneiden”, was “doch” verboten sein soll.

Sobald ich Deny verwende, ist meine Policy nicht mehr composable, da ein Deny immer “gewinnt”, ganz egal was ich noch an Grants habe.

Deny ist als escape hatch (letztes Mittel) gedacht, da man es manchmal zur Umsetzung besonders komplexer Regeln benötigt.

Regel 4: Wenn auf einen Node mehrere PrivilegeTargets zutreffen, ist der Zugriff erlaubt, sobald der Nutzer eines dieser PrivilegeTargets granted hat …

… Diese Regel gilt nur, wenn man kein deny verwendet (s.o.; composability).

Das bedeutet - jetzt kommen wir dem konkreten Use Case näher:

privilegeTargets:
  'Neos\Neos\Security\Authorization\Privilege\EditNodePrivilege':
    'Vendor.Project:AllNodes':
      matcher: 'TRUE'
    'Vendor.Project:AccessSite2':
      matcher: 'isDescendantNodeOf("3f0bc644-4a48-11e9-8646-d663bd873d93")'
roles:
  'Vendor.Project:AccessSite2':
    privileges:
      -
        privilegeTarget: 'Vendor.Project:AccessSite2'
        permission: GRANT
  'Neos.Neos:Administrator':
    privileges:
      -
        privilegeTarget: 'Vendor.Project:AllNodes'
        permission: GRANT

Was passiert nun hier?

  • durch die AllNodes Regel müssen für alle Nodes die Rechte explizit gesetzt werden.
  • wenn ich die Rolle Administrator habe, habe ich ein Recht auf alle Nodes
  • wenn ich die Rolle AccessSite2 habe, ist alles für mich verboten (wg. der AllNodes-Regel), außer dem Teilbaum, der durch AccessSite2 definiert ist - diese nodes sind erlaubt.

zusätzliche Problematik: Einschränken des Seitenbaumes

Es war ja gefordert, dass zusätzlich noch der Seitenbaum eingeschränkt werden soll auf den entsprechenden Teilbaum, den der Redakteur sehen kann.

Mit dem Recht von gerade eben sieht der Redakteur weiterhin den gesamten Baum, er darf aber nur noch in seinem Teilbaum editieren.

Wir haben zwar ein NodeTreePrivilege, mit dem Verhalten bin ich aber nicht so sehr happy: Dieses erbt nämlich von EditNodePrivilege, d.h. wenn ich eine Seite im Node Tree sehe, dann kann ich sie automatisch auch editieren.

IMHO ist das ein Thema, was wir im Core ändern müssen: Wir müssen zusätzlich ermöglichen, eine Seite im Seitenbaum readonly anzuzeigen - über einen extra privilege type.

Soweit ich weiß, ist es nämlich momentan nicht standardisiert möglich, den “Root”-Node des Seitenbaumes zu manipulieren, also zu sagen “bitte beginne an Seite X” mit dem Rendering.
Ich hatte dieses Verhalten mal auf der neos.io Seite gesehen, aber das ist IMHO kein standardisiertes Verhalten, auf das man sich verlassen sollte.

Da ich mir da nicht sicher bin, ob es hier eine gute Lösung gibt, habe ich die Frage selbst mal auf "Start Point" in the Neos Document Tree gestellt.

Closing Thoughts

Ich hoffe, diese Beschreibung hier hilft ein bisschen :slight_smile: :slight_smile: IMHO ist das Thema definitiv einer der Schwachpunkte von Neos. Das Policy Framework intern ist recht “low-level”, und für Endbenutzer und diese Common Cases wie den, den du beschrieben hast, leider etwas komplex.

Aus dem Grunde bin ich gerade auch dabei, ein Package zu schreiben, um diese Art von Einschränkungen auch per Backend Module zu machen. Ich kann da zeitlich noch nichts versprechen, aber wenn da jemand mithelfen will, das wäre super cool :slight_smile: (Einen Prototypen habe ich lokal schon, der zeigt dass das Package grundsätzlich funktioniert).

Hätte jemand Lust, die Inhalte aus diesem Post in https://docs.neos.io/cms/manual/permissions einfließen zu lassen? Das wäre super :slight_smile: (dann bitte hier oder im Slack in guild-documentation melden)

Viele Grüße,
Sebastian


(Jörg Käseberg) #9

Hallo Sebastian,

vielen Dank für die ausführliche Antwort!

Für mich bedeutet das jetzt, dass die Aufgabenstellung, wie oben beschrieben, aktuell mit Neos nicht zu lösen ist. Ich werde die weitere Entwicklung im Auge behalten.

Jörg


(Sebastian Kurfuerst) #10

Hey zusammen,

FYI - dank @chkoeppel ist das jetzt auch auf https://docs.neos.io/cms/manual/permissions/user-rights-in-page-tree beschrieben :slight_smile:

LG, Sebastian