2
votes

I have a Sitecore 6.4 setup where an editor can click a button to generate a Word doc. I was adding the file to the media library and that was working fine. The editor would click the button in the content editor, the file was generated, media item was generated, then the content editor would show the new item in the media library and the editor could click the "download" button on the ribbon or the item to download it. However, my media library was getting unnecessarily filled up so I am trying to bypass the media library.

Instead of making the file in an arbitrary location as before, I am putting it in the temp directory like this:

wordOutputPath = Sitecore.IO.FileUtil.GetWorkFilename(Sitecore.Configuration.Settings.TempFolderPath, printItem.Name, ".docx");
File.Copy(wordTemplatePath, wordOutputPath);
        
WordprocessingDocument doc = WordprocessingDocument.Open(wordOutputPath, true);

After I "fill in" the file with content, I do this:

Sitecore.Context.ClientPage.ClientResponse.Download(wordFilePath);

Now if I am logged in as a Sitecore admin I get the browser's download dialog and can download the file. However, if I am logged in as a non-admin user, I get a little clicking and whirring, so to speak, and the file is generated, but the save file dialog never comes up in the browser. I can go in through the file system and see & open the Word doc, and it looks fine.

I found something in the Sitecore release notes for 6.6:

Released Sitecore CMS and DMS 6.6.0 rev. 130111 (6.6.0 Update-3)

[...]

Miscellaneous

Only Administrators were allowed to download files. (316774, 348557)

    This was a problem in several areas of the system, for example the Package Generator and the Export Language Wizard in the CMS. It also affected the Export Users Wizard in the ECM module.

So I tried using SecurityDisabler (no longer have the code handy) and UserSwitcher like this:

using (new Sitecore.Security.Accounts.UserSwitcher(Sitecore.Security.Accounts.User.FromName("sitecore\admin", false)))
                    {
                        Sitecore.Context.ClientPage.ClientResponse.Download(wordFilePath);
                    }

The IUSR and IIS_IUSRS accounts both have read, list & read/execute permissions on the temp folder and the individual files show read & read/execute permissions for those two accounts as well.

What can I do to allow non-admin users to download these files? Does the bug that was fixed in 6.6 have anything to do with it?

Thank you.

1
What is happening when a non-admin user clicks it? Is there an error message being displayed or logged? Also, have you checked Sitecore permissions for the items involved?Andrew Arnott
You best bet is to check the permissions as Andrew suggests. It can't be a permissions problem with the worker process user (IUSR, etc.) or the admin user wouldn't be able to touch it easier, so that's a dead end.Matt J.

1 Answers

0
votes

Calling Sitecore.Context.ClientPage.ClientResponse.Download() method will result in a Download command sent back to the Sitecore Client in the Web browser, which in turn will make a call back to the server to execute it. This will be why using a security switcher (or a security disabler for that matter) before calling the Sitecore.Context.ClientPage.ClientResponse.Download() method has no effect, as the admin only restriction is being applied to the download else where.

If you search through sitecore\shell directory in your webroot, you will find that there is a file called download.aspx. This should be the actual page the download request is sent to. This web form page inherits the Sitecore.Shell.DownloadPage class, so if you take a look at that class's implementation, you will find that the OnLoad method is implemented as such:

protected override void OnLoad(EventArgs e)
{
    Assert.ArgumentNotNull(e, "e");
    base.OnLoad(e);
    string fileHandle = StringUtil.GetString(new string[] { base.Request.QueryString["file"] });
    bool flag = false;
    string filename = FileHandle.GetFilename(fileHandle);
    if (!string.IsNullOrEmpty(filename))
    {
        fileHandle = filename;
        flag = true;
    }
    if (!string.IsNullOrEmpty(fileHandle))
    {
        if (MediaManager.IsMediaUrl(fileHandle))
        {
            this.DownloadMediaFile(fileHandle);
        }
        else if (fileHandle.IndexOf("id=", StringComparison.OrdinalIgnoreCase) >= 0)
        {
            this.DownloadMediaById(fileHandle);
        }
        else if (flag || Context.IsAdministrator)
        {
            this.DownloadFile(fileHandle);
        }
    }
}

As you can see, the last if block has an IsAdministrator check which would be where your non-admin users are getting blocked.

Although I haven't 100% verified that this is where the problem lies, the download restriction issue can be resolved, by creating a new class that inherits Sitecore.Shell.DownloadPage and overrides the OnLoad implementation with some extra security checks as required. I recommend that you don't remove the IsAdministrator check altogether as it is there for a good reason. Update the Inherits attribute in the download.aspx to make it use it instead.