code guidelines

This commit is contained in:
2020-10-09 19:35:39 +01:00
parent 7b529cd3e8
commit c907b387d7
82 changed files with 470 additions and 375 deletions

View File

@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.OptionsModel;
using Yavsc;
using Yavsc.Models;
using Yavsc.Services;
public class DiskUsageTracker : IDiskUsageTracker
{
public class DUTInfo
{
public DUTInfo()
{
Creation = DateTime.Now;
}
public long Usage { get; set; }
public long Quota { get; set; }
public readonly DateTime Creation;
}
readonly Dictionary<string, DUTInfo> DiskUsage;
readonly ApplicationDbContext context;
readonly int ulistLength;
public DiskUsageTracker(IOptions<SiteSettings> options, ApplicationDbContext context)
{
ulistLength = options.Value.DUUserListLen;
DiskUsage = new Dictionary<string, DUTInfo>();
this.context = context;
}
readonly static object userInfoLock = new object();
DUTInfo GetInfo(string username)
{
lock (userInfoLock)
{
if (!DiskUsage.ContainsKey(username))
{
var user = context.Users.SingleOrDefault(u => u.UserName == username);
if (user == null) throw new Exception($"Not an user : {username}");
DUTInfo usage = new DUTInfo
{
Usage = user.DiskUsage,
Quota = user.DiskQuota
};
DiskUsage.Add(username, usage);
if (DiskUsage.Count > ulistLength)
{
// remove the oldest
var oldestts = DateTime.Now;
DUTInfo oinfo = null;
string ouname = null;
foreach (var diskusage in DiskUsage)
{
if (oldestts > usage.Creation)
{
oldestts = diskusage.Value.Creation;
ouname = diskusage.Key;
oinfo = diskusage.Value;
}
}
var ouser = context.Users.SingleOrDefault(u => u.UserName == ouname);
ouser.DiskUsage = oinfo.Usage;
context.SaveChanges();
DiskUsage.Remove(ouname);
}
return usage;
}
return DiskUsage[username];
}
}
public bool GetSpace(string userName, long space)
{
var info = GetInfo(userName);
if (info.Quota < info.Usage + space) return false;
info.Usage += space;
#pragma warning disable CS4014
SaveUserUsage(userName,info.Usage);
#pragma warning restore CS4014
return true;
}
public void Release(string userName, long space)
{
var info = GetInfo(userName);
info.Usage -= space;
#pragma warning disable CS4014
SaveUserUsage(userName,info.Usage);
#pragma warning restore CS4014
}
async Task SaveUserUsage(string username, long usage)
{
await Task.Run(() =>
{
var ouser = context.Users.SingleOrDefault(u => u.UserName == username);
ouser.DiskUsage = usage;
context.SaveChanges();
});
}
}

View File

@ -4,6 +4,9 @@ using System.Security.Principal;
using System.Security.Claims;
using Yavsc.Models;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.OptionsModel;
using System.IO;
using rules;
namespace Yavsc.Services
{
@ -12,10 +15,20 @@ namespace Yavsc.Services
readonly ApplicationDbContext _dbContext;
readonly ILogger _logger;
public FileSystemAuthManager(ApplicationDbContext dbContext, ILoggerFactory loggerFactory)
readonly SiteSettings SiteSettings;
readonly string aclfileName;
readonly RuleSetParser ruleSetParser;
public FileSystemAuthManager(ApplicationDbContext dbContext, ILoggerFactory loggerFactory,
IOptions<SiteSettings> sitesOptions)
{
_dbContext = dbContext;
_logger = loggerFactory.CreateLogger<FileSystemAuthManager>();
SiteSettings = sitesOptions.Value;
aclfileName = SiteSettings.AccessListFileName;
ruleSetParser = new RuleSetParser(true);
}
public FileAccessRight GetFilePathAccess(ClaimsPrincipal user, string normalizedFullPath)
@ -25,38 +38,45 @@ namespace Yavsc.Services
var parts = normalizedFullPath.Split('/');
// below 4 parts, no file name.
if (parts.Length<4) return FileAccessRight.None;
var filePath = string.Join("/",parts.Skip(3));
if (parts.Length < 4) return FileAccessRight.None;
var fileDir = string.Join("/", parts.Take(parts.Length - 1));
var firstFileNamePart = parts[3];
if (firstFileNamePart == "pub")
{
_logger.LogInformation("Serving public file.");
return FileAccessRight.Read;
}
if (firstFileNamePart == "pub")
{
_logger.LogInformation("Serving public file.");
return FileAccessRight.Read;
}
var funame = parts[2];
_logger.LogInformation($"{normalizedFullPath} from {funame}");
if (funame == user?.GetUserName())
{
_logger.LogInformation("Serving file to owner.");
return FileAccessRight.Read | FileAccessRight.Write;
}
_logger.LogInformation($"Accessing {normalizedFullPath} from {funame}");
if (funame == user?.GetUserName())
{
_logger.LogInformation("Serving file to owner.");
return FileAccessRight.Read | FileAccessRight.Write;
}
var aclfi = new FileInfo(Path.Combine(Environment.CurrentDirectory, fileDir, aclfileName));
// TODO default user scoped file access policy
if (!aclfi.Exists) return FileAccessRight.Read;
ruleSetParser.Reset();
ruleSetParser.ParseFile(aclfi.FullName);
if (ruleSetParser.Rules.Allow(user.GetUserName()))
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);
)
{
var ok = _dbContext.CircleAuthorizationToFile.Any(a => a.CircleId == cid && a.FullPath == fileDir);
if (ok) return FileAccessRight.Read;
}
return FileAccessRight.None;
}

View File

@ -26,7 +26,6 @@ namespace Yavsc.Services
readonly IHubContext _hubContext;
private readonly ILogger _logger;
readonly ApplicationDbContext _dbContext;
public PathString LiveCastingPath { get; set; } = Constants.LivePath;
public ConcurrentDictionary<string, LiveCastHandler> Casters { get; } = new ConcurrentDictionary<string, LiveCastHandler>();
@ -38,23 +37,12 @@ namespace Yavsc.Services
_logger = loggerFactory.CreateLogger<LiveProcessor>();
}
public async Task<bool> AcceptStream(HttpContext context)
public async Task<bool> AcceptStream(HttpContext context, ApplicationUser user, string destDir, string fileName)
{
// TODO defer request handling
var liveId = long.Parse(context.Request.Path.Value.Substring(LiveCastingPath.Value.Length + 1));
var userId = context.User.GetUserId();
var user = await _dbContext.Users.FirstAsync(u => u.Id == userId);
var uname = user.UserName;
var flow = _dbContext.LiveFlow.Include(f => f.Owner).SingleOrDefault(f => (f.OwnerId == userId && f.Id == liveId));
if (flow == null)
{
_logger.LogWarning("Aborting. Flow info was not found.");
context.Response.StatusCode = 400;
return false;
}
_logger.LogInformation("flow : " + flow.Title + " for " + uname);
string uname = user.UserName;
LiveCastHandler liveHandler = null;
if (Casters.ContainsKey(uname))
{
@ -100,35 +88,15 @@ namespace Yavsc.Services
_logger.LogInformation($"Received bytes : {received.Count}");
_logger.LogInformation($"Is the end : {received.EndOfMessage}");
const string livePath = "live";
string destDir = context.User.InitPostToFileSystem(livePath);
_logger.LogInformation($"Saving flow to {destDir}");
string fileName = flow.GetFileName();
FileInfo destFileInfo = new FileInfo(Path.Combine(destDir, fileName));
// this should end :-)
while (destFileInfo.Exists)
{
flow.SequenceNumber++;
fileName = flow.GetFileName();
destFileInfo = new FileInfo(Path.Combine(destDir, fileName));
}
var fsInputQueue = new Queue<ArraySegment<byte>>();
bool endOfInput = false;
fsInputQueue.Enqueue(sBuffer);
var taskWritingToFs = liveHandler.ReceiveUserFile(user, _logger, destDir, fsInputQueue, fileName, flow.MediaType, () => endOfInput);
var hubContext = GlobalHost.ConnectionManager.GetHubContext<ChatHub>();
hubContext.Clients.All.addPublicStream(new PublicStreamInfo
{
id = flow.Id,
sender = flow.Owner.UserName,
title = flow.Title,
url = flow.GetFileUrl(),
mediaType = flow.MediaType
}, $"{flow.Owner.UserName} is starting a stream!");
var taskWritingToFs = liveHandler.ReceiveUserFile(user, _logger, destDir, fsInputQueue, fileName, () => endOfInput);
Stack<string> ToClose = new Stack<string>();
@ -136,7 +104,6 @@ namespace Yavsc.Services
{
do
{
_logger.LogInformation($"Echoing {received.Count} bytes received in a {received.MessageType} message; Fin={received.EndOfMessage}");
// Echo anything we receive
// and send to all listner found