You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Sam Gendler <sg...@ideasculptor.com> on 2006/11/09 01:04:58 UTC

users want to load same page with different entities in parallel. How?

Say I have a page to edit an entity, and that includes a table
component. When the page is rendered, various bits of state about
components of the page are stored in the session, especially for the
table component, since it stores current page and various other things
in the session.

Now, my users want to bring up the EditObject page for an object with
id 1, then bring up the same page for an object with id 2 in a
different window.  Now they make some edits to object 1 based on
information visible in the entity 2 page.  When they click submit,
however, they will get a stale link exception (if they are lucky. If
they are unlucky, they could wind up making their changes to entity 2
instead of entity 1).

Is there any way to prevent this.  Multiple similar windows is
fundamental to the way my users want to work (of course, they didn't
tell me this until the app was all the way through testing and had
been released), and it appears as though Tapestry's persistence
mechanism makes it utterly impossible to provide, since I would need
some kind of mechanism that would ensure that all state about a page
were persisted to the client, rather than to the session, and I don't
have any way to do that for components that I don't control.  I could
rewrite every component I use which has persistent properties, I
guess, but that's a huge amount of work and code duplication.

I don't suppose there is some kind of undocumented method of
associating a unique id with a page instance so that all session
persistent data associated with the page were stored under a
page:uniqueId combination, preventing conflicts with other instances
of the same page.  Of course, then I need some way to clean the
session of state for a single instance, as well as for all instances
of a given page, and that method clearly doesn't exist in the API, so
I am concerned that this isn't possible at all.

I'm in tap 4.0 for now, but likely negotiating an upgrade to tap 4.1
in the near future.

While I'm at it, I haven't seen anyone complain about the inherent
security vulnerabilities that come along with client side persistence,
as implemented .  Storing the true or false values for every
conditional in a form as an (unsigned/unencrypted) hidden field is
just asking for a user to change an F to a T in order to gain access
to something they shouldn't.  It seems strange to me that the default
would be to store the state in the form, and you have to explicitly
request tapestry not to do so.  I'd love an override which would cause
tapestry to assume conditionals and iterations are volatile unless I
explicitly request otherwise.  To my mind, defaults should always be
the MORE secure option, and then on those conditions and iterations
which aren't at risk, set volatile to false.

But really, I want all client side persistence to include a hash of
the values (or encrypt them) so that we can automatically detect
malicious modifications on the part of a user.

--sam

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: users want to load same page with different entities in parallel. How?

Posted by Sam Gendler <sg...@ideasculptor.com>.
Yeah, it is easy to do it with session state that I control.  My
concern is purely with components that have their own persistent
fields, so I can't make them 'conversation-aware' without some amount
of hacking.  This bothers my sense of elegance.  Sure, it is doable,
especially since every tap components I have ever seen is open source,
but I sure don't want to have to do it.  Being able to associate all
session state with a conversation in the framework itself would be
fantastic, especially if the conversation id were part of the request
cycle, so it could be discovered automagically whenever anything is
persisted to the session.  The real trick then, of course, is to make
it simple to determine when a new conversation should be started vs
using a previously existing one.  At least in my app, however, it
would be acceptable to force users to click an 'edit in new window'
link in order to start a new conversation.  I'll have to look into
doing a persistence strategy like that.

--sam


On 11/8/06, Daniel Tabuenca <dt...@gmail.com> wrote:
> Storing data to the client is always an option but for larger amounts
> of data this becomes a problem due to large amount of data that needs
> to be encoded in the urls of every link or in hidden fields of a form.
>  I think what you are looking for is a way to scope the session data
> so that you can have separate threads referencing distinct data.
>
> If I recall correctly, this type of scope is not directly supported by
> tapestry natively as it is in other frameworks (like Jboss Seam for
> example). I find the "Conversation" strategy very useful and I
> implement it pretty easily yourself. What I do is I generate a numeric
> ConversationId at the beginning of a new wizard. I store this Id in a
> property with @Persist("client"). I then have a HashMap that is stored
> to the session and use this id as the key to store whatever data I
> need (for example storing a state object). You can then automate the
> retriaval of this state object from the session on each request by
> attaching a listener before the page begins to render. This has proven
> to work good at least for me.
>
> I'm sure you could also try to implement a new persistent scope in
> hivemind to somewhat automate this better and make it more clean. But
> this seemed easy enough to do that I didn't feel it necessary to go
> that far.
>
> I think it'd be really good if in the future such functionality was
> integrated into the framework. The idea is to have some way to easily
> delineate when the scope of a conversation starts/stops some method
> for expiring dead conversations and of course, allowing multiple
> independent concurrent conversations at the same time. Although I have
> never actually used it, I think Seam is based around the idea of
> contextual conversations and might serve as a good starting point for
> seeing this idea in action.
>
>
>
> On 11/8/06, Sam Gendler <sg...@ideasculptor.com> wrote:
> > ok, some investigation into the version of contrib:Table that comes
> > with tacos shows that you can specify that a table stores its
> > persistent state to the client on a page or app basis, so it would
> > appear that that is solved for the table component.  Are there other
> > components in the core libraries (tapestry, contrib, tacos) which have
> > persistent properties stored in the session?  If not, then I can just
> > modify my forms to store the entity id in the form (currently, I've
> > got them in a session state object) and force the correct entity to be
> > reloaded when the page is submitted and everything else should come
> > together with minimal fuss, I think.
> >
> > --sam
> >
> >
> > On 11/8/06, Sam Gendler <sg...@ideasculptor.com> wrote:
> > > Say I have a page to edit an entity, and that includes a table
> > > component. When the page is rendered, various bits of state about
> > > components of the page are stored in the session, especially for the
> > > table component, since it stores current page and various other things
> > > in the session.
> > >
> > > Now, my users want to bring up the EditObject page for an object with
> > > id 1, then bring up the same page for an object with id 2 in a
> > > different window.  Now they make some edits to object 1 based on
> > > information visible in the entity 2 page.  When they click submit,
> > > however, they will get a stale link exception (if they are lucky. If
> > > they are unlucky, they could wind up making their changes to entity 2
> > > instead of entity 1).
> > >
> > > Is there any way to prevent this.  Multiple similar windows is
> > > fundamental to the way my users want to work (of course, they didn't
> > > tell me this until the app was all the way through testing and had
> > > been released), and it appears as though Tapestry's persistence
> > > mechanism makes it utterly impossible to provide, since I would need
> > > some kind of mechanism that would ensure that all state about a page
> > > were persisted to the client, rather than to the session, and I don't
> > > have any way to do that for components that I don't control.  I could
> > > rewrite every component I use which has persistent properties, I
> > > guess, but that's a huge amount of work and code duplication.
> > >
> > > I don't suppose there is some kind of undocumented method of
> > > associating a unique id with a page instance so that all session
> > > persistent data associated with the page were stored under a
> > > page:uniqueId combination, preventing conflicts with other instances
> > > of the same page.  Of course, then I need some way to clean the
> > > session of state for a single instance, as well as for all instances
> > > of a given page, and that method clearly doesn't exist in the API, so
> > > I am concerned that this isn't possible at all.
> > >
> > > I'm in tap 4.0 for now, but likely negotiating an upgrade to tap 4.1
> > > in the near future.
> > >
> > > While I'm at it, I haven't seen anyone complain about the inherent
> > > security vulnerabilities that come along with client side persistence,
> > > as implemented .  Storing the true or false values for every
> > > conditional in a form as an (unsigned/unencrypted) hidden field is
> > > just asking for a user to change an F to a T in order to gain access
> > > to something they shouldn't.  It seems strange to me that the default
> > > would be to store the state in the form, and you have to explicitly
> > > request tapestry not to do so.  I'd love an override which would cause
> > > tapestry to assume conditionals and iterations are volatile unless I
> > > explicitly request otherwise.  To my mind, defaults should always be
> > > the MORE secure option, and then on those conditions and iterations
> > > which aren't at risk, set volatile to false.
> > >
> > > But really, I want all client side persistence to include a hash of
> > > the values (or encrypt them) so that we can automatically detect
> > > malicious modifications on the part of a user.
> > >
> > > --sam
> > >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> > For additional commands, e-mail: users-help@tapestry.apache.org
> >
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: users want to load same page with different entities in parallel. How?

Posted by Daniel Tabuenca <dt...@gmail.com>.
Storing data to the client is always an option but for larger amounts
of data this becomes a problem due to large amount of data that needs
to be encoded in the urls of every link or in hidden fields of a form.
 I think what you are looking for is a way to scope the session data
so that you can have separate threads referencing distinct data.

If I recall correctly, this type of scope is not directly supported by
tapestry natively as it is in other frameworks (like Jboss Seam for
example). I find the "Conversation" strategy very useful and I
implement it pretty easily yourself. What I do is I generate a numeric
ConversationId at the beginning of a new wizard. I store this Id in a
property with @Persist("client"). I then have a HashMap that is stored
to the session and use this id as the key to store whatever data I
need (for example storing a state object). You can then automate the
retriaval of this state object from the session on each request by
attaching a listener before the page begins to render. This has proven
to work good at least for me.

I'm sure you could also try to implement a new persistent scope in
hivemind to somewhat automate this better and make it more clean. But
this seemed easy enough to do that I didn't feel it necessary to go
that far.

I think it'd be really good if in the future such functionality was
integrated into the framework. The idea is to have some way to easily
delineate when the scope of a conversation starts/stops some method
for expiring dead conversations and of course, allowing multiple
independent concurrent conversations at the same time. Although I have
never actually used it, I think Seam is based around the idea of
contextual conversations and might serve as a good starting point for
seeing this idea in action.



On 11/8/06, Sam Gendler <sg...@ideasculptor.com> wrote:
> ok, some investigation into the version of contrib:Table that comes
> with tacos shows that you can specify that a table stores its
> persistent state to the client on a page or app basis, so it would
> appear that that is solved for the table component.  Are there other
> components in the core libraries (tapestry, contrib, tacos) which have
> persistent properties stored in the session?  If not, then I can just
> modify my forms to store the entity id in the form (currently, I've
> got them in a session state object) and force the correct entity to be
> reloaded when the page is submitted and everything else should come
> together with minimal fuss, I think.
>
> --sam
>
>
> On 11/8/06, Sam Gendler <sg...@ideasculptor.com> wrote:
> > Say I have a page to edit an entity, and that includes a table
> > component. When the page is rendered, various bits of state about
> > components of the page are stored in the session, especially for the
> > table component, since it stores current page and various other things
> > in the session.
> >
> > Now, my users want to bring up the EditObject page for an object with
> > id 1, then bring up the same page for an object with id 2 in a
> > different window.  Now they make some edits to object 1 based on
> > information visible in the entity 2 page.  When they click submit,
> > however, they will get a stale link exception (if they are lucky. If
> > they are unlucky, they could wind up making their changes to entity 2
> > instead of entity 1).
> >
> > Is there any way to prevent this.  Multiple similar windows is
> > fundamental to the way my users want to work (of course, they didn't
> > tell me this until the app was all the way through testing and had
> > been released), and it appears as though Tapestry's persistence
> > mechanism makes it utterly impossible to provide, since I would need
> > some kind of mechanism that would ensure that all state about a page
> > were persisted to the client, rather than to the session, and I don't
> > have any way to do that for components that I don't control.  I could
> > rewrite every component I use which has persistent properties, I
> > guess, but that's a huge amount of work and code duplication.
> >
> > I don't suppose there is some kind of undocumented method of
> > associating a unique id with a page instance so that all session
> > persistent data associated with the page were stored under a
> > page:uniqueId combination, preventing conflicts with other instances
> > of the same page.  Of course, then I need some way to clean the
> > session of state for a single instance, as well as for all instances
> > of a given page, and that method clearly doesn't exist in the API, so
> > I am concerned that this isn't possible at all.
> >
> > I'm in tap 4.0 for now, but likely negotiating an upgrade to tap 4.1
> > in the near future.
> >
> > While I'm at it, I haven't seen anyone complain about the inherent
> > security vulnerabilities that come along with client side persistence,
> > as implemented .  Storing the true or false values for every
> > conditional in a form as an (unsigned/unencrypted) hidden field is
> > just asking for a user to change an F to a T in order to gain access
> > to something they shouldn't.  It seems strange to me that the default
> > would be to store the state in the form, and you have to explicitly
> > request tapestry not to do so.  I'd love an override which would cause
> > tapestry to assume conditionals and iterations are volatile unless I
> > explicitly request otherwise.  To my mind, defaults should always be
> > the MORE secure option, and then on those conditions and iterations
> > which aren't at risk, set volatile to false.
> >
> > But really, I want all client side persistence to include a hash of
> > the values (or encrypt them) so that we can automatically detect
> > malicious modifications on the part of a user.
> >
> > --sam
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: users want to load same page with different entities in parallel. How?

Posted by Sam Gendler <sg...@ideasculptor.com>.
ok, some investigation into the version of contrib:Table that comes
with tacos shows that you can specify that a table stores its
persistent state to the client on a page or app basis, so it would
appear that that is solved for the table component.  Are there other
components in the core libraries (tapestry, contrib, tacos) which have
persistent properties stored in the session?  If not, then I can just
modify my forms to store the entity id in the form (currently, I've
got them in a session state object) and force the correct entity to be
reloaded when the page is submitted and everything else should come
together with minimal fuss, I think.

--sam


On 11/8/06, Sam Gendler <sg...@ideasculptor.com> wrote:
> Say I have a page to edit an entity, and that includes a table
> component. When the page is rendered, various bits of state about
> components of the page are stored in the session, especially for the
> table component, since it stores current page and various other things
> in the session.
>
> Now, my users want to bring up the EditObject page for an object with
> id 1, then bring up the same page for an object with id 2 in a
> different window.  Now they make some edits to object 1 based on
> information visible in the entity 2 page.  When they click submit,
> however, they will get a stale link exception (if they are lucky. If
> they are unlucky, they could wind up making their changes to entity 2
> instead of entity 1).
>
> Is there any way to prevent this.  Multiple similar windows is
> fundamental to the way my users want to work (of course, they didn't
> tell me this until the app was all the way through testing and had
> been released), and it appears as though Tapestry's persistence
> mechanism makes it utterly impossible to provide, since I would need
> some kind of mechanism that would ensure that all state about a page
> were persisted to the client, rather than to the session, and I don't
> have any way to do that for components that I don't control.  I could
> rewrite every component I use which has persistent properties, I
> guess, but that's a huge amount of work and code duplication.
>
> I don't suppose there is some kind of undocumented method of
> associating a unique id with a page instance so that all session
> persistent data associated with the page were stored under a
> page:uniqueId combination, preventing conflicts with other instances
> of the same page.  Of course, then I need some way to clean the
> session of state for a single instance, as well as for all instances
> of a given page, and that method clearly doesn't exist in the API, so
> I am concerned that this isn't possible at all.
>
> I'm in tap 4.0 for now, but likely negotiating an upgrade to tap 4.1
> in the near future.
>
> While I'm at it, I haven't seen anyone complain about the inherent
> security vulnerabilities that come along with client side persistence,
> as implemented .  Storing the true or false values for every
> conditional in a form as an (unsigned/unencrypted) hidden field is
> just asking for a user to change an F to a T in order to gain access
> to something they shouldn't.  It seems strange to me that the default
> would be to store the state in the form, and you have to explicitly
> request tapestry not to do so.  I'd love an override which would cause
> tapestry to assume conditionals and iterations are volatile unless I
> explicitly request otherwise.  To my mind, defaults should always be
> the MORE secure option, and then on those conditions and iterations
> which aren't at risk, set volatile to false.
>
> But really, I want all client side persistence to include a hash of
> the values (or encrypt them) so that we can automatically detect
> malicious modifications on the part of a user.
>
> --sam
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org