[DONT MERGE] give a spec to input files
This commit is contained in:
30
Yavsc.Abstract/FileSystem/FileSystemHelpers.cs
Normal file
30
Yavsc.Abstract/FileSystem/FileSystemHelpers.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using System.Linq;
|
||||
|
||||
namespace Yavsc.Abstract.FileSystem
|
||||
{
|
||||
public static class FileSystemHelpers
|
||||
{
|
||||
public static bool IsValidYavscPath(this string path)
|
||||
{
|
||||
if (path == null) return true;
|
||||
foreach (var name in path.Split('/'))
|
||||
{
|
||||
if (!IsValidDirectoryName(name) || name.Equals("..") || name.Equals("."))
|
||||
return false;
|
||||
}
|
||||
if (path[path.Length]==FileSystemConstants.RemoteDirectorySeparator) return false;
|
||||
return true;
|
||||
}
|
||||
public static bool IsValidDirectoryName(this string name)
|
||||
{
|
||||
return !name.Any(c => !FileSystemConstants.ValidFileNameChars.Contains(c));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class FileSystemConstants
|
||||
{
|
||||
public const char RemoteDirectorySeparator = '/';
|
||||
public static char[] ValidFileNameChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-=_~. ".ToCharArray();
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Abstract.FileSystem;
|
||||
|
||||
namespace Yavsc.ViewModels.UserFiles
|
||||
{
|
||||
@ -9,14 +9,14 @@ namespace Yavsc.ViewModels.UserFiles
|
||||
{
|
||||
public string UserName { get; private set; }
|
||||
public string SubPath { get; private set; }
|
||||
public DefaultFileInfo [] Files {
|
||||
public RemoteFileInfo [] Files {
|
||||
get; private set;
|
||||
}
|
||||
public string [] SubDirectories {
|
||||
get; private set;
|
||||
}
|
||||
private DirectoryInfo dInfo;
|
||||
public UserDirectoryInfo(string username, string path)
|
||||
public UserDirectoryInfo(string userReposPath, string username, string path)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(username))
|
||||
throw new NotSupportedException("No user name, no user dir.");
|
||||
@ -24,15 +24,15 @@ namespace Yavsc.ViewModels.UserFiles
|
||||
var finalPath = username;
|
||||
if (!string.IsNullOrWhiteSpace(path))
|
||||
finalPath += Path.DirectorySeparatorChar + path;
|
||||
if (!finalPath.IsValidPath())
|
||||
if (!finalPath.IsValidYavscPath())
|
||||
throw new InvalidOperationException(
|
||||
$"File name contains invalid chars, using path {finalPath}");
|
||||
|
||||
dInfo = new DirectoryInfo(
|
||||
Startup.UserFilesDirName+Path.DirectorySeparatorChar+finalPath);
|
||||
userReposPath+FileSystemConstants.RemoteDirectorySeparator+finalPath);
|
||||
if (!dInfo.Exists) dInfo.Create();
|
||||
Files = dInfo.GetFiles().Select
|
||||
( entry => new DefaultFileInfo { Name = entry.Name, Size = entry.Length,
|
||||
( entry => new RemoteFileInfo { Name = entry.Name, Size = entry.Length,
|
||||
CreationTime = entry.CreationTime, LastModified = entry.LastWriteTime }).ToArray();
|
||||
SubDirectories = dInfo.GetDirectories().Select
|
||||
( d=> d.Name ).ToArray();
|
@ -2,7 +2,7 @@ using System;
|
||||
|
||||
namespace Yavsc.ViewModels
|
||||
{
|
||||
public class DefaultFileInfo
|
||||
public class RemoteFileInfo
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
@ -10,6 +10,7 @@ using Yavsc.Models;
|
||||
namespace Yavsc.ApiControllers
|
||||
{
|
||||
using System.Threading.Tasks;
|
||||
using Yavsc.Abstract.FileSystem;
|
||||
using Yavsc.Exceptions;
|
||||
public class FSQuotaException : Exception {
|
||||
|
||||
@ -38,16 +39,17 @@ namespace Yavsc.ApiControllers
|
||||
public IActionResult GetDir(string subdir="")
|
||||
{
|
||||
if (subdir !=null)
|
||||
if (!FileSystemHelpers.IsValidPath(subdir))
|
||||
if (!subdir.IsValidYavscPath())
|
||||
return new BadRequestResult();
|
||||
var files = User.GetUserFiles(subdir);
|
||||
return Ok(files);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IEnumerable<IActionResult> Post(string subdir="")
|
||||
public IEnumerable<IActionResult> Post(string subdir="", string names = null)
|
||||
{
|
||||
string root = null;
|
||||
string [] destinationFileNames = names?.Split('/');
|
||||
|
||||
InvalidPathException pathex = null;
|
||||
try {
|
||||
@ -61,10 +63,12 @@ namespace Yavsc.ApiControllers
|
||||
var user = dbContext.Users.Single(
|
||||
u => u.Id == User.GetUserId()
|
||||
);
|
||||
|
||||
int i=0;
|
||||
foreach (var f in Request.Form.Files)
|
||||
{
|
||||
var item = user.ReceiveUserFile(root, f);
|
||||
var destFileName = destinationFileNames?.Length >i ? destinationFileNames[i] : null;
|
||||
|
||||
var item = user.ReceiveUserFile(root, f, destFileName);
|
||||
dbContext.SaveChanges(User.GetUserId());
|
||||
yield return Ok(item);
|
||||
};
|
||||
|
@ -30,7 +30,7 @@ namespace Yavsc
|
||||
AvatarsPath = "/avatars",
|
||||
DefaultAvatar = "/images/Users/icon_user.png",
|
||||
AnonAvatar = "/images/Users/icon_anon_user.png";
|
||||
public static char[] ValidChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-=_~. ".ToCharArray();
|
||||
|
||||
public static readonly long DefaultFSQ = 1024*1024*500;
|
||||
|
||||
public static readonly Scope[] SiteScopes = {
|
||||
|
@ -11,7 +11,6 @@ using Microsoft.AspNet.Mvc.Rendering;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.OptionsModel;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Services;
|
||||
using Yavsc.ViewModels.Account;
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
@ -13,10 +12,8 @@ using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.OptionsModel;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using OAuth.AspNet.AuthServer;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.Auth;
|
||||
using Yavsc.ViewModels.Account;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
|
@ -7,8 +7,10 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Mime;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Yavsc.Abstract.FileSystem;
|
||||
using Yavsc.Exceptions;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.FileSystem;
|
||||
@ -20,33 +22,30 @@ namespace Yavsc.Helpers
|
||||
public static class FileSystemHelpers
|
||||
{
|
||||
|
||||
|
||||
public static UserDirectoryInfo GetUserFiles(this ClaimsPrincipal user, string subdir)
|
||||
{
|
||||
|
||||
UserDirectoryInfo di = new UserDirectoryInfo(user.Identity.Name, subdir);
|
||||
UserDirectoryInfo di = new UserDirectoryInfo(Startup.UserFilesDirName, user.Identity.Name, subdir);
|
||||
|
||||
return di;
|
||||
}
|
||||
|
||||
|
||||
public static bool IsValidDirectoryName(this string name)
|
||||
{
|
||||
return !name.Any(c => !Constants.ValidChars.Contains(c));
|
||||
}
|
||||
|
||||
// Ensure this path is canonical,
|
||||
// No "dirto/./this", neither "dirt/to/that/"
|
||||
// no .. and each char must be listed as valid in constants
|
||||
public static bool IsValidPath(this string path)
|
||||
|
||||
public static string FilterFileName(string fileName)
|
||||
{
|
||||
if (path == null) return true;
|
||||
foreach (var name in path.Split(Path.DirectorySeparatorChar))
|
||||
if (fileName==null) return null;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach (var c in fileName)
|
||||
{
|
||||
if (!IsValidDirectoryName(name) || name.Equals("..") || name.Equals("."))
|
||||
return false;
|
||||
if (FileSystemConstants.ValidFileNameChars.Contains(c))
|
||||
sb.Append(c);
|
||||
else sb.Append('_');
|
||||
}
|
||||
if (path.EndsWith($"{Path.DirectorySeparatorChar}")) return false;
|
||||
return true;
|
||||
return sb.ToString();
|
||||
}
|
||||
public static string InitPostToFileSystem(
|
||||
this ClaimsPrincipal user,
|
||||
@ -56,7 +55,7 @@ namespace Yavsc.Helpers
|
||||
var diRoot = new DirectoryInfo(root);
|
||||
if (!diRoot.Exists) diRoot.Create();
|
||||
if (!string.IsNullOrWhiteSpace(subpath)) {
|
||||
if (!subpath.IsValidPath())
|
||||
if (!subpath.IsValidYavscPath())
|
||||
{
|
||||
throw new InvalidPathException();
|
||||
}
|
||||
@ -66,6 +65,7 @@ namespace Yavsc.Helpers
|
||||
if (!di.Exists) di.Create();
|
||||
return root;
|
||||
}
|
||||
|
||||
public static void DeleteUserFile(this ApplicationUser user, string fileName)
|
||||
{
|
||||
var root = Path.Combine(Startup.UserFilesDirName, user.UserName);
|
||||
@ -74,14 +74,14 @@ namespace Yavsc.Helpers
|
||||
fi.Delete();
|
||||
user.DiskUsage -= fi.Length;
|
||||
}
|
||||
public static FileRecievedInfo ReceiveUserFile(this ApplicationUser user, string root, IFormFile f)
|
||||
public static FileRecievedInfo ReceiveUserFile(this ApplicationUser user, string root, IFormFile f, string destFileName = null)
|
||||
{
|
||||
long usage = user.DiskUsage;
|
||||
|
||||
var item = new FileRecievedInfo();
|
||||
// form-data; name="file"; filename="capt0008.jpg"
|
||||
ContentDisposition contentDisposition = new ContentDisposition(f.ContentDisposition);
|
||||
item.FileName = contentDisposition.FileName;
|
||||
item.FileName = FilterFileName (destFileName ?? contentDisposition.FileName);
|
||||
item.MimeType = contentDisposition.DispositionType;
|
||||
var fi = new FileInfo(Path.Combine(root, item.FileName));
|
||||
if (fi.Exists) item.Overriden = true;
|
||||
@ -111,7 +111,7 @@ namespace Yavsc.Helpers
|
||||
user.DiskUsage = usage;
|
||||
return item;
|
||||
}
|
||||
public static HtmlString FileLink(this DefaultFileInfo info, string username, string subpath)
|
||||
public static HtmlString FileLink(this RemoteFileInfo info, string username, string subpath)
|
||||
{
|
||||
return new HtmlString( Startup.UserFilesOptions.RequestPath+"/"+ username + "/" + subpath + "/" +
|
||||
HttpUtility.UrlEncode(info.Name) );
|
||||
|
@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using Microsoft.Data.Entity;
|
||||
using Microsoft.Data.Entity.Infrastructure;
|
||||
using Microsoft.Data.Entity.Metadata;
|
||||
using Microsoft.Data.Entity.Migrations;
|
||||
using Yavsc.Models;
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Data.Entity.Migrations;
|
||||
|
||||
namespace Yavsc.Migrations
|
||||
|
@ -12,7 +12,7 @@ namespace Yavsc.ViewComponents
|
||||
IViewComponentResult result = null;
|
||||
await Task.Run(() =>
|
||||
{
|
||||
result = View(new UserDirectoryInfo(User.Identity.Name, dirname));
|
||||
result = View(new UserDirectoryInfo(Startup.UserFilesDirName, User.Identity.Name, dirname));
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
@ -1,8 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Yavsc.Models.Auth
|
||||
namespace Yavsc.Models.Auth
|
||||
{
|
||||
public class Me : IApplicationUser {
|
||||
public Me(ApplicationUser user)
|
||||
|
Reference in New Issue
Block a user