webdav portal owa editing alpha
This commit is contained in:
parent
7aa68cd775
commit
aedc7ec08e
33 changed files with 969 additions and 153 deletions
BIN
WebsitePanel/Lib/References/Microsoft/Microsoft.CobaltCore.dll
Normal file
BIN
WebsitePanel/Lib/References/Microsoft/Microsoft.CobaltCore.dll
Normal file
Binary file not shown.
|
@ -13,11 +13,13 @@ namespace WebsitePanel.WebDav.Core.Config.Entities
|
||||||
{
|
{
|
||||||
IsEnabled = ConfigSection.OfficeOnline.IsEnabled;
|
IsEnabled = ConfigSection.OfficeOnline.IsEnabled;
|
||||||
Url = ConfigSection.OfficeOnline.Url;
|
Url = ConfigSection.OfficeOnline.Url;
|
||||||
|
CobaltFileTtl = ConfigSection.OfficeOnline.CobaltFileTtl;
|
||||||
_officeExtensions = ConfigSection.OfficeOnline.Cast<OfficeOnlineElement>().ToList();
|
_officeExtensions = ConfigSection.OfficeOnline.Cast<OfficeOnlineElement>().ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsEnabled { get; private set; }
|
public bool IsEnabled { get; private set; }
|
||||||
public string Url { get; private set; }
|
public string Url { get; private set; }
|
||||||
|
public int CobaltFileTtl { get; private set; }
|
||||||
|
|
||||||
public IEnumerator<OfficeOnlineElement> GetEnumerator()
|
public IEnumerator<OfficeOnlineElement> GetEnumerator()
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,7 +5,8 @@ namespace WebsitePanel.WebDavPortal.WebConfigSections
|
||||||
public class OfficeOnlineElement : ConfigurationElement
|
public class OfficeOnlineElement : ConfigurationElement
|
||||||
{
|
{
|
||||||
private const string ExtensionKey = "extension";
|
private const string ExtensionKey = "extension";
|
||||||
private const string OwaOpenerKey = "owaOpener";
|
private const string OwaViewKey = "OwaView";
|
||||||
|
private const string OwaEditorKey = "OwaEditor";
|
||||||
|
|
||||||
[ConfigurationProperty(ExtensionKey, IsKey = true, IsRequired = true)]
|
[ConfigurationProperty(ExtensionKey, IsKey = true, IsRequired = true)]
|
||||||
public string Extension
|
public string Extension
|
||||||
|
@ -14,11 +15,18 @@ namespace WebsitePanel.WebDavPortal.WebConfigSections
|
||||||
set { this[ExtensionKey] = value; }
|
set { this[ExtensionKey] = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[ConfigurationProperty(OwaOpenerKey, IsKey = true, IsRequired = true)]
|
[ConfigurationProperty(OwaViewKey, IsKey = true, IsRequired = true)]
|
||||||
public string OwaOpener
|
public string OwaView
|
||||||
{
|
{
|
||||||
get { return this[OwaOpenerKey].ToString(); }
|
get { return this[OwaViewKey].ToString(); }
|
||||||
set { this[OwaOpenerKey] = value; }
|
set { this[OwaViewKey] = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConfigurationProperty(OwaEditorKey, IsKey = true, IsRequired = true)]
|
||||||
|
public string OwaEditor
|
||||||
|
{
|
||||||
|
get { return this[OwaEditorKey].ToString(); }
|
||||||
|
set { this[OwaEditorKey] = value; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -8,6 +8,7 @@ namespace WebsitePanel.WebDavPortal.WebConfigSections
|
||||||
{
|
{
|
||||||
private const string UrlKey = "url";
|
private const string UrlKey = "url";
|
||||||
private const string IsEnabledKey = "isEnabled";
|
private const string IsEnabledKey = "isEnabled";
|
||||||
|
private const string CobaltFileTtlKey = "cobaltFileTtl";
|
||||||
|
|
||||||
[ConfigurationProperty(UrlKey, IsKey = true, IsRequired = true)]
|
[ConfigurationProperty(UrlKey, IsKey = true, IsRequired = true)]
|
||||||
public string Url
|
public string Url
|
||||||
|
@ -23,6 +24,13 @@ namespace WebsitePanel.WebDavPortal.WebConfigSections
|
||||||
set { this[IsEnabledKey] = value; }
|
set { this[IsEnabledKey] = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[ConfigurationProperty(CobaltFileTtlKey, IsKey = true, IsRequired = true)]
|
||||||
|
public int CobaltFileTtl
|
||||||
|
{
|
||||||
|
get { return int.Parse(this[CobaltFileTtlKey].ToString()); }
|
||||||
|
set { this[CobaltFileTtlKey] = value; }
|
||||||
|
}
|
||||||
|
|
||||||
protected override ConfigurationElement CreateNewElement()
|
protected override ConfigurationElement CreateNewElement()
|
||||||
{
|
{
|
||||||
return new OfficeOnlineElement();
|
return new OfficeOnlineElement();
|
||||||
|
|
|
@ -13,6 +13,24 @@ namespace WebsitePanel.WebDav.Core.Entities.Owa
|
||||||
public long Size { get; set; }
|
public long Size { get; set; }
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public string Version { get; set; }
|
public string Version { get; set; }
|
||||||
|
[DataMember]
|
||||||
|
public bool SupportsCoauth { get; set; }
|
||||||
|
[DataMember]
|
||||||
|
public bool SupportsCobalt { get; set; }
|
||||||
|
[DataMember]
|
||||||
|
public bool SupportsFolders { get; set; }
|
||||||
|
[DataMember]
|
||||||
|
public bool SupportsLocks { get; set; }
|
||||||
|
[DataMember]
|
||||||
|
public bool SupportsScenarioLinks { get; set; }
|
||||||
|
[DataMember]
|
||||||
|
public bool SupportsSecureStore { get; set; }
|
||||||
|
[DataMember]
|
||||||
|
public bool SupportsUpdate { get; set; }
|
||||||
|
[DataMember]
|
||||||
|
public bool UserCanWrite { get; set; }
|
||||||
|
//[DataMember]
|
||||||
|
//public bool ReadOnly { get; set; }
|
||||||
|
|
||||||
//[DataMember]
|
//[DataMember]
|
||||||
//public string SHA256 { get; set; }
|
//public string SHA256 { get; set; }
|
||||||
|
@ -85,20 +103,7 @@ namespace WebsitePanel.WebDav.Core.Entities.Owa
|
||||||
//[DataMember]
|
//[DataMember]
|
||||||
//public string SignoutUrl { get; set; }
|
//public string SignoutUrl { get; set; }
|
||||||
|
|
||||||
//[DataMember]
|
|
||||||
//public bool SupportsCoauth { get; set; }
|
|
||||||
//[DataMember]
|
|
||||||
//public bool SupportsCobalt { get; set; }
|
|
||||||
//[DataMember]
|
|
||||||
//public bool SupportsFolders { get; set; }
|
|
||||||
//[DataMember]
|
|
||||||
//public bool SupportsLocks { get; set; }
|
|
||||||
//[DataMember]
|
|
||||||
//public bool SupportsScenarioLinks { get; set; }
|
|
||||||
//[DataMember]
|
|
||||||
//public bool SupportsSecureStore { get; set; }
|
|
||||||
//[DataMember]
|
|
||||||
//public bool SupportsUpdate { get; set; }
|
|
||||||
//[DataMember]
|
//[DataMember]
|
||||||
//public string TenantId { get; set; }
|
//public string TenantId { get; set; }
|
||||||
//[DataMember]
|
//[DataMember]
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using WebsitePanel.WebDav.Core.Client;
|
using WebsitePanel.WebDav.Core.Client;
|
||||||
|
|
||||||
|
@ -10,6 +11,8 @@ namespace WebsitePanel.WebDav.Core.Interfaces.Managers
|
||||||
bool IsFile(string path);
|
bool IsFile(string path);
|
||||||
byte[] GetFileBytes(string path);
|
byte[] GetFileBytes(string path);
|
||||||
void UploadFile(string path, HttpPostedFileBase file);
|
void UploadFile(string path, HttpPostedFileBase file);
|
||||||
|
void UploadFile(string path, byte[] bytes);
|
||||||
|
void UploadFile(string path, Stream stream);
|
||||||
IResource GetResource(string path);
|
IResource GetResource(string path);
|
||||||
string GetFileUrl(string path);
|
string GetFileUrl(string path);
|
||||||
void DeleteResource(string path);
|
void DeleteResource(string path);
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
using System.IO;
|
||||||
|
using Cobalt;
|
||||||
|
|
||||||
|
namespace WebsitePanel.WebDav.Core.Interfaces.Owa
|
||||||
|
{
|
||||||
|
public interface ICobaltManager
|
||||||
|
{
|
||||||
|
Atom ProcessRequest(int accessTokenId, Stream requestStream);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
using Cobalt;
|
||||||
|
|
||||||
|
namespace WebsitePanel.WebDav.Core.Interfaces.Owa
|
||||||
|
{
|
||||||
|
public interface IWopiFileManager
|
||||||
|
{
|
||||||
|
CobaltFile Create(int accessTokenId);
|
||||||
|
CobaltFile Get(int accessTokenId);
|
||||||
|
bool Add(int accessTokenId, CobaltFile file);
|
||||||
|
bool Delete(int accessTokenId);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
namespace WebsitePanel.WebDav.Core.Interfaces.Storages
|
||||||
|
{
|
||||||
|
public interface IKeyValueStorage
|
||||||
|
{
|
||||||
|
TV Get<TV>(string id);
|
||||||
|
bool Add<TV>(string id, TV value);
|
||||||
|
bool Delete(string id);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
using WebsitePanel.Ecommerce.EnterpriseServer;
|
||||||
|
|
||||||
|
namespace WebsitePanel.WebDav.Core.Interfaces.Storages
|
||||||
|
{
|
||||||
|
public interface ITtlStorage : IKeyValueStorage
|
||||||
|
{
|
||||||
|
void SetTtl<TV>(string id, TV value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -143,6 +143,36 @@ namespace WebsitePanel.WebDav.Core.Managers
|
||||||
resource.Upload(bytes);
|
resource.Upload(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UploadFile(string path, byte[] bytes)
|
||||||
|
{
|
||||||
|
var resource = new WebDavResource();
|
||||||
|
|
||||||
|
var fileUrl = new Uri(WebDavAppConfigManager.Instance.WebdavRoot)
|
||||||
|
.Append(WspContext.User.OrganizationId)
|
||||||
|
.Append(path);
|
||||||
|
|
||||||
|
resource.SetHref(fileUrl);
|
||||||
|
resource.SetCredentials(new NetworkCredential(WspContext.User.Login, _cryptography.Decrypt(WspContext.User.EncryptedPassword)));
|
||||||
|
|
||||||
|
resource.Upload(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UploadFile(string path, Stream stream)
|
||||||
|
{
|
||||||
|
var resource = new WebDavResource();
|
||||||
|
|
||||||
|
var fileUrl = new Uri(WebDavAppConfigManager.Instance.WebdavRoot)
|
||||||
|
.Append(WspContext.User.OrganizationId)
|
||||||
|
.Append(path);
|
||||||
|
|
||||||
|
resource.SetHref(fileUrl);
|
||||||
|
resource.SetCredentials(new NetworkCredential(WspContext.User.Login, _cryptography.Decrypt(WspContext.User.EncryptedPassword)));
|
||||||
|
|
||||||
|
var bytes = ReadFully(stream);
|
||||||
|
|
||||||
|
resource.Upload(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
public void DeleteResource(string path)
|
public void DeleteResource(string path)
|
||||||
{
|
{
|
||||||
path = RemoveLeadingFromPath(path, "office365");
|
path = RemoveLeadingFromPath(path, "office365");
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.Caching;
|
||||||
|
using Cobalt;
|
||||||
|
using WebsitePanel.WebDav.Core.Client;
|
||||||
|
using WebsitePanel.WebDav.Core.Config;
|
||||||
|
using WebsitePanel.WebDav.Core.Interfaces.Managers;
|
||||||
|
using WebsitePanel.WebDav.Core.Interfaces.Owa;
|
||||||
|
using WebsitePanel.WebDav.Core.Interfaces.Storages;
|
||||||
|
|
||||||
|
namespace WebsitePanel.WebDav.Core.Owa
|
||||||
|
{
|
||||||
|
public class CobaltFileManager : IWopiFileManager
|
||||||
|
{
|
||||||
|
private readonly IWebDavManager _webDavManager;
|
||||||
|
private readonly IAccessTokenManager _tokenManager;
|
||||||
|
private readonly ITtlStorage _storage;
|
||||||
|
|
||||||
|
public CobaltFileManager(IWebDavManager webDavManager, IAccessTokenManager tokenManager, ITtlStorage storage)
|
||||||
|
{
|
||||||
|
_webDavManager = webDavManager;
|
||||||
|
|
||||||
|
_tokenManager = tokenManager;
|
||||||
|
_storage = storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CobaltFile Create(int accessTokenId)
|
||||||
|
{
|
||||||
|
var disposal = new DisposalEscrow(accessTokenId.ToString(CultureInfo.InvariantCulture));
|
||||||
|
|
||||||
|
var content = new CobaltFilePartitionConfig
|
||||||
|
{
|
||||||
|
IsNewFile = true,
|
||||||
|
HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), disposal, accessTokenId + @".Content"),
|
||||||
|
cellSchemaIsGenericFda = true,
|
||||||
|
CellStorageConfig = new CellStorageConfig(),
|
||||||
|
Schema = CobaltFilePartition.Schema.ShreddedCobalt,
|
||||||
|
PartitionId = FilePartitionId.Content
|
||||||
|
};
|
||||||
|
|
||||||
|
var coauth = new CobaltFilePartitionConfig
|
||||||
|
{
|
||||||
|
IsNewFile = true,
|
||||||
|
HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), disposal, accessTokenId + @".CoauthMetadata"),
|
||||||
|
cellSchemaIsGenericFda = false,
|
||||||
|
CellStorageConfig = new CellStorageConfig(),
|
||||||
|
Schema = CobaltFilePartition.Schema.ShreddedCobalt,
|
||||||
|
PartitionId = FilePartitionId.CoauthMetadata
|
||||||
|
};
|
||||||
|
|
||||||
|
var wacupdate = new CobaltFilePartitionConfig
|
||||||
|
{
|
||||||
|
IsNewFile = true,
|
||||||
|
HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), disposal, accessTokenId + @".WordWacUpdate"),
|
||||||
|
cellSchemaIsGenericFda = false,
|
||||||
|
CellStorageConfig = new CellStorageConfig(),
|
||||||
|
Schema = CobaltFilePartition.Schema.ShreddedCobalt,
|
||||||
|
PartitionId = FilePartitionId.WordWacUpdate
|
||||||
|
};
|
||||||
|
|
||||||
|
var partitionConfs = new Dictionary<FilePartitionId, CobaltFilePartitionConfig>
|
||||||
|
{
|
||||||
|
{FilePartitionId.Content, content},
|
||||||
|
{FilePartitionId.WordWacUpdate, wacupdate},
|
||||||
|
{FilePartitionId.CoauthMetadata, coauth}
|
||||||
|
};
|
||||||
|
|
||||||
|
var cobaltFile = new CobaltFile(disposal, partitionConfs, new CobaltHostLockingStore(), null);
|
||||||
|
|
||||||
|
var token = _tokenManager.GetToken(accessTokenId);
|
||||||
|
|
||||||
|
var fileBytes = _webDavManager.GetFileBytes(token.FilePath);
|
||||||
|
|
||||||
|
var atom = new AtomFromByteArray(fileBytes);
|
||||||
|
|
||||||
|
Cobalt.Metrics o1;
|
||||||
|
cobaltFile.GetCobaltFilePartition(FilePartitionId.Content).SetStream(RootId.Default.Value, atom, out o1);
|
||||||
|
cobaltFile.GetCobaltFilePartition(FilePartitionId.Content).GetStream(RootId.Default.Value).Flush();
|
||||||
|
|
||||||
|
Add(accessTokenId, cobaltFile);
|
||||||
|
|
||||||
|
return cobaltFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CobaltFile Get(int accessTokenId)
|
||||||
|
{
|
||||||
|
return _storage.Get<CobaltFile>(GetFileKey(accessTokenId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Add(int accessTokenId, CobaltFile file)
|
||||||
|
{
|
||||||
|
return _storage.Add(GetFileKey(accessTokenId), file);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Delete(int accessTokenId)
|
||||||
|
{
|
||||||
|
return _storage.Delete(GetFileKey(accessTokenId));
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetFileKey(int accessTokenId)
|
||||||
|
{
|
||||||
|
return string.Format("{0}", accessTokenId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,245 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using Cobalt;
|
||||||
|
using WebsitePanel.WebDav.Core;
|
||||||
|
|
||||||
|
namespace WebsitePanel.WebDav.Core.Owa
|
||||||
|
{
|
||||||
|
public class CobaltHostLockingStore : HostLockingStore
|
||||||
|
{
|
||||||
|
public override WhoAmIRequest.OutputType HandleWhoAmI(WhoAmIRequest.InputType input)
|
||||||
|
{
|
||||||
|
WhoAmIRequest.OutputType result = new WhoAmIRequest.OutputType();
|
||||||
|
result.UserIsAnonymous = WspContext.User == null;
|
||||||
|
if (WspContext.User != null)
|
||||||
|
{
|
||||||
|
result.UserEmailAddress = WspContext.User.Login;
|
||||||
|
result.UserLogin = WspContext.User.Login;
|
||||||
|
result.UserName = WspContext.User.DisplayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ServerTimeRequest.OutputType HandleServerTime(ServerTimeRequest.InputType input)
|
||||||
|
{
|
||||||
|
ServerTimeRequest.OutputType result = new ServerTimeRequest.OutputType();
|
||||||
|
result.ServerTime = DateTime.UtcNow;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override LockAndCheckOutStatusRequest.OutputType HandleLockAndCheckOutStatus(LockAndCheckOutStatusRequest.InputType input)
|
||||||
|
{
|
||||||
|
LockAndCheckOutStatusRequest.OutputType result = new LockAndCheckOutStatusRequest.OutputType();
|
||||||
|
result.LockType = 1U;
|
||||||
|
result.CheckOutType = 0U;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override GetExclusiveLockRequest.OutputType HandleGetExclusiveLock(GetExclusiveLockRequest.InputType input)
|
||||||
|
{
|
||||||
|
GetExclusiveLockRequest.OutputType result = new GetExclusiveLockRequest.OutputType();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override RefreshExclusiveLockRequest.OutputType HandleRefreshExclusiveLock(RefreshExclusiveLockRequest.InputType input)
|
||||||
|
{
|
||||||
|
RefreshExclusiveLockRequest.OutputType result = new RefreshExclusiveLockRequest.OutputType();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override CheckExclusiveLockAvailabilityRequest.OutputType HandleCheckExclusiveLockAvailability(CheckExclusiveLockAvailabilityRequest.InputType input)
|
||||||
|
{
|
||||||
|
CheckExclusiveLockAvailabilityRequest.OutputType result = new CheckExclusiveLockAvailabilityRequest.OutputType();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ConvertExclusiveLockToSchemaLockRequest.OutputType HandleConvertExclusiveLockToSchemaLock(ConvertExclusiveLockToSchemaLockRequest.InputType input, int protocolMajorVersion, int protocolMinorVersion)
|
||||||
|
{
|
||||||
|
ConvertExclusiveLockToSchemaLockRequest.OutputType result = new ConvertExclusiveLockToSchemaLockRequest.OutputType();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ConvertExclusiveLockWithCoauthTransitionRequest.OutputType HandleConvertExclusiveLockWithCoauthTransition(ConvertExclusiveLockWithCoauthTransitionRequest.InputType input, int protocolMajorVersion, int protocolMinorVersion)
|
||||||
|
{
|
||||||
|
ConvertExclusiveLockWithCoauthTransitionRequest.OutputType result = new ConvertExclusiveLockWithCoauthTransitionRequest.OutputType();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override GetSchemaLockRequest.OutputType HandleGetSchemaLock(GetSchemaLockRequest.InputType input, int protocolMajorVersion, int protocolMinorVersion)
|
||||||
|
{
|
||||||
|
GetSchemaLockRequest.OutputType result = new GetSchemaLockRequest.OutputType();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override ReleaseExclusiveLockRequest.OutputType HandleReleaseExclusiveLock(ReleaseExclusiveLockRequest.InputType input)
|
||||||
|
{
|
||||||
|
ReleaseExclusiveLockRequest.OutputType result = new ReleaseExclusiveLockRequest.OutputType();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ReleaseSchemaLockRequest.OutputType HandleReleaseSchemaLock(ReleaseSchemaLockRequest.InputType input, int protocolMajorVersion, int protocolMinorVersion)
|
||||||
|
{
|
||||||
|
ReleaseSchemaLockRequest.OutputType result = new ReleaseSchemaLockRequest.OutputType();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override RefreshSchemaLockRequest.OutputType HandleRefreshSchemaLock(RefreshSchemaLockRequest.InputType input, int protocolMajorVersion, int protocolMinorVersion)
|
||||||
|
{
|
||||||
|
RefreshSchemaLockRequest.OutputType result = new RefreshSchemaLockRequest.OutputType();
|
||||||
|
result.Lock = LockType.SchemaLock;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ConvertSchemaLockToExclusiveLockRequest.OutputType HandleConvertSchemaLockToExclusiveLock(ConvertSchemaLockToExclusiveLockRequest.InputType input)
|
||||||
|
{
|
||||||
|
ConvertSchemaLockToExclusiveLockRequest.OutputType result = new ConvertSchemaLockToExclusiveLockRequest.OutputType();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override CheckSchemaLockAvailabilityRequest.OutputType HandleCheckSchemaLockAvailability(CheckSchemaLockAvailabilityRequest.InputType input)
|
||||||
|
{
|
||||||
|
CheckSchemaLockAvailabilityRequest.OutputType result = new CheckSchemaLockAvailabilityRequest.OutputType();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override JoinCoauthoringRequest.OutputType HandleJoinCoauthoring(JoinCoauthoringRequest.InputType input, int protocolMajorVersion, int protocolMinorVersion)
|
||||||
|
{
|
||||||
|
JoinCoauthoringRequest.OutputType result = new JoinCoauthoringRequest.OutputType();
|
||||||
|
result.Lock = LockType.SchemaLock;
|
||||||
|
result.CoauthStatus = CoauthStatusType.Alone;
|
||||||
|
result.TransitionId = Guid.NewGuid();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ExitCoauthoringRequest.OutputType HandleExitCoauthoring(ExitCoauthoringRequest.InputType input, int protocolMajorVersion, int protocolMinorVersion)
|
||||||
|
{
|
||||||
|
ExitCoauthoringRequest.OutputType result = new ExitCoauthoringRequest.OutputType();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override RefreshCoauthoringSessionRequest.OutputType HandleRefreshCoauthoring(RefreshCoauthoringSessionRequest.InputType input, int protocolMajorVersion, int protocolMinorVersion)
|
||||||
|
{
|
||||||
|
RefreshCoauthoringSessionRequest.OutputType result = new RefreshCoauthoringSessionRequest.OutputType();
|
||||||
|
result.Lock = LockType.SchemaLock;
|
||||||
|
result.CoauthStatus = CoauthStatusType.Alone;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ConvertCoauthLockToExclusiveLockRequest.OutputType HandleConvertCoauthLockToExclusiveLock(ConvertCoauthLockToExclusiveLockRequest.InputType input)
|
||||||
|
{
|
||||||
|
ConvertCoauthLockToExclusiveLockRequest.OutputType result = new ConvertCoauthLockToExclusiveLockRequest.OutputType();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override CheckCoauthLockAvailabilityRequest.OutputType HandleCheckCoauthLockAvailability(CheckCoauthLockAvailabilityRequest.InputType input)
|
||||||
|
{
|
||||||
|
CheckCoauthLockAvailabilityRequest.OutputType result = new CheckCoauthLockAvailabilityRequest.OutputType();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override MarkCoauthTransitionCompleteRequest.OutputType HandleMarkCoauthTransitionComplete(MarkCoauthTransitionCompleteRequest.InputType input)
|
||||||
|
{
|
||||||
|
MarkCoauthTransitionCompleteRequest.OutputType result = new MarkCoauthTransitionCompleteRequest.OutputType();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override GetCoauthoringStatusRequest.OutputType HandleGetCoauthoringStatus(GetCoauthoringStatusRequest.InputType input)
|
||||||
|
{
|
||||||
|
GetCoauthoringStatusRequest.OutputType result = new GetCoauthoringStatusRequest.OutputType();
|
||||||
|
result.CoauthStatus = CoauthStatusType.Alone;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Dictionary<string, EditorsTableEntry> QueryEditorsTable()
|
||||||
|
{
|
||||||
|
return new Dictionary<string, EditorsTableEntry>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override JoinEditingSessionRequest.OutputType HandleJoinEditingSession(JoinEditingSessionRequest.InputType input)
|
||||||
|
{
|
||||||
|
JoinEditingSessionRequest.OutputType result = new JoinEditingSessionRequest.OutputType();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override RefreshEditingSessionRequest.OutputType HandleRefreshEditingSession(RefreshEditingSessionRequest.InputType input)
|
||||||
|
{
|
||||||
|
RefreshEditingSessionRequest.OutputType result = new RefreshEditingSessionRequest.OutputType();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override LeaveEditingSessionRequest.OutputType HandleLeaveEditingSession(LeaveEditingSessionRequest.InputType input)
|
||||||
|
{
|
||||||
|
LeaveEditingSessionRequest.OutputType result = new LeaveEditingSessionRequest.OutputType();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override UpdateEditorMetadataRequest.OutputType HandleUpdateEditorMetadata(UpdateEditorMetadataRequest.InputType input)
|
||||||
|
{
|
||||||
|
UpdateEditorMetadataRequest.OutputType result = new UpdateEditorMetadataRequest.OutputType();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override RemoveEditorMetadataRequest.OutputType HandleRemoveEditorMetadata(RemoveEditorMetadataRequest.InputType input)
|
||||||
|
{
|
||||||
|
RemoveEditorMetadataRequest.OutputType result = new RemoveEditorMetadataRequest.OutputType();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ulong GetEditorsTableWaterline()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override AmIAloneRequest.OutputType HandleAmIAlone(AmIAloneRequest.InputType input)
|
||||||
|
{
|
||||||
|
AmIAloneRequest.OutputType result = new AmIAloneRequest.OutputType();
|
||||||
|
result.AmIAlone = true;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override DocMetaInfoRequest.OutputType HandleDocMetaInfo(DocMetaInfoRequest.InputType input)
|
||||||
|
{
|
||||||
|
DocMetaInfoRequest.OutputType result = new DocMetaInfoRequest.OutputType();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override VersionsRequest.OutputType HandleVersions(VersionsRequest.InputType input)
|
||||||
|
{
|
||||||
|
VersionsRequest.OutputType result = new VersionsRequest.OutputType();
|
||||||
|
result.Enabled = false;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using Cobalt;
|
||||||
|
using WebsitePanel.WebDav.Core.Interfaces.Managers;
|
||||||
|
using WebsitePanel.WebDav.Core.Interfaces.Owa;
|
||||||
|
|
||||||
|
namespace WebsitePanel.WebDav.Core.Owa
|
||||||
|
{
|
||||||
|
public class CobaltManager : ICobaltManager
|
||||||
|
{
|
||||||
|
private readonly IWebDavManager _webDavManager;
|
||||||
|
private readonly IWopiFileManager _fileManager;
|
||||||
|
private readonly IAccessTokenManager _tokenManager;
|
||||||
|
|
||||||
|
public CobaltManager(IWebDavManager webDavManager, IWopiFileManager fileManager, IAccessTokenManager tokenManager)
|
||||||
|
{
|
||||||
|
_webDavManager = webDavManager;
|
||||||
|
_fileManager = fileManager;
|
||||||
|
_tokenManager = tokenManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Atom ProcessRequest(int accessTokenId, Stream requestStream)
|
||||||
|
{
|
||||||
|
var token = _tokenManager.GetToken(accessTokenId);
|
||||||
|
|
||||||
|
var atomRequest = new AtomFromStream(requestStream);
|
||||||
|
|
||||||
|
var requestBatch = new RequestBatch();
|
||||||
|
|
||||||
|
var cobaltFile = _fileManager.Get(accessTokenId) ?? _fileManager.Create(accessTokenId);
|
||||||
|
|
||||||
|
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())
|
||||||
|
{
|
||||||
|
GenericFdaStream myCobaltStream = new GenericFda(cobaltFile.CobaltEndpoint, null).GetContentStream();
|
||||||
|
myCobaltStream.CopyTo(saveStream);
|
||||||
|
|
||||||
|
_webDavManager.UploadFile(token.FilePath, saveStream.ToArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return requestBatch.SerializeOutputToProtocol(protocolVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,9 +28,17 @@ namespace WebsitePanel.WebDav.Core.Owa
|
||||||
var cFileInfo = new CheckFileInfo
|
var cFileInfo = new CheckFileInfo
|
||||||
{
|
{
|
||||||
BaseFileName = resource.DisplayName,
|
BaseFileName = resource.DisplayName,
|
||||||
OwnerId = @"4257508bfe174aa28b461536d8b6b648",
|
OwnerId = @"4257508bfe174aa28b461536d8b6b648",// WspContext.User.Login,
|
||||||
Size = resource.ContentLength,
|
Size = resource.ContentLength,
|
||||||
Version = @"%22%7B59CCD75F%2D0687%2D4F86%2DBBCF%2D059126640640%7D%2C1%22"
|
Version = DateTime.Now.ToString("s"),
|
||||||
|
SupportsCoauth = false,
|
||||||
|
SupportsCobalt = true,
|
||||||
|
SupportsFolders = true,
|
||||||
|
SupportsLocks = false,
|
||||||
|
SupportsScenarioLinks = false,
|
||||||
|
SupportsSecureStore = false,
|
||||||
|
SupportsUpdate = true,
|
||||||
|
UserCanWrite = true
|
||||||
};
|
};
|
||||||
|
|
||||||
return cFileInfo;
|
return cFileInfo;
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.Caching;
|
||||||
|
using Microsoft.Web.Services3.Design;
|
||||||
|
using WebsitePanel.WebDav.Core.Config;
|
||||||
|
using WebsitePanel.WebDav.Core.Interfaces.Storages;
|
||||||
|
|
||||||
|
namespace WebsitePanel.WebDav.Core.Storages
|
||||||
|
{
|
||||||
|
public class CacheTtlStorage : ITtlStorage
|
||||||
|
{
|
||||||
|
private static readonly ObjectCache Cache;
|
||||||
|
|
||||||
|
static CacheTtlStorage()
|
||||||
|
{
|
||||||
|
Cache = MemoryCache.Default;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TV Get<TV>(string id)
|
||||||
|
{
|
||||||
|
var value = (TV)Cache[id];
|
||||||
|
|
||||||
|
if (!EqualityComparer<TV>.Default.Equals(value, default(TV)))
|
||||||
|
{
|
||||||
|
SetTtl(id, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Add<TV>(string id, TV value)
|
||||||
|
{
|
||||||
|
return Cache.Add(id, value, DateTime.Now.AddMinutes(WebDavAppConfigManager.Instance.OfficeOnline.CobaltFileTtl));
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Delete(string id)
|
||||||
|
{
|
||||||
|
if (Cache.Any(x => x.Key == id))
|
||||||
|
{
|
||||||
|
Cache.Remove(id);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetTtl<TV>(string id, TV value)
|
||||||
|
{
|
||||||
|
Cache.Set(id, value, DateTime.Now.AddMinutes(WebDavAppConfigManager.Instance.OfficeOnline.CobaltFileTtl));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,6 +35,9 @@
|
||||||
<Reference Include="log4net">
|
<Reference Include="log4net">
|
||||||
<HintPath>..\packages\log4net.2.0.0\lib\net40-full\log4net.dll</HintPath>
|
<HintPath>..\packages\log4net.2.0.0\lib\net40-full\log4net.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.CobaltCore">
|
||||||
|
<HintPath>..\..\Lib\References\Microsoft\Microsoft.CobaltCore.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
<Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
<HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
|
<HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
|
||||||
|
@ -49,6 +52,7 @@
|
||||||
<Reference Include="System.Configuration" />
|
<Reference Include="System.Configuration" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.DirectoryServices.AccountManagement" />
|
<Reference Include="System.DirectoryServices.AccountManagement" />
|
||||||
|
<Reference Include="System.Runtime.Caching" />
|
||||||
<Reference Include="System.Runtime.Serialization" />
|
<Reference Include="System.Runtime.Serialization" />
|
||||||
<Reference Include="System.Web">
|
<Reference Include="System.Web">
|
||||||
<HintPath>C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Web.dll</HintPath>
|
<HintPath>C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Web.dll</HintPath>
|
||||||
|
@ -128,6 +132,11 @@
|
||||||
<Compile Include="IFolder.cs" />
|
<Compile Include="IFolder.cs" />
|
||||||
<Compile Include="IHierarchyItem.cs" />
|
<Compile Include="IHierarchyItem.cs" />
|
||||||
<Compile Include="IItemContent.cs" />
|
<Compile Include="IItemContent.cs" />
|
||||||
|
<Compile Include="Interfaces\Storages\IKeyValueStorage.cs" />
|
||||||
|
<Compile Include="Interfaces\Storages\ITtlStorage.cs" />
|
||||||
|
<Compile Include="Owa\CobaltManager.cs" />
|
||||||
|
<Compile Include="Interfaces\Owa\ICobaltManager.cs" />
|
||||||
|
<Compile Include="Interfaces\Owa\IWopiFileManager.cs" />
|
||||||
<Compile Include="Interfaces\Security\IWebDavAuthorizationService.cs" />
|
<Compile Include="Interfaces\Security\IWebDavAuthorizationService.cs" />
|
||||||
<Compile Include="Managers\AccessTokenManager.cs" />
|
<Compile Include="Managers\AccessTokenManager.cs" />
|
||||||
<Compile Include="Interfaces\Managers\IAccessTokenManager.cs" />
|
<Compile Include="Interfaces\Managers\IAccessTokenManager.cs" />
|
||||||
|
@ -139,6 +148,8 @@
|
||||||
<Compile Include="ItemType.cs" />
|
<Compile Include="ItemType.cs" />
|
||||||
<Compile Include="LockUriTokenPair.cs" />
|
<Compile Include="LockUriTokenPair.cs" />
|
||||||
<Compile Include="Managers\WebDavManager.cs" />
|
<Compile Include="Managers\WebDavManager.cs" />
|
||||||
|
<Compile Include="Owa\CobaltFileManager.cs" />
|
||||||
|
<Compile Include="Owa\CobaltHostLockingStore.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Property.cs" />
|
<Compile Include="Property.cs" />
|
||||||
<Compile Include="PropertyName.cs" />
|
<Compile Include="PropertyName.cs" />
|
||||||
|
@ -159,6 +170,7 @@
|
||||||
<Compile Include="Security\Authentication\FormsAuthenticationService.cs" />
|
<Compile Include="Security\Authentication\FormsAuthenticationService.cs" />
|
||||||
<Compile Include="Security\Authentication\Principals\WspPrincipal.cs" />
|
<Compile Include="Security\Authentication\Principals\WspPrincipal.cs" />
|
||||||
<Compile Include="Owa\WopiServer.cs" />
|
<Compile Include="Owa\WopiServer.cs" />
|
||||||
|
<Compile Include="Storages\CacheTtlStorage.cs" />
|
||||||
<Compile Include="WebDavSession.cs" />
|
<Compile Include="WebDavSession.cs" />
|
||||||
<Compile Include="WspContext.cs" />
|
<Compile Include="WspContext.cs" />
|
||||||
<Compile Include="Wsp\Framework\WSP.cs" />
|
<Compile Include="Wsp\Framework\WSP.cs" />
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<!-- Display Settings -->
|
<!-- Display Settings -->
|
||||||
<PortalName>WebsitePanel</PortalName>
|
<PortalName>WebsitePanel</PortalName>
|
||||||
<!-- Enterprise Server -->
|
<!-- Enterprise Server -->
|
||||||
<EnterpriseServer>http://127.0.0.1:9555</EnterpriseServer>
|
<EnterpriseServer>http://localhost:9002</EnterpriseServer>
|
||||||
<!-- General Settings -->
|
<!-- General Settings -->
|
||||||
<CultureCookieName>UserCulture</CultureCookieName>
|
<CultureCookieName>UserCulture</CultureCookieName>
|
||||||
<ThemeCookieName>UserTheme</ThemeCookieName>
|
<ThemeCookieName>UserTheme</ThemeCookieName>
|
||||||
|
|
|
@ -26,22 +26,6 @@ namespace WebsitePanel.WebDavPortal
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Owa
|
|
||||||
|
|
||||||
routes.MapRoute(
|
|
||||||
name: OwaRouteNames.GetFile,
|
|
||||||
url: "owa/wopi*/files/{accessTokenId}/contents",
|
|
||||||
defaults: new { controller = "Owa", action = "GetFile" }
|
|
||||||
);
|
|
||||||
|
|
||||||
routes.MapRoute(
|
|
||||||
name: OwaRouteNames.CheckFileInfo,
|
|
||||||
url: "owa/wopi*/files/{accessTokenId}",
|
|
||||||
defaults: new { controller = "Owa", action = "CheckFileInfo" }
|
|
||||||
);
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
routes.MapRoute(
|
routes.MapRoute(
|
||||||
name: FileSystemRouteNames.DeleteFiles,
|
name: FileSystemRouteNames.DeleteFiles,
|
||||||
url: "files-group-action/delete",
|
url: "files-group-action/delete",
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Http;
|
||||||
|
using WebsitePanel.WebDavPortal.DependencyInjection;
|
||||||
|
using WebsitePanel.WebDavPortal.UI.Routes;
|
||||||
|
|
||||||
|
namespace WebsitePanel.WebDavPortal.App_Start
|
||||||
|
{
|
||||||
|
public class WebApiConfig
|
||||||
|
{
|
||||||
|
public static void Register(HttpConfiguration configuration)
|
||||||
|
{
|
||||||
|
#region Owa
|
||||||
|
|
||||||
|
configuration.Routes.MapHttpRoute(
|
||||||
|
name: OwaRouteNames.GetFile,
|
||||||
|
routeTemplate: "owa/wopi*/files/{accessTokenId}/contents",
|
||||||
|
defaults: new {controller = "Owa", action = "GetFile"});
|
||||||
|
|
||||||
|
configuration.Routes.MapHttpRoute(
|
||||||
|
name: OwaRouteNames.CheckFileInfo,
|
||||||
|
routeTemplate: "owa/wopi*/files/{accessTokenId}",
|
||||||
|
defaults: new {controller = "Owa", action = "CheckFileInfo"});
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
configuration.Routes.MapHttpRoute("API Default", "api/{controller}/{id}",
|
||||||
|
new { id = RouteParameter.Optional });
|
||||||
|
|
||||||
|
configuration.DependencyResolver = new NinjectDependecyResolver();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web.Http.Controllers;
|
||||||
|
|
||||||
|
namespace WebsitePanel.WebDavPortal.Configurations.ActionSelectors
|
||||||
|
{
|
||||||
|
public class OwaActionSelector : ApiControllerActionSelector
|
||||||
|
{
|
||||||
|
public override HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
|
||||||
|
{
|
||||||
|
if (controllerContext.Request.Headers.Contains("X-WOPI-Override"))
|
||||||
|
{
|
||||||
|
var matchingHeaders = controllerContext.Request.Headers.GetValues("X-WOPI-Override");
|
||||||
|
var headerValue = (matchingHeaders == null) ? "" : (matchingHeaders.FirstOrDefault() ?? "");
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(headerValue))
|
||||||
|
{
|
||||||
|
controllerContext.RouteData.Values["action"] = headerValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.SelectAction(controllerContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Http.Controllers;
|
||||||
|
using WebsitePanel.WebDavPortal.Configurations.ActionSelectors;
|
||||||
|
|
||||||
|
namespace WebsitePanel.WebDavPortal.Configurations.ControllerConfigurations
|
||||||
|
{
|
||||||
|
public class OwaControllerConfiguration : Attribute, IControllerConfiguration
|
||||||
|
{
|
||||||
|
public void Initialize(HttpControllerSettings controllerSettings, HttpControllerDescriptor controllerDescriptor)
|
||||||
|
{
|
||||||
|
controllerSettings.Services.Replace(typeof(IHttpActionSelector), new OwaActionSelector());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,129 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Hosting;
|
||||||
|
using System.Web.Http;
|
||||||
|
using Cobalt;
|
||||||
|
using WebsitePanel.EnterpriseServer.Base.HostedSolution;
|
||||||
|
using WebsitePanel.WebDav.Core;
|
||||||
|
using WebsitePanel.WebDav.Core.Client;
|
||||||
|
using WebsitePanel.WebDav.Core.Entities.Owa;
|
||||||
|
using WebsitePanel.WebDav.Core.Interfaces.Managers;
|
||||||
|
using WebsitePanel.WebDav.Core.Interfaces.Owa;
|
||||||
|
using WebsitePanel.WebDav.Core.Interfaces.Security;
|
||||||
|
using WebsitePanel.WebDav.Core.Security.Cryptography;
|
||||||
|
using WebsitePanel.WebDav.Core.Wsp.Framework;
|
||||||
|
using WebsitePanel.WebDavPortal.Configurations.ControllerConfigurations;
|
||||||
|
|
||||||
|
namespace WebsitePanel.WebDavPortal.Controllers.Api
|
||||||
|
{
|
||||||
|
[Authorize]
|
||||||
|
[OwaControllerConfiguration]
|
||||||
|
public class OwaController : ApiController
|
||||||
|
{
|
||||||
|
private readonly IWopiServer _wopiServer;
|
||||||
|
private readonly IWebDavManager _webDavManager;
|
||||||
|
private readonly IAuthenticationService _authenticationService;
|
||||||
|
private readonly IAccessTokenManager _tokenManager;
|
||||||
|
private readonly ICryptography _cryptography;
|
||||||
|
//private static WopiSession _session;
|
||||||
|
private readonly ICobaltManager _cobaltManager;
|
||||||
|
|
||||||
|
public OwaController(IWopiServer wopiServer, IWebDavManager webDavManager, IAuthenticationService authenticationService, IAccessTokenManager tokenManager, ICryptography cryptography, ICobaltManager cobaltManager)
|
||||||
|
{
|
||||||
|
_wopiServer = wopiServer;
|
||||||
|
_webDavManager = webDavManager;
|
||||||
|
_authenticationService = authenticationService;
|
||||||
|
_tokenManager = tokenManager;
|
||||||
|
_cryptography = cryptography;
|
||||||
|
_cobaltManager = cobaltManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public CheckFileInfo CheckFileInfo(int accessTokenId)
|
||||||
|
{
|
||||||
|
var token = _tokenManager.GetToken(accessTokenId);
|
||||||
|
|
||||||
|
var fileInfo = _wopiServer.GetCheckFileInfo(token.FilePath);
|
||||||
|
|
||||||
|
return fileInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpResponseMessage GetFile(int accessTokenId)
|
||||||
|
{
|
||||||
|
var token = _tokenManager.GetToken(accessTokenId);
|
||||||
|
|
||||||
|
var bytes = _webDavManager.GetFileBytes(token.FilePath);
|
||||||
|
|
||||||
|
var result = new HttpResponseMessage(HttpStatusCode.OK);
|
||||||
|
|
||||||
|
var stream = new MemoryStream(bytes);
|
||||||
|
|
||||||
|
result.Content = new StreamContent(stream);
|
||||||
|
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<HttpResponseMessage> Cobalt(int accessTokenId)
|
||||||
|
{
|
||||||
|
var memoryStream = new MemoryStream();
|
||||||
|
|
||||||
|
await Request.Content.CopyToAsync(memoryStream);
|
||||||
|
|
||||||
|
var responseBatch = _cobaltManager.ProcessRequest(accessTokenId, memoryStream);
|
||||||
|
|
||||||
|
var correlationId = Request.Headers.GetValues("X-WOPI-CorrelationID").FirstOrDefault() ?? "";
|
||||||
|
|
||||||
|
var response = new HttpResponseMessage();
|
||||||
|
|
||||||
|
response.Content = new PushStreamContent(
|
||||||
|
(stream, content, context) =>
|
||||||
|
{
|
||||||
|
responseBatch.CopyTo(stream);
|
||||||
|
stream.Close();
|
||||||
|
});
|
||||||
|
|
||||||
|
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
|
||||||
|
response.Content.Headers.ContentLength = responseBatch.Length;
|
||||||
|
|
||||||
|
response.Headers.Add("X-WOPI-CorellationID", correlationId);
|
||||||
|
response.Headers.Add("request-id", correlationId);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public HttpResponseMessage Lock(int accessTokenId)
|
||||||
|
{
|
||||||
|
return new HttpResponseMessage(HttpStatusCode.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public HttpResponseMessage UnLock(int accessTokenId)
|
||||||
|
{
|
||||||
|
return new HttpResponseMessage(HttpStatusCode.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<HttpResponseMessage> Put(int accessTokenId)
|
||||||
|
{
|
||||||
|
var token = _tokenManager.GetToken(accessTokenId);
|
||||||
|
|
||||||
|
var bytes = await Request.Content.ReadAsByteArrayAsync();
|
||||||
|
|
||||||
|
_webDavManager.UploadFile(token.FilePath, bytes);
|
||||||
|
|
||||||
|
return new HttpResponseMessage(HttpStatusCode.OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,6 +14,7 @@ using WebsitePanel.WebDav.Core.Config;
|
||||||
using WebsitePanel.WebDav.Core.Exceptions;
|
using WebsitePanel.WebDav.Core.Exceptions;
|
||||||
using WebsitePanel.WebDav.Core.Interfaces.Managers;
|
using WebsitePanel.WebDav.Core.Interfaces.Managers;
|
||||||
using WebsitePanel.WebDav.Core.Interfaces.Security;
|
using WebsitePanel.WebDav.Core.Interfaces.Security;
|
||||||
|
using WebsitePanel.WebDav.Core.Security.Authorization.Enums;
|
||||||
using WebsitePanel.WebDav.Core.Security.Cryptography;
|
using WebsitePanel.WebDav.Core.Security.Cryptography;
|
||||||
using WebsitePanel.WebDavPortal.CustomAttributes;
|
using WebsitePanel.WebDavPortal.CustomAttributes;
|
||||||
using WebsitePanel.WebDavPortal.Extensions;
|
using WebsitePanel.WebDavPortal.Extensions;
|
||||||
|
@ -84,14 +85,21 @@ namespace WebsitePanel.WebDavPortal.Controllers
|
||||||
|
|
||||||
public ActionResult ShowOfficeDocument(string org, string pathPart = "")
|
public ActionResult ShowOfficeDocument(string org, string pathPart = "")
|
||||||
{
|
{
|
||||||
|
var permissions = _webDavAuthorizationService.GetPermissions(WspContext.User, pathPart);
|
||||||
|
|
||||||
var owaOpener = WebDavAppConfigManager.Instance.OfficeOnline.Single(x => x.Extension == Path.GetExtension(pathPart));
|
var owaOpener = WebDavAppConfigManager.Instance.OfficeOnline.Single(x => x.Extension == Path.GetExtension(pathPart));
|
||||||
|
|
||||||
string fileUrl = WebDavAppConfigManager.Instance.WebdavRoot+ org + "/" + pathPart.TrimStart('/');
|
string fileUrl = WebDavAppConfigManager.Instance.WebdavRoot+ org + "/" + pathPart.TrimStart('/');
|
||||||
var accessToken = _tokenManager.CreateToken(WspContext.User, pathPart);
|
var accessToken = _tokenManager.CreateToken(WspContext.User, pathPart);
|
||||||
|
|
||||||
string wopiSrc = Server.UrlDecode(Url.RouteUrl(OwaRouteNames.CheckFileInfo, new { accessTokenId = accessToken.Id }, Request.Url.Scheme));
|
var urlPart = Url.HttpRouteUrl(OwaRouteNames.CheckFileInfo, new {accessTokenId = accessToken.Id});
|
||||||
|
var url = new Uri(Request.Url, urlPart).ToString();
|
||||||
|
|
||||||
var uri = string.Format("{0}/{1}?WOPISrc={2}&access_token={3}", WebDavAppConfigManager.Instance.OfficeOnline.Url, owaOpener.OwaOpener, Server.UrlEncode(wopiSrc), Server.UrlEncode(accessToken.AccessToken.ToString("N")));
|
string wopiSrc = Server.UrlDecode(url);
|
||||||
|
|
||||||
|
string owaOpenerUri = permissions.HasFlag(WebDavPermissions.Write) ? owaOpener.OwaEditor : owaOpener.OwaView;
|
||||||
|
|
||||||
|
var uri = string.Format("{0}/{1}WOPISrc={2}&access_token={3}", WebDavAppConfigManager.Instance.OfficeOnline.Url, owaOpenerUri, Server.UrlEncode(wopiSrc), Server.UrlEncode(accessToken.AccessToken.ToString("N")));
|
||||||
|
|
||||||
return View(new OfficeOnlineModel(uri, new Uri(fileUrl).Segments.Last()));
|
return View(new OfficeOnlineModel(uri, new Uri(fileUrl).Segments.Last()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,86 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
|
||||||
using System.Web;
|
|
||||||
using System.Web.Mvc;
|
|
||||||
using WebsitePanel.EnterpriseServer.Base.HostedSolution;
|
|
||||||
using WebsitePanel.WebDav.Core.Interfaces.Managers;
|
|
||||||
using WebsitePanel.WebDav.Core.Interfaces.Owa;
|
|
||||||
using WebsitePanel.WebDav.Core.Interfaces.Security;
|
|
||||||
using WebsitePanel.WebDav.Core.Security.Cryptography;
|
|
||||||
using WebsitePanel.WebDav.Core.Wsp.Framework;
|
|
||||||
|
|
||||||
namespace WebsitePanel.WebDavPortal.Controllers
|
|
||||||
{
|
|
||||||
[AllowAnonymous]
|
|
||||||
public class OwaController : Controller
|
|
||||||
{
|
|
||||||
private readonly IWopiServer _wopiServer;
|
|
||||||
private readonly IWebDavManager _webDavManager;
|
|
||||||
private readonly IAuthenticationService _authenticationService;
|
|
||||||
private readonly IAccessTokenManager _tokenManager;
|
|
||||||
private readonly ICryptography _cryptography;
|
|
||||||
private WebDavAccessToken _token;
|
|
||||||
|
|
||||||
|
|
||||||
public OwaController(IWopiServer wopiServer, IWebDavManager webDavManager, IAuthenticationService authenticationService, IAccessTokenManager tokenManager, ICryptography cryptography)
|
|
||||||
{
|
|
||||||
_wopiServer = wopiServer;
|
|
||||||
_webDavManager = webDavManager;
|
|
||||||
_authenticationService = authenticationService;
|
|
||||||
_tokenManager = tokenManager;
|
|
||||||
_cryptography = cryptography;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionResult CheckFileInfo(int accessTokenId)
|
|
||||||
{
|
|
||||||
if (!CheckAccess(accessTokenId))
|
|
||||||
{
|
|
||||||
return new HttpStatusCodeResult(HttpStatusCode.NoContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
var fileInfo = _wopiServer.GetCheckFileInfo(_token.FilePath);
|
|
||||||
|
|
||||||
return Json(fileInfo, JsonRequestBehavior.AllowGet);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionResult GetFile(int accessTokenId)
|
|
||||||
{
|
|
||||||
if (!CheckAccess(accessTokenId))
|
|
||||||
{
|
|
||||||
return new HttpStatusCodeResult(HttpStatusCode.NoContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _wopiServer.GetFile((_token.FilePath));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnActionExecuting(ActionExecutingContext filterContext)
|
|
||||||
{
|
|
||||||
base.OnActionExecuting(filterContext);
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(Request["access_token"]))
|
|
||||||
{
|
|
||||||
var guid = Guid.Parse((Request["access_token"]));
|
|
||||||
|
|
||||||
_tokenManager.ClearExpiredTokens();
|
|
||||||
|
|
||||||
_token = _tokenManager.GetToken(guid);
|
|
||||||
|
|
||||||
var user = WSP.Services.ExchangeServer.GetAccount(_token.ItemId, _token.AccountId);
|
|
||||||
|
|
||||||
_authenticationService.LogIn(user.UserPrincipalName, _cryptography.Decrypt(_token.AuthData));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool CheckAccess(int accessTokenId)
|
|
||||||
{
|
|
||||||
if (_token == null || accessTokenId != _token.Id)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Ninject;
|
using System.Web.Http.Dependencies;
|
||||||
|
using Ninject;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -7,13 +8,14 @@ using System.Web.Mvc;
|
||||||
|
|
||||||
namespace WebsitePanel.WebDavPortal.DependencyInjection
|
namespace WebsitePanel.WebDavPortal.DependencyInjection
|
||||||
{
|
{
|
||||||
public class NinjectDependecyResolver : IDependencyResolver
|
public class NinjectDependecyResolver : System.Web.Mvc.IDependencyResolver, System.Web.Http.Dependencies.IDependencyResolver
|
||||||
{
|
{
|
||||||
IKernel kernal;
|
IKernel kernal;
|
||||||
|
|
||||||
public NinjectDependecyResolver()
|
public NinjectDependecyResolver()
|
||||||
{
|
{
|
||||||
kernal = new StandardKernel(new NinjectSettings { AllowNullInjection = true });
|
kernal = new StandardKernel(new NinjectSettings { AllowNullInjection = true });
|
||||||
|
|
||||||
AddBindings();
|
AddBindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,9 +29,19 @@ namespace WebsitePanel.WebDavPortal.DependencyInjection
|
||||||
return kernal.GetAll(serviceType);
|
return kernal.GetAll(serviceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IDependencyScope BeginScope()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
private void AddBindings()
|
private void AddBindings()
|
||||||
{
|
{
|
||||||
PortalDependencies.Configure(kernal);
|
PortalDependencies.Configure(kernal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,11 +3,13 @@ using System.Web.SessionState;
|
||||||
using WebsitePanel.WebDav.Core.Interfaces.Managers;
|
using WebsitePanel.WebDav.Core.Interfaces.Managers;
|
||||||
using WebsitePanel.WebDav.Core.Interfaces.Owa;
|
using WebsitePanel.WebDav.Core.Interfaces.Owa;
|
||||||
using WebsitePanel.WebDav.Core.Interfaces.Security;
|
using WebsitePanel.WebDav.Core.Interfaces.Security;
|
||||||
|
using WebsitePanel.WebDav.Core.Interfaces.Storages;
|
||||||
using WebsitePanel.WebDav.Core.Managers;
|
using WebsitePanel.WebDav.Core.Managers;
|
||||||
using WebsitePanel.WebDav.Core.Owa;
|
using WebsitePanel.WebDav.Core.Owa;
|
||||||
using WebsitePanel.WebDav.Core.Security.Authentication;
|
using WebsitePanel.WebDav.Core.Security.Authentication;
|
||||||
using WebsitePanel.WebDav.Core.Security.Authorization;
|
using WebsitePanel.WebDav.Core.Security.Authorization;
|
||||||
using WebsitePanel.WebDav.Core.Security.Cryptography;
|
using WebsitePanel.WebDav.Core.Security.Cryptography;
|
||||||
|
using WebsitePanel.WebDav.Core.Storages;
|
||||||
using WebsitePanel.WebDavPortal.DependencyInjection.Providers;
|
using WebsitePanel.WebDavPortal.DependencyInjection.Providers;
|
||||||
|
|
||||||
namespace WebsitePanel.WebDavPortal.DependencyInjection
|
namespace WebsitePanel.WebDavPortal.DependencyInjection
|
||||||
|
@ -22,7 +24,10 @@ namespace WebsitePanel.WebDavPortal.DependencyInjection
|
||||||
kernel.Bind<IWebDavManager>().To<WebDavManager>();
|
kernel.Bind<IWebDavManager>().To<WebDavManager>();
|
||||||
kernel.Bind<IAccessTokenManager>().To<AccessTokenManager>();
|
kernel.Bind<IAccessTokenManager>().To<AccessTokenManager>();
|
||||||
kernel.Bind<IWopiServer>().To<WopiServer>();
|
kernel.Bind<IWopiServer>().To<WopiServer>();
|
||||||
|
kernel.Bind<IWopiFileManager>().To<CobaltFileManager>();
|
||||||
kernel.Bind<IWebDavAuthorizationService>().To<WebDavAuthorizationService>();
|
kernel.Bind<IWebDavAuthorizationService>().To<WebDavAuthorizationService>();
|
||||||
|
kernel.Bind<ICobaltManager>().To<CobaltManager>();
|
||||||
|
kernel.Bind<ITtlStorage>().To<CacheTtlStorage>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,15 +1,18 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
|
using System.Web.Http;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
using System.Web.Optimization;
|
using System.Web.Optimization;
|
||||||
using System.Web.Routing;
|
using System.Web.Routing;
|
||||||
using System.Web.Script.Serialization;
|
using System.Web.Script.Serialization;
|
||||||
using System.Web.Security;
|
using System.Web.Security;
|
||||||
|
using System.Web.SessionState;
|
||||||
using WebsitePanel.WebDav.Core.Config;
|
using WebsitePanel.WebDav.Core.Config;
|
||||||
using WebsitePanel.WebDav.Core.Interfaces.Security;
|
using WebsitePanel.WebDav.Core.Interfaces.Security;
|
||||||
using WebsitePanel.WebDav.Core.Security.Authentication.Principals;
|
using WebsitePanel.WebDav.Core.Security.Authentication.Principals;
|
||||||
using WebsitePanel.WebDav.Core.Security.Cryptography;
|
using WebsitePanel.WebDav.Core.Security.Cryptography;
|
||||||
|
using WebsitePanel.WebDavPortal.App_Start;
|
||||||
using WebsitePanel.WebDavPortal.Controllers;
|
using WebsitePanel.WebDavPortal.Controllers;
|
||||||
using WebsitePanel.WebDavPortal.DependencyInjection;
|
using WebsitePanel.WebDavPortal.DependencyInjection;
|
||||||
using WebsitePanel.WebDavPortal.HttpHandlers;
|
using WebsitePanel.WebDavPortal.HttpHandlers;
|
||||||
|
@ -22,8 +25,10 @@ namespace WebsitePanel.WebDavPortal
|
||||||
{
|
{
|
||||||
AreaRegistration.RegisterAllAreas();
|
AreaRegistration.RegisterAllAreas();
|
||||||
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
|
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
|
||||||
|
WebApiConfig.Register(GlobalConfiguration.Configuration);
|
||||||
RouteConfig.RegisterRoutes(RouteTable.Routes);
|
RouteConfig.RegisterRoutes(RouteTable.Routes);
|
||||||
BundleConfig.RegisterBundles(BundleTable.Bundles);
|
BundleConfig.RegisterBundles(BundleTable.Bundles);
|
||||||
|
GlobalConfiguration.Configuration.MessageHandlers.Add(new AccessTokenHandler());
|
||||||
|
|
||||||
DependencyResolver.SetResolver(new NinjectDependecyResolver());
|
DependencyResolver.SetResolver(new NinjectDependecyResolver());
|
||||||
|
|
||||||
|
@ -57,7 +62,14 @@ namespace WebsitePanel.WebDavPortal
|
||||||
Response.End();
|
Response.End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void Application_BeginRequest(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var s = HttpContext.Current.Request;
|
||||||
|
}
|
||||||
|
|
||||||
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
|
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (!IsOwaRequest())
|
||||||
{
|
{
|
||||||
var contextWrapper = new HttpContextWrapper(Context);
|
var contextWrapper = new HttpContextWrapper(Context);
|
||||||
HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
|
HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
|
||||||
|
@ -73,7 +85,8 @@ namespace WebsitePanel.WebDavPortal
|
||||||
|
|
||||||
var principalSerialized = serializer.Deserialize<WspPrincipal>(authTicket.UserData);
|
var principalSerialized = serializer.Deserialize<WspPrincipal>(authTicket.UserData);
|
||||||
|
|
||||||
authService.LogIn(principalSerialized.Login, cryptography.Decrypt(principalSerialized.EncryptedPassword));
|
authService.LogIn(principalSerialized.Login,
|
||||||
|
cryptography.Decrypt(principalSerialized.EncryptedPassword));
|
||||||
|
|
||||||
if (!contextWrapper.Request.IsAjaxRequest())
|
if (!contextWrapper.Request.IsAjaxRequest())
|
||||||
{
|
{
|
||||||
|
@ -81,6 +94,14 @@ namespace WebsitePanel.WebDavPortal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private bool IsOwaRequest()
|
||||||
|
{
|
||||||
|
return HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath.StartsWith("~/owa");
|
||||||
|
}
|
||||||
|
|
||||||
public static void SetAuthenticationExpirationTicket()
|
public static void SetAuthenticationExpirationTicket()
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Mvc;
|
||||||
|
using WebsitePanel.WebDav.Core.Interfaces.Managers;
|
||||||
|
using WebsitePanel.WebDav.Core.Interfaces.Security;
|
||||||
|
using WebsitePanel.WebDav.Core.Security.Cryptography;
|
||||||
|
using WebsitePanel.WebDav.Core.Wsp.Framework;
|
||||||
|
|
||||||
|
namespace WebsitePanel.WebDavPortal.HttpHandlers
|
||||||
|
{
|
||||||
|
public class AccessTokenHandler : DelegatingHandler
|
||||||
|
{
|
||||||
|
private const string Bearer = "Bearer ";
|
||||||
|
|
||||||
|
protected override async Task<HttpResponseMessage> SendAsync(
|
||||||
|
HttpRequestMessage request, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
if (request.Headers.Contains("Authorization"))
|
||||||
|
{
|
||||||
|
var tokenString = request.Headers.GetValues("Authorization").First();
|
||||||
|
if (!string.IsNullOrEmpty(tokenString) && tokenString.StartsWith(Bearer))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var accessToken = tokenString.Substring(Bearer.Length - 1);
|
||||||
|
|
||||||
|
var tokenManager = DependencyResolver.Current.GetService<IAccessTokenManager>();
|
||||||
|
|
||||||
|
var guid = Guid.Parse(accessToken);
|
||||||
|
tokenManager.ClearExpiredTokens();
|
||||||
|
|
||||||
|
var token = tokenManager.GetToken(guid);
|
||||||
|
|
||||||
|
if (token != null)
|
||||||
|
{
|
||||||
|
var authenticationService = DependencyResolver.Current.GetService<IAuthenticationService>();
|
||||||
|
var cryptography = DependencyResolver.Current.GetService<ICryptography>();
|
||||||
|
|
||||||
|
|
||||||
|
var user = WSP.Services.ExchangeServer.GetAccount(token.ItemId, token.AccountId);
|
||||||
|
|
||||||
|
authenticationService.LogIn(user.UserPrincipalName, cryptography.Decrypt(token.AuthData));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return await
|
||||||
|
base.SendAsync(request, cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -61,13 +61,13 @@
|
||||||
<add extension=".xlsx" path="~/Content/Images/excel-icon.png" />
|
<add extension=".xlsx" path="~/Content/Images/excel-icon.png" />
|
||||||
<add extension=".png" path="~/Content/Images/png-icon.png" />
|
<add extension=".png" path="~/Content/Images/png-icon.png" />
|
||||||
</fileIcons>
|
</fileIcons>
|
||||||
<officeOnline isEnabled="True" url="https://vir-owa.virtuworks.net">
|
<officeOnline isEnabled="True" url="https://vir-owa.virtuworks.net" cobaltFileTtl="30">
|
||||||
<add extension=".doc" owaOpener="wv/wordviewerframe.aspx" />
|
<add extension=".doc" OwaView="wv/wordviewerframe.aspx?" OwaEditor="we/wordeditorframe.aspx?" />
|
||||||
<add extension=".docx" owaOpener="wv/wordviewerframe.aspx" />
|
<add extension=".docx" OwaView="wv/wordviewerframe.aspx?" OwaEditor="we/wordeditorframe.aspx?" />
|
||||||
<add extension=".xls" owaOpener="x/_layouts/xlviewerinternal.aspx" />
|
<add extension=".xls" OwaView="x/_layouts/xlviewerinternal.aspx?" OwaEditor="x/_layouts/xlviewerinternal.aspx?edit=1&" />
|
||||||
<add extension=".xlsx" owaOpener="x/_layouts/xlviewerinternal.aspx" />
|
<add extension=".xlsx" OwaView="x/_layouts/xlviewerinternal.aspx?" OwaEditor="x/_layouts/xlviewerinternal.aspx?edit=1&" />
|
||||||
<add extension=".ppt" owaOpener="p/PowerPointFrame.aspx" />
|
<add extension=".ppt" OwaView="p/PowerPointFrame.aspx?" OwaEditor="p/PowerPointFrame.aspx?PowerPointView=EditView&" />
|
||||||
<add extension=".pptx" owaOpener="p/PowerPointFrame.aspx" />
|
<add extension=".pptx" OwaView="p/PowerPointFrame.aspx?" OwaEditor="p/PowerPointFrame.aspx?PowerPointView=EditView&" />
|
||||||
</officeOnline>
|
</officeOnline>
|
||||||
</webDavExplorerConfigurationSettings>
|
</webDavExplorerConfigurationSettings>
|
||||||
<!--
|
<!--
|
||||||
|
@ -79,6 +79,7 @@
|
||||||
</system.Web>
|
</system.Web>
|
||||||
-->
|
-->
|
||||||
<system.web>
|
<system.web>
|
||||||
|
<customErrors mode="Off"/>
|
||||||
<!--<identity impersonate="true"/>-->
|
<!--<identity impersonate="true"/>-->
|
||||||
<compilation debug="true" targetFramework="4.5" />
|
<compilation debug="true" targetFramework="4.5" />
|
||||||
<!-- Maximum size of uploaded file, in MB -->
|
<!-- Maximum size of uploaded file, in MB -->
|
||||||
|
@ -101,7 +102,7 @@
|
||||||
<remove name="UrlRoutingModule-4.0" />
|
<remove name="UrlRoutingModule-4.0" />
|
||||||
<add name="ChartImg" path="ChartImg.axd" verb="GET,HEAD,POST" type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, System.Web.DataVisualization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" resourceType="Unspecified" preCondition="integratedMode" />
|
<add name="ChartImg" path="ChartImg.axd" verb="GET,HEAD,POST" type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, System.Web.DataVisualization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" resourceType="Unspecified" preCondition="integratedMode" />
|
||||||
<add name="FileHandler" path="*.*" verb="GET" type="WebsitePanel.WebDavPortal.HttpHandlers.FileTransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
<add name="FileHandler" path="*.*" verb="GET" type="WebsitePanel.WebDavPortal.HttpHandlers.FileTransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
</handlers>
|
<remove name="ExtensionlessUrlHandler-Integrated-4.0" /><remove name="OPTIONSVerbHandler" /><remove name="TRACEVerbHandler" /><add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /></handlers>
|
||||||
<modules>
|
<modules>
|
||||||
<add name="SecureSession" type="WebsitePanel.WebPortal.SecureSessionModule" />
|
<add name="SecureSession" type="WebsitePanel.WebPortal.SecureSessionModule" />
|
||||||
</modules>
|
</modules>
|
||||||
|
|
|
@ -51,6 +51,9 @@
|
||||||
<Reference Include="log4net">
|
<Reference Include="log4net">
|
||||||
<HintPath>..\packages\log4net.2.0.0\lib\net40-full\log4net.dll</HintPath>
|
<HintPath>..\packages\log4net.2.0.0\lib\net40-full\log4net.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.CobaltCore">
|
||||||
|
<HintPath>..\..\Lib\References\Microsoft\Microsoft.CobaltCore.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
<Reference Include="Microsoft.Web.Services3">
|
<Reference Include="Microsoft.Web.Services3">
|
||||||
<HintPath>..\..\Lib\Microsoft.Web.Services3.dll</HintPath>
|
<HintPath>..\..\Lib\Microsoft.Web.Services3.dll</HintPath>
|
||||||
|
@ -71,6 +74,10 @@
|
||||||
<Reference Include="System.Data.Entity" />
|
<Reference Include="System.Data.Entity" />
|
||||||
<Reference Include="System.DirectoryServices" />
|
<Reference Include="System.DirectoryServices" />
|
||||||
<Reference Include="System.Drawing" />
|
<Reference Include="System.Drawing" />
|
||||||
|
<Reference Include="System.Net.Http.Formatting, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.2\lib\net45\System.Net.Http.Formatting.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System.Web.DataVisualization" />
|
<Reference Include="System.Web.DataVisualization" />
|
||||||
<Reference Include="System.Web.DynamicData" />
|
<Reference Include="System.Web.DynamicData" />
|
||||||
<Reference Include="System.Web.Entity" />
|
<Reference Include="System.Web.Entity" />
|
||||||
|
@ -81,6 +88,14 @@
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.2\lib\net45\System.Web.Helpers.dll</HintPath>
|
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.2\lib\net45\System.Web.Helpers.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="System.Web.Http, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.2\lib\net45\System.Web.Http.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Web.Http.WebHost, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.2\lib\net45\System.Web.Http.WebHost.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System.Web.Mvc, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
<Reference Include="System.Web.Mvc, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Microsoft.AspNet.Mvc.5.2.2\lib\net45\System.Web.Mvc.dll</HintPath>
|
<HintPath>..\packages\Microsoft.AspNet.Mvc.5.2.2\lib\net45\System.Web.Mvc.dll</HintPath>
|
||||||
|
@ -140,11 +155,15 @@
|
||||||
<Compile Include="App_Start\BundleConfig.cs" />
|
<Compile Include="App_Start\BundleConfig.cs" />
|
||||||
<Compile Include="App_Start\FilterConfig.cs" />
|
<Compile Include="App_Start\FilterConfig.cs" />
|
||||||
<Compile Include="App_Start\RouteConfig.cs" />
|
<Compile Include="App_Start\RouteConfig.cs" />
|
||||||
<Compile Include="Constraints\OrganizationRouteConstraint.cs" />
|
<Compile Include="App_Start\WebApiConfig.cs" />
|
||||||
|
<Compile Include="Configurations\ActionSelectors\OwaActionSelector.cs" />
|
||||||
|
<Compile Include="Configurations\Constraints\OrganizationRouteConstraint.cs" />
|
||||||
|
<Compile Include="Configurations\ControllerConfigurations\OwaControllerConfiguration.cs" />
|
||||||
<Compile Include="Controllers\AccountController.cs" />
|
<Compile Include="Controllers\AccountController.cs" />
|
||||||
<Compile Include="Controllers\ErrorController.cs" />
|
<Compile Include="Controllers\ErrorController.cs" />
|
||||||
<Compile Include="Controllers\FileSystemController.cs" />
|
<Compile Include="Controllers\FileSystemController.cs" />
|
||||||
<Compile Include="Controllers\OwaController.cs" />
|
<Compile Include="Controllers\Api\OwaController.cs" />
|
||||||
|
<Compile Include="Controllers\WopiSession.cs" />
|
||||||
<Compile Include="CustomAttributes\FormValueRequiredAttribute.cs" />
|
<Compile Include="CustomAttributes\FormValueRequiredAttribute.cs" />
|
||||||
<Compile Include="CustomAttributes\LdapAuthorizationAttribute.cs" />
|
<Compile Include="CustomAttributes\LdapAuthorizationAttribute.cs" />
|
||||||
<Compile Include="DependencyInjection\NinjectDependecyResolver.cs" />
|
<Compile Include="DependencyInjection\NinjectDependecyResolver.cs" />
|
||||||
|
@ -158,6 +177,7 @@
|
||||||
<Compile Include="Global.asax.cs">
|
<Compile Include="Global.asax.cs">
|
||||||
<DependentUpon>Global.asax</DependentUpon>
|
<DependentUpon>Global.asax</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="HttpHandlers\AccessTokenHandler.cs" />
|
||||||
<Compile Include="HttpHandlers\FileTransferRequestHandler.cs" />
|
<Compile Include="HttpHandlers\FileTransferRequestHandler.cs" />
|
||||||
<Compile Include="Models\AccountModel.cs" />
|
<Compile Include="Models\AccountModel.cs" />
|
||||||
<Compile Include="Models\Common\BaseModel.cs" />
|
<Compile Include="Models\Common\BaseModel.cs" />
|
||||||
|
|
|
@ -9,6 +9,10 @@
|
||||||
<package id="Microsoft.AspNet.Mvc" version="5.2.2" targetFramework="net45" />
|
<package id="Microsoft.AspNet.Mvc" version="5.2.2" targetFramework="net45" />
|
||||||
<package id="Microsoft.AspNet.Razor" version="3.2.2" targetFramework="net45" />
|
<package id="Microsoft.AspNet.Razor" version="3.2.2" targetFramework="net45" />
|
||||||
<package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net45" />
|
<package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net45" />
|
||||||
|
<package id="Microsoft.AspNet.WebApi" version="5.2.2" targetFramework="net45" />
|
||||||
|
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.2" targetFramework="net45" />
|
||||||
|
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.2" targetFramework="net45" />
|
||||||
|
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.2" targetFramework="net45" />
|
||||||
<package id="Microsoft.AspNet.WebPages" version="3.2.2" targetFramework="net45" />
|
<package id="Microsoft.AspNet.WebPages" version="3.2.2" targetFramework="net45" />
|
||||||
<package id="Microsoft.jQuery.Unobtrusive.Validation" version="3.2.2" targetFramework="net45" />
|
<package id="Microsoft.jQuery.Unobtrusive.Validation" version="3.2.2" targetFramework="net45" />
|
||||||
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
|
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue