webdav portal upload func added

This commit is contained in:
vfedosevich 2015-01-20 01:24:39 -08:00
parent 1da7c6c3b3
commit a882072b02
23 changed files with 553 additions and 17 deletions

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

@ -110,6 +110,23 @@ namespace WebsitePanel.WebDav.Core
webClient.UploadFile(Href, "PUT", filename); 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> /// <summary>
/// Loads content of the resource from WebDAV server. /// Loads content of the resource from WebDAV server.
/// </summary> /// </summary>

View file

@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Web;
using WebsitePanel.WebDav.Core.Client; using WebsitePanel.WebDav.Core.Client;
namespace WebsitePanel.WebDav.Core.Interfaces.Managers namespace WebsitePanel.WebDav.Core.Interfaces.Managers
@ -8,6 +9,7 @@ namespace WebsitePanel.WebDav.Core.Interfaces.Managers
IEnumerable<IHierarchyItem> OpenFolder(string path); IEnumerable<IHierarchyItem> OpenFolder(string path);
bool IsFile(string path); bool IsFile(string path);
byte[] GetFileBytes(string path); byte[] GetFileBytes(string path);
void UploadFile(string path, HttpPostedFileBase file);
IResource GetResource(string path); IResource GetResource(string path);
string GetFileUrl(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.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Text;
using System.Web;
using System.Xml.Serialization;
using log4net; using log4net;
using WebsitePanel.Providers.OS; using WebsitePanel.Providers.OS;
using WebsitePanel.WebDav.Core.Client; using WebsitePanel.WebDav.Core.Client;
using WebsitePanel.WebDav.Core.Config; using WebsitePanel.WebDav.Core.Config;
using WebsitePanel.WebDav.Core.Exceptions; using WebsitePanel.WebDav.Core.Exceptions;
using WebsitePanel.WebDav.Core.Extensions;
using WebsitePanel.WebDav.Core.Interfaces.Managers; using WebsitePanel.WebDav.Core.Interfaces.Managers;
using WebsitePanel.WebDav.Core.Security.Cryptography; using WebsitePanel.WebDav.Core.Security.Cryptography;
using WebsitePanel.WebDav.Core.Wsp.Framework; using WebsitePanel.WebDav.Core.Wsp.Framework;
@ -108,6 +112,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) public IResource GetResource(string path)
{ {
try try
@ -184,6 +206,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) private string GetFileFolder(string path)
{ {
path = path.TrimEnd('/'); 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

@ -123,10 +123,12 @@
<Compile Include="Exceptions\UnauthorizedException.cs" /> <Compile Include="Exceptions\UnauthorizedException.cs" />
<Compile Include="Exceptions\WebDavException.cs" /> <Compile Include="Exceptions\WebDavException.cs" />
<Compile Include="Exceptions\WebDavHttpException.cs" /> <Compile Include="Exceptions\WebDavHttpException.cs" />
<Compile Include="Extensions\UriExtensions.cs" />
<Compile Include="IConnectionSettings.cs" /> <Compile Include="IConnectionSettings.cs" />
<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\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" />
<Compile Include="Interfaces\Managers\IWebDavManager.cs" /> <Compile Include="Interfaces\Managers\IWebDavManager.cs" />
@ -145,6 +147,8 @@
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
<DependentUpon>HttpErrors.resx</DependentUpon> <DependentUpon>HttpErrors.resx</DependentUpon>
</Compile> </Compile>
<Compile Include="Security\Authorization\Enums\WebDavPermissions.cs" />
<Compile Include="Security\Authorization\WebDavAuthorizationService.cs" />
<Compile Include="Security\Cryptography\CryptoUtils.cs" /> <Compile Include="Security\Cryptography\CryptoUtils.cs" />
<Compile Include="Security\Cryptography\ICryptography.cs" /> <Compile Include="Security\Cryptography\ICryptography.cs" />
<Compile Include="Security\Authentication\FormsAuthenticationService.cs" /> <Compile Include="Security\Authentication\FormsAuthenticationService.cs" />

View file

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

View file

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

View file

@ -29,7 +29,7 @@ namespace WebsitePanel.WebDavPortal.Controllers
{ {
if (WspContext.User != null && WspContext.User.Identity.IsAuthenticated) 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(); return View();
@ -46,7 +46,7 @@ namespace WebsitePanel.WebDavPortal.Controllers
{ {
_authenticationService.CreateAuthenticationTicket(user); _authenticationService.CreateAuthenticationTicket(user);
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" }); return View(new AccountModel { LdapError = "The user name or password is incorrect" });

View file

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net.Mime; using System.Net.Mime;
@ -30,13 +31,15 @@ namespace WebsitePanel.WebDavPortal.Controllers
private readonly IWebDavManager _webdavManager; private readonly IWebDavManager _webdavManager;
private readonly IAuthenticationService _authenticationService; private readonly IAuthenticationService _authenticationService;
private readonly IAccessTokenManager _tokenManager; private readonly IAccessTokenManager _tokenManager;
private readonly IWebDavAuthorizationService _webDavAuthorizationService;
public FileSystemController(ICryptography cryptography, IWebDavManager webdavManager, IAuthenticationService authenticationService, IAccessTokenManager tokenManager) public FileSystemController(ICryptography cryptography, IWebDavManager webdavManager, IAuthenticationService authenticationService, IAccessTokenManager tokenManager, IWebDavAuthorizationService webDavAuthorizationService)
{ {
_cryptography = cryptography; _cryptography = cryptography;
_webdavManager = webdavManager; _webdavManager = webdavManager;
_authenticationService = authenticationService; _authenticationService = authenticationService;
_tokenManager = tokenManager; _tokenManager = tokenManager;
_webDavAuthorizationService = webDavAuthorizationService;
} }
[HttpGet] [HttpGet]
@ -59,7 +62,9 @@ namespace WebsitePanel.WebDavPortal.Controllers
{ {
IEnumerable<IHierarchyItem> children = _webdavManager.OpenFolder(pathPart); IEnumerable<IHierarchyItem> children = _webdavManager.OpenFolder(pathPart);
var model = new ModelForWebDav { Items = children.Take(WebDavAppConfigManager.Instance.ElementsRendering.DefaultCount), UrlSuffix = pathPart }; 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); return View(model);
} }
@ -94,5 +99,23 @@ namespace WebsitePanel.WebDavPortal.Controllers
return PartialView("_ResourseCollectionPartial", result); 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 Ninject;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.SessionState; 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.Managers; using WebsitePanel.WebDav.Core.Managers;
using WebsitePanel.WebDav.Core.Owa; using WebsitePanel.WebDav.Core.Owa;
using WebsitePanel.WebDav.Core.Security;
using WebsitePanel.WebDav.Core.Security.Authentication; using WebsitePanel.WebDav.Core.Security.Authentication;
using WebsitePanel.WebDav.Core.Security.Authorization;
using WebsitePanel.WebDav.Core.Security.Cryptography; using WebsitePanel.WebDav.Core.Security.Cryptography;
using WebsitePanel.WebDavPortal.DependencyInjection.Providers; using WebsitePanel.WebDavPortal.DependencyInjection.Providers;
using WebsitePanel.WebDavPortal.Models;
namespace WebsitePanel.WebDavPortal.DependencyInjection namespace WebsitePanel.WebDavPortal.DependencyInjection
{ {
@ -27,6 +22,7 @@ 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<IWebDavAuthorizationService>().To<WebDavAuthorizationService>();
} }
} }
} }

View file

@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using WebsitePanel.WebDav.Core.Client; using WebsitePanel.WebDav.Core.Client;
using WebsitePanel.WebDav.Core.Security.Authorization.Enums;
namespace WebsitePanel.WebDavPortal.Models namespace WebsitePanel.WebDavPortal.Models
{ {
@ -8,5 +9,6 @@ namespace WebsitePanel.WebDavPortal.Models
public IEnumerable<IHierarchyItem> Items { get; set; } public IEnumerable<IHierarchyItem> Items { get; set; }
public string UrlSuffix { get; set; } public string UrlSuffix { get; set; }
public string Error { 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,117 @@
//------------------------------------------------------------------------------
// <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 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,138 @@
<?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="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,8 +7,10 @@ namespace WebsitePanel.WebDavPortal.UI.Routes
{ {
public class FileSystemRouteNames public class FileSystemRouteNames
{ {
public const string FilePath = "FilePathRoute"; public const string ShowContentPath = "ShowContentRoute";
public const string OfficeOnlinePath = "OfficeOnline"; public const string ShowOfficeOnlinePath = "ShowOfficeOnlineRoute";
public const string ShowAdditionalContent = "ShowAdditionalContentRoute"; public const string ShowAdditionalContent = "ShowAdditionalContentRoute";
public const string UploadFile = "UplaodFIleRoute";
} }
} }

View file

@ -3,6 +3,9 @@
@using Ninject @using Ninject
@using WebsitePanel.WebDav.Core.Config @using WebsitePanel.WebDav.Core.Config
@using WebsitePanel.WebDav.Core.Interfaces.Managers @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 @model WebsitePanel.WebDavPortal.Models.ModelForWebDav
@{ @{
@ -34,6 +37,21 @@ else
<span class="glyphicon glyphicon-chevron-right" style="top: 2px;"></span> <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> <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> </div>
<br /> <br />
@ -48,4 +66,31 @@ else
} }
</div> </div>
</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

@ -17,7 +17,7 @@
case FileOpenerType.OfficeOnline: case FileOpenerType.OfficeOnline:
isTargetBlank = true; isTargetBlank = true;
var pathPart = Model.Href.AbsolutePath.Replace("/" + WspContext.User.OrganizationId, ""); var pathPart = Model.Href.AbsolutePath.Replace("/" + WspContext.User.OrganizationId, "");
href = string.Concat(Url.RouteUrl(FileSystemRouteNames.OfficeOnlinePath, new { org = WspContext.User.OrganizationId, pathPart = "" }), pathPart); href = string.Concat(Url.RouteUrl(FileSystemRouteNames.ShowOfficeOnlinePath, new { org = WspContext.User.OrganizationId, pathPart = "" }), pathPart);
break; break;
default: default:
isTargetBlank = false; isTargetBlank = false;

View file

@ -23,7 +23,7 @@
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
</button> </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>
<div class="navbar-collapse collapse"> <div class="navbar-collapse collapse">
@{ @{
@ -39,6 +39,8 @@
<div class="container body-content"> <div class="container body-content">
@RenderBody() @RenderBody()
</div> </div>
@RenderSection("popups", required: false)
@Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap") @Scripts.Render("~/bundles/bootstrap")

View file

@ -0,0 +1,11 @@
@using WebsitePanel.WebDavPortal.UI
<div id="processDialog" class="modal fade" tabindex="-1" role="dialog" data-backdrop="static" data-keyboard="false" aria-hidden="true" style="display: none;">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<h4 class="modal-title">@Resources.ProcessingWithDots</h4>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div>

View file

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