using BeWo.Data.Entities; using BS.Shared; using BS.Shared.Core; using BS.Shared.Exceptions; using BS.Shared.Interface; using DevExpress.DataAccess.Native.Web; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.Remoting.Messaging; using System.Security.Cryptography; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Web.UI.WebControls; using Task = System.Threading.Tasks.Task; namespace BeWo.Data.Access { public class LocalTenantFileStorageDAO { public string Tenant => MultitenancyOperationContextExt.Current?.Tenant ?? throw new BeWoInvalidOperationException(AppError.MultitenancyOperationTenantUnknown); private readonly string _rootPath; public LocalTenantFileStorageDAO(string rootPath) { _rootPath = rootPath; } public string GetXRechnungFileName(long invoicebase_oid) { return $"invoicebase_{invoicebase_oid}_xrechnung.pdf"; } private string GetFilePath(string filePath) { return Path.Combine(_rootPath, Tenant, filePath); } public StoredFile SaveHybridFile(BWPFeature feature, string pFileName, string pContentType, Stream content, int? pBeWoObjectTid = null, long? pBeWoObjectOid = null, CancellationToken cancellationToken = default) { // Prüfe Namen if (SecurityUtils.ContainsInvalidFilenameChars(pFileName)) throw new BeWoInvalidOperationException(AppError.FileNameInvalidChar); var lFilePath = Path.Combine(feature.ToString(), pFileName); // Prüfe Path if (Path.GetFileName(lFilePath) != pFileName) throw new BeWoInvalidOperationException(AppError.FileNameNotEqFilePath); // Prüfe Doppelte Belegung if (DAOFactory.GenericDAO.Exists(nameof(StoredFile.FilePath), lFilePath)) throw new BeWoInvalidOperationException(AppError.StoredFileAlreadyExists); // Erstelle DB Eintrag var storedfile = new StoredFile(); storedfile.FileName = pFileName; storedfile.FilePath = lFilePath; storedfile.ContentType = pContentType; storedfile.BeWoObjectTid = pBeWoObjectTid; storedfile.BeWoObjectOid = pBeWoObjectOid; // Speichere FileAsync storedfile = SaveFileAsync(storedfile, content, cancellationToken).GetAwaiter().GetResult(); // Speichere DB Eintrag DAOFactory.GenericDAO.Insert(storedfile); return storedfile; } private async Task SaveFileAsync(StoredFile storedFile, Stream content, CancellationToken cancellationToken = default) { // Erstelle File Ordner var path = GetFilePath(storedFile.FilePath); var directory = Path.GetDirectoryName(path); Directory.CreateDirectory(directory); // Speichere Datei using (var stream = File.Create(path)) { await content.CopyToAsync(stream, bufferSize: 81920, cancellationToken).ConfigureAwait(true); storedFile.Size = content.Position; storedFile.Checksum = SecurityUtils.GetChecksumBuffered(content); } return storedFile; } public IStoredFile GetFileInfo(BWPFeature feature, string pFileName) { var lFilePath = Path.Combine(feature.ToString(), pFileName); return GetFileInfo(lFilePath); } public IStoredFile GetFileInfo(string filePath) { var file = DAOFactory.GenericDAO.GetByProperty(nameof(StoredFile.FilePath), filePath); return file; } public Stream GetFileContent(IStoredFile storedFile, CancellationToken cancellationToken = default) { var path = GetFilePath(storedFile.FilePath); if (!File.Exists(path)) return null; Stream stream = File.OpenRead(path); return stream; } public bool DeleteFile(IStoredFile storedFile, CancellationToken cancellationToken = default) { var path = GetFilePath(storedFile.FilePath); if (File.Exists(path)) { File.Delete(path); return true; } return false; } } }