Unpublish Link/Button

Topics: Administration, Customizing Orchard
Jan 3, 2013 at 8:38 PM
Edited Jan 3, 2013 at 8:41 PM

I replied this same question on the Administration page, to an old post by someone else. Hoping to get some help from here as well. What I am trying to do is create an unpublish link in a content type, so that on my front end it has a way to unpublish an item.

My original plan was to just have the link as: 

<a href="http://server/Contents/Unpublish/{Content.Id}">Unpublish</a>

 

The problem is I get a 404 not found when I click it, or even try to go directly to the direct URL when copied from the admin menu, which is "http://server/Contents/Unpublish/1010?returnUrl=http%3A%2F%2Fserver%2FAdmin%2FContents%2FList"

The {Content.Id} does successfully obtain and fill out the Id correctly, so that is not the problem. Any help with this would be very much appreciated!

Jan 3, 2013 at 11:19 PM

Generally it is not a good practice to have a link which modifies something (delete, unpublish etc.) as there are various issues (search engines, users copying and pasting links, cross site scripting etc.).

For this reason it looks like the link is not actually being invoked when you click the link.

If you look at the network tab in Chrome developer tools you'll see that it's actually doing a post to that URL and including the __RequestVerificationToken form field.

Here's the code in /Core/Shapes/Scripts/base.js that is overriding the click event on links that have the itemprop attribute set to "UnsafeUrl":

 // UnsafeUrl links -> form POST
    //todo: need some real microdata support eventually (incl. revisiting usage of data-* attributes)
    $(function () {
        var magicToken = $("input[name=__RequestVerificationToken]").first();
        if (!magicToken) { return; } // no sense in continuing if form POSTS will fail
        $("a[itemprop~=UnsafeUrl]").each(function () {
            var _this = $(this);
            var hrefParts = _this.attr("href").split("?");
            var form = $("<form action=\"" + hrefParts[0] + "\" method=\"POST\" />");
            form.append(magicToken.clone());
            if (hrefParts.length > 1) {
                var queryParts = hrefParts[1].split("&");
                for (var i = 0; i < queryParts.length; i++) {
                    var queryPartKVP = queryParts[i].split("=");
                    //trusting hrefs in the page here
                    form.append($("<input type=\"hidden\" name=\"" + decodeURIComponent(queryPartKVP[0]) + "\" value=\"" + decodeURIComponent(queryPartKVP[1]) + "\" />"));
                }
            }
            form.css({ "position": "absolute", "left": "-9999em" });
            $("body").append(form);
            _this.click(function () {
                if (_this.filter("[itemprop~='RemoveUrl']").length == 1) {
                    if (!confirm(confirmRemoveMessage)) {
                        return false;
                    }
                }

                form.submit();
                return false;
            });
        });
    });

Jan 4, 2013 at 6:50 PM

Thanks for the input. This site is an intranet site that is requiring a domain account to even access that URL, so every person accessing this account is technically "authenticated" by Orchard using the Active Directory Authorization module. I can understand not wanting just non-authenticated users to alter site data, that would be a poor practice. I've already committed to not altering code to Orchard to get this to work, so if you or any others have a suggestion it'll be a great help. :)

Thanks again.

Jan 7, 2013 at 7:26 PM

Anyone with any ideas?

Jan 7, 2013 at 11:22 PM
Edited Jan 7, 2013 at 11:35 PM

Did some looking at the code mentioned above. I will admit I am not a coder, so please forgive if I am wrong entirely.

It would appear that the above javascript initially checks to see if you have the requested "magicToken". How is the token acquired? Is it something that is only acquired by being in the admin section of the site? If it currently is supposed to be acquired by just being logged in, I would think that the link to the unpublish should work.

If it is currently only acquired by being on the admin page, is there any thought into changing that?

Jan 11, 2013 at 6:43 PM

Ok so I placed the link directly in layout.cshtml file of TheAdmin theme and tested from there, still the same result. Can anyone help with this? I do not understand why this should not work even logged into the admin side of this site.

Coordinator
Jan 11, 2013 at 6:57 PM

There is a Html.ActionLink helper that is sure to give you the correct URL. Much better than building the URL yourself.