This commit is contained in:
vfedosevich 2015-01-21 01:58:26 -08:00
commit 7e2cdb1782
32 changed files with 723 additions and 106 deletions

View file

@ -5,11 +5,11 @@
</configSections>
<!-- Connection strings -->
<connectionStrings>
<add name="EnterpriseServer" connectionString="server=dev-sql;database=WebsitePanel;uid=WebsitePanel;pwd=sbbk40q85dc7jzj8b5kn;" providerName="System.Data.SqlClient"/>
<add name="EnterpriseServer" connectionString="Server=(local)\SQLExpress;Database=WebsitePanel;uid=sa;pwd=Password12" providerName="System.Data.SqlClient"/>
</connectionStrings>
<appSettings>
<!-- Encryption util settings -->
<add key="WebsitePanel.CryptoKey" value="jj2n22t2kje035cg4l77"/>
<add key="WebsitePanel.CryptoKey" value="1234567890"/>
<!-- A1D4KDHUE83NKHddF -->
<add key="WebsitePanel.EncryptionEnabled" value="true"/>
<!-- Web Applications -->

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0"?>
<configuration>
<!-- Custom configuration sections -->
<configSections>
@ -8,7 +8,12 @@
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
</sectionGroup>
<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
</sectionGroup>
</sectionGroup>
</configSections>
@ -50,7 +55,7 @@
<!-- Perform security check -->
<enabled value="true"/>
<!-- Server password -->
<password value="TaIF+82DBVpZ/Ix216bG/o02fUE=" />
<password value="+uxnDOdf55yuH6iZYXgYAxsfIBw="/>
</security>
</websitepanel.server>
<system.web>
@ -168,7 +173,7 @@
</dependentAssembly>
</assemblyBinding>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="bin/Crm2011;bin/Crm2013;bin/Exchange2013;bin/Sharepoint2013;bin/Lync2013;bin/Lync2013HP;bin/Dns2012" />
<probing privatePath="bin/Crm2011;bin/Crm2013;bin/Exchange2013;bin/Sharepoint2013;bin/Lync2013;bin/Lync2013HP;bin/Dns2012;bin/IceWarp;bin/IIs80"/>
</assemblyBinding>
</runtime>
</configuration>

View file

@ -17,9 +17,9 @@
<OldToolsVersion>4.0</OldToolsVersion>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
<UseIISExpress>true</UseIISExpress>
<UseIISExpress>false</UseIISExpress>
<IISExpressSSLPort />
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
@ -79,7 +79,6 @@
<Reference Include="System.ServiceModel" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Web" />
<Reference Include="System.Web.ApplicationServices" />
<Reference Include="System.Web.DynamicData" />
<Reference Include="System.Web.Entity" />
<Reference Include="System.Web.Extensions" />
@ -272,11 +271,12 @@
<VisualStudio>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
<UseIIS>True</UseIIS>
<UseIIS>False</UseIIS>
<AutoAssignPort>False</AutoAssignPort>
<DevelopmentServerPort>9004</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:9003/</IISUrl>
<IISUrl>
</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>

View file

@ -0,0 +1,13 @@
using System;
using System.Linq;
namespace WebsitePanel.WebDav.Core.Extensions
{
static class UriExtensions
{
public static Uri Append(this Uri uri, params string[] paths)
{
return new Uri(paths.Aggregate(uri.AbsoluteUri, (current, path) => string.Format("{0}/{1}", current.TrimEnd('/'), path.TrimStart('/'))));
}
}
}

View file

@ -17,6 +17,7 @@ namespace WebsitePanel.WebDav.Core
DateTime CreationDate { get; }
string CreatorDisplayName { get; }
string DisplayName { get; }
bool IsRootItem { get; set; }
Uri Href { get; }
ItemType ItemType { get;}
DateTime LastModified { get; }
@ -73,6 +74,8 @@ namespace WebsitePanel.WebDav.Core
}
}
public bool IsRootItem { get; set; }
public Uri Href
{
get { return _href; }

View file

@ -7,6 +7,7 @@ namespace WebsitePanel.WebDav.Core
public interface IItemContent
{
long ContentLength { get; }
long AllocatedSpace { get; set; }
string ContentType { get; }
void Download(string filename);

View file

@ -64,6 +64,7 @@ namespace WebsitePanel.WebDav.Core
public long ContentLength
{
get { return _contentLength; }
set { _contentLength = value; }
}
public string ContentType
@ -110,6 +111,23 @@ namespace WebsitePanel.WebDav.Core
webClient.UploadFile(Href, "PUT", filename);
}
/// <summary>
/// Uploads content of a file specified by filename to the server
/// </summary>
/// <param name="data">Posted file data to be uploaded</param>
public void Upload(byte[] data)
{
var credentials = (NetworkCredential)_credentials;
string auth = "Basic " +
Convert.ToBase64String(
Encoding.Default.GetBytes(credentials.UserName + ":" + credentials.Password));
var webClient = new WebClient();
webClient.Credentials = credentials;
webClient.Headers.Add("Authorization", auth);
webClient.UploadData(Href, "PUT", data);
}
/// <summary>
/// Loads content of the resource from WebDAV server.
/// </summary>
@ -233,14 +251,19 @@ namespace WebsitePanel.WebDav.Core
}
}
public long AllocatedSpace { get; set; }
public bool IsRootItem { get; set; }
public Uri Href
{
get { return _href; }
set { SetHref(value.ToString(), new Uri(value.Scheme + "://" + value.Host + value.Segments[0] + value.Segments[1])); }
}
public ItemType ItemType
{
get { return _itemType; }
set { _itemType = value; }
}
public DateTime LastModified

View file

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Web;
using WebsitePanel.WebDav.Core.Client;
namespace WebsitePanel.WebDav.Core.Interfaces.Managers
@ -8,6 +9,7 @@ namespace WebsitePanel.WebDav.Core.Interfaces.Managers
IEnumerable<IHierarchyItem> OpenFolder(string path);
bool IsFile(string path);
byte[] GetFileBytes(string path);
void UploadFile(string path, HttpPostedFileBase file);
IResource GetResource(string path);
string GetFileUrl(string path);
}

View file

@ -0,0 +1,11 @@
using WebsitePanel.WebDav.Core.Security.Authentication.Principals;
using WebsitePanel.WebDav.Core.Security.Authorization.Enums;
namespace WebsitePanel.WebDav.Core.Interfaces.Security
{
public interface IWebDavAuthorizationService
{
bool HasAccess(WspPrincipal principal, string path);
WebDavPermissions GetPermissions(WspPrincipal principal, string path);
}
}

View file

@ -3,11 +3,15 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Xml.Serialization;
using log4net;
using WebsitePanel.Providers.OS;
using WebsitePanel.WebDav.Core.Client;
using WebsitePanel.WebDav.Core.Config;
using WebsitePanel.WebDav.Core.Exceptions;
using WebsitePanel.WebDav.Core.Extensions;
using WebsitePanel.WebDav.Core.Interfaces.Managers;
using WebsitePanel.WebDav.Core.Security.Cryptography;
using WebsitePanel.WebDav.Core.Wsp.Framework;
@ -38,7 +42,25 @@ namespace WebsitePanel.WebDav.Core.Managers
if (string.IsNullOrWhiteSpace(pathPart))
{
children = ConnectToWebDavServer().Select(x => new WebDavHierarchyItem { Href = new Uri(x.Url), ItemType = ItemType.Folder }).ToArray();
var resources = ConnectToWebDavServer().Select(x => new WebDavResource { Href = new Uri(x.Url), ItemType = ItemType.Folder }).ToArray();
var items = WSP.Services.EnterpriseStorage.GetEnterpriseFolders(WspContext.User.ItemId);
foreach (var resource in resources)
{
var folder = items.FirstOrDefault(x => x.Name == resource.DisplayName);
if (folder == null)
{
continue;
}
resource.ContentLength = folder.Size;
resource.AllocatedSpace = folder.FRSMQuotaMB;
resource.IsRootItem = true;
}
children = resources;
}
else
{
@ -51,7 +73,7 @@ namespace WebsitePanel.WebDav.Core.Managers
_currentFolder = _webDavSession.OpenFolder(string.Format("{0}{1}/{2}", WebDavAppConfigManager.Instance.WebdavRoot, WspContext.User.OrganizationId, pathPart));
}
children = _currentFolder.GetChildren();
children = _currentFolder.GetChildren().Where(x => !WebDavAppConfigManager.Instance.ElementsRendering.ElementsToIgnore.Contains(x.DisplayName.Trim('/'))).ToArray();
}
List<IHierarchyItem> sortedChildren = children.Where(x => x.ItemType == ItemType.Folder).OrderBy(x => x.DisplayName).ToList();
@ -108,6 +130,24 @@ namespace WebsitePanel.WebDav.Core.Managers
}
}
public void UploadFile(string path, HttpPostedFileBase file)
{
var resource = new WebDavResource();
var fileUrl = new Uri(WebDavAppConfigManager.Instance.WebdavRoot)
.Append(WspContext.User.OrganizationId)
.Append(path)
.Append(Path.GetFileName(file.FileName));
resource.SetHref(fileUrl);
resource.SetCredentials(new NetworkCredential(WspContext.User.Login, _cryptography.Decrypt(WspContext.User.EncryptedPassword)));
file.InputStream.Seek(0, SeekOrigin.Begin);
var bytes = ReadFully(file.InputStream);
resource.Upload(bytes);
}
public IResource GetResource(string path)
{
try
@ -184,6 +224,14 @@ namespace WebsitePanel.WebDav.Core.Managers
}
}
public void WriteTo(Stream sourceStream, Stream targetStream)
{
byte[] buffer = new byte[16 * 1024];
int n;
while ((n = sourceStream.Read(buffer, 0, buffer.Length)) != 0)
targetStream.Write(buffer, 0, n);
}
private string GetFileFolder(string path)
{
path = path.TrimEnd('/');

View file

@ -0,0 +1,13 @@
using System;
namespace WebsitePanel.WebDav.Core.Security.Authorization.Enums
{
[Flags]
public enum WebDavPermissions
{
Empty = 0,
None = 1,
Read = 2,
Write = 4
}
}

View file

@ -0,0 +1,69 @@
using System;
using System.Linq;
using WebsitePanel.WebDav.Core.Interfaces.Security;
using WebsitePanel.WebDav.Core.Security.Authentication.Principals;
using WebsitePanel.WebDav.Core.Security.Authorization.Enums;
using WebsitePanel.WebDav.Core.Wsp.Framework;
namespace WebsitePanel.WebDav.Core.Security.Authorization
{
public class WebDavAuthorizationService : IWebDavAuthorizationService
{
public bool HasAccess(WspPrincipal principal, string path)
{
var permissions = GetPermissions(principal, path);
return permissions.HasFlag(WebDavPermissions.Read) || permissions.HasFlag(WebDavPermissions.Write);
}
public WebDavPermissions GetPermissions(WspPrincipal principal, string path)
{
if (string.IsNullOrEmpty(path))
{
return WebDavPermissions.Read;
}
var resultPermissions = WebDavPermissions.Empty;
var rootFolder = GetRootFolder(path);
var userGroups = WSP.Services.Organizations.GetSecurityGroupsByMember(principal.ItemId, principal.AccountId);
var rootFolders = WSP.Services.EnterpriseStorage.GetEnterpriseFolders(principal.ItemId);
var esRootFolder = rootFolders.FirstOrDefault(x => x.Name == rootFolder);
if (esRootFolder == null)
{
return WebDavPermissions.None;
}
var permissions = WSP.Services.EnterpriseStorage.GetEnterpriseFolderPermissions(principal.ItemId, esRootFolder.Name);
foreach (var permission in permissions)
{
if ((!permission.IsGroup
&& (permission.DisplayName == principal.UserName || permission.DisplayName == principal.DisplayName))
|| (permission.IsGroup && userGroups.Any(x => x.DisplayName == permission.DisplayName)))
{
if (permission.Access.ToLowerInvariant().Contains("read"))
{
resultPermissions |= WebDavPermissions.Read;
}
if (permission.Access.ToLowerInvariant().Contains("write"))
{
resultPermissions |= WebDavPermissions.Write;
}
}
}
return resultPermissions;
}
private string GetRootFolder(string path)
{
return path.Split(new[]{'/'}, StringSplitOptions.RemoveEmptyEntries)[0];
}
}
}

View file

@ -41,7 +41,7 @@
</Reference>
<Reference Include="Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.Web.Services3.3.0.0.0\lib\net20\Microsoft.Web.Services3.dll</HintPath>
<HintPath>..\..\..\..\Scheduler Domains\WebsitePanel\Bin\Microsoft.Web.Services3.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
@ -123,10 +123,12 @@
<Compile Include="Exceptions\UnauthorizedException.cs" />
<Compile Include="Exceptions\WebDavException.cs" />
<Compile Include="Exceptions\WebDavHttpException.cs" />
<Compile Include="Extensions\UriExtensions.cs" />
<Compile Include="IConnectionSettings.cs" />
<Compile Include="IFolder.cs" />
<Compile Include="IHierarchyItem.cs" />
<Compile Include="IItemContent.cs" />
<Compile Include="Interfaces\Security\IWebDavAuthorizationService.cs" />
<Compile Include="Managers\AccessTokenManager.cs" />
<Compile Include="Interfaces\Managers\IAccessTokenManager.cs" />
<Compile Include="Interfaces\Managers\IWebDavManager.cs" />
@ -145,6 +147,8 @@
<DesignTime>True</DesignTime>
<DependentUpon>HttpErrors.resx</DependentUpon>
</Compile>
<Compile Include="Security\Authorization\Enums\WebDavPermissions.cs" />
<Compile Include="Security\Authorization\WebDavAuthorizationService.cs" />
<Compile Include="Security\Cryptography\CryptoUtils.cs" />
<Compile Include="Security\Cryptography\ICryptography.cs" />
<Compile Include="Security\Authentication\FormsAuthenticationService.cs" />

View file

@ -5,5 +5,4 @@
<package id="Microsoft.AspNet.Razor" version="3.2.2" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="3.2.2" targetFramework="net45" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
<package id="Microsoft.Web.Services3" version="3.0.0.0" targetFramework="net45" />
</packages>

View file

@ -3,7 +3,7 @@
<!-- Display Settings -->
<PortalName>WebsitePanel</PortalName>
<!-- Enterprise Server -->
<EnterpriseServer>http://localhost:9002</EnterpriseServer>
<EnterpriseServer>http://127.0.0.1:9555</EnterpriseServer>
<!-- General Settings -->
<CultureCookieName>UserCulture</CultureCookieName>
<ThemeCookieName>UserTheme</ThemeCookieName>

View file

@ -26,7 +26,8 @@ namespace WebsitePanel.WebDavPortal
bundles.Add(new ScriptBundle("~/bundles/appScripts").Include(
"~/Scripts/appScripts/recalculateResourseHeight.js",
"~/Scripts/appScripts/uploadingData2.js",
"~/Scripts/appScripts/authentication.js"));
"~/Scripts/appScripts/authentication.js",
"~/Scripts/appScripts/dialogs.js"));
bundles.Add(new ScriptBundle("~/bundles/authScripts").Include(
"~/Scripts/appScripts/authentication.js"));

View file

@ -43,7 +43,13 @@ namespace WebsitePanel.WebDavPortal
#endregion
routes.MapRoute(
name: "Office365DocumentRoute",
name: FileSystemRouteNames.UploadFile,
url: "upload-file/{org}/{*pathPart}",
defaults: new { controller = "FileSystem", action = "UploadFile" }
);
routes.MapRoute(
name: FileSystemRouteNames.ShowOfficeOnlinePath,
url: "office365/{org}/{*pathPart}",
defaults: new { controller = "FileSystem", action = "ShowOfficeDocument", pathPart = UrlParameter.Optional }
);
@ -55,7 +61,7 @@ namespace WebsitePanel.WebDavPortal
);
routes.MapRoute(
name: FileSystemRouteNames.FilePath,
name: FileSystemRouteNames.ShowContentPath,
url: "{org}/{*pathPart}",
defaults: new { controller = "FileSystem", action = "ShowContent", pathPart = UrlParameter.Optional }
);

View file

@ -46,3 +46,12 @@ textarea {
#logout :hover {
color: white;
}
.web-dav-folder-progress {
margin-bottom: 0px;
}
.modal-vertical-centered {
margin-top: 25%;
}

View file

@ -29,7 +29,7 @@ namespace WebsitePanel.WebDavPortal.Controllers
{
if (WspContext.User != null && WspContext.User.Identity.IsAuthenticated)
{
return RedirectToRoute(FileSystemRouteNames.FilePath, new { org = WspContext.User.OrganizationId });
return RedirectToRoute(FileSystemRouteNames.ShowContentPath, new { org = WspContext.User.OrganizationId });
}
return View();
@ -46,9 +46,7 @@ namespace WebsitePanel.WebDavPortal.Controllers
{
_authenticationService.CreateAuthenticationTicket(user);
Session[WebDavAppConfigManager.Instance.SessionKeys.WebDavManager] = null;
return RedirectToRoute(FileSystemRouteNames.FilePath, new { org = WspContext.User.OrganizationId });
return RedirectToRoute(FileSystemRouteNames.ShowContentPath, new { org = WspContext.User.OrganizationId });
}
return View(new AccountModel { LdapError = "The user name or password is incorrect" });
@ -59,8 +57,6 @@ namespace WebsitePanel.WebDavPortal.Controllers
{
_authenticationService.LogOut();
Session[WebDavAppConfigManager.Instance.SessionKeys.WebDavManager] = null;
return RedirectToRoute(AccountRouteNames.Login);
}
}

View file

@ -1,11 +1,13 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Mime;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using log4net;
using WebsitePanel.WebDav.Core;
using WebsitePanel.WebDav.Core.Client;
using WebsitePanel.WebDav.Core.Config;
@ -30,13 +32,18 @@ namespace WebsitePanel.WebDavPortal.Controllers
private readonly IWebDavManager _webdavManager;
private readonly IAuthenticationService _authenticationService;
private readonly IAccessTokenManager _tokenManager;
private readonly IWebDavAuthorizationService _webDavAuthorizationService;
private readonly ILog Log;
public FileSystemController(ICryptography cryptography, IWebDavManager webdavManager, IAuthenticationService authenticationService, IAccessTokenManager tokenManager)
public FileSystemController(ICryptography cryptography, IWebDavManager webdavManager, IAuthenticationService authenticationService, IAccessTokenManager tokenManager, IWebDavAuthorizationService webDavAuthorizationService)
{
_cryptography = cryptography;
_webdavManager = webdavManager;
_authenticationService = authenticationService;
_tokenManager = tokenManager;
_webDavAuthorizationService = webDavAuthorizationService;
Log = LogManager.GetLogger(this.GetType());
}
[HttpGet]
@ -57,10 +64,11 @@ namespace WebsitePanel.WebDavPortal.Controllers
try
{
IEnumerable<IHierarchyItem> children = _webdavManager.OpenFolder(pathPart).Where(x => !WebDavAppConfigManager.Instance.ElementsRendering.ElementsToIgnore.Contains(x.DisplayName.Trim('/')));
IEnumerable<IHierarchyItem> children = _webdavManager.OpenFolder(pathPart);
var model = new ModelForWebDav { Items = children.Take(WebDavAppConfigManager.Instance.ElementsRendering.DefaultCount), UrlSuffix = pathPart };
Session[WebDavAppConfigManager.Instance.SessionKeys.ResourseRenderCount] = WebDavAppConfigManager.Instance.ElementsRendering.DefaultCount;
var permissions = _webDavAuthorizationService.GetPermissions(WspContext.User, pathPart);
var model = new ModelForWebDav { Items = children.Take(WebDavAppConfigManager.Instance.ElementsRendering.DefaultCount), UrlSuffix = pathPart, Permissions = permissions};
return View(model);
}
@ -95,5 +103,23 @@ namespace WebsitePanel.WebDavPortal.Controllers
return PartialView("_ResourseCollectionPartial", result);
}
[HttpPost]
public ActionResult UploadFile(string org, string pathPart)
{
foreach (string fileName in Request.Files)
{
var file = Request.Files[fileName];
if (file == null || file.ContentLength == 0)
{
continue;
}
_webdavManager.UploadFile(pathPart, file);
}
return RedirectToRoute(FileSystemRouteNames.ShowContentPath);
}
}
}

View file

@ -1,19 +1,14 @@
using Ninject;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.SessionState;
using WebsitePanel.WebDav.Core.Interfaces.Managers;
using WebsitePanel.WebDav.Core.Interfaces.Owa;
using WebsitePanel.WebDav.Core.Interfaces.Security;
using WebsitePanel.WebDav.Core.Managers;
using WebsitePanel.WebDav.Core.Owa;
using WebsitePanel.WebDav.Core.Security;
using WebsitePanel.WebDav.Core.Security.Authentication;
using WebsitePanel.WebDav.Core.Security.Authorization;
using WebsitePanel.WebDav.Core.Security.Cryptography;
using WebsitePanel.WebDavPortal.DependencyInjection.Providers;
using WebsitePanel.WebDavPortal.Models;
namespace WebsitePanel.WebDavPortal.DependencyInjection
{
@ -27,6 +22,7 @@ namespace WebsitePanel.WebDavPortal.DependencyInjection
kernel.Bind<IWebDavManager>().To<WebDavManager>();
kernel.Bind<IAccessTokenManager>().To<AccessTokenManager>();
kernel.Bind<IWopiServer>().To<WopiServer>();
kernel.Bind<IWebDavAuthorizationService>().To<WebDavAuthorizationService>();
}
}
}

View file

@ -1,5 +1,6 @@
using System.Collections.Generic;
using WebsitePanel.WebDav.Core.Client;
using WebsitePanel.WebDav.Core.Security.Authorization.Enums;
namespace WebsitePanel.WebDavPortal.Models
{
@ -8,5 +9,6 @@ namespace WebsitePanel.WebDavPortal.Models
public IEnumerable<IHierarchyItem> Items { get; set; }
public string UrlSuffix { get; set; }
public string Error { get; set; }
public WebDavPermissions Permissions { get; set; }
}
}

View file

@ -0,0 +1,20 @@
var processDialog;
processDialog = processDialog || (function () {
var processDialogDiv = $('#processDialog');
return {
showPleaseWait: function () {
$('#processDialog').modal();
},
hidePleaseWait: function () {
$('#processDialog').modal('hide');
},
};
})();
$(document).ready(function() {
$('.processing-dialog').click(function () {
processDialog.showPleaseWait();
});
});

View file

@ -0,0 +1,126 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.33440
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace WebsitePanel.WebDavPortal.UI {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WebsitePanel.WebDavPortal.UI.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Actions.
/// </summary>
public static string Actions {
get {
return ResourceManager.GetString("Actions", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Close.
/// </summary>
public static string Close {
get {
return ResourceManager.GetString("Close", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to File Upload.
/// </summary>
public static string FileUpload {
get {
return ResourceManager.GetString("FileUpload", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Gb.
/// </summary>
public static string GigabyteShort {
get {
return ResourceManager.GetString("GigabyteShort", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Processing.
/// </summary>
public static string Processing {
get {
return ResourceManager.GetString("Processing", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Processing....
/// </summary>
public static string ProcessingWithDots {
get {
return ResourceManager.GetString("ProcessingWithDots", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Upload.
/// </summary>
public static string Upload {
get {
return ResourceManager.GetString("Upload", resourceCulture);
}
}
}
}

View file

@ -0,0 +1,141 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Actions" xml:space="preserve">
<value>Actions</value>
</data>
<data name="Close" xml:space="preserve">
<value>Close</value>
</data>
<data name="FileUpload" xml:space="preserve">
<value>File Upload</value>
</data>
<data name="GigabyteShort" xml:space="preserve">
<value>Gb</value>
</data>
<data name="Processing" xml:space="preserve">
<value>Processing</value>
</data>
<data name="ProcessingWithDots" xml:space="preserve">
<value>Processing...</value>
</data>
<data name="Upload" xml:space="preserve">
<value>Upload</value>
</data>
</root>

View file

@ -7,7 +7,10 @@ namespace WebsitePanel.WebDavPortal.UI.Routes
{
public class FileSystemRouteNames
{
public const string FilePath = "FilePathRoute";
public const string ShowContentPath = "ShowContentRoute";
public const string ShowOfficeOnlinePath = "ShowOfficeOnlineRoute";
public const string ShowAdditionalContent = "ShowAdditionalContentRoute";
public const string UploadFile = "UplaodFIleRoute";
}
}

View file

@ -3,6 +3,9 @@
@using Ninject
@using WebsitePanel.WebDav.Core.Config
@using WebsitePanel.WebDav.Core.Interfaces.Managers
@using WebsitePanel.WebDav.Core.Security.Authorization.Enums
@using WebsitePanel.WebDavPortal.UI
@using WebsitePanel.WebDavPortal.UI.Routes
@model WebsitePanel.WebDavPortal.Models.ModelForWebDav
@{
@ -34,6 +37,21 @@ else
<span class="glyphicon glyphicon-chevron-right" style="top: 2px;"></span>
<a href="@string.Concat("/" + header + "/", string.Join("/", elements.Take(i + 1)))" class="btn btn-primary btn-sm active" role="button">@elements[i]</a>
}
if (Model.Permissions.HasFlag(WebDavPermissions.Write))
{
@*<a id="upload-button" class="btn btn-success btn-sm active" data-toggle="modal" data-target="#file-upload" role="button">@Resources.FileUpload</a>*@
<div class="dropdown navbar-right">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-expanded="true">
@Resources.Actions
<span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
<li role="presentation"><a id="upload-button" data-toggle="modal" data-target="#file-upload" role="menuitem" tabindex="-1" href="#">@Resources.FileUpload</a></li>
</ul>
</div>
}
}
</div>
<br />
@ -49,3 +67,30 @@ else
</div>
</div>
}
@section popups
{
<div id="file-upload" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="modal-file-upload-title" aria-hidden="true" style="display: none;">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="modal-file-upload-title">@Resources.FileUpload</h4>
</div>
@using (Html.BeginRouteForm(FileSystemRouteNames.UploadFile, FormMethod.Post, new {enctype = "multipart/form-data"}))
{
<div class="modal-body">
<input type="file" name="file" />
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">@Resources.Close</button>
<button type="submit" class="btn btn-primary processing-dialog">@Resources.Upload</button>
</div>
}
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div>
@Html.Partial("_ProcessDialog", null)
}

View file

@ -1,7 +1,10 @@
@using WebsitePanel.WebDav.Core.Client
@using WebsitePanel.WebDav.Core
@using WebsitePanel.WebDav.Core.Client
@using WebsitePanel.WebDav.Core.Config
@using WebsitePanel.WebDavPortal.FileOperations
@using Ninject;
@using WebsitePanel.WebDavPortal.UI
@using WebsitePanel.WebDavPortal.UI.Routes
@model IHierarchyItem
@{
@ -14,17 +17,39 @@
{
case FileOpenerType.OfficeOnline:
isTargetBlank = true;
href = string.Concat(Url.Action("ShowOfficeDocument", "FileSystem"), Model.DisplayName);
var pathPart = Model.Href.AbsolutePath.Replace("/" + WspContext.User.OrganizationId, "");
href = string.Concat(Url.RouteUrl(FileSystemRouteNames.ShowOfficeOnlinePath, new { org = WspContext.User.OrganizationId, pathPart = "" }), pathPart);
break;
default:
isTargetBlank = false;
href = Model.Href.AbsolutePath;
break;
}
var resource = Model as IResource;
bool showStatistic = Model.ItemType == ItemType.Folder && Model.IsRootItem && resource != null;
int percent = 0;
if (showStatistic)
{
percent = (int)(resource.AllocatedSpace != 0 ? 100 * resource.ContentLength / resource.AllocatedSpace : 0);
}
}
<div class="col-sm-2 element-container">
<a href="@href" @Html.Raw(isTargetBlank ? "target=\"_blank\"" : string.Empty) title="@name">
<img class="icon-size" src="@Url.Content(actualPath)" />
<p style="word-wrap: break-word;">@name</p>
</a>
@if (showStatistic)
{
<div class="progress web-dav-folder-progress">
<div class="progress-bar" role="progressbar" aria-valuenow="@percent" aria-valuemin="0" aria-valuemax="100" style="width: @percent%;">
@percent%
</div>
</div>
<p>@Math.Round(Convert.ToDecimal(resource.ContentLength) / 1024, 2) / @Math.Round(Convert.ToDecimal(resource.AllocatedSpace) / 1024, 2) @Resources.GigabyteShort</p>
}
</div>

View file

@ -23,7 +23,7 @@
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
@Html.RouteLink(WebDavAppConfigManager.Instance.ApplicationName, FileSystemRouteNames.FilePath, new { pathPart = string.Empty }, new { @class = "navbar-brand" })
@Html.RouteLink(WebDavAppConfigManager.Instance.ApplicationName, FileSystemRouteNames.ShowContentPath, new { pathPart = string.Empty }, new { @class = "navbar-brand" })
</div>
<div class="navbar-collapse collapse">
@{
@ -40,6 +40,8 @@
@RenderBody()
</div>
@RenderSection("popups", required: false)
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")

View file

@ -0,0 +1,17 @@
@using WebsitePanel.WebDavPortal.UI
<div id="processDialog" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="modal-process-dialog-title" data-backdrop="static" data-keyboard="false" aria-hidden="true" style="display: none;">
<div class="modal-dialog modal-vertical-centered">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="modal-process-dialog-title">@Resources.ProcessingWithDots</h4>
</div>
<div class="modal-body">
<div class="progress progress-striped active">
<div class="progress-bar" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%;">
</div>
</div>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div>

View file

@ -164,6 +164,11 @@
<Compile Include="Models\ModelForWebDav.cs" />
<Compile Include="Models\OfficeOnlineModel.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="UI\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="UI\Routes\AccountRouteNames.cs" />
<Compile Include="UI\Routes\FileSystemRouteNames.cs" />
<Compile Include="UI\Routes\OwaRouteNames.cs" />
@ -219,6 +224,7 @@
</Content>
<None Include="Scripts\jquery-2.1.1.intellisense.js" />
<Content Include="Scripts\appScripts\authentication.js" />
<Content Include="Scripts\appScripts\dialogs.js" />
<Content Include="Scripts\appScripts\recalculateResourseHeight.js" />
<Content Include="Scripts\appScripts\uploadingData2.js" />
<Content Include="Scripts\bootstrap.js" />
@ -258,6 +264,7 @@
<Content Include="Views\FileSystem\ShowOfficeDocument.cshtml" />
<Content Include="Views\FileSystem\_ResourseCollectionPartial.cshtml" />
<Content Include="Views\FileSystem\_ResoursePartial.cshtml" />
<Content Include="Views\Shared\_ProcessDialog.cshtml" />
</ItemGroup>
<ItemGroup>
<Folder Include="Views\Owa\" />
@ -272,6 +279,13 @@
<Name>WebsitePanel.WebDav.Core</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="UI\Resources.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>

View file

@ -24,8 +24,6 @@
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -76,7 +74,8 @@
</Reference>
<Reference Include="Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.Web.Services3.3.0.0.0\lib\net20\Microsoft.Web.Services3.dll</HintPath>
<HintPath>..\..\Lib\Microsoft.Web.Services3.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
@ -294,7 +293,6 @@
<Content Include="App_Themes\Default\Common.skin" />
<Content Include="App_Themes\Default\DataBoundControls.skin" />
<Content Include="App_Themes\Default\Icons.skin" />
<Content Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Content Include="App_Containers\Default\TopPane.ascx" />
@ -805,5 +803,4 @@
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
</Project>