2013-02-13 8 views
13

Symfony ACL meiner Lehre Abfragen filtern kann mir Zugang zu einem Unternehmen gewähren, und dann überprüfen:Wie mit Symfony ACL

if (false === $securityContext->isGranted('EDIT', $comment)) { 
    throw new AccessDeniedException(); 
} 

Allerdings, wenn ich Tausende von Entitäten in der Datenbank habe und der Benutzer hat Ich möchte nur auf 10 von ihnen zugreifen, ich möchte nicht alle Elemente im Speicher laden und sie hydratisieren.

Wie kann ich eine einfache "SELECT * FROM X" machen, während nur die Entitäten gefiltert werden, auf die der Benutzer Zugriff hat (auf SQL-Ebene)?

+1

Haben Sie diese SO Antwort angeschaut? http://stackoverflow.com/questions/9652755/best-way-to-manage-user-group-object-permissions-with-symfony2 –

+0

Haben Sie versucht, [createQuery] (http: //docs.doctrine-project .org/de/latest/reference/dql-document-abfrage-sprache.html # dql-select-klausel) methode? –

Antwort

3

Nun, es ist es: ist es nicht möglich.

Im letzten Jahr habe ich an einem alternativen ACL-System gearbeitet, das es erlauben würde, direkt in Datenbankabfragen zu filtern.

Meine Firma vor kurzer Quelle zu öffnen vereinbart es, so ist es hier: http://myclabs.github.io/ACL/

+1

Es gibt jedoch eine Problemumgehung. Man kann den ACE für eine SecurityIdentity und die UserSecurityIdentity auflisten und dann die WHERE-Klausel in die Abfrage einfügen, ohne sich zu verbinden, nur die IDs. – gregor

+0

Ja, aber das ist eine Abfrage wie 'WHERE ID IN (1, 2, 3, ...)', die (wenn sie viele IDs erhalten) sehr ineffizient wäre :(Aber du hast Recht, das ist erwähnenswert. Auch das wäre 2 DB-Abfragen statt einer (mit einem JOIN). –

+0

nicht wahr, WHERE IN() sollte schnell sein - http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#function_in Das Limit für die Anzahl der IDs hängt von der zulässigen Größe des Abfragepakets ab, die standardmäßig 16 MB (auf 1 GB erweiterbar) beträgt, genug für mindestens 1 Mio. IDS in der Abfrage (denke ich.) Die Anzahl der Abfragen hängt davon ab, wo Sie speichern die ACL-Regeln - könnten in einer Datei oder Memcached sein - also 1 Abfrage alle zusammen – gregor

-1

Sie könnten einen Blick in die Doctrine filters werfen. Auf diese Weise können Sie alle Abfragen erweitern. Ich habe das noch nicht gemacht und es sind einige Einschränkungen dokumentiert. Aber vielleicht hilft es dir. Sie finden eine Beschreibung der ACL-Datenbanktabellen here.

UPDATE

Jeder Filter wird eine Zeichenfolge zurück, und alle werden diese Zeichenfolgen in SQL-Abfragen wie so hinzugefügt werden:

der Filtermethode
SELECT ... FROM ... WHERE ... AND (<result of filter 1> AND <result of filter 2> ...) 

Auch der Tabelle alias geführt wird. Ich denke, Sie können hier Unterabfragen hinzufügen, um Ihre Entitäten zu filtern.

+2

Danke für deine Antwort, ich habe es nicht gesehen. Doctrine-Filter helfen nicht, weil sie nicht erlauben, mit einer Tabelle zu verbinden, sie erlauben nur das Hinzufügen von SQL in der WHERE-Klausel. –

0

Wie @gregor in der vorangegangenen Diskussion,

In Ihrer ersten Abfrage ausgeführt hat, eine Liste erhalten (mit einem benutzerdefinierten Abfrage) aller object_identity_ids (für eine bestimmte Entität/Klasse X), auf die ein Benutzer Zugriff hat.

Wenn Sie dann eine Liste von Objekten für Entität/Klasse X abfragen, fügen Sie "IN (object_identity_ids)" zu Ihrer Abfrage hinzu.

Matthieu, ich war nicht zufrieden mit mehr von Vermutungen zu antworten (da meine Vermutungen nichts Wertvolles zum Gespräch hinzufügen). So Ich habe einige Bench-Kennzeichnung auf diesem Ansatz (Digital Ocean 5 $/mo VPS).

Benchmark

Wie erwartet, hat Tabellengröße keine Rolle, wenn die Array-Ansatz verwendet wird. Aber eine große Array-Größe lässt die Dinge außer Kontrolle geraten.

So, Join approach vs IN array approach?

JOIN ist in der Tat besser, wenn die Array-Größe riesig ist. ABER, das geht davon aus, dass wir die Tabellengröße nicht berücksichtigen sollten. Stellt sich heraus, in der Praxis IN-Array ist schneller - außer wenn es eine große Tabelle von Objekten und die ACL-Einträge fast jedes Objekt abdecken (siehe die verknüpfte Frage).

Ich habe meine Überlegungen zu einer separaten Frage erweitert.Bitte sehen Sie When using Symfony's ACL, is it better to use a JOIN query or an IN array query?