Is it possible to resolve navigation outcome in order to validate it? - jsf-2

I've got a WebFilter that redirects to the login page in my application. In order to redirect back to the referring page I've also added a view parameter called redirectOnLogin which is then used on successful logins in order to perform the final navigation.
If one were to manipulate this query parameter, one could easily provoke JSF navigation errors. I would therefore like to pre-empt this by checking that the outcome is valid but I've not been able to uncover a mechanism for pre-validating a JSF outcome.

Easiest and best is to make sure the redirectToLogin parameter cannot be manipulated. Or that manipulation is detected.
You could solve this in (at least) two ways
Taking the original page name, adding a 'salt' to it and creating a hash.
Addin this has that in the request to the login server
Make sure it is returned by the login server (maybe adding it as # to the return page or as a param.
On receiving it on the 'redirectOnLogin' page, use the page name, the same salt and create a hash in the same way. Compare these and if they match you are fine, if they don't throw an error.
Or you could
Store the 'redirectOnLogin' page in a session to
Check on returning from the login server if it matches with the page you end-up on.

Related

URL: Include a parameter inside a destination query

I've searched a lot to try and solve this problem, but I'm not quite sure what to search for. I didn't really manage to find anything.
Essentially I'm working on a website in which users can register for an event. However, if the user is not logged in, I need to redirect them to the registration screen. This much I've been able to accomplish without much difficulty. However I need to redirect back to the event that they attempted to register for.
My real problem is that the URL of the page I need to return to contains an a parameter, and I'm not sure how to make the registration page take that parameter into account when it redirects back.
Currently when an anonymous user tries to go to
http://[...].com/drupal/?q=civicrm/event/register&id=6
I have it redirect you to
http://[...].com/drupal/?q=user/register&destination=civicrm/event/register&id=6
However, once the form is submitted the "&id=6" is not taken as part of the destination parameter, which means you just go to.
http://[...].com/drupal/?q=civicrm/event/register
Which is not a valid page.
Is there a way for me make the destination parameter include "&id=6"?
On a whim I've also tried.
[...]destination='civicrm/event/register&id=6'
[...]destination="civicrm/event/register&id=6"
[...]destination=civicrm/event/register#id=6
You need to url-encode the value for your destination. Try this:
[..]destination=civicrm/event/register%3Fid%3D6
%3F is hex code for question mark (?), %3D is code for equals (=).

Make a URL available only from within application

Say, I have a URL to edit a post .../posts/1/edit
I don't want this URL to navigate to a link when a user pastes it on his browser. However, if I have a link to this URL from within my application, the application should route to this URL.
Is it possible to achieve something like that?
I have no authentication system in the application.
I am just looking to see if there is an elegant solution to it. Else, I am sure I can find ways around. Thanks.
Use request.referer to get the page the user is coming from. This should allow you to achieve what you want. Note that this is not 100% reliable, sometimes the referer header might not be set. But in most cases it will work.
Alternatively, you can set a session variable that indicates whether the user is allowed (or not) to open a page (set a session variable on the main page with session[:allowed] = true, check its presence on the hidden page). When the user does not have a session variable set, render error or redirect to the main page (something like render :status=>403 and return unless session[:allowed]).
One of the easy ways would be send a unique header with the GET request and in the edit page, make sure you verify this header and only if it is present go ahead else throw a 401.
Ofcourse to make it much simpler, send a unique argument like /posts/1/edit?application="not-browser-1234"
and in edit page
if $_GET[application] != "not-browser-1234"
exit

grails registration page

I use grails and I have few registration pages.When user enter few textField values, with "Next" link user have to go to the other page....
After user entered all values data have to be saved.
My problem is that I do not know how to take one page's values from another.
What can I use(sessions, setter and getter methods...) to take all entered values in the last page?
I would recommend looking into Grails Web Flow
There are numerous ways to do it
1) Doing a post back, This will send all your form variables as part of HTTP request and you can then query the params to get the values
2) Grails has got a special artifact which is flash. Once you put anything in flash , its remains till the next request
3) You can use session to retain the values till the session does't expire
Hope that help

Symfony: question about a piece of code of sfDoctrineGuardPlugin

there is this code below in sfDoctrineGuardPlugin.
$a = sfConfig::get('app_sf_guard_plugin_success_signin_url');
var_dump($a);
$signinUrl = sfConfig::get('app_sf_guard_plugin_success_signin_url', $user->getReferer($request->getReferer()));
var_dump($signinUrl);
var_dump($user->getReferer($request->getReferer()));
It prints this:
null
string
'http://rs3.localhost/frontend_dev.php/'
(length=38)
string
'http://rs3.localhost/frontend_dev.php/miembros' (length=46)
I don't know why the the second and the third lines are different..any idea?
Regards
Javi
Weird. Spooky.
I wonder if maybe the two calls to getReferer() are in different contexts? Maybe the first (as the second arg to sfConfig::get()) implicitly uses __toString() whereas when you use var_dump(), maybe it's printing the raw value of the referer object?
Hrmm... the API says getReferer() returns a string, so that's probably not it.
What are you trying to do, BTW? Is it not honoring your app_sf_guard_plugin_success_signin_url setting from app.yml?
sfDoctrineGuardPlugin sets a referer attribute in the user, so that it can redirect back to the page originally requested. When you call getReferer it removes the attribute. (This is causing bugs for me, which is what brought me here.)
yitznewton pointed me towards a solution. The sfGuardSecurityUser class uses a method setReferer that saves a referer attribute but only if one is not yet set.
If somehow you manage to get to the executeSignin method in the sfGuard actions twice only the first referer attribute will be saved, this means that the second time the referer in the request and the referer in the user attribute can be different.
The getReferer method removes that attribute, and falls back to the request referer when the attribute is not set. this explains why calling $user->getReferer($request->getReferer()) twice returns different values sometimes.
The solution i found was to overwrite the setReferer method of the sfGuardSecurityUser in the myUser class:
public function setReferer($referer) {
$this->setAttribute('referer', $referer);
}
So far i have not found any side effects, this change ensures the user attribute will allways be the most recent, however there has to be a reason to explain why the symfony folk chose to implement this as it was.
Ive tested this by switching between apps on the login screen, allowing the session to die, killing the session manually and normally using the application and so far i have not found any side effects.

How do I make a "back" link?

I have a detail page that gets called from various places and has a nice readable url like
"www.mypage.com/product/best-product-ever".
The calling pages (list of products) have a more complex url like:
"www.mypage.com/offers/category/electronic/page/1/filter/manufacturer/sony/sort/price" and
"www.mypage.com/bestseller/this-week".
How can I make a backlink from the detailpage to the calling product list?
I cannot use javascript
I don't want to have the calling page in the URL, because it gets to long
I really want links between pages, no http-post
I cannot use Sessionstate
EDIT:
Sessionstate is ruled out, because if there are 2 Windows open, then they would share the same "Back" page information.
Like Lee said, use the referrer value:
Back
If you don't want the URL in the link because it's too long, try running some sort of simple compression algorithm over the URL, display the compressed data as unicode text and then append the compressed URL as a parameter to a redirect page, e.g:
Back
What about using the referrer header value?
Here's a crazy idea that will require a fair but of work and may not be healthy for performance (depending on your users).. but here we go:
Create a repository for caching 'ListResults' (and wire it to persist to the DB of you like.. or just leave it in memory on the server).
In short what this Repo can do is store a ListResult which will include everything to persist the state of the current view of the list any given user is looking at. This might include routes and other values.. but essentially everything that is needed to redirect back to that specific page of the filtered and sorted list.
As the ListResult item is added to the repo a small unique hash/key is generated that will be url friendly - something like this "k29shjk4" - it is added to the item along with a datetime stamp.
ListResults are only persisted from the moment a list gets off the default view (ie. no filtering, sorting and Page 1) - this will help in a small way for performance.
A ListResult item may never actually get used but all detail actionlinks on the particular list view have the ListResult.Key hash value added to the route. So yes, it might end up as a querystring but it will be short (url friendly) and if you wanna mess with routes more, you can tidy it up further.
For navigation "back" to the list, you may need a new small controller which accepts simply the ListResult.Key hash value and redirects/re-creates the state of the list view (paging, filtering and sorting included) from the lookup in the repo.
So we have met the requirements so far: no calling page in the url (in the sense that its not the whole page - just a hash lookup of it); no POSTing, no sessions, no js.
To stop the ListResult repo from getting to big (and dangerous: if you persist it to the DB), you can use a ASP.NET background service to periodically prune the 'old' routes by way of the timestamp.. and 'extend' the life of routes that are continuously being used by adding time to the stamp of a ListResult item when it's requested via the new controller. No need to persist a route indefinitely coz if a user wants a permalink to a list view, they can bookmark the long list route itself.
hope this helps somehow
Do you have a cookie?
If so, you can put it in there, or use it to create your own session state.
I think this is more like a "Back to results" then a generic "<< back" link, because you would expect the generic back link to return to the genetic list, not the heavily filtered list you described, right?
I don't know if this falls into your "no post" condition, but the only option I can see is having the Detail action be POST-only ([AcceptVerbs(HttpVerbs.Post)]) and include another parameter like string fullRoute which is converted to the 'link' on the detail page for "Back to results". Overload the Detail action missing the fullRoute param and have the overloaded action be a GET action so that the POST fullRoute value is not required (for when users are ok with the 'generic' "Back" link). This should serve both 'generic' GET requests to the Detail page and the POST request which will include the specific "Back to results" link for the filtered list.

Resources