diff --git a/src/Yavsc/AuthorizationHandlers/ViewFileHandler.cs b/src/Yavsc/AuthorizationHandlers/ViewFileHandler.cs index 6685a78b..9bb99fe3 100644 --- a/src/Yavsc/AuthorizationHandlers/ViewFileHandler.cs +++ b/src/Yavsc/AuthorizationHandlers/ViewFileHandler.cs @@ -20,7 +20,7 @@ namespace Yavsc.AuthorizationHandlers { if (!fileContext.Path.StartsWith ("/")) context.Fail (); else { - var rights = _authManager.GetFilePathAccess (context.User, fileContext.Path.Substring (1)); + var rights = _authManager.GetFilePathAccess (context.User, fileContext.Path); 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 index 46f7c81d..06a15d29 100644 --- a/src/Yavsc/Services/FileSystemAuthManager.cs +++ b/src/Yavsc/Services/FileSystemAuthManager.cs @@ -3,31 +3,46 @@ using System.Linq; using System.Security.Principal; using System.Security.Claims; using Yavsc.Models; +using Microsoft.Extensions.Logging; namespace Yavsc.Services { public class FileSystemAuthManager : IFileSystemAuthManager { ApplicationDbContext _dbContext; + ILogger _logger; - public FileSystemAuthManager(ApplicationDbContext dbContext) + public FileSystemAuthManager(ApplicationDbContext dbContext, ILoggerFactory loggerFactory) { _dbContext = dbContext; + _logger = loggerFactory.CreateLogger(); } 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 (parts.Length<4) return FileAccessRight.None; + var funame = parts[2]; + var filePath = string.Join("/",parts.Skip(3)); + + _logger.LogInformation($"{normalizedFullPath} from {funame}"); + + if (funame == user?.GetUserName()) return FileAccessRight.Read | FileAccessRight.Write; - if (_dbContext.CircleAuthorizationToFile.Any( - r => r.FullPath == normalizedFullPath && ucl.Contains(r.CircleId) - )) return FileAccessRight.Read; + var ucl = user.Claims.Where(c => c.Type == YavscClaimTypes.CircleMembership).Select(c => long.Parse(c.Value)).Distinct().ToArray(); + + var uclString = string.Join(",", ucl); + _logger.LogInformation($"{uclString} "); + foreach ( + var cid in ucl + ) { + var ok = _dbContext.CircleAuthorizationToFile.Any(a => a.CircleId == cid && a.FullPath == filePath); + if (ok) return FileAccessRight.Read; + } + return FileAccessRight.None; } diff --git a/src/Yavsc/Startup/Startup.FileServer.cs b/src/Yavsc/Startup/Startup.FileServer.cs index b40c5ea8..ce855b7e 100644 --- a/src/Yavsc/Startup/Startup.FileServer.cs +++ b/src/Yavsc/Startup/Startup.FileServer.cs @@ -40,7 +40,7 @@ namespace Yavsc /* 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 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());