Hi,
Two things:
> I must go through each component and the add a
> "disabled" attribute (only 130+ of them).
I presume you refer to your own custom components here.
This is what I would suggest: make your own base component class, say
SecureBaseComponent that extends BaseComponent.
In SecureBaseComponent implement the renderComponent() method in the
following way:
protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle) {
boolean render = ...; // some kind of a security condition,
// e.g. one depending on the component id, type,
// the page properties (<meta> in T4) etc.
if (render)
super.renderComponent(writer, cycle);
}
Have your component classes extend SecureBaseComponent rather than
BaseComponent.
I do not know the specifics of what you are doind, but that approach
will probably do what you want very quickly.
> This is going to take more time than I likely have and is a real pain
since
> I'll need to essentially wrap all of the basic Tapestry components
> (ProperSelection, Insert, DirectLink, PageLink, Submit, Button).
Implementing wrappers that make the basic components do what you want
(provide security, have help icons, log something, etc) is actually
quite easy.
Here is the wrapper of PropertySelection I just wrote with Spindle:
SecurePropertySelection.jwc:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE component-specification PUBLIC
"-//Apache Software Foundation//Tapestry Specification 3.0//EN"
"http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
<!-- generated by Spindle, http://spindle.sourceforge.net -->
<component-specification
class="org.mb.tapestry.test.SecurePropertySelection"
allow-body="yes"
allow-informal-parameters="yes">
<description>add a description</description>
<parameter name="value" type="java.lang.Object"/>
<parameter name="model"
type="org.apache.tapestry.form.IPropertySelectionModel"/>
<parameter name="renderer"
type="org.apache.tapestry.form.IPropertySelectionRenderer"/>
<parameter name="submitOnChange" type="boolean"/>
<parameter name="disabled" type="boolean"/>
<component id="propertySelection" type="PropertySelection"
inherit-informal-parameters="yes">
<inherited-binding name="model" parameter-name="model"/>
<inherited-binding name="value" parameter-name="value"/>
<inherited-binding name="renderer" parameter-name="renderer"/>
<inherited-binding name="submitOnChange"
parameter-name="submitOnChange"/>
<inherited-binding name="disabled" parameter-name="disabled"/>
</component>
</component-specification>
SecurePropertySelection.html:
<span jwcid="@Conditional" condition="ognl: render">
<span jwcid="propertySelection"/>
</span>
SecurePropertySelection.java:
package org.mb.tapestry.test;
import org.apache.tapestry.BaseComponent;
public abstract class SecurePropertySelection extends BaseComponent {
public boolean getRender() {
...
}
}
The above code took me less than 3 minutes to write (I timed it). I
presume the time would be less for other components with less parameters.
You could of course have in the JWC instead:
class="...SecureBaseComponent"
That would eliminate the .java file completely and reduce the .html to
the simple:
<span jwcid="propertySelection"/>
In my opinion the ability to easily build new components and to wrap
existing ones quickly (typically with much more than just security) is a
rather significant advantage.
I hope those suggestions help.
-mb
RR wrote:
I've spent some time analyzing my concerns/requirements and Tapestry's
abilities. This is what I've come up with (please correct if I'm
wrong):
1. Components must be defined prior to render. Which means, you need
to have the "disabled" attribute/binding set to false on *every*
single component you want to protect, at build-time. It is a pain to
add a "binding" at run-time and highly discouraged.
(http://article.gmane.org/gmane.comp.java.tapestry.user/25209).
2. Tapestry is incapable of removing components at render time. You
don't have access to the DOM, you can't set a flag, I have not found
anything to enable this. I should clarify, this is the case for all
default Tapestry components OR you can sort of work around this by
wrapping the component in a Conditional component.
3. Tapestry default components do not allow render flags. In
conjunction with issue #2, you can't just set a flag informing
Tapestry to NOT render the component.
So, why does this pose a large issue for me? Because I have many pages
in which I now need to implement security by either
removing/not-rendering the component or adding/modifying the
"disabled" attribute. I cannot, out-of-the-box, do what I need with
Tapestry 3.1. I must go through each component and the add a
"disabled" attribute (only 130+ of them). I must choose to wrap the
components in Conditionals if I don't want them rendered. IMO, this is
a ton of work and really defeats the purpose of dynamic page
generation and server-side page manipulation. Perhaps this is part of
the general Tapestry paradigm, but I don't understand that paradigm
correctly (or not well enough), because this is quite frustrating.
The only acceptable solution (I've thus found) is to go through and
create wrapper components for each of the Tapestry components we're
using. I'll add a default "disabled" attribute that I can hose with at
run-time (so the designer doesn't have to add it specifically) and a
flag that determines whether the component should render. This is
going to take more time than I likely have and is a real pain since
I'll need to essentially wrap all of the basic Tapestry components
(ProperSelection, Insert, DirectLink, PageLink, Submit, Button).
On the other hand, JSF provides the convenience of both the ability to
update attributes (mutable map, getAttributes()) and set a render flag
(setRender()). What's prohibiting Tapestry's inclusion of the same
principles? Has no one else been disturbed because of these inherent
weaknesses?
Feedback and correction is appreciated.
On 9/2/05, Robert Zeigler <[EMAIL PROTECTED]> wrote:
I'll try to find the thread information.
What concerns me about the original poster's idea is the thought of
"removing" the component. Rendering or not rendering the component is
fine; that's "dynamic behavior". Adding or removing components at
runtime violates the idea of "static structure".
The thread subject was "programmatically adding a binding to a component".
Gmane:
http://article.gmane.org/gmane.comp.java.tapestry.user/25209
The thread was talking specifically about component bindings, but the
specific quote I was thinking of was:
"The various setter methods exist for the framework, you
should treat components as immutable."
This includes adding and removing components to the component at
runtime. Note that pages are just specialized components.
Again, the fundamental issue is not rendering vs. not rendering
components, but rather adding/removing the components. It sounded to me
like the original poster was wanting to do the latter.
The "requires role" component that you implemented sounds fine; this is
the sort of approach I was advocating.
Robert
LOCHART,DOUGLAS E wrote:
Robert,
I am interested in reading this HLS thread. I did a search but did not
find it. Could you possibly point me to the thread (dates, keywords to
search etc)
I would appreciate it.
The approach I took was to create a component (based on the Conditional
component) called RequiresRole. If the user logged in does not have the
role, the menu option/links etc are not visible. It works fine for me.
Maybe I am missing the point in "rendering of pages at runtime" but my
component is JUST LIKE Conditional so I do see what is the problem.
thanks
Doug
To be honest, personally, I don't think that approach is really going to
mix well with tapestry. As was mentioned by HLS in a recent thread, you
should consider pages at runtime as immutable. Removing elements will
prove problematic, I think.
An approach I used was to create a sort of "inRole" component. It takes
as parameters either a requisite permission name or an object for which
permission is required. It's essentially an "if" wrapper, but has the
advantage of centralizing the render-oriented permission logic to a single
component.
You could also create custom wrappers around any components. So you
could, for instance, create a "SecureTable" component which wraps a table
component, adds parameters related to permission checking, and
conditionally renders the component. Then you could use your SecureTable
just like table, and still have your dynamic behavior.... static
structure, dynamic behavior. :)
Robert
I'm wondering if anyone has impemented a security model that requires
dynamic (render-time) removal of certain HTML elements? And if so, how
hefty
was the work? I need to remove elements at render time based upon roles
and
rights and *do not* want to wrap all of the secure elements in
conditionals.
Rather, I'd wish to determine at render time the necessity of removing
certain elements and simply not render them.
TIA,
-RR-
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]