Temporary repo to track my changes on LTS functions app porting
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.

427 lines
15 KiB

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;
}
}
}