From 8eddb95fa54cf45bb8e37f6c51857b9a9f7b8d50 Mon Sep 17 00:00:00 2001 From: Paul Schneider Date: Sun, 4 Aug 2019 11:45:00 +0200 Subject: [PATCH] file dl auth --- .../AuthorizationHandlers/ViewFileHandler.cs | 32 +++++++++----- src/Yavsc/Services/FileSystemAuthManager.cs | 44 +++++++++++++++++++ src/Yavsc/Services/IFileSystemAuthManager.cs | 32 ++------------ src/Yavsc/Startup/Startup.FileServer.cs | 13 ++++-- src/Yavsc/Startup/Startup.cs | 1 + 5 files changed, 81 insertions(+), 41 deletions(-) create mode 100644 src/Yavsc/Services/FileSystemAuthManager.cs diff --git a/src/Yavsc/AuthorizationHandlers/ViewFileHandler.cs b/src/Yavsc/AuthorizationHandlers/ViewFileHandler.cs index 4ad39f02..6685a78b 100644 --- a/src/Yavsc/AuthorizationHandlers/ViewFileHandler.cs +++ b/src/Yavsc/AuthorizationHandlers/ViewFileHandler.cs @@ -1,18 +1,30 @@ using Microsoft.AspNet.Authorization; +using Yavsc.Services; using Yavsc.ViewModels.Auth; -namespace Yavsc.AuthorizationHandlers -{ - public class ViewFileHandler : AuthorizationHandler - { - protected override void Handle(AuthorizationContext context, ViewRequirement requirement, ViewFileContext fileContext) - { +namespace Yavsc.AuthorizationHandlers { + + public class ViewFileHandler : AuthorizationHandler { + + IFileSystemAuthManager _authManager; + + public ViewFileHandler (IFileSystemAuthManager authManager) { + _authManager = authManager; + } + + protected override void Handle (AuthorizationContext context, ViewRequirement requirement, ViewFileContext fileContext) { // TODO file access rules - if (fileContext.Path.StartsWith("/pub/")) - context.Succeed(requirement); + if (fileContext.Path.StartsWith ("/pub/")) + context.Succeed (requirement); else { - // TODO use "/blog/{num}/" path to link to blog access list - context.Succeed(requirement); + if (!fileContext.Path.StartsWith ("/")) + context.Fail (); + else { + var rights = _authManager.GetFilePathAccess (context.User, fileContext.Path.Substring (1)); + if ((rights & FileAccessRight.Read) > 0) + context.Succeed (requirement); + else context.Fail (); + } } } } diff --git a/src/Yavsc/Services/FileSystemAuthManager.cs b/src/Yavsc/Services/FileSystemAuthManager.cs new file mode 100644 index 00000000..46f7c81d --- /dev/null +++ b/src/Yavsc/Services/FileSystemAuthManager.cs @@ -0,0 +1,44 @@ +using System; +using System.Linq; +using System.Security.Principal; +using System.Security.Claims; +using Yavsc.Models; + +namespace Yavsc.Services +{ + public class FileSystemAuthManager : IFileSystemAuthManager + { + ApplicationDbContext _dbContext; + + public FileSystemAuthManager(ApplicationDbContext dbContext) + { + _dbContext = dbContext; + } + + public FileAccessRight GetFilePathAccess(ClaimsPrincipal user, string normalizedFullPath) + { + // Assert (normalizedFullPath!=null) + var parts = normalizedFullPath.Split('/'); + if (parts.Length<2) return FileAccessRight.None; + var funame = parts[0]; + if (funame == user.GetUserName()) return FileAccessRight.Read | FileAccessRight.Write; + + var ucl = user.Claims.Where(c => c.Type == YavscClaimTypes.CircleMembership).Select(c => long.Parse(c.Value)).ToArray(); + + if (_dbContext.CircleAuthorizationToFile.Any( + r => r.FullPath == normalizedFullPath && ucl.Contains(r.CircleId) + )) return FileAccessRight.Read; + return FileAccessRight.None; + } + + public string NormalizePath(string path) + { + throw new NotImplementedException(); + } + + public void SetAccess(long circleId, string normalizedFullPath, FileAccessRight access) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/src/Yavsc/Services/IFileSystemAuthManager.cs b/src/Yavsc/Services/IFileSystemAuthManager.cs index 9e13294e..26cc3560 100644 --- a/src/Yavsc/Services/IFileSystemAuthManager.cs +++ b/src/Yavsc/Services/IFileSystemAuthManager.cs @@ -1,8 +1,9 @@ using System; +using System.Security.Claims; using System.Security.Principal; -using Yavsc.Models; -namespace Yavsc.Services { +namespace Yavsc.Services +{ [Flags] public enum FileAccessRight { None = 0, @@ -22,34 +23,9 @@ namespace Yavsc.Services { /// /// /// - FileAccessRight GetFilePathAccess(IPrincipal user, string normalizedFullPath); + FileAccessRight GetFilePathAccess(ClaimsPrincipal user, string normalizedFullPath); void SetAccess (long circleId, string normalizedFullPath, FileAccessRight access); } - - public class FileSystemAuthManager : IFileSystemAuthManager - { - ApplicationDbContext _dbContext; - - public FileSystemAuthManager(ApplicationDbContext dbContext) - { - _dbContext = dbContext; - } - - public FileAccessRight GetFilePathAccess(IPrincipal user, string normalizedFullPath) - { - throw new NotImplementedException(); - } - - public string NormalizePath(string path) - { - throw new NotImplementedException(); - } - - public void SetAccess(long circleId, string normalizedFullPath, FileAccessRight access) - { - throw new NotImplementedException(); - } - } } \ No newline at end of file diff --git a/src/Yavsc/Startup/Startup.FileServer.cs b/src/Yavsc/Startup/Startup.FileServer.cs index 78fd1ced..b40c5ea8 100644 --- a/src/Yavsc/Startup/Startup.FileServer.cs +++ b/src/Yavsc/Startup/Startup.FileServer.cs @@ -1,4 +1,5 @@ using System.IO; +using System.Security.Claims; using Microsoft.AspNet.Authorization; using Microsoft.AspNet.Builder; using Microsoft.AspNet.FileProviders; @@ -7,6 +8,8 @@ using Microsoft.AspNet.Http; using Microsoft.AspNet.StaticFiles; using Microsoft.Extensions.Logging; using Yavsc.Abstract.FileSystem; +using Yavsc.Services; +using Yavsc.ViewModels.Auth; namespace Yavsc { @@ -17,7 +20,8 @@ namespace Yavsc public static FileServerOptions AvatarsOptions { get; set; } public void ConfigureFileServerApp(IApplicationBuilder app, - SiteSettings siteSettings, IHostingEnvironment env, IAuthorizationService authorizationService) + SiteSettings siteSettings, IHostingEnvironment env, + IAuthorizationService authorizationService) { var userFilesDirInfo = new DirectoryInfo( siteSettings.Blog ); AbstractFileSystemHelpers.UserFilesDirName = userFilesDirInfo.FullName; @@ -33,15 +37,18 @@ namespace Yavsc UserFilesOptions.EnableDefaultFiles=true; UserFilesOptions.StaticFileOptions.ServeUnknownFileTypes=true; - /* TODO needs a better design, at implementation time (don't use database, but in memory data) + /* TODO needs a better design, at implementation time (don't use database, but in memory data) */ UserFilesOptions.StaticFileOptions.OnPrepareResponse += async context => { var uname = context.Context.User.GetUserName(); var path = context.Context.Request.Path; var result = await authorizationService.AuthorizeAsync(context.Context.User, new ViewFileContext { UserName = uname, File = context.File, Path = path } , new ViewRequirement()); + if (!result) { + context.Context.Response.StatusCode = 403; + context.Context.Abort(); + } }; - */ var avatarsDirInfo = new DirectoryInfo(Startup.SiteSetup.Avatars); if (!avatarsDirInfo.Exists) avatarsDirInfo.Create(); AvatarsDirName = avatarsDirInfo.FullName; diff --git a/src/Yavsc/Startup/Startup.cs b/src/Yavsc/Startup/Startup.cs index 591e0251..9e386b76 100755 --- a/src/Yavsc/Startup/Startup.cs +++ b/src/Yavsc/Startup/Startup.cs @@ -232,6 +232,7 @@ namespace Yavsc services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); services.AddMvc(config => {