Skeleton controllers
Moderator: General Moderators
-
alex.barylski
- DevNet Evangelist
- Posts: 6267
- Joined: Tue Dec 21, 2004 5:00 pm
- Location: Winnipeg
Skeleton controllers
I was going to ask arborint directly via PM but figured I'd post publically and see what came of it...
Anyway, a while back I recall arborint saying that in order to support forward'ing you simply inherit from a base controller class.
In my framework I handled this slightly differently. Instead my front controller essentially invokes the action and checks the return value and if the value is of instance Controller_Forward($controller, $action) the forward is handled by the front by calling a function recusively.
I'm curious what were the reasons behind forward'ing being done in a base class? Was this to support both page/front controller architecture?
Cheers,
Alex
Anyway, a while back I recall arborint saying that in order to support forward'ing you simply inherit from a base controller class.
In my framework I handled this slightly differently. Instead my front controller essentially invokes the action and checks the return value and if the value is of instance Controller_Forward($controller, $action) the forward is handled by the front by calling a function recusively.
I'm curious what were the reasons behind forward'ing being done in a base class? Was this to support both page/front controller architecture?
Cheers,
Alex
- Christopher
- Site Administrator
- Posts: 13596
- Joined: Wed Aug 25, 2004 7:54 pm
- Location: New York, NY, US
Re: Skeleton controllers
I'm not sure what I said, perhaps it was that an Action Controller base class could provide support for forwarding. Many frameworks provide a method and you do return $this->forward('foo'); In Skeleton you return an object from the dispatched method to tell the Front Controller to dispatch another action. The dispatch loop runs until there are no actions to dispatch. The Action Controller provide a forward() method for convenience.
(#10850)
-
alex.barylski
- DevNet Evangelist
- Posts: 6267
- Joined: Tue Dec 21, 2004 5:00 pm
- Location: Winnipeg
Re: Skeleton controllers
Yes, sorry man. I didn't mean that remark to interpreted verbatim, you very well could have had said something like that and I'm remembering wrong. You could have been refering to another framework. This was a few days (maybe a week) ago that I went digging through past messages, so this could have been said years ago for all I can remember. I don't really feel like digging through all those messages again.I'm not sure what I said, perhaps it was that an Action Controller base class could provide support for forwarding
So your front controller, implements a dispatch loop?
Assume that a base controller did handle forward'ing -- can you see any benefit to that?
Although my front has served me well for a couple years now, I have always had this sneaking suspicion about it's security. Let me ask you this...
Your front, does it invoke pre/post filters? If so are they re-invoked upon forward being called?
Mine are not and while I have yet to stumble upon a security issue I cannot help but feel this is a fundamental security flaw.
In theory, I can see someone invoking a controller:action which would run in an unauthorized environment, like say login form, however the problem I see, is that if that controller inadvertently forwarded to a more privileged controller:action, say delete users, then an attacker could effectively execute some nasty business.
On one hand, I think to myself: "Not going to happen, a forward wouldn't work that way"
And for the most part, this is true as I have yet to have a problem like this, but monitoring the actions and making sure the code never breaks this rule of thumb is just begging for human error -- Murphys Law?
The apparent simple solution is to re-invoke the pre/post filters on every forward, but the problem with doing that, is there are at times filters that if run twice in the same instance of a application would result in weird output or worse.
I can't think of any examples of the top of my head and all the standad examples would work fine (headers, HTML filtering, authorization, etc).
The work around would require each action to register it's own pre/post filters or possibly have each controller register it's pre/post filters because I believe that is where the problem came in.
So if forwarding was implemented via dispatch loop, how then do page controllers forward to external page controller actions?
Cheers,
Alex
- Christopher
- Site Administrator
- Posts: 13596
- Joined: Wed Aug 25, 2004 7:54 pm
- Location: New York, NY, US
Re: Skeleton controllers
YesPCSpectra wrote:Yes, sorry man. I didn't mean that remark to interpreted verbatim, you very well could have had said something like that and I'm remembering wrong. You could have been refering to another framework. This was a few days (maybe a week) ago that I went digging through past messages, so this could have been said years ago for all I can remember. I don't really feel like digging through all those messages again.I'm not sure what I said, perhaps it was that an Action Controller base class could provide support for forwarding
So your front controller, implements a dispatch loop?
Technically if a Action Controller "forwards" then it would really be dispatching as sub-Controller. I think of forward means exiting, but I may be mistaken.PCSpectra wrote:Assume that a base controller did handle forward'ing -- can you see any benefit to that?
I should note that the Skeleton Front Controller will dispatch any class -- no base Action Controller is required. There currently two Action Controller base classes. As simple one that provides some helper methods, and one that adds pre and post dispatch filters in the Action Controller.
Yes, Skeleton pre/post filters run every loop in the Front Contoroller;. I suppose that you could have a problem with some filter. I guess you'd just have to deal with that. Usually though you want them always to run because they are things like Access Control that need to be universally applied. You can always work around for edge cases.PCSpectra wrote:Although my front has served me well for a couple years now, I have always had this sneaking suspicion about it's security. Let me ask you this...
Your front, does it invoke pre/post filters? If so are they re-invoked upon forward being called?
Mine are not and while I have yet to stumble upon a security issue I cannot help but feel this is a fundamental security flaw.
In theory, I can see someone invoking a controller:action which would run in an unauthorized environment, like say login form, however the problem I see, is that if that controller inadvertently forwarded to a more privileged controller:action, say delete users, then an attacker could effectively execute some nasty business.
On one hand, I think to myself: "Not going to happen, a forward wouldn't work that way"
And for the most part, this is true as I have yet to have a problem like this, but monitoring the actions and making sure the code never breaks this rule of thumb is just begging for human error -- Murphys Law?
The apparent simple solution is to re-invoke the pre/post filters on every forward, but the problem with doing that, is there are at times filters that if run twice in the same instance of a application would result in weird output or worse.
I can't think of any examples of the top of my head and all the standad examples would work fine (headers, HTML filtering, authorization, etc).
The work around would require each action to register it's own pre/post filters or possibly have each controller register it's pre/post filters because I believe that is where the problem came in.
I assume that Page Controllers would dispatch a sub-Controller or redirect. Remember that for web applications that redirect and forward are similar. Redirect gets rid of back button problems. Forward maintains context between two Controllers.PCSpectra wrote:So if forwarding was implemented via dispatch loop, how then do page controllers forward to external page controller actions?
(#10850)
-
alex.barylski
- DevNet Evangelist
- Posts: 6267
- Joined: Tue Dec 21, 2004 5:00 pm
- Location: Winnipeg
Re: Skeleton controllers
Hmmm...I'm interested in hearing more as to why you chose to use a base class to handle pre/post filters? Did you encounter a security exploit as I descibed above and found this to be the more robust solution, or was this just how it fell into place?I should note that the Skeleton Front Controller will dispatch any class -- no base Action Controller is required. There currently two Action Controller base classes. As simple one that provides some helper methods, and one that adds pre and post dispatch filters in the Action Controller.
My bootstrap actually invoke the pre-filters on the front object, dispatch the action (recursively handling forwards) and then the boot again invokes the post filters. I think anyway, it's been a while and I just breifly peaked at the code to confirm this.
Access control is what has me questioning the design. I can't htink of any conceivable case where a non-privileged controller would forward un-knowingly to a more privileged controller, but the thing is, I should never have to worry about that as the design should be secure by default. Only running filters twice in one application instance, like I said, caused issues in the past. I think the work around might be to have each controller specify it's own filters, so it minimizes the chance of two filters colliding or being descrutive.Yes, Skeleton pre/post filters run every loop in the Front Contoroller;. I suppose that you could have a problem with some filter. I guess you'd just have to deal with that. Usually though you want them always to run because they are things like Access Control that need to be universally applied. You can always work around for edge cases.
Not sure I follow, can you show me a trivial example using both front and page as comparison?I assume that Page Controllers would dispatch a sub-Controller or redirect. Remember that for web applications that redirect and forward are similar. Redirect gets rid of back button problems. Forward maintains context between two Controllers.
-
snehalatha1912
- Forum Newbie
- Posts: 1
- Joined: Fri Feb 06, 2009 6:45 am
Re: Skeleton controllers
not sure
-
alex.barylski
- DevNet Evangelist
- Posts: 6267
- Joined: Tue Dec 21, 2004 5:00 pm
- Location: Winnipeg
Re: Skeleton controllers
^^^ Great reply
where did that come from? 
- Christopher
- Site Administrator
- Posts: 13596
- Joined: Wed Aug 25, 2004 7:54 pm
- Location: New York, NY, US
Re: Skeleton controllers
Just to be clear, I said that Skelton has the option of using one of the Action Controllers that has pre/post filters. This Action Controller allows the Action itself to specify the pre/post filters. The pre/post filters in the Front Controller are specified in the bootstrap.PCSpectra wrote:Hmmm...I'm interested in hearing more as to why you chose to use a base class to handle pre/post filters? Did you encounter a security exploit as I descibed above and found this to be the more robust solution, or was this just how it fell into place?
My bootstrap actually invoke the pre-filters on the front object, dispatch the action (recursively handling forwards) and then the boot again invokes the post filters. I think anyway, it's been a while and I just breifly peaked at the code to confirm this.
I think there is a greater chance of a programmer screwing up and un-knowingly forwarding to a more privileged controller than two filters colliding. And I don't see how the could be destructive.PCSpectra wrote:Access control is what has me questioning the design. I can't htink of any conceivable case where a non-privileged controller would forward un-knowingly to a more privileged controller, but the thing is, I should never have to worry about that as the design should be secure by default. Only running filters twice in one application instance, like I said, caused issues in the past. I think the work around might be to have each controller specify it's own filters, so it minimizes the chance of two filters colliding or being descrutive.
A Page Controller is not dispatched, so it really cannot forward. I guess you could wrap it in a dispatch loop just for forwarding. But then you are just implementing a Front Controller for every Page Controller?!? Hey ... that give me an idea on how to simplify these Page Controllers ...PCSpectra wrote:Not sure I follow, can you show me a trivial example using both front and page as comparison?
(#10850)
Re: Skeleton controllers
Generally its done the way arborint said from what I can tell, that way you have a nice "stack" of actions which is an object itself, then other parts of the framework can look at & manipulate that stack in a centralized way, instead of checking return values of actions & such. Implementation of chain of commands if you will.
Re: Skeleton controllers
Depends on what your filters do. If they manipulate request values (like undoing the magic_quotes) it wouldn't be great idea to run them twice. Another example might be gzipping the output - run it twice and no browser will understand the results.arborint wrote:I think there is a greater chance of a programmer screwing up and un-knowingly forwarding to a more privileged controller than two filters colliding. And I don't see how the could be destructive.
Re: Skeleton controllers
hah i didnt notice that, signed up just to share that with us. thats great. Also on the ACL topic I handle this with a dispatch plugin for the FC, so on each dispatched action it checks. If I forwarded to a controller that wasnt allowed I'd get forwarded to the errorController in my setupPCSpectra wrote:^^^ Great replywhere did that come from?
- Christopher
- Site Administrator
- Posts: 13596
- Joined: Wed Aug 25, 2004 7:54 pm
- Location: New York, NY, US
Re: Skeleton controllers
While I agree that there are possible problems with running filters on forwarded Actions, the problem would be rare and could be dealt with because these filters are optional and in your control.Weirdan wrote:Depends on what your filters do. If they manipulate request values (like undoing the magic_quotes) it wouldn't be great idea to run them twice. Another example might be gzipping the output - run it twice and no browser will understand the results.
You example of gzipping output is a good example of something that might cause a problem. It is also an example of something that I don't think should be done as a Action post-filter. That work should be done in a separate View/Response object because Controllers should not be messing with output. A framework that encourages doing this is encouraging bad practices in my opinion.
I really don't think that Controller filters would be the types of things that would have this problem. Conversely, useful Controller filters like Access Control probably should be run on every forwarded object.
(#10850)
Re: Skeleton controllers
I agree w/ the first point, but wanted to mention it could be done in a dispatchLoopShutdown ( Zend ontology ) plugin, meaning it would only 1x per request.arborint wrote:You example of gzipping output is a good example of something that might cause a problem. It is also an example of something that I don't think should be done as a Action post-filter. That work should be done in a separate View/Response object
-
alex.barylski
- DevNet Evangelist
- Posts: 6267
- Joined: Tue Dec 21, 2004 5:00 pm
- Location: Winnipeg
Re: Skeleton controllers
Interesting discussion, this is what I was hoping for. 
My filters are essentially 'for' request/response objects so maybe access control is best done in a base controller. I think we simply have different opinions on what filters should do.
Personally I want filters to be 'plug and play'. Removable without affecting the core system. Access control is not really something you want to be ever disable, so I think I was wrong in keeping that logic in a filter. Although that was a intentional decision as I wanted to disable access control completely for the demo's -- I probably should just have separate logins for demo'ing different roles.
While I don't agree compression should be done in View or Response objects, I suppose whether and where something is done really depends on your goals. I'm not sure what or how I would address this issue, but I think maybe inheriting privileged controllers from a authorization controller might be a solution.That work should be done in a separate View/Response object because Controllers should not be messing with output. A framework that encourages doing this is encouraging bad practices in my opinion.
My filters are essentially 'for' request/response objects so maybe access control is best done in a base controller. I think we simply have different opinions on what filters should do.
Personally I want filters to be 'plug and play'. Removable without affecting the core system. Access control is not really something you want to be ever disable, so I think I was wrong in keeping that logic in a filter. Although that was a intentional decision as I wanted to disable access control completely for the demo's -- I probably should just have separate logins for demo'ing different roles.
- Christopher
- Site Administrator
- Posts: 13596
- Joined: Wed Aug 25, 2004 7:54 pm
- Location: New York, NY, US
Re: Skeleton controllers
If it is just opinion then there is no help to be had. You will just listen to opinions and find one that matches yours.PCSpectra wrote:While I don't agree compression should be done in View or Response objects, I suppose whether and where something is done really depends on your goals.
...
My filters are essentially 'for' request/response objects so maybe access control is best done in a base controller. I think we simply have different opinions on what filters should do.
I think there actually is a reason why Controllers and Views should have different responsibilities. Because of that, I think there is much less chance -- by design -- that Front Controller filters would do anything problematic. That's because they would only be doing Controller stuff. To me that is just further validation of why they say that View/Controller separation in the Presentation layer is a good practice.
(#10850)