webdav portal filter + detail view added

This commit is contained in:
vfedosevich 2015-02-18 02:35:32 -08:00
parent 280628e362
commit 51d432fd2e
156 changed files with 32494 additions and 260 deletions

View file

@ -0,0 +1,29 @@
using System;
using System.ComponentModel;
using System.Resources;
namespace WebsitePanel.WebDav.Core.Attributes.Resources
{
public class LocalizedDescriptionAttribute : DescriptionAttribute
{
private readonly string _resourceKey;
private readonly ResourceManager _resource;
public LocalizedDescriptionAttribute(Type resourceType, string resourceKey)
{
_resource = new ResourceManager(resourceType);
_resourceKey = resourceKey;
}
public override string Description
{
get
{
string displayName = _resource.GetString(_resourceKey);
return string.IsNullOrEmpty(displayName)
? string.Format("[[{0}]]", _resourceKey)
: displayName;
}
}
}
}

View file

@ -7,13 +7,11 @@ namespace WebsitePanel.WebDav.Core.Config.Entities
{
public int DefaultCount { get; private set; }
public int AddElementsCount { get; private set; }
public List<string> ElementsToIgnore { get; private set; }
public ElementsRendering()
{
DefaultCount = ConfigSection.ElementsRendering.DefaultCount;
AddElementsCount = ConfigSection.ElementsRendering.AddElementsCount;
ElementsToIgnore = ConfigSection.ElementsRendering.ElementsToIgnore.Split(',').ToList();
}
}
}

View file

@ -12,10 +12,12 @@ namespace WebsitePanel.WebDav.Core.Config.Entities
public FileIconsDictionary()
{
DefaultPath = ConfigSection.FileIcons.DefaultPath;
FolderPath = ConfigSection.FileIcons.FolderPath;
_fileIcons = ConfigSection.FileIcons.Cast<FileIconsElement>().ToDictionary(x => x.Extension, y => y.Path);
}
public string DefaultPath { get; private set; }
public string FolderPath { get; private set; }
public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
{
@ -57,4 +59,4 @@ namespace WebsitePanel.WebDav.Core.Config.Entities
get { return _fileIcons.Values; }
}
}
}
}

View file

@ -0,0 +1,38 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using WebsitePanel.WebDav.Core.Config.WebConfigSections;
using WebsitePanel.WebDavPortal.WebConfigSections;
namespace WebsitePanel.WebDav.Core.Config.Entities
{
public class FilesToIgnoreCollection : AbstractConfigCollection, IReadOnlyCollection<FilesToIgnoreElement>
{
private readonly IList<FilesToIgnoreElement> _filesToIgnore;
public FilesToIgnoreCollection()
{
_filesToIgnore = ConfigSection.FilesToIgnore.Cast<FilesToIgnoreElement>().ToList();
}
public IEnumerator<FilesToIgnoreElement> GetEnumerator()
{
return _filesToIgnore.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public int Count
{
get { return _filesToIgnore.Count; }
}
public bool Contains(string name)
{
return _filesToIgnore.Any(x => x.Name == name);
}
}
}

View file

@ -13,5 +13,6 @@ namespace WebsitePanel.WebDav.Core.Config
HttpErrorsCollection HttpErrors { get; }
OfficeOnlineCollection OfficeOnline { get; }
OwaSupportedBrowsersCollection OwaSupportedBrowsers { get; }
FilesToIgnoreCollection FilesToIgnore { get; }
}
}

View file

@ -6,7 +6,6 @@ namespace WebsitePanel.WebDav.Core.Config.WebConfigSections
{
private const string DefaultCountKey = "defaultCount";
private const string AddElementsCountKey = "addElementsCount";
private const string ElementsToIgnoreKey = "elementsToIgnoreKey";
[ConfigurationProperty(DefaultCountKey, IsKey = true, IsRequired = true, DefaultValue = 30)]
public int DefaultCount
@ -21,12 +20,5 @@ namespace WebsitePanel.WebDav.Core.Config.WebConfigSections
get { return (int)this[AddElementsCountKey]; }
set { this[AddElementsCountKey] = value; }
}
[ConfigurationProperty(ElementsToIgnoreKey, IsKey = true, IsRequired = true, DefaultValue = "")]
public string ElementsToIgnore
{
get { return (string)this[ElementsToIgnoreKey]; }
set { this[ElementsToIgnoreKey] = value; }
}
}
}

View file

@ -6,6 +6,7 @@ namespace WebsitePanel.WebDav.Core.Config.WebConfigSections
public class FileIconsElementCollection : ConfigurationElementCollection
{
private const string DefaultPathKey = "defaultPath";
private const string FolderPathKey = "folderPath";
[ConfigurationProperty(DefaultPathKey, IsRequired = false, DefaultValue = "/")]
public string DefaultPath
@ -14,6 +15,13 @@ namespace WebsitePanel.WebDav.Core.Config.WebConfigSections
set { this[DefaultPathKey] = value; }
}
[ConfigurationProperty(FolderPathKey, IsRequired = false)]
public string FolderPath
{
get { return (string)this[FolderPathKey]; }
set { this[FolderPathKey] = value; }
}
protected override ConfigurationElement CreateNewElement()
{
return new FileIconsElement();

View file

@ -0,0 +1,24 @@
using System.Configuration;
namespace WebsitePanel.WebDav.Core.Config.WebConfigSections
{
public class FilesToIgnoreElement : ConfigurationElement
{
private const string NameKey = "name";
private const string RegexKey = "regex";
[ConfigurationProperty(NameKey, IsKey = true, IsRequired = true)]
public string Name
{
get { return this[NameKey].ToString(); }
set { this[NameKey] = value; }
}
[ConfigurationProperty(RegexKey, IsKey = true, IsRequired = true)]
public string Regex
{
get { return this[RegexKey].ToString(); }
set { this[RegexKey] = value; }
}
}
}

View file

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

View file

@ -17,6 +17,7 @@ namespace WebsitePanel.WebDavPortal.WebConfigSections
private const string FileIconsKey = "fileIcons";
private const string OwaSupportedBrowsersKey = "owaSupportedBrowsers";
private const string OfficeOnlineKey = "officeOnline";
private const string FilesToIgnoreKey = "filesToIgnore";
public const string SectionName = "webDavExplorerConfigurationSettings";
@ -89,5 +90,12 @@ namespace WebsitePanel.WebDavPortal.WebConfigSections
get { return (OfficeOnlineElementCollection)this[OfficeOnlineKey]; }
set { this[OfficeOnlineKey] = value; }
}
[ConfigurationProperty(FilesToIgnoreKey, IsDefaultCollection = false)]
public FilesToIgnoreElementCollection FilesToIgnore
{
get { return (FilesToIgnoreElementCollection)this[FilesToIgnoreKey]; }
set { this[FilesToIgnoreKey] = value; }
}
}
}

View file

@ -19,6 +19,7 @@ namespace WebsitePanel.WebDav.Core.Config
HttpErrors = new HttpErrorsCollection();
OfficeOnline = new OfficeOnlineCollection();
OwaSupportedBrowsers = new OwaSupportedBrowsersCollection();
FilesToIgnore = new FilesToIgnoreCollection();
}
public static WebDavAppConfigManager Instance
@ -53,5 +54,6 @@ namespace WebsitePanel.WebDav.Core.Config
public HttpErrorsCollection HttpErrors { get; private set; }
public OfficeOnlineCollection OfficeOnline { get; private set; }
public OwaSupportedBrowsersCollection OwaSupportedBrowsers { get; private set; }
public FilesToIgnoreCollection FilesToIgnore { get; private set; }
}
}

View file

@ -0,0 +1,8 @@
namespace WebsitePanel.WebDav.Core.Entities.Account.Enums
{
public enum FolderViewTypes
{
BigIcons,
Table
}
}

View file

@ -0,0 +1,9 @@
using WebsitePanel.WebDav.Core.Entities.Account.Enums;
namespace WebsitePanel.WebDav.Core.Entities.Account
{
public class UserPortalSettings
{
public FolderViewTypes WebDavViewType { get; set; }
}
}

View file

@ -0,0 +1,23 @@
using System;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Resources;
using WebsitePanel.WebDav.Core.Attributes.Resources;
namespace WebsitePanel.WebDav.Core.Extensions
{
public static class EnumExtensions
{
public static string GetDescription(this Enum value)
{
FieldInfo field = value.GetType().GetField(value.ToString());
DescriptionAttribute attribute
= Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute))
as DescriptionAttribute;
return attribute == null ? value.ToString() : attribute.Description;
}
}
}

View file

@ -0,0 +1,41 @@
using System.IO;
using System.Xml;
using System.Xml.Serialization;
namespace WebsitePanel.WebDav.Core.Helper
{
public class SerializeHelper
{
public static TResult Deserialize<TResult>(string inputString)
{
TResult result;
var serializer = new XmlSerializer(typeof(TResult));
using (TextReader reader = new StringReader(inputString))
{
result = (TResult)serializer.Deserialize(reader);
}
return result;
}
public static string Serialize<TEntity>(TEntity entity)
{
string result = string.Empty;
var xmlSerializer = new XmlSerializer(typeof(TEntity));
using (var stringWriter = new StringWriter())
{
using (XmlWriter writer = XmlWriter.Create(stringWriter))
{
xmlSerializer.Serialize(writer, entity);
result = stringWriter.ToString();
}
}
return result;
}
}
}

View file

@ -218,6 +218,68 @@ namespace WebsitePanel.WebDav.Core
Open();
}
public void OpenPaged(string path)
{
_path = new Uri(path);
OpenPaged();
}
public void OpenPaged()
{
var request = (HttpWebRequest)WebRequest.Create(_path);
//request.PreAuthenticate = true;
request.Method = "SEARCH";
//TODO Disable SSL
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return true; });
var credentials = (NetworkCredential)_credentials;
if (credentials != null && credentials.UserName != null)
{
request.Credentials = _credentials;
string auth = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes(credentials.UserName + ":" + credentials.Password));
request.Headers.Add("Authorization", auth);
}
var strQuery = "<?xml version=\"1.0\"?><D:searchrequest xmlns:D = \"DAV:\" >"
+ "<D:sql>SELECT \"DAV:displayname\" FROM \"" + _path + "\""
+ "WHERE \"DAV:ishidden\" = false"
+ "</D:sql></D:searchrequest>";
try
{
var bytes = Encoding.UTF8.GetBytes(strQuery);
request.ContentLength = bytes.Length;
using (var requestStream = request.GetRequestStream())
{
// Write the SQL query to the request stream.
requestStream.Write(bytes, 0, bytes.Length);
}
request.ContentType = "text/xml";
using (var response = (HttpWebResponse)request.GetResponse())
{
using (var responseStream = new StreamReader(response.GetResponseStream()))
{
string responseString = responseStream.ReadToEnd();
ProcessResponse(responseString);
}
}
}
catch (WebException e)
{
if (e.Status == WebExceptionStatus.ProtocolError)
{
throw new UnauthorizedException();
}
throw e;
}
}
/// <summary>
/// Processes the response from the server.
/// </summary>

View file

@ -44,6 +44,15 @@ namespace WebsitePanel.WebDav.Core
AllowWriteStreamBuffering = false;
}
public WebDavResource(ICredentials credentials, IHierarchyItem item)
{
SendChunked = false;
AllowWriteStreamBuffering = false;
SetCredentials(credentials);
SetHierarchyItem(item);
}
public Uri BaseUri
{
get { return _baseUri; }

View file

@ -0,0 +1,13 @@
using WebsitePanel.EnterpriseServer;
using WebsitePanel.WebDav.Core.Entities.Account;
using WebsitePanel.WebDav.Core.Entities.Account.Enums;
namespace WebsitePanel.WebDav.Core.Interfaces.Managers.Users
{
public interface IUserSettingsManager
{
UserPortalSettings GetUserSettings(int accountId);
void UpdateSettings(int accountId, UserPortalSettings settings);
void ChangeWebDavViewType(int accountId, FolderViewTypes type);
}
}

View file

@ -1,10 +1,15 @@
using WebsitePanel.WebDav.Core.Attributes.Resources;
using WebsitePanel.WebDav.Core.Resources;
namespace WebsitePanel.WebDav.Core
{
namespace Client
{
public enum ItemType
{
[LocalizedDescription(typeof(WebDavResources), "ItemTypeResource")]
Resource,
[LocalizedDescription(typeof(WebDavResources), "ItemTypeFolder")]
Folder,
Version,
VersionHistory

View file

@ -0,0 +1,40 @@
using WebsitePanel.EnterpriseServer;
using WebsitePanel.WebDav.Core.Entities.Account;
using WebsitePanel.WebDav.Core.Entities.Account.Enums;
using WebsitePanel.WebDav.Core.Helper;
using WebsitePanel.WebDav.Core.Interfaces.Managers.Users;
using WebsitePanel.WebDav.Core.Wsp.Framework;
namespace WebsitePanel.WebDav.Core.Managers.Users
{
public class UserSettingsManager : IUserSettingsManager
{
public UserPortalSettings GetUserSettings(int accountId)
{
string xml = WSP.Services.EnterpriseStorage.GetWebDavPortalUserSettingsByAccountId(accountId);
if (string.IsNullOrEmpty(xml))
{
return new UserPortalSettings();
}
return SerializeHelper.Deserialize<UserPortalSettings>(xml);
}
public void UpdateSettings(int accountId, UserPortalSettings settings)
{
var xml = SerializeHelper.Serialize(settings);
WSP.Services.EnterpriseStorage.UpdateWebDavPortalUserSettings(accountId, xml);
}
public void ChangeWebDavViewType(int accountId, FolderViewTypes type)
{
var settings = GetUserSettings(accountId);
settings.WebDavViewType = type;
UpdateSettings(accountId, settings);
}
}
}

View file

@ -4,6 +4,7 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Xml.Serialization;
using log4net;
@ -74,7 +75,7 @@ namespace WebsitePanel.WebDav.Core.Managers
_currentFolder = _webDavSession.OpenFolder(string.Format("{0}{1}/{2}", WebDavAppConfigManager.Instance.WebdavRoot, WspContext.User.OrganizationId, pathPart.TrimStart('/')));
}
children = _currentFolder.GetChildren().Where(x => !WebDavAppConfigManager.Instance.ElementsRendering.ElementsToIgnore.Contains(x.DisplayName.Trim('/'))).ToArray();
children = FilterResult(_currentFolder.GetChildren()).ToArray();
}
List<IHierarchyItem> sortedChildren = children.Where(x => x.ItemType == ItemType.Folder).OrderBy(x => x.DisplayName).ToList();
@ -352,7 +353,31 @@ namespace WebsitePanel.WebDav.Core.Managers
}
return path.Split('/').Last(); ;
}
}
private IEnumerable<IHierarchyItem> FilterResult(IEnumerable<IHierarchyItem> items)
{
var result = items.ToList();
foreach (var item in items)
{
foreach (var itemToIgnore in WebDavAppConfigManager.Instance.FilesToIgnore)
{
var regex = new Regex(itemToIgnore.Regex);
Match match = regex.Match(item.DisplayName.Trim('/'));
if (match.Success && result.Contains(item))
{
result.Remove(item);
break;
}
}
}
return result;
}
#endregion
}

View file

@ -68,5 +68,23 @@ namespace WebsitePanel.WebDav.Core.Resources {
return ResourceManager.GetString("FolderIsNotEmptyFormat", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Folder.
/// </summary>
internal static string ItemTypeFolder {
get {
return ResourceManager.GetString("ItemTypeFolder", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Document.
/// </summary>
internal static string ItemTypeResource {
get {
return ResourceManager.GetString("ItemTypeResource", resourceCulture);
}
}
}
}

View file

@ -120,4 +120,10 @@
<data name="FolderIsNotEmptyFormat" xml:space="preserve">
<value>Folder {0} is not empty.</value>
</data>
<data name="ItemTypeFolder" xml:space="preserve">
<value>Folder</value>
</data>
<data name="ItemTypeResource" xml:space="preserve">
<value>Document</value>
</data>
</root>

View file

@ -39,6 +39,19 @@ namespace WebsitePanel.WebDav.Core
return folder;
}
/// <summary>
/// Returns IFolder corresponding to path.
/// </summary>
/// <param name="path">Path to the folder.</param>
/// <returns>Folder corresponding to requested path.</returns>
public IFolder OpenFolderPaged(string path)
{
var folder = new WebDavFolder();
folder.SetCredentials(Credentials);
folder.OpenPaged(path);
return folder;
}
/// <summary>
/// Returns IResource corresponding to path.
/// </summary>

View file

@ -99,10 +99,12 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Attributes\Resources\LocalizedDescriptionAttribute.cs" />
<Compile Include="Config\Entities\AbstractConfigCollection.cs" />
<Compile Include="Config\Entities\ElementsRendering.cs" />
<Compile Include="Config\Entities\FileIconsDictionary.cs" />
<Compile Include="Config\Entities\HttpErrorsCollection.cs" />
<Compile Include="Config\Entities\FilesToIgnoreCollection.cs" />
<Compile Include="Config\Entities\OfficeOnlineCollection.cs" />
<Compile Include="Config\Entities\OwaSupportedBrowsersCollection.cs" />
<Compile Include="Config\Entities\SessionKeysCollection.cs" />
@ -113,6 +115,8 @@
<Compile Include="Config\WebConfigSections\ElementsRenderingElement.cs" />
<Compile Include="Config\WebConfigSections\FileIconsElement.cs" />
<Compile Include="Config\WebConfigSections\FileIconsElementCollection.cs" />
<Compile Include="Config\WebConfigSections\FilesToIgnoreElement.cs" />
<Compile Include="Config\WebConfigSections\FilesToIgnoreElementCollection.cs" />
<Compile Include="Config\WebConfigSections\OfficeOnlineElement.cs" />
<Compile Include="Config\WebConfigSections\OfficeOnlineElementCollection.cs" />
<Compile Include="Config\WebConfigSections\OwaSupportedBrowsersElement.cs" />
@ -124,6 +128,8 @@
<Compile Include="Config\WebConfigSections\WebdavRootElement.cs" />
<Compile Include="Config\WebConfigSections\WebsitePanelConstantUserElement.cs" />
<Compile Include="Config\WebDavAppConfigManager.cs" />
<Compile Include="Entities\Account\Enums\FolderViewTypes.cs" />
<Compile Include="Entities\Account\UserPortalSettings.cs" />
<Compile Include="Entities\Owa\CheckFileInfo.cs" />
<Compile Include="Entities\Owa\PutRelativeFile.cs" />
<Compile Include="Exceptions\ConnectToWebDavServerException.cs" />
@ -131,14 +137,18 @@
<Compile Include="Exceptions\UnauthorizedException.cs" />
<Compile Include="Exceptions\WebDavException.cs" />
<Compile Include="Exceptions\WebDavHttpException.cs" />
<Compile Include="Extensions\EnumExtensions.cs" />
<Compile Include="Extensions\StringExtensions.cs" />
<Compile Include="Extensions\UriExtensions.cs" />
<Compile Include="Helper\SerializeHelper.cs" />
<Compile Include="IConnectionSettings.cs" />
<Compile Include="IFolder.cs" />
<Compile Include="IHierarchyItem.cs" />
<Compile Include="IItemContent.cs" />
<Compile Include="Interfaces\Managers\Users\IUserSettingsManager.cs" />
<Compile Include="Interfaces\Storages\IKeyValueStorage.cs" />
<Compile Include="Interfaces\Storages\ITtlStorage.cs" />
<Compile Include="Managers\Users\UserSettingsManager.cs" />
<Compile Include="Owa\CobaltManager.cs" />
<Compile Include="Interfaces\Owa\ICobaltManager.cs" />
<Compile Include="Interfaces\Owa\IWopiFileManager.cs" />

View file

@ -5,11 +5,13 @@ using System.Text;
using System.Threading.Tasks;
using System.Web;
using WebsitePanel.WebDav.Core.Security.Authentication.Principals;
using WebsitePanel.WebDav.Core.Wsp.Framework;
namespace WebsitePanel.WebDav.Core
{
public class WspContext
{
public static WspPrincipal User { get { return HttpContext.Current.User as WspPrincipal; } }
public static WSP Services { get { return WSP.Services; } }
}
}