Forum OpenACS Q&A: Re: Question about linking to other acs site nodes

Collapse
Posted by Gustaf Neumann on
As always, there are multiple ways to achieve this. A simple approach is the following:
  1. Add the following snippet to the form-field-procs within the namespace ::xowiki::formfield
      Class redirect -superclass text
      redirect instproc pretty_value {v} {
        return [[[my object] package_id] returnredirect $v]
      }
    
  2. Create a form with a single field of this type (if the field is called "r", add "r:redirect,required" to the form constraints).
  3. Create an instance of this form and enter the relative url of the redirection target.
  4. The redirect happens upon viewing the entry.
This way, one can use categories for organizing the associated form pages (e.g. to add it to your menues), one can provide labels, titles etc. like for other xowiki pages, the approach provides revisions etc. Furthermore, by using the form, one has a convenient form to enter/edit the redirection target.

i have used this approach before in another context and added it just now to xowiki in CVS head. I am not sure, how old your installation is, but this should work with fairly old versions of xowiki as well.

hope this helps

-gustaf neumann

Collapse
Posted by Richard Hamilton on
Gustaf,

It helps on so many levels, thank you.

It answers my immediate need, it also gives me greater insight into the way the whole framework fits together. I have just read the Developing Framework presentation and so this is just beginning to make sense to me.

I can see immediately that this would also be an excellent way to redirect to another xowiki instance that had been programmed as a custom application as per your showcases.

I am finally starting to wrap my head around this OO business!

Thank you very much.
Richard

Collapse
Posted by Richard Hamilton on
Gustaf,

I have added the snippet as above, re-started the server to source the new code, and created the form spec and filled-out the form constraints as follows:

{destination_url:redirect,required,label=Redirect to}
{menubar:select,optional,category_tree=Contents,label=Menu bar position}

Xowiki clearly recognises the new subclass because no error is thrown when I complete the form. But when I navigate to the new page, I am shown a simple two field page displaying the link I entered and the Menubar position field and value. These fields are greyed out as one might expect on a view page.

It seems to me that it is the:

return [[[my object] package_id] returnredirect $v]

...that is not working for some reason.

I want to redirect to an external link but I have tried a local one also with the same result.

What is pretty value? Is that the field label?

Sorry to have to ask again but stumped.

Richard

Collapse
Posted by Gustaf Neumann on
dear richard,

hmm, i have tried your example including the menubar, and it works as expected (http://alice.wu-wien.ac.at:8000/xowiki/de/Redirect-form). The problem looks like a version issue to me. i would recommend that you install for testing purposes on your site a second installation of OpenACS with the version of XoWiki from the cvs head.

-gustaf neumann

Collapse
Posted by Richard Hamilton on
Gustaf,

Thank you very much, I will try that now.

Just as a matter of interest, when I click the link above, all I see is the display version of the xowiki::Form, not a redirect or anything. Is that correct or do I need to register and log-in?

Regards
Richard

Collapse
Posted by Gustaf Neumann on
you should see the view-page of the form with a link "entries for this form" on its right lower border. If you click on the link, you see the instances (FormPages) of this form (current de:r1). If you view de:r1 you are redirected.

You should see this in the same way whether you are logged in or not.

Collapse
Posted by Richard Hamilton on
Oh goodness me - sorry to be thick!. Yes, I see that works perfectly. I have taked the code and put it in my installation and it doesn't so I'm sure you're right. I am installing a new OpenACS as we speak.

Just to save some time, has the data model changed recently? Could I just checkout a HEAD version of xowiki into the existing system tree (having made a copy of the old one!)?

Richard

Collapse
Posted by Gustaf Neumann on
Concerning updates in general: xowiki (as all other good openacs packages) takes care about data model changes etc. through the update scripts (and dependencies against other packages). so, replacing the files package folders will work ... but there are multiple paths.

The question is, what you want to do:
a) get a fresh installation of everything: not need to replace a single package, so everything resides in the new installation tree.

b) upgrade your existing installation: xowiki will ask you
to install some other packages as well, but will certainly care about updating the database if needed.

Getting a fresh installation from HEAD is often a good idea to try things out without having the need to update a running installation. I would recommend (a), and when you are happy with that, do (b) (after making a backup of the program files on disk and a backup of the database via database dump).

Collapse
Posted by Richard Hamilton on
Dear Gustaf,

A welcome end to a long but productive day! Thank you very much. I did as you suggested, and the same thing happened (or rather didn't happen!). After staring disbelievingly at your form definition for a good while, I realised my mistake. :-|

I had put the @vars@ into the form spec instead of the template. Conseqently, I assume the renderer was never called upon to do its job. I'm learning though, thanks to you!

Of course delighted with my working redirect, I replaced the internal link with a fully qualified external link only to find that ad_redirect chokes on external redirects.

Consequently, I apologise, but I now have to ask you what is the best way of implementing this is for links to non-local urls?

Richard

Collapse
Posted by Dave Bauer on
ad_returnredirect changed to a by default secure version in OpenACS 5.5 (I think.)

See: http://www.openacs.org/api-doc/proc-view?proc=ad_returnredirect

-allow_complete_url (boolean) (optional)
By default we disallow redirecting to urls outside the current host. This is based on the currently set host header or the host name in the config file if there is no host header. Set allow_complete_url if you are redirecting to a known safe external web site. This prevents redirecting to a site by URL query hacking.

Only use allow_complete_url on data from your database don't even pass unsanitized data from a URL or POST variable to that to prevent problems.

The error message is not really helpful.

error "Redirction to external hosts is not allowed."

It is allowed if the programmer specifically specifies it.

Collapse
Posted by Richard Hamilton on
Oh, thank you Dave. So...

Class redirect -superclass text
redirect instproc pretty_value {v} {
return [[[my object] package_id] returnredirect -allow_complete_url $v]
}

..in my subclassed object, and be careful who's allowed to use it! I'll give it a whirl.

How are you by the way, I hope you're well.

Regards,
Richard

Collapse
Posted by Richard Hamilton on
Oh dear, not so fast Ricky!

The redirector is using 'returnredirect' rather than 'ad_returnredirect'.

My foolish attempt to substitute ad_returnredirect resulted in:

"::882: unable to dispatch method 'ad_returnredirect'"

....because it clearly isn't a method!

Am I correct in thinking that 'returnredirect' is a method of the package object? It clearly doesn't accept the -allow_complete_url flag so for the time being I'm stumped again!

R.

Collapse
Posted by Dave Bauer on
It sounds like you are correct. Most likely returnredirect method should be updated to support that flag.
Collapse
Posted by Gustaf Neumann on
the "allow_complete_url" option is intentionally not included, since it is an evil security problem.

The point of using such forms is that one can enter easily links (or menu-entries in your case) without having to write HTML/CSS/JS .... this increased convenience is mostly for end-users, which are normally not aware of security implications, or which are so many, such that a site-wide-admin or a package-admin can't trust all of them. The evil part of redirects is that a user sees a link to a trusted site, but it might direct him to a maybe same-looking fake-site setup for a phishing attack.

So, supporting the flag by default is definitely not a good idea. One could add a parameter in the form definition to allow insecure redirects, but since the form-definitions are as well designed in a way that the user cannot break the system, this does not help, when end-users are allowed to enter/change forms. So a possible path is add a policy which specifies, who is allowed to enter insecure field definitions and extend the form-validator to check these.

but maybe, there are other solutions as well.

Collapse
Posted by Richard Hamilton on
Well of course you're absolutely right! The most obvious method is to put the link into the xowiki::formpage title field.

I have just tried this and it works fine. Much simpler. I suppose I expected html title entries to be disallowed. But on reflection, this represents less of a risk, because the xowiki instance can be set to only allow certain parties to add formpages, and with page level permissions set it could even be restricted to only formpages of class redirect.

Thank you Gustaf for your guidance.

Is that the best way to do it, or can anyone think of a better or more elegant alternative?

Regards
Richard

Collapse
Posted by Richard Hamilton on
Not so fast!! Whilst this worked fine on the current repository version, but the HEAD version that I checked-out yesterday converts tag characters such as the '<' to the &xx; code equivalent to prevent the entered value being used as HTML.

I therefore can't enter HTML into the xowiki::Formpage title field any more which prevents me using this to link from the menu.

I can't think of any other way of doing this from within xowiki itself, so my next plan is to recreate the redirector class previously discussed to redirect to a redirect.tcl in the site root that contains a call to ad_returnredirect.

This will be a double internal redirect which I am uncomfortable with.

Can anyone point me in the direction of a better way of doing this?

Regards
Richard

Collapse
Posted by Richard Hamilton on
In my previous post I mentioned creating a redirector class as per Gustaf's earlier instructions that links to a /redirect.tcl file that calls ad_returnredirect with the -allow_complete_url flag.

Whilst I think this will work ok I wonder if there is a better way than a double redirect.

Whilst thinking about the possibilities it ocurred to me that I could create a simple, standard xowiki::page that has an adp include as its only content. The tcl file associated with that adp include could contain simply the ad_returnredirect call, so the template would never actually be returned, and control would never pass back to the calling xowiki object.

Can I do this safely? Can I be sure that all the processes will end, or will I end up with processes waiting indefinitely for return values?

R.

Collapse
Posted by Gustaf Neumann on
Richard, nobody hinders you to use on your site e.g.
  redirect instproc pretty_value {v} {
    ad_returnredirect -allow_complete_url $v
    ad_script_abort
  }
instead of the version based on the returnredirect method sketched earlier. However, i am not in favor of adding this variant to CVS because of the abuse potential. A good solution (see above) would require more effort than i can spend right now.

In case someone wonders, why my first version was using the returnredirect method rather than the ad_returnredirect function: The xo*-method be used outside of a connection thread while ad_returnredirect requires to be executed in a connection thread. Therefore, the method can be used safely e.g. in a regression test or in a scheduled procedure, etc. Allowing the title-field to contain HTML markup (which is rendered without escaping) must have been a bug in some earlier xowiki versions.

Collapse
Posted by Richard Hamilton on
Gustaf,

Thank you for taking the time to explain. I am working through the xotcl documentation and examples so hopefully I will be less clueless in the future! :-)

Regards
Richard