2019-08-04 11:45:00 +02:00
|
|
|
using System.Security.Claims;
|
2023-03-19 17:57:55 +00:00
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
|
using Microsoft.Extensions.FileProviders;
|
|
|
|
|
using Microsoft.Extensions.Options;
|
2020-10-09 19:35:39 +01:00
|
|
|
using rules;
|
2023-03-19 17:57:55 +00:00
|
|
|
using Yavsc.Helpers;
|
|
|
|
|
using Yavsc.Models;
|
2025-07-15 19:43:41 +01:00
|
|
|
using Yavsc.Server.Helpers;
|
2019-08-04 11:45:00 +02:00
|
|
|
|
|
|
|
|
namespace Yavsc.Services
|
|
|
|
|
{
|
|
|
|
|
public class FileSystemAuthManager : IFileSystemAuthManager
|
|
|
|
|
{
|
2020-10-17 11:35:15 +01:00
|
|
|
class BelongsToCircle : UserMatch
|
|
|
|
|
{
|
|
|
|
|
public override bool Match(string userId)
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
class OutOfCircle : UserMatch
|
|
|
|
|
{
|
|
|
|
|
public override bool Match(string userId)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-10 01:41:31 +00:00
|
|
|
private readonly UserMatch Out = new OutOfCircle();
|
|
|
|
|
private readonly UserMatch In = new BelongsToCircle();
|
2019-08-04 11:45:00 +02:00
|
|
|
|
2021-03-10 01:41:31 +00:00
|
|
|
private readonly ApplicationDbContext _dbContext;
|
2020-10-09 19:35:39 +01:00
|
|
|
|
2021-03-10 01:41:31 +00:00
|
|
|
private readonly SiteSettings SiteSettings;
|
|
|
|
|
|
2020-10-09 19:35:39 +01:00
|
|
|
readonly RuleSetParser ruleSetParser;
|
|
|
|
|
|
2021-03-10 01:41:31 +00:00
|
|
|
public FileSystemAuthManager(ApplicationDbContext dbContext, IOptions<SiteSettings> sitesOptions)
|
2019-08-04 11:45:00 +02:00
|
|
|
{
|
|
|
|
|
_dbContext = dbContext;
|
2020-10-09 19:35:39 +01:00
|
|
|
SiteSettings = sitesOptions.Value;
|
2020-10-17 23:40:37 +01:00
|
|
|
ruleSetParser = new RuleSetParser(false);
|
2019-08-04 11:45:00 +02:00
|
|
|
}
|
|
|
|
|
|
2026-03-01 02:13:26 +00:00
|
|
|
/// <summary>
|
|
|
|
|
/// Get the file access info, for a given user, to a given FS absolute path
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="clientUser"></param>
|
|
|
|
|
/// <param name="providerUserFilePath"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public FileAccessRight GetFilePathAccess(ClaimsPrincipal clientUser, string providerUserFilePath)
|
2019-08-04 11:45:00 +02:00
|
|
|
{
|
2026-03-01 02:13:26 +00:00
|
|
|
|
|
|
|
|
var clientUserName = clientUser.GetUserName();
|
2025-02-26 18:59:08 +00:00
|
|
|
FileInfo fi = new FileInfo(
|
2026-03-01 02:13:26 +00:00
|
|
|
Path.Combine(Config.UserFilesDirName, providerUserFilePath));
|
|
|
|
|
|
|
|
|
|
if (providerUserFilePath.StartsWith(clientUserName + '/'))
|
2020-10-09 19:35:39 +01:00
|
|
|
{
|
|
|
|
|
return FileAccessRight.Read | FileAccessRight.Write;
|
|
|
|
|
}
|
2026-03-01 02:13:26 +00:00
|
|
|
var providerUserName = providerUserFilePath.Split('/')[0];
|
2020-10-17 11:35:15 +01:00
|
|
|
|
2020-10-09 19:35:39 +01:00
|
|
|
ruleSetParser.Reset();
|
2026-03-01 02:13:26 +00:00
|
|
|
var cuserid = clientUser.GetUserId();
|
2020-10-17 23:40:37 +01:00
|
|
|
|
2026-03-01 02:13:26 +00:00
|
|
|
var providerUserId = _dbContext.Users.SingleOrDefault(u => u.UserName == providerUserName).Id;
|
2020-10-18 10:15:08 +01:00
|
|
|
|
2026-03-01 02:13:26 +00:00
|
|
|
if (string.IsNullOrEmpty(providerUserId)) return FileAccessRight.None;
|
2020-10-18 10:15:08 +01:00
|
|
|
|
2026-03-01 02:13:26 +00:00
|
|
|
var circles = _dbContext.Circle.Include(mb => mb.Members).Where(c => c.OwnerId == providerUserId).ToArray();
|
2020-10-17 11:35:15 +01:00
|
|
|
foreach (var circle in circles)
|
|
|
|
|
{
|
|
|
|
|
if (circle.Members.Any(m => m.MemberId == cuserid))
|
|
|
|
|
ruleSetParser.Definitions.Add(circle.Name, In);
|
|
|
|
|
else ruleSetParser.Definitions.Add(circle.Name, Out);
|
|
|
|
|
}
|
2025-02-26 18:59:08 +00:00
|
|
|
var userFilesDir = new DirectoryInfo(
|
2026-03-01 02:13:26 +00:00
|
|
|
Path.Combine(Config.UserFilesDirName, providerUserName));
|
2025-02-26 18:59:08 +00:00
|
|
|
var currentACLDir = fi.Directory;
|
|
|
|
|
do
|
2020-10-11 01:45:45 +01:00
|
|
|
{
|
2026-03-01 02:13:26 +00:00
|
|
|
var aclfileName = Path.Combine(currentACLDir.FullName,
|
2025-02-26 18:59:08 +00:00
|
|
|
SiteSettings.AccessListFileName);
|
|
|
|
|
FileInfo accessFileInfo = new FileInfo(aclfileName);
|
|
|
|
|
if (accessFileInfo.Exists)
|
|
|
|
|
ruleSetParser.ParseFile(accessFileInfo.FullName);
|
|
|
|
|
currentACLDir = currentACLDir.Parent;
|
|
|
|
|
} while (currentACLDir != userFilesDir);
|
|
|
|
|
|
2020-10-09 19:35:39 +01:00
|
|
|
|
2026-03-01 02:13:26 +00:00
|
|
|
if (ruleSetParser.Rules.Allow(clientUserName))
|
2020-10-09 19:35:39 +01:00
|
|
|
{
|
2020-10-17 23:40:37 +01:00
|
|
|
return FileAccessRight.Read;
|
2019-08-14 14:11:27 +01:00
|
|
|
}
|
2026-03-01 02:13:26 +00:00
|
|
|
return FileAccessRight.None;
|
2020-10-18 10:15:08 +01:00
|
|
|
// TODO default user scoped file access policy
|
2020-10-09 19:35:39 +01:00
|
|
|
|
2019-08-04 11:45:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SetAccess(long circleId, string normalizedFullPath, FileAccessRight access)
|
|
|
|
|
{
|
|
|
|
|
throw new NotImplementedException();
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-12 01:11:30 +01:00
|
|
|
}
|