The next generation of the Teknik Services. Written in ASP.NET. https://www.teknik.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

156 lines
6.6 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using Teknik.Configuration;
using Teknik.Models;
using Teknik.Utilities;
using System.Text;
using Teknik.Utilities.Cryptography;
using Teknik.Data;
using Teknik.StorageService;
using Teknik.Logging;
using Microsoft.Extensions.Logging;
namespace Teknik.Areas.Upload
{
public static class UploadHelper
{
public static Models.Upload SaveFile(TeknikEntities db, Config config, Stream file, string contentType, long contentLength, bool encrypt, ExpirationUnit expirationUnit, int expirationLength)
{
return SaveFile(db, config, file, contentType, contentLength, encrypt, expirationUnit, expirationLength, string.Empty, null, null, 256, 128);
}
public static Models.Upload SaveFile(TeknikEntities db, Config config, Stream file, string contentType, long contentLength, bool encrypt, ExpirationUnit expirationUnit, int expirationLength, string fileExt)
{
return SaveFile(db, config, file, contentType, contentLength, encrypt, expirationUnit, expirationLength, fileExt, null, null, 256, 128);
}
public static Models.Upload SaveFile(TeknikEntities db, Config config, Stream file, string contentType, long contentLength, bool encrypt, ExpirationUnit expirationUnit, int expirationLength, string fileExt, string iv)
{
return SaveFile(db, config, file, contentType, contentLength, encrypt, expirationUnit, expirationLength, fileExt, iv, null, 256, 128);
}
public static Models.Upload SaveFile(TeknikEntities db, Config config, Stream file, string contentType, long contentLength, bool encrypt, ExpirationUnit expirationUnit, int expirationLength, string fileExt, string iv, string key)
{
return SaveFile(db, config, file, contentType, contentLength, encrypt, expirationUnit, expirationLength, fileExt, iv, key, 256, 128);
}
public static Models.Upload SaveFile(TeknikEntities db, Config config, Stream file, string contentType, long contentLength, bool encrypt, ExpirationUnit expirationUnit, int expirationLength, string fileExt, string iv, string key, int keySize, int blockSize)
{
var storageService = StorageServiceFactory.GetStorageService(config.UploadConfig.StorageConfig);
// Generate a unique file name that does not currently exist
var fileName = storageService.GetUniqueFileName();
// once we have the filename, lets save the file
if (encrypt)
{
// Generate a key and iv
if (string.IsNullOrEmpty(key))
key = StringHelper.RandomString(config.UploadConfig.KeySize / 8);
if (string.IsNullOrEmpty(iv))
iv = StringHelper.RandomString(config.UploadConfig.BlockSize / 8);
byte[] keyBytes = Encoding.UTF8.GetBytes(key);
byte[] ivBytes = Encoding.UTF8.GetBytes(iv);
storageService.SaveEncryptedFile(fileName, file, config.UploadConfig.ChunkSize, keyBytes, ivBytes);
}
else
{
storageService.SaveFile(fileName, file);
}
// Generate a unique url
string extension = (config.UploadConfig.IncludeExtension) ? fileExt : string.Empty;
string url = StringHelper.RandomString(config.UploadConfig.UrlLength) + extension;
while (db.Uploads.Where(u => u.Url == url).FirstOrDefault() != null)
{
url = StringHelper.RandomString(config.UploadConfig.UrlLength) + extension;
}
// Generate a deletion key
string delKey = StringHelper.RandomString(config.UploadConfig.DeleteKeyLength);
// Now we need to update the database with the new upload information
Models.Upload upload = new Models.Upload();
upload.DateUploaded = DateTime.Now;
upload.Url = url;
upload.FileName = fileName;
upload.ContentType = (!string.IsNullOrEmpty(contentType)) ? contentType : "application/octet-stream";
upload.ContentLength = contentLength;
upload.Key = key;
upload.IV = iv;
upload.KeySize = keySize;
upload.BlockSize = blockSize;
upload.DeleteKey = delKey;
if (expirationUnit == ExpirationUnit.Views)
{
upload.MaxDownloads = expirationLength;
}
else
{
switch (expirationUnit)
{
case ExpirationUnit.Minutes:
upload.ExpireDate = DateTime.Now.AddMinutes(expirationLength);
break;
case ExpirationUnit.Hours:
upload.ExpireDate = DateTime.Now.AddHours(expirationLength);
break;
case ExpirationUnit.Days:
upload.ExpireDate = DateTime.Now.AddDays(expirationLength);
break;
case ExpirationUnit.Months:
upload.ExpireDate = DateTime.Now.AddMonths(expirationLength);
break;
case ExpirationUnit.Years:
upload.ExpireDate = DateTime.Now.AddYears(expirationLength);
break;
}
}
db.Uploads.Add(upload);
db.SaveChanges();
return upload;
}
public static bool CheckExpiration(Models.Upload upload)
{
if (upload.ExpireDate != null && DateTime.Now >= upload.ExpireDate)
return true;
if (upload.MaxDownloads > 0 && upload.Downloads >= upload.MaxDownloads)
return true;
return false;
}
public static Models.Upload GetUpload(TeknikEntities db, string url)
{
Models.Upload upload = db.Uploads.Where(up => up.Url == url).FirstOrDefault();
return upload;
}
public static void DeleteFile(TeknikEntities db, Config config, ILogger<Logger> logger, Models.Upload upload)
{
try
{
var storageService = StorageServiceFactory.GetStorageService(config.UploadConfig.StorageConfig);
storageService.DeleteFile(upload.FileName);
}
catch (Exception ex)
{
logger.LogError(ex, "Unable to delete file: {0}", upload.FileName);
}
// Delete from the DB
db.Uploads.Remove(upload);
db.SaveChanges();
}
}
}