|
|
using Microsoft.Azure.Cosmos; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;
namespace CDP { public class CDPDB { //https://learn.microsoft.com/en-us/azure/azure-functions/manage-connections?tabs=csharp#azure-cosmos-db-clients
private static Lazy<CosmosClient> lazyClient = new Lazy<CosmosClient>(InitializeCosmosClient); private static CosmosClient cosmosClient => lazyClient.Value; private static string DatabaseName = "CDP"; private static string FilesContainerName = "Files";
private static CosmosClient InitializeCosmosClient() { // Perform any initialization here
var uri = "https://cdplite.documents.azure.com:443/"; var authKey = "VPbg8RpzyI3XwhC2o0dIUtYFs33ghxORCqZeNAyg8vg4HWUBjM41BUxP0qLFXEvFh6ewQY1uKv52ACDbsEN1AQ==";
return new CosmosClient(uri, authKey); }
public static async Task<FileRecord> AddFile(string appKey, string fileId, string userId, string aesKey, AccessPolicy ac) { Container container = cosmosClient.GetContainer(DatabaseName, FilesContainerName); // get the Files Container
FileRecord fr = new FileRecord() { AppKey = appKey, FileId = fileId, UserId = userId, Policy = ac }; try { ItemResponse<FileRecord> r = await container.CreateItemAsync(fr); //
return r; } catch (Exception e) { return null; } }
public static async Task<FileRecord> UpsertFile(string appKey, string fileId, string fileName, string userId, string aesKey, AccessPolicy ac) { Container container = cosmosClient.GetContainer(DatabaseName, FilesContainerName); // get the Files Container
FileRecord fr = new FileRecord() { AppKey = appKey, FileId = fileId, FileName = fileName, UserId = userId, Policy = ac }; try { ItemResponse<FileRecord> r = await container.UpsertItemAsync(fr); //
return r; } catch (Exception e) { return null; } } public static async Task<FileRecord> GetFile(string appKey, string fileId, string userId) { Container container = cosmosClient.GetContainer(DatabaseName, FilesContainerName); // get the Files Container
FileRecord dto = new FileRecord() { AppKey = appKey, FileId = fileId, UserId = userId, }; try { // Store the unique identifier
string id = dto.id;
// Build the full partition key path
PartitionKey partitionKey = new PartitionKeyBuilder() .Add(appKey) .Add(fileId) .Add(userId) .Build();
// Perform a point read
ItemResponse<FileRecord> r = await container.ReadItemAsync<FileRecord>(id, partitionKey); return r; }
catch (Exception e) { return null; } }
public static async Task revokePolicies(string appKey, string userEmail, string contactEmail) { Task<List<FileRecord>> allFilesTask = GetAllOwnerFiles(appKey, userEmail.ToLower()); List<FileRecord> allFiles = await allFilesTask; if (allFiles == null) { return; }
foreach (FileRecord file in allFiles) { string fileId = file.FileId; string fileName = file.FileName; if (fileId == null) { continue; } string userId = Helpers.HashAndShortenText(contactEmail.ToLower()); AccessPolicy ac = new AccessPolicy() { Access = "None", Email = contactEmail.ToLower(), Group = null, GroupId = "", Key = "" };
string message = string.Format($"{contactEmail} contact deleted by {userEmail} and hence, access is revoked on file having id {fileId}"); string action = "Delete contact"; // await new CDPLite(null).AddAudits(appKey, fileId, userId, "", action, message);
await UpsertFile(appKey, fileId, fileName, userId, "", ac); } }
public static async Task revokeRegisteredUserPolicies(string appKey, string userEmail, string contactEmail, string registeredAdmin) { Task<List<FileRecord>> allFiles = GetAllOwnerFiles(appKey, userEmail.ToLower()); foreach (FileRecord file in await allFiles) { string fileId = file.FileId; string fileName = file.FileName; if (fileId == null) { continue; } string userId = Helpers.HashAndShortenText(contactEmail.ToLower()); AccessPolicy ac = new AccessPolicy() { Access = "None", Email = contactEmail.ToLower(), Group = null, GroupId = "", Key = "" };
string message = string.Format($"{contactEmail} Registered User deleted by {registeredAdmin} and hence, access is revoked on all the Tenant files having id {fileId}"); string action = "Delete Registered User"; // await new CDPLite(null).AddAudits(appKey, fileId, userId, "", action, message);
await UpsertFile(appKey, fileId, fileName, userId, "", ac); } }
public static async Task<List<FileRecord>> GetAllOwnerFiles(string appKey, string userId) { Container container = cosmosClient.GetContainer(DatabaseName, FilesContainerName); // get the Files Container
var queryText = "SELECT * FROM c WHERE c.AppKey = @appKey AND c.Policy.Email = @userId AND c.Policy.Access = 'Owner'"; var queryDefinition = new QueryDefinition(queryText) .WithParameter("@appKey", appKey) .WithParameter("@userId", userId);
var queryResultSetIterator = container.GetItemQueryIterator<FileRecord>(queryDefinition);
var results = new List<FileRecord>(); while (queryResultSetIterator.HasMoreResults) { var response = await queryResultSetIterator.ReadNextAsync(); results.AddRange(response.ToList()); } return results; }
public static async Task<List<FileRecord>> GetPoliciesForFile(string appKey, string fileId) { Container container = cosmosClient.GetContainer(DatabaseName, FilesContainerName); // get the Files Container
var queryText = "SELECT * FROM c WHERE c.AppKey = @appKey AND c.FileId = @fileId"; var queryDefinition = new QueryDefinition(queryText) .WithParameter("@appKey", appKey) .WithParameter("@fileId", fileId);
var queryResultSetIterator = container.GetItemQueryIterator<FileRecord>(queryDefinition);
var results = new List<FileRecord>(); while (queryResultSetIterator.HasMoreResults) { var response = await queryResultSetIterator.ReadNextAsync(); foreach (FileRecord fileRecord in response) { fileRecord.Policy.Key = "nunya"; } results.AddRange(response.ToList()); } return results; } }
class AddFileDto { public string AppKey { get; set; } // the customer's AppKey
public string Email { get; set; } // This is owner of the file...they will get a manage policy
public string FileName { get; set; } // user and group auditing is pretty worthless without this (less we do gobs of queries)
public string GroupId { get; set; }
}
class DeleteUserContactsDto { public string AppKey { get; set; } public string UserEmail { get; set; } public string ContactEmail { get; set; } } class DeleteRegisteredUserDto { public string AppKey { get; set; } public string UserEmail { get; set; } public string ContactEmail { get; set; } public string AdminEmail { get; set; } }
class AddUserGroupDto { public string AppKey { get; set; } public string EmailId { get; set; } public string GroupName { get; set; } public string GroupDescription { get; set; } public List<Contact> Contacts { get; set; } } class GetUserGroupDto { public string AppKey { get; set; } public string EmailId { get; set; } }
class Contact { public string Name { get; set; } public string Email { get; set; } public string Company { get; set; } public string Phone { get; set; } public string Address { get; set; } }
class AddUserContactsDto { public string AppKey { get; set; } public string EmailId { get; set; } public string ContactName { get; set; } public string ContactEmail { get; set; } public string ContactCompany { get; set; } public string ContactPhone { get; set; } public string ContactAddress { get; set; } }
class GetContactsDto { public string Email { get; set; } public string AppKey { get; set; } } class AddFileUserDto { public string AppKey { get; set; } // the customer's AppKey
public string FileId { get; set; } public string Email { get; set; } // email of user with power to add a user
public string EmailToAdd { get; set; } public GroupsRecord Group { get; set; } public string GroupId { get; set; } public string Policy { get; set; } // Manage/Read/Write/etc...
public string FileName { get; set; } // user and group auditing is pretty worthless without this (less we do gobs of queries)
} class GetFileForUserDto { public string AppKey { get; set; } // the customer's AppKey
public string FileId { get; set; } public string Email { get; set; } // email of user with power to add a user
public string FileName { get; set; } // user and group auditing is pretty worthless without this (less we do gobs of queries)
}
class GetPoliciesForFileDto { public string AppKey { get; set; } // the customer's AppKey
public string FileId { get; set; } }
class GetFileDto { public string AppKey { get; set; } // the customer's AppKey
public string FileId { get; set; } public string Email { get; set; }
} class CreateSessionDto { public string AppKey { get; set; } // the customer's AppKey
public string CallbackUrl { get; set; } public string Payload { get; set; } public string WebHookUrl { get; set; } } class GetAuditLogForFileDto { public string FileId { get; set; } }
class GetAuditLogForUserDto { public string Email { get; set; } } class GetAuditLogForTenantDto { public string AppKey { get; set; } } class AddAccessViolationDto { public String FileId { get; set; } public string AppKey { get; set; } public string FileName { get; set; } } class GetAuditLogForGroupDto { public string GroupId { get; set; } } class GetTenantDto { public string AppKey { get; set; } // the customer's AppKey
}
class GetGroupDto { public string GroupId { get; set; } }
class DeleteGroupDto { public string GroupId { get; set; } public string AppKey { get; set; } public string UserEmail { get; set; } } class UpdateGroupDto { public string AppKey { get; set; } public string UserEmail { get; set; } public string GroupId { get; set; } public string GroupName { get; set; } public string GroupDescription { get; set; } public List<Contact> Contacts { get; set; } } class CreateClientQRCodeDto { public string SignalRConnectionId { get; set; } public string AppKey { get; set; } // the customer's AppKey
public string Payload { get; set; } } class GetJwtsQRCode { public string SignalRConnectionId { get; set; } public List<string> AppKeys { get; set; } } class ClientJwts { public List<string> HashedEmails { get; set; } public List<string> Jwts { get; set; }
public ClientJwts() { HashedEmails = new List<string>(); Jwts = new List<string>(); } }
public class FileRecord { public string id { get { string s = Helpers.HashAndShortenText(UserId + FileId); // Cosmos db doesn't like '/', '\', '?', '#' and base64 strings can have '/'
return s.Replace('/', '-');
} }
public string AppKey { get; set; } // the customer's AppKey
public string FileId { get; set; } public string FileName { get; set; } public string UserId { get; set; } // This is owner of the file...they will get a manage policy
public AccessPolicy Policy { get; set; } }
public class AccessPolicy { public string Email { get; set; } // for sanity's sake. The end user will probably want this anyway.
public GroupsRecord Group { get; set; } public string GroupId { get; set; } public string Access { get; set; } // Read Only, Manage, Print. CSV...opting for usability over a sexier bit flag.
public string Key { get; set; } // encrypted with Constants.PublicKey
public Boolean CheckAccess(string accessToCheck) { // Split the input string into an array of entries using commas as the separator
string[] entries = Access.Split(',');
// Iterate through the entries and check if any match the target string
foreach (string entry in entries) { // Use StringComparison.OrdinalIgnoreCase for case-insensitive comparison
if (entry.Trim().Equals(accessToCheck, StringComparison.OrdinalIgnoreCase)) { return true; // Found a match
} }
// No matching entry found
return false; } } }
|