Mike Snare wrote:
I originally did use a base page, but decided against it for a number
of reasons.
The first is that nearly all pages in the app are protected (it's a
management app), so nearly every page would need to extend this base
class just to get this otherwise free feature. I don't really like
that.
I can tell tapestry that the default base page is this page, but then
pages that don't otherwise need a page class at all AND don't need the
security check have to create a page class that extends BasePage just
to avoid the security check. Seem pointless.
OK, I think I see your point. You have a lot of pages with no page
class(?). In the Tapestry app's I've developed so far, most pages tend
to need a class anyway (if not an individual class, at least an
app-specific base class), so marking them with a meta annotation or
having them extend the appropriate base class has never involved any
significant effort. In the relatively huge app I'm working on now, all
pages (except Login) are protected so my situation is probably similar
to yours.
If I had a significant number of pages that didn't need their own class,
I would use the default base page solution you referred to. The base
class approach would start to break down in the last scenario you
mentioned (pages that don't otherwise need a page class at all AND don't
need the security check have to create a page class that extends
BasePage just to avoid the security check). However, it doesn't sound
like your app falls into this category (you said nearly every page is
protected) and I've found that most apps are either primarily protected
or primarily unprotected, so there is always a logical default base
class. In addition, your anonymous pages don't need to have a class to
avoid the security check, they would only need a page spec with a meta tag.
Another issue is that of enforcement. If a developer needs to
implement the pageAttach method they need to remember to call
super.pageAttach first. Alternatively, I can make the pageAttach
method final in the base class to eliminate the potential security
bugs and redirect to a new method (say, realPageAttach) that needs to
be overridden by pages that need that callback -- except, again, for
those classes that don't need authentication, which should extend
directly from BasePage and implement PageAttachedListener and
implement the method themselves. Seems alot for people to have to
remember just to use the authentication features correctly.
pageAttach? Does pageValidate() not get invoked if pageAttach is
overridden? Since it's critical that pageValidate be invoked for my
authentication to function properly, I'm very interested in hearing
about this or any other pitfalls that would cause pageValidate to be
ignored.
Even if the logic exists in the base class, the callback issue remains
the same. Pages that want to be callbackable will have to implement
some method that I can call from the base class to get the parameter
array. That would lead to code of the following ilk, which seems odd
at the very least (if it will even work).
if (this instanceof IParamProvidingCallback) {
IParamProvidingCallback ppcb = (IParamProvidingCallback) this;
Obect[] params = ppcb.getParamArray();
// use my param array to create an ExternalCallback
}
Ouch - no, I wouldn't go for that. More like this (superclass for "view"
pages) :
public abstract class BaseViewPage extends AppBasePage implements
IExternalPage {
/**
* Gets the id of the item being viewed.
*
* @return item id
*/
@Persist
public abstract Integer getItemId();
/**
* Gets the callback for this page.
*
* @return callback for this page
*/
@Override
public ICallback getPageCallback() {
Object[] parameters = new Object[1];
parameters[0] = getItemId();
return new ExternalCallback( getPageName(), parameters );
}
}
Page subclasses can override getPageCallback() to include their specific
parameters and create the correct type of callback. With the service
interceptor approach, don't you still have to define callbacks per page
if you want specific parameters included and if you want specific types
of callbacks, or do you have generic solution that packages all page
parameters and figures out if it should create an External, Direct or
Page callback?
As to the duplication of hivemind configurations, there are 5 services
to which I am contributing an interceptor factory (by reference,
anyway) and there are significantly more pages that need protection.
I'm not really worried about *that* duplication.
If I can get callbacks to work with the fix that Jesse said he'll look
into (thanks again) than I see this as a significant improvement to
what people would look at as the 'standard' approach to authentication
for tapestry frameworks. It's a much, much better separation of
concerns.
Couldn't you make the same "seperation of concerns" argument for
performing authentication in the container via URL mapping? Seperating
concerns is well and good, but it's in line with modern security
practices to define security on the object being secured rather than at
a higher level (each approach has its advantages and disadvantages,
somewhat akin to RBAC vs MAC). Obviously the security monitor itself
should be separated from the objects being secured, but there's nothing
wrong with bringing the hooks down closer to the objects.
I appreciate the input, but the base page approach just isn't workable.
*cough*, well, it actually works just fine because it's been the
standard approach in Tapestry since at least 3.0 ;)
Anyway, I certainly don't *mind* having an alternate place to hook
authentication into Tapestry and I think a lot of people would agree
with you that it should be as seperate a concern as possible. I just
think that if you pursued a strategy using pageValidate, base classes
and normal, clean OO design, you wouldn't think the result was bad
practice or unworkable.
-Ryan
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]