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