From 9cd05f50a167b0b78287c8320fac59f68ff9e71c Mon Sep 17 00:00:00 2001 From: Paul Schneider Date: Mon, 14 Nov 2016 12:17:07 +0100 Subject: [PATCH] refactoring fs --- .../ApiControllers/FileSystemApiController.cs | 24 ++++++----- Yavsc/Helpers/FileSystemHelpers.cs | 40 ++++++++++++------- Yavsc/Startup/Startup.FileServer.cs | 8 ++-- Yavsc/Startup/Startup.cs | 12 ++---- Yavsc/ViewModels/UserFiles/BlogFilesPost.cs | 11 ----- Yavsc/ViewModels/UserFiles/FileInfo.cs | 19 --------- .../ViewModels/UserFiles/UserDirectoryInfo.cs | 35 ++++++++++++++++ Yavsc/ViewModels/UserFiles/UserFileInfo.cs | 17 ++++++++ 8 files changed, 98 insertions(+), 68 deletions(-) delete mode 100644 Yavsc/ViewModels/UserFiles/BlogFilesPost.cs delete mode 100644 Yavsc/ViewModels/UserFiles/FileInfo.cs create mode 100644 Yavsc/ViewModels/UserFiles/UserDirectoryInfo.cs create mode 100644 Yavsc/ViewModels/UserFiles/UserFileInfo.cs diff --git a/Yavsc/ApiControllers/FileSystemApiController.cs b/Yavsc/ApiControllers/FileSystemApiController.cs index b9530e8d..a65302a1 100644 --- a/Yavsc/ApiControllers/FileSystemApiController.cs +++ b/Yavsc/ApiControllers/FileSystemApiController.cs @@ -1,9 +1,8 @@ using System.Collections.Generic; using System.IO; -using System.Linq; -using System.Security.Claims; using Microsoft.AspNet.Authorization; using Microsoft.AspNet.Mvc; +using Yavsc.Helpers; using Yavsc.Models; namespace Yavsc.ApiControllers @@ -26,14 +25,13 @@ namespace Yavsc.ApiControllers } [HttpGet("{subdir}")] - public IActionResult GetDir(string subdir) + public IActionResult GetDir(string subdir="") { - var path = User.GetUserId(); - if (subdir!=null) path = Path.Combine(path,subdir); - var result = Startup.UserFilesOptions.FileProvider.GetDirectoryContents(path); - return Ok(result.Select( - c => new { Name = c.Name, IdDir = c.IsDirectory } - )); + if (subdir !=null) + if (!FileSystemHelpers.IsValidPath(subdir)) + return new BadRequestResult(); + var files = User.GetUserFiles(subdir); + return Ok(files); } public class FileRecievedInfo @@ -43,9 +41,13 @@ namespace Yavsc.ApiControllers public bool Overriden { get; set; } } [HttpPost] - public IEnumerable Post() + public IEnumerable Post(string subdir="") { - var root = Path.Combine(Startup.UserFilesDirName, User.GetUserId()); + var root = Path.Combine(Startup.UserFilesDirName, User.Identity.Name); + // TOSO secure this path + // if (subdir!=null) root = Path.Combine(root, subdir); + var diRoot = new DirectoryInfo(root); + if (!diRoot.Exists) diRoot.Create(); foreach (var f in Request.Form.Files.GetFiles("Files")) { diff --git a/Yavsc/Helpers/FileSystemHelpers.cs b/Yavsc/Helpers/FileSystemHelpers.cs index 3d8d30c6..2cd44afc 100644 --- a/Yavsc/Helpers/FileSystemHelpers.cs +++ b/Yavsc/Helpers/FileSystemHelpers.cs @@ -1,24 +1,36 @@ + using System.IO; +using System.Linq; +using System.Security.Claims; using Microsoft.AspNet.FileProviders; -using Yavsc.Models.Billing; +using Yavsc.ViewModels.UserFiles; namespace Yavsc.Helpers { public static class FileSystemHelpers { - public static IDirectoryContents GetFileContent(this Estimate estimate, string userFileDir) - { - if (estimate?.Query?.PerformerProfile?.Performer == null) - return null; - var di = new DirectoryInfo(Path.Combine( - userFileDir, - estimate.Query.PerformerProfile.Performer.UserName - )); - if (!di.Exists) return null; - var fsp = new PhysicalFileProvider(di.FullName); - return fsp.GetDirectoryContents( - Path.Combine(Constants.UserBillsFilesDir, estimate.Id.ToString()) - ); + public static UserDirectoryInfo GetUserFiles(this ClaimsPrincipal user,string subdir) { + + UserDirectoryInfo di = new UserDirectoryInfo(user.Identity.Name,subdir); + + return di; + } + static char [] ValidChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_~.".ToCharArray(); + + public static bool IsValidDirectoryName(this string name) + {  + return !name.Any(c=> !ValidChars.Contains(c)); + } + public static bool IsValidPath(this string path) + {  + if (path==null) return true; + foreach (var name in path.Split(Path.DirectorySeparatorChar)) + { + if (name!=null) + if (!IsValidDirectoryName(name) + || name.Equals("..")) return false; + } + return true; } } diff --git a/Yavsc/Startup/Startup.FileServer.cs b/Yavsc/Startup/Startup.FileServer.cs index d9012fb0..e46898df 100644 --- a/Yavsc/Startup/Startup.FileServer.cs +++ b/Yavsc/Startup/Startup.FileServer.cs @@ -16,12 +16,10 @@ namespace Yavsc public void ConfigureFileServerApp(IApplicationBuilder app, SiteSettings siteSettings, IHostingEnvironment env) { - UserFilesDirName = Path.Combine( - env.WebRootPath, - siteSettings.UserFiles.DirName); + var userFilesDirInfo = new DirectoryInfo( siteSettings.UserFiles.DirName ); + UserFilesDirName = userFilesDirInfo.FullName; - var rootInfo = new DirectoryInfo(UserFilesDirName); - if (!rootInfo.Exists) rootInfo.Create(); + if (!userFilesDirInfo.Exists) userFilesDirInfo.Create(); UserFilesOptions = new FileServerOptions() { diff --git a/Yavsc/Startup/Startup.cs b/Yavsc/Startup/Startup.cs index 55729918..3d11ff41 100755 --- a/Yavsc/Startup/Startup.cs +++ b/Yavsc/Startup/Startup.cs @@ -29,14 +29,13 @@ using Yavsc.Services; namespace Yavsc { - public partial class Startup { public static string ConnectionString { get; private set; } - public static string UserBillsDirName { private set; get; } + public static string UserBillsDirName { private set; get; } public static string Authority { get; private set; } public static string Audience { get; private set; } - public static SiteSettings SiteSetup { get; private set; } + public static SiteSettings SiteSetup { get; private set; } private static ILogger logger; public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv) @@ -326,12 +325,8 @@ namespace Yavsc Audience = siteSettings.Value.Audience; ConfigureOAuthApp(app, siteSettings.Value); - - app.UseWebSockets(); - - app.UseSignalR("/api/signalr"); - ConfigureFileServerApp(app, siteSettings.Value, env); + ConfigureWebSocketsApp(app, siteSettings.Value, env); app.UseRequestLocalization(localizationOptions.Value, (RequestCulture)new RequestCulture((string)"en")); @@ -348,3 +343,4 @@ namespace Yavsc } } +// \ No newline at end of file diff --git a/Yavsc/ViewModels/UserFiles/BlogFilesPost.cs b/Yavsc/ViewModels/UserFiles/BlogFilesPost.cs deleted file mode 100644 index 0948664e..00000000 --- a/Yavsc/ViewModels/UserFiles/BlogFilesPost.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.ComponentModel.DataAnnotations; -using System.Collections.Generic; - -using Microsoft.AspNet.Http; - -public class BlogFilesPost { - [Required] - public long PostId {get; set; } - [Required] - public IList File { get; set; } -} \ No newline at end of file diff --git a/Yavsc/ViewModels/UserFiles/FileInfo.cs b/Yavsc/ViewModels/UserFiles/FileInfo.cs deleted file mode 100644 index 66668bdb..00000000 --- a/Yavsc/ViewModels/UserFiles/FileInfo.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; - -namespace Yavsc.ViewModels -{ - public class FileInfo - { - - public string PermanentUri { get; set; } - public string Name { get; set; } - - public int Size { get; set; } - - public DateTime Creation { get; set; } - - public string MimeType { get; set; } - - } - -} \ No newline at end of file diff --git a/Yavsc/ViewModels/UserFiles/UserDirectoryInfo.cs b/Yavsc/ViewModels/UserFiles/UserDirectoryInfo.cs new file mode 100644 index 00000000..eb2b6420 --- /dev/null +++ b/Yavsc/ViewModels/UserFiles/UserDirectoryInfo.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Yavsc.Helpers; + +namespace Yavsc.ViewModels.UserFiles +{ + public class UserDirectoryInfo + { + public string SubPath { get; private set; } + public UserFileInfo [] Files { + get; private set; + } + public string [] SubDirectories {  + get; private set; + } + private DirectoryInfo dInfo; + public UserDirectoryInfo(string username, string path) + { + SubPath = (path==null) ? username : username + Path.DirectorySeparatorChar + path; + if ( !SubPath.IsValidPath() ) + throw new InvalidOperationException( + $"File name contains invalid chars, using path {SubPath}"); + + dInfo = new DirectoryInfo( + Path.Combine(Startup.UserFilesDirName,SubPath)); + Files = dInfo.GetFiles().Select + ( entry => new UserFileInfo { Name = entry.Name, Size = entry.Length, + CreationTime = entry.CreationTime, LastModified = entry.LastWriteTime }).ToArray(); + SubDirectories = dInfo.GetDirectories().Select + ( d=> d.Name ).ToArray(); + } + } +} \ No newline at end of file diff --git a/Yavsc/ViewModels/UserFiles/UserFileInfo.cs b/Yavsc/ViewModels/UserFiles/UserFileInfo.cs new file mode 100644 index 00000000..def0425b --- /dev/null +++ b/Yavsc/ViewModels/UserFiles/UserFileInfo.cs @@ -0,0 +1,17 @@ +using System; + +namespace Yavsc.ViewModels +{ + public class UserFileInfo + { + + public string Name { get; set; } + + public long Size { get; set; } + + public DateTime CreationTime { get; set; } + + public DateTime LastModified { get; set; } + } + +} \ No newline at end of file