webdav portal owa support check added

This commit is contained in:
vfedosevich 2015-02-04 02:01:46 -08:00
parent 5795ffb0bc
commit 010c258502
16 changed files with 246 additions and 20 deletions

View file

@ -0,0 +1,57 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using WebsitePanel.WebDav.Core.Config.WebConfigSections;
namespace WebsitePanel.WebDav.Core.Config.Entities
{
public class OwaSupportedBrowsersCollection : AbstractConfigCollection, IReadOnlyDictionary<string, int>
{
private readonly IDictionary<string, int> _browsers;
public OwaSupportedBrowsersCollection()
{
_browsers = ConfigSection.OwaSupportedBrowsers.Cast<OwaSupportedBrowsersElement>().ToDictionary(x => x.Browser, y => y.Version);
}
public IEnumerator<KeyValuePair<string, int>> GetEnumerator()
{
return _browsers.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public int Count
{
get { return _browsers.Count; }
}
public bool ContainsKey(string browser)
{
return _browsers.ContainsKey(browser);
}
public bool TryGetValue(string browser, out int version)
{
return _browsers.TryGetValue(browser, out version);
}
public int this[string browser]
{
get { return ContainsKey(browser) ? _browsers[browser] : 0; }
}
public IEnumerable<string> Keys
{
get { return _browsers.Keys; }
}
public IEnumerable<int> Values
{
get { return _browsers.Values; }
}
}
}

View file

@ -12,5 +12,6 @@ namespace WebsitePanel.WebDav.Core.Config
FileIconsDictionary FileIcons { get; } FileIconsDictionary FileIcons { get; }
HttpErrorsCollection HttpErrors { get; } HttpErrorsCollection HttpErrors { get; }
OfficeOnlineCollection OfficeOnline { get; } OfficeOnlineCollection OfficeOnline { get; }
OwaSupportedBrowsersCollection OwaSupportedBrowsers { get; }
} }
} }

View file

@ -0,0 +1,24 @@
using System.Configuration;
namespace WebsitePanel.WebDav.Core.Config.WebConfigSections
{
public class OwaSupportedBrowsersElement : ConfigurationElement
{
private const string BrowserKey = "browser";
private const string VersionKey = "version";
[ConfigurationProperty(BrowserKey, IsKey = true, IsRequired = true)]
public string Browser
{
get { return (string)this[BrowserKey]; }
set { this[BrowserKey] = value; }
}
[ConfigurationProperty(VersionKey, IsKey = true, IsRequired = true)]
public int Version
{
get { return (int)this[VersionKey]; }
set { this[VersionKey] = value; }
}
}
}

View file

@ -0,0 +1,18 @@
using System.Configuration;
namespace WebsitePanel.WebDav.Core.Config.WebConfigSections
{
[ConfigurationCollection(typeof(OwaSupportedBrowsersElement))]
public class OwaSupportedBrowsersElementCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new OwaSupportedBrowsersElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((OwaSupportedBrowsersElement)element).Browser;
}
}
}

View file

@ -15,6 +15,7 @@ namespace WebsitePanel.WebDavPortal.WebConfigSections
private const string ConnectionStringsKey = "appConnectionStrings"; private const string ConnectionStringsKey = "appConnectionStrings";
private const string SessionKeysKey = "sessionKeys"; private const string SessionKeysKey = "sessionKeys";
private const string FileIconsKey = "fileIcons"; private const string FileIconsKey = "fileIcons";
private const string OwaSupportedBrowsersKey = "owaSupportedBrowsers";
private const string OfficeOnlineKey = "officeOnline"; private const string OfficeOnlineKey = "officeOnline";
public const string SectionName = "webDavExplorerConfigurationSettings"; public const string SectionName = "webDavExplorerConfigurationSettings";
@ -75,6 +76,13 @@ namespace WebsitePanel.WebDavPortal.WebConfigSections
set { this[FileIconsKey] = value; } set { this[FileIconsKey] = value; }
} }
[ConfigurationProperty(OwaSupportedBrowsersKey, IsDefaultCollection = false)]
public OwaSupportedBrowsersElementCollection OwaSupportedBrowsers
{
get { return (OwaSupportedBrowsersElementCollection)this[OwaSupportedBrowsersKey]; }
set { this[OwaSupportedBrowsersKey] = value; }
}
[ConfigurationProperty(OfficeOnlineKey, IsDefaultCollection = false)] [ConfigurationProperty(OfficeOnlineKey, IsDefaultCollection = false)]
public OfficeOnlineElementCollection OfficeOnline public OfficeOnlineElementCollection OfficeOnline
{ {

View file

@ -18,6 +18,7 @@ namespace WebsitePanel.WebDav.Core.Config
FileIcons = new FileIconsDictionary(); FileIcons = new FileIconsDictionary();
HttpErrors = new HttpErrorsCollection(); HttpErrors = new HttpErrorsCollection();
OfficeOnline = new OfficeOnlineCollection(); OfficeOnline = new OfficeOnlineCollection();
OwaSupportedBrowsers = new OwaSupportedBrowsersCollection();
} }
public static WebDavAppConfigManager Instance public static WebDavAppConfigManager Instance
@ -51,5 +52,6 @@ namespace WebsitePanel.WebDav.Core.Config
public FileIconsDictionary FileIcons { get; private set; } public FileIconsDictionary FileIcons { get; private set; }
public HttpErrorsCollection HttpErrors { get; private set; } public HttpErrorsCollection HttpErrors { get; private set; }
public OfficeOnlineCollection OfficeOnline { get; private set; } public OfficeOnlineCollection OfficeOnline { get; private set; }
public OwaSupportedBrowsersCollection OwaSupportedBrowsers { get; private set; }
} }
} }

View file

@ -1,6 +1,8 @@
using System; using System;
using System.IO; using System.IO;
using System.Threading;
using Cobalt; using Cobalt;
using log4net;
using WebsitePanel.WebDav.Core.Interfaces.Managers; using WebsitePanel.WebDav.Core.Interfaces.Managers;
using WebsitePanel.WebDav.Core.Interfaces.Owa; using WebsitePanel.WebDav.Core.Interfaces.Owa;
@ -11,12 +13,16 @@ namespace WebsitePanel.WebDav.Core.Owa
private readonly IWebDavManager _webDavManager; private readonly IWebDavManager _webDavManager;
private readonly IWopiFileManager _fileManager; private readonly IWopiFileManager _fileManager;
private readonly IAccessTokenManager _tokenManager; private readonly IAccessTokenManager _tokenManager;
private readonly ILog Log;
public CobaltManager(IWebDavManager webDavManager, IWopiFileManager fileManager, IAccessTokenManager tokenManager) public CobaltManager(IWebDavManager webDavManager, IWopiFileManager fileManager,
IAccessTokenManager tokenManager)
{ {
_webDavManager = webDavManager; _webDavManager = webDavManager;
_fileManager = fileManager; _fileManager = fileManager;
_tokenManager = tokenManager; _tokenManager = tokenManager;
Log = LogManager.GetLogger(this.GetType());
} }
public Atom ProcessRequest(int accessTokenId, Stream requestStream) public Atom ProcessRequest(int accessTokenId, Stream requestStream)
@ -27,30 +33,69 @@ namespace WebsitePanel.WebDav.Core.Owa
var requestBatch = new RequestBatch(); var requestBatch = new RequestBatch();
var cobaltFile = _fileManager.Get(token.FilePath) ?? _fileManager.Create(accessTokenId); try
Object ctx;
ProtocolVersion protocolVersion;
requestBatch.DeserializeInputFromProtocol(atomRequest, out ctx, out protocolVersion);
cobaltFile.CobaltEndpoint.ExecuteRequestBatch(requestBatch);
foreach (var request in requestBatch.Requests)
{ {
if (request.GetType() == typeof(PutChangesRequest) && request.PartitionId == FilePartitionId.Content && request.CompletedSuccessfully) var cobaltFile = _fileManager.Get(token.FilePath) ?? _fileManager.Create(accessTokenId);
{
using (var saveStream = new MemoryStream())
{
GenericFdaStream myCobaltStream = new GenericFda(cobaltFile.CobaltEndpoint, null).GetContentStream();
myCobaltStream.CopyTo(saveStream);
_webDavManager.UploadFile(token.FilePath, saveStream.ToArray()); Object ctx;
ProtocolVersion protocolVersion;
requestBatch.DeserializeInputFromProtocol(atomRequest, out ctx, out protocolVersion);
cobaltFile.CobaltEndpoint.ExecuteRequestBatch(requestBatch);
foreach (var request in requestBatch.Requests)
{
if (request.GetType() == typeof (PutChangesRequest) &&
request.PartitionId == FilePartitionId.Content && request.CompletedSuccessfully)
{
using (var saveStream = new MemoryStream())
{
CopyStream(cobaltFile, saveStream);
_webDavManager.UploadFile(token.FilePath, saveStream.ToArray());
}
} }
} }
return requestBatch.SerializeOutputToProtocol(protocolVersion);
} }
return requestBatch.SerializeOutputToProtocol(protocolVersion); catch (Exception e)
{
Log.Error("Cobalt manager Process request", e);
throw;
}
}
private void CopyStream(CobaltFile file, Stream stream)
{
var tries = 3;
for (int i = 0; i < tries; i++)
{
try
{
GenericFdaStream myCobaltStream = new GenericFda(file.CobaltEndpoint, null).GetContentStream();
myCobaltStream.CopyTo(stream);
break;
}
catch (Exception)
{
//unable to read update - save failed
if (i == tries - 1)
{
throw;
}
//waiting for cobalt completion
Thread.Sleep(50);
}
}
} }
} }
} }

View file

@ -104,6 +104,7 @@
<Compile Include="Config\Entities\FileIconsDictionary.cs" /> <Compile Include="Config\Entities\FileIconsDictionary.cs" />
<Compile Include="Config\Entities\HttpErrorsCollection.cs" /> <Compile Include="Config\Entities\HttpErrorsCollection.cs" />
<Compile Include="Config\Entities\OfficeOnlineCollection.cs" /> <Compile Include="Config\Entities\OfficeOnlineCollection.cs" />
<Compile Include="Config\Entities\OwaSupportedBrowsersCollection.cs" />
<Compile Include="Config\Entities\SessionKeysCollection.cs" /> <Compile Include="Config\Entities\SessionKeysCollection.cs" />
<Compile Include="Config\Entities\WebsitePanelConstantUserParameters.cs" /> <Compile Include="Config\Entities\WebsitePanelConstantUserParameters.cs" />
<Compile Include="Config\IWebDavAppConfig.cs" /> <Compile Include="Config\IWebDavAppConfig.cs" />
@ -114,6 +115,8 @@
<Compile Include="Config\WebConfigSections\FileIconsElementCollection.cs" /> <Compile Include="Config\WebConfigSections\FileIconsElementCollection.cs" />
<Compile Include="Config\WebConfigSections\OfficeOnlineElement.cs" /> <Compile Include="Config\WebConfigSections\OfficeOnlineElement.cs" />
<Compile Include="Config\WebConfigSections\OfficeOnlineElementCollection.cs" /> <Compile Include="Config\WebConfigSections\OfficeOnlineElementCollection.cs" />
<Compile Include="Config\WebConfigSections\OwaSupportedBrowsersElement.cs" />
<Compile Include="Config\WebConfigSections\OwaSupportedBrowsersElementCollection.cs" />
<Compile Include="Config\WebConfigSections\SessionKeysElement.cs" /> <Compile Include="Config\WebConfigSections\SessionKeysElement.cs" />
<Compile Include="Config\WebConfigSections\SessionKeysElementCollection.cs" /> <Compile Include="Config\WebConfigSections\SessionKeysElementCollection.cs" />
<Compile Include="Config\WebConfigSections\UserDomainElement.cs" /> <Compile Include="Config\WebConfigSections\UserDomainElement.cs" />

View file

@ -38,6 +38,12 @@ namespace WebsitePanel.WebDavPortal
defaults: new { controller = "FileSystem", action = "UploadFile" } defaults: new { controller = "FileSystem", action = "UploadFile" }
); );
routes.MapRoute(
name: FileSystemRouteNames.DownloadFile,
url: "download-file/{org}/{*pathPart}",
defaults: new { controller = "FileSystem", action = "DownloadFile" }
);
routes.MapRoute( routes.MapRoute(
name: FileSystemRouteNames.ShowOfficeOnlinePath, name: FileSystemRouteNames.ShowOfficeOnlinePath,
url: "office365/{org}/{*pathPart}", url: "office365/{org}/{*pathPart}",

View file

@ -105,6 +105,12 @@ namespace WebsitePanel.WebDavPortal.Controllers.Api
return new HttpResponseMessage(HttpStatusCode.OK); return new HttpResponseMessage(HttpStatusCode.OK);
} }
[HttpPost]
public HttpResponseMessage Refresh_Lock(int accessTokenId)
{
return new HttpResponseMessage(HttpStatusCode.OK);
}
[HttpPost] [HttpPost]
public HttpResponseMessage UnLock(int accessTokenId) public HttpResponseMessage UnLock(int accessTokenId)
{ {

View file

@ -116,6 +116,26 @@ namespace WebsitePanel.WebDavPortal.Controllers
return PartialView("_ResourseCollectionPartial", result); return PartialView("_ResourseCollectionPartial", result);
} }
[HttpGet]
public ActionResult DownloadFile(string org, string pathPart)
{
if (org != WspContext.User.OrganizationId)
{
return new HttpStatusCodeResult(HttpStatusCode.NoContent);
}
string fileName = pathPart.Split('/').Last();
if (_webdavManager.IsFile(pathPart) == false)
{
throw new Exception(Resources.NotAFile);
}
var fileBytes = _webdavManager.GetFileBytes(pathPart);
return File(fileBytes, MediaTypeNames.Application.Octet, fileName);
}
[HttpPost] [HttpPost]
public ActionResult UploadFile(string org, string pathPart) public ActionResult UploadFile(string org, string pathPart)
{ {

View file

@ -1,5 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net;
using System.Web;
using WebsitePanel.WebDav.Core.Config; using WebsitePanel.WebDav.Core.Config;
using WebsitePanel.WebDavPortal.Extensions; using WebsitePanel.WebDavPortal.Extensions;
@ -20,10 +22,23 @@ namespace WebsitePanel.WebDavPortal.FileOperations
get get
{ {
FileOpenerType result; FileOpenerType result;
if (_operationTypes.TryGetValue(fileExtension, out result)) if (_operationTypes.TryGetValue(fileExtension, out result) && CheckBrowserSupport())
return result; return result;
return FileOpenerType.Download; return FileOpenerType.Download;
} }
} }
private bool CheckBrowserSupport()
{
var request = HttpContext.Current.Request;
int supportedVersion;
if (WebDavAppConfigManager.Instance.OwaSupportedBrowsers.TryGetValue(request.Browser.Browser, out supportedVersion) == false)
{
return false;
}
return supportedVersion <= request.Browser.MajorVersion;
}
} }
} }

View file

@ -159,6 +159,15 @@ namespace WebsitePanel.WebDavPortal.UI {
} }
} }
/// <summary>
/// Looks up a localized string similar to Not a file..
/// </summary>
public static string NotAFile {
get {
return ResourceManager.GetString("NotAFile", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Processing. /// Looks up a localized string similar to Processing.
/// </summary> /// </summary>

View file

@ -150,6 +150,9 @@
<data name="NoFilesAreSelected" xml:space="preserve"> <data name="NoFilesAreSelected" xml:space="preserve">
<value>No files are selected.</value> <value>No files are selected.</value>
</data> </data>
<data name="NotAFile" xml:space="preserve">
<value>Not a file.</value>
</data>
<data name="Processing" xml:space="preserve"> <data name="Processing" xml:space="preserve">
<value>Processing</value> <value>Processing</value>
</data> </data>

View file

@ -14,5 +14,7 @@ namespace WebsitePanel.WebDavPortal.UI.Routes
public const string UploadFile = "UplaodFIleRoute"; public const string UploadFile = "UplaodFIleRoute";
public const string DeleteFiles = "DeleteFilesRoute"; public const string DeleteFiles = "DeleteFilesRoute";
public const string DownloadFile = "DownloadFileRoute";
} }
} }

View file

@ -22,6 +22,7 @@
</root> </root>
</log4net> </log4net>
<appSettings> <appSettings>
<add key="webpages:Version" value="3.0.0.0" /> <add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" /> <add key="webpages:Enabled" value="false" />
@ -72,6 +73,12 @@
<add extension=".csv" path="~/Content/Images/csv-icon.png" /> <add extension=".csv" path="~/Content/Images/csv-icon.png" />
<add extension=".zip" path="~/Content/Images/zip-icon.png" /> <add extension=".zip" path="~/Content/Images/zip-icon.png" />
</fileIcons> </fileIcons>
<owaSupportedBrowsers>
<add browser="Chrome" version="20" />
<add browser="Firefox" version="6" />
<add browser="InternetExplorer" version="8" />
<add browser="Safari" version="4" />
</owaSupportedBrowsers>
<officeOnline isEnabled="True" url="https://vir-owa.virtuworks.net" cobaltFileTtl="1"> <officeOnline isEnabled="True" url="https://vir-owa.virtuworks.net" cobaltFileTtl="1">
<add extension=".doc" OwaView="wv/wordviewerframe.aspx?" OwaEditor="wv/wordviewerframe.aspx?" /> <add extension=".doc" OwaView="wv/wordviewerframe.aspx?" OwaEditor="wv/wordviewerframe.aspx?" />
<add extension=".docx" OwaView="wv/wordviewerframe.aspx?" OwaEditor="we/wordeditorframe.aspx?" /> <add extension=".docx" OwaView="wv/wordviewerframe.aspx?" OwaEditor="we/wordeditorframe.aspx?" />