Les ACL et les Contrôleurs
Tout d'abord: ce sont des choses différentes / couches le plus souvent. Comme vous le critiquer les exemplaires code du contrôleur, il met les deux ensemble - le plus évidemment trop serré.
tereško déjà décrites d'une manière dont on pourrait dissocier ce plus avec le décorateur modèle.
Je ferais un pas en arrière, d'abord à chercher l'origine du problème auquel vous êtes confronté et d'en discuter un peu, puis.
D'une part, vous voulez avoir les contrôleurs de juste faire le travail qu'ils commandé (commande ou action, appelons ça de la commande).
D'autre part, vous voulez être en mesure de mettre des ACL dans votre application. Le domaine de travail de ces listes doit être - si j'ai bien compris votre question de droit de contrôler l'accès à certaines commandes de vos applications.
Ce type de contrôle d'accès a donc besoin de quelque chose d'autre qui rapproche ces deux ensemble. Basé sur le contexte dans lequel une commande est exécutée dans, ACL de coups de pied dans les décisions doivent être fait si ou non d'une commande peut être exécutée par un sujet particulier (par exemple l'utilisateur).
Résumons à ce point ce que nous avons:
- Commande
- ACL
- L'utilisateur
Le composant ACL est ici une place centrale: Il doit au moins savoir quelque chose au sujet de la commande (pour identifier la commande pour être précis) et il doit être en mesure d'identifier l'utilisateur. Les utilisateurs sont normalement facilement identifié par un ID unique. Mais souvent dans les applications il y a des utilisateurs qui ne sont pas identifiés, souvent appelé invité, anonyme, tout le monde etc.. Pour cet exemple, nous supposons que l'ACL peut consommer un objet utilisateur et encapsuler ces détails loin. L'utilisateur de l'objet est lié à la demande d'application de l'objet et de l'ACL peut consommer.
Ce sujet de l'identification d'une commande? Votre interprétation du modèle MVC suggère qu'une commande est composé d'un nom de classe et un nom de méthode. Si nous regardons de plus près il y a même des arguments (paramètres) pour une commande. Donc c'est valable pour demander ce qu'est exactement identifie une commande? Le nom de la classe, le methodname, le numéro ou le nom des arguments, même les données à l'intérieur des arguments ou un mélange de tout cela?
Selon le niveau de détail dont vous avez besoin pour identifier une commande dans votre ACL pratiquent, cela peut varier beaucoup. Pour l'exemple, nous allons le garder simplement et de préciser qu'une commande est identifiée par le nom de la classe et le nom de la méthode.
De sorte que le contexte de la façon dont ces trois parties (ACL, de Commande et de l'Utilisateur) appartiennent les uns aux autres est maintenant plus clair.
On pourrait dire, avec un imaginaire ACL compontent on peut déjà faire le suivant:
$acl->commandAllowedForUser($command, $user);
Juste à voir ce qui est happeninig ici: En faisant à la fois le commandement et l'utilisateur identifiable, de l'ACL peut faire, c'est le travail. Le travail de l'ACL est sans rapport avec le travail de l'utilisateur de l'objet et le béton de commande.
Il y a une seule chose qui manque, ce ne peut pas vivre dans l'air. Et il ne le fait pas. Si vous avez besoin de localiser l'endroit où le contrôle d'accès doit coup de pied dans. Jetons un coup d'oeil ce qui se passe dans une norme webapplication:
User -> Browser -> Request (HTTP)
-> Request (Command) -> Action (Command) -> Response (Command)
-> Response(HTTP) -> Browser -> User
Pour localiser ce lieu, nous savons que cela doit être avant que la commande est exécutée, de sorte que nous pouvons réduire la liste, puis seulement besoin de regarder dans la suite (potentiel) des lieux:
User -> Browser -> Request (HTTP)
-> Request (Command)
À un certain moment dans votre application, vous savez qu'un utilisateur a demandé de réaliser un béton de commande. Vous faites déjà une sorte d'ACL avec ici: Si un utilisateur demande une commande qui n'existe pas, vous ne laissez pas que la commande à exécuter. Alors, où jamais qui se passe dans votre application pourrait être un bon endroit pour ajouter le "réel" ACL vérifie:
La commande a été localisé et que nous pouvons créer l'identification de celui-ci afin de l'ACL peut traiter avec elle. Dans le cas où la commande n'est pas autorisé pour un utilisateur, la commande ne sera pas exécutée (action). Peut-être un CommandNotAllowedResponse
, au lieu de l' CommandNotFoundResponse
pour les cas une demande ne peut pas être résolu sur un béton de commande.
L'endroit où la cartographie d'un béton HTTPRequest est mappée sur une commande est souvent appelé Routage. Comme le Routage a déjà le travail pour repérer une commande, pourquoi ne pas l'étendre à vérifier si la commande est effectivement autorisé par l'ACL? E. g. par l'extension de l' Router
d'une ACL conscient routeur: RouterACL
. Si votre routeur ne connaissent pas encore l' User
, puis l' Router
n'est pas le bon endroit, parce que pour l'ACL qui pratiquent non seulement la commande, mais aussi l'utilisateur doit être identifié. Si ce lieu peut varier, mais je suis sûr que vous pouvez facilement localiser l'endroit où vous devez étendre, parce que c'est l'endroit capable de réaliser l'utilisateur et la commande exigence:
User -> Browser -> Request (HTTP)
-> Request (Command)
L'utilisateur est disponible depuis le début, d'abord la Commande avec Request(Command)
.
Ainsi, au lieu de mettre votre ACL contrôles à l'intérieur de chaque commande de la mise en œuvre concrète, vous la placez à l'avant. Vous n'avez pas besoin de lourdes modèles, de la magie, ou que ce soit, l'ACL-t-il son travail, l'utilisateur t-il son travail et surtout de la commande-t-il son emploi: il suffit de la commande, rien d'autre. La commande n'a aucun intérêt à savoir si ou de ne pas les rôles s'appliquer à elle, si c'est gardée quelque part ou pas.
Il suffit donc de garder les choses en dehors qui n'appartiennent pas les uns aux autres. Un peu la reformulation du Principe de Responsabilité Unique (SRP): Il devrait y avoir qu'une seule raison de changer une commande parce que la commande a changé. Non pas parce que vous présentez ACL pratiquent dans votre application. Non pas parce que vous passez l'Utilisateur de l'objet. Non pas parce que vous migrez à partir d'une adresse HTTP/HTML interface à un SAVON ou une interface de ligne de commande.
L'ACL dans votre cas, les contrôles de l'accès à une commande, pas la commande elle-même.