//------------ Destroy Data ------ internal static DataAccessResponseType DestroySqlSchemaAndTables(Account account) { var response = new DataAccessResponseType(); try { return(Sql.Statements.StoredProcedures.DestroySchema(account.SchemaName, account.SqlPartition)); } catch (Exception e) { response.isSuccess = false; response.ErrorMessage = e.Message; //Log exception and email platform admins PlatformExceptionsHelper.LogExceptionAndAlertAdmins( e, "attempting to destroy SQL schema and tables for : " + account.AccountName, System.Reflection.MethodBase.GetCurrentMethod() ); PlatformLogManager.LogActivity(CategoryType.Error, ActivityType.Error_Exception, "Error destroying schema for: '" + account.AccountName + "' on: ' " + account.SqlPartition + "'", "AccountID: '" + account.AccountID + "' AccountNameKey: '" + account.AccountNameKey + "' Error: '" + e.Message + "'", account.AccountID.ToString(), account.AccountName); } return(response); }
/// <summary> /// Deletes a single image record from table storage /// </summary> /// <param name="accountId"></param> /// <param name="objectId"></param> /// <param name="imageGroupTypeNameKey"></param> /// <param name="imageGroupNameKey"></param> /// <param name="imageFormatNameKey"></param> /// <returns></returns> internal static DataAccessResponseType DeleteImageRecord(string accountId, string storagePartition, string imageFormatGroupTypeNameKey, string objectId, string imageGroupNameKey, string imageFormatNameKey) { var response = new DataAccessResponseType(); var imageKey = imageGroupNameKey + "-" + imageFormatNameKey; //CloudTableClient cloudTableClient = Sahara.Core.Settings.Azure.Storage.StorageConnections.AccountsStorage.CreateCloudTableClient(); CloudTableClient cloudTableClient = Settings.Azure.Storage.GetStoragePartitionAccount(storagePartition).CreateCloudTableClient(); //Create and set retry policy //IRetryPolicy exponentialRetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(1), 4); IRetryPolicy linearRetryPolicy = new LinearRetry(TimeSpan.FromSeconds(1), 4); cloudTableClient.DefaultRequestOptions.RetryPolicy = linearRetryPolicy; try { //Delete from MAIN table CloudTable cloudTable1 = cloudTableClient.GetTableReference(Sahara.Core.Common.Methods.SchemaNames.AccountIdToTableStorageName(accountId) + ImageRecordTableName(imageFormatGroupTypeNameKey)); //cloudTable1.CreateIfNotExists(); TableEntity productImageEntity1 = cloudTable1.CreateQuery <TableEntity>().Where(p => p.PartitionKey == objectId && p.RowKey == imageKey).FirstOrDefault(); cloudTable1.Execute(TableOperation.Delete(productImageEntity1)); //Delete from LISTINGS table (We allow this to fail silently in case this is not a listing image try { CloudTable cloudTable2 = cloudTableClient.GetTableReference(Sahara.Core.Common.Methods.SchemaNames.AccountIdToTableStorageName(accountId) + ImageRecordListingTableName(imageFormatGroupTypeNameKey)); //cloudTable2.CreateIfNotExists(); TableEntity productImageEntity2 = cloudTable2.CreateQuery <TableEntity>().Where(p => p.PartitionKey == objectId && p.RowKey == imageKey).FirstOrDefault(); cloudTable2.Execute(TableOperation.Delete(productImageEntity2)); } catch { } response.isSuccess = true; } catch (Exception e) { PlatformLogManager.LogActivity( CategoryType.Error, ActivityType.Error_Exception, e.Message, "Exception while attempting to delete image record/rowKey'" + imageKey + "' for " + imageFormatGroupTypeNameKey + " '" + objectId + "' in table storage", accountId, null, null, null, null, null, System.Reflection.MethodBase.GetCurrentMethod().ToString(), null ); } return(response); }
public static DataAccessResponseType ClearStripeWebhooksLog() { var response = new DataAccessResponseType(); try { int amountOfDays = Sahara.Core.Settings.Platform.GarbageCollection.StripeWebhookEventLogDaysToPurge; CloudTableClient cloudTableClient = Sahara.Core.Settings.Azure.Storage.StorageConnections.PlatformStorage.CreateCloudTableClient(); //Create and set retry policy //IRetryPolicy exponentialRetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(1), 4); IRetryPolicy linearRetryPolicy = new LinearRetry(TimeSpan.FromSeconds(1), 3); cloudTableClient.DefaultRequestOptions.RetryPolicy = linearRetryPolicy; CloudTable cloudTable = cloudTableClient.GetTableReference("stripewebhookeventslog"); cloudTable.CreateIfNotExists(); TableQuery <TableEntity> query = new TableQuery <TableEntity>() .Where(TableQuery.GenerateFilterConditionForDate("DateTimeUTC", QueryComparisons.LessThanOrEqual, DateTimeOffset.UtcNow.AddDays(amountOfDays * -1))); var stripeWebhooks = cloudTable.ExecuteQuery(query); int count = stripeWebhooks.Count(); foreach (var log in stripeWebhooks) { cloudTable.Execute(TableOperation.Delete(log)); } if (count > 0) { //Log Garbage Collection PlatformLogManager.LogActivity( CategoryType.GarbageCollection, ActivityType.GarbageCollection_StripeEventLog, "Purged " + count.ToString("#,##0") + " item(s) from the stripe webhook events logs", count.ToString("#,##0") + " stripe webhook event(s) past " + amountOfDays + " days have been purged" ); } response.isSuccess = true; } catch (Exception e) { //Log exception and email platform admins PlatformExceptionsHelper.LogExceptionAndAlertAdmins( e, "attempting to clear stripe webhooks log", System.Reflection.MethodBase.GetCurrentMethod() ); response.isSuccess = false; response.ErrorMessage = e.Message; } return(response); }
internal static DataAccessResponseType DestroyDocumentCollection(Account account) { var response = new DataAccessResponseType { isSuccess = false }; try { // Create new stopwatch & begin timing tasks Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); #region Connect to the DocumentDB Client & Get Collection Object //Get the DocumentDB Client //var client = Sahara.Core.Settings.Azure.DocumentDbClients.AccountDocumentClient; //var dbSelfLink = Sahara.Core.Settings.Azure.DocumentDB.AccountPartitionDatabaseSelfLink; //Sahara.Core.Settings.Azure.DocumentDbClients.AccountDocumentClient.OpenAsync(); //Build a collection Uri out of the known IDs //(These helpers allow you to properly generate the following URI format for Document DB: //"dbs/{xxx}/colls/{xxx}/docs/{xxx}" Uri collectionUri = UriFactory.CreateDocumentCollectionUri(Sahara.Core.Settings.Azure.DocumentDB.AccountPartitionDatabaseId, account.DocumentPartition); #endregion #region Delete the document collection for this account var result = Sahara.Core.Settings.Azure.DocumentDbClients.AccountDocumentClient.DeleteDocumentCollectionAsync(collectionUri.ToString()).Result; #endregion } catch { #region Manual Task Instructions (if failure occurs) response.isSuccess = false; PlatformLogManager.LogActivity( CategoryType.ManualTask, ActivityType.ManualTask_DocumentDB, "Deletion of Document Collection for closed account '" + account.AccountName + "' failed.", "DocumentPartition: '" + account.DocumentPartition + "' partition for: '" + account.AccountName + "'. Please manually delete the '" + account.DocumentPartition + "' Document Collection", null, null, null, null, null, null, System.Reflection.MethodBase.GetCurrentMethod().ToString() ); #endregion } return(response); }
public DataAccessResponseType DeletePlatformUser(string userId, string requesterId, RequesterType requesterType, string sharedClientKey) { // Ensure the clients are certified. if (sharedClientKey != Sahara.Core.Platform.Requests.RequestManager.SharedClientKey) { return(null); } #region Validate Request var requesterName = string.Empty; var requesterEmail = string.Empty; var requestResponseType = RequestManager.ValidateRequest(requesterId, requesterType, out requesterName, out requesterEmail, Sahara.Core.Settings.Platform.Users.Authorization.Roles.SuperAdmin, null); if (!requestResponseType.isApproved) { //Request is not approved, send results: return(new DataAccessResponseType { isSuccess = false, ErrorMessage = requestResponseType.requestMessage }); } #endregion var user = PlatformUserManager.GetUser(userId); var result = PlatformUserManager.DeleteUser(userId); #region Log Platform Activity if (result.isSuccess) { try { PlatformLogManager.LogActivity( CategoryType.PlatformUser, ActivityType.PlatformUser_Deleted, "User deleted", requesterName + " deleted " + user.FullName + "'s account", null, null, requesterId, requesterName, requesterEmail ); } catch { } } #endregion return(result); }
/// <summary> /// Helper function to Logs exceptions AND send emails to alert platform admins /// </summary> /// <param name="exception"></param> /// <param name="details"></param> /// <param name="codeLocation"></param> /// <param name="accountId"></param> /// <param name="accountName"></param> /// <param name="serializedObject"></param> /// <returns></returns> public static bool LogExceptionAndAlertAdmins(Exception exception, string attemptedAction, MethodBase methodBase, string accountId = null, string accountName = null) { var serializedException = JsonConvert.SerializeObject(exception); attemptedAction = "An exception occurred while " + attemptedAction; #region Log The Error PlatformLogManager.LogActivity( CategoryType.Error, ActivityType.Error_Exception, exception.Message, attemptedAction, accountId, accountName, null, null, null, null, methodBase.ReflectedType.FullName + "." + methodBase.Name, serializedException ); #endregion #region Email Platform Admins EmailManager.Send( Settings.Endpoints.Emails.PlatformEmailAddresses, Settings.Endpoints.Emails.FromExceptions, "Platform Exception", "Exception Alert!", "Exception location: <b>" + methodBase.ReflectedType.FullName + "." + methodBase.Name + "</b>" + "<br/><br/>" + attemptedAction + "<br/><br/><b>" + exception.Message + "</b><br/><br/>" + accountId + "<br/><br/>" + accountName + "<br/><br/>" + serializedException, true, true ); #endregion return(true); }
internal static DataAccessResponseType DestroySchema(string schemaName, string databasePartitionName) { var response = new DataAccessResponseType(); //SqlCommand sqlCommand = new SqlCommand("DestroySchema", Sahara.Core.Settings.Azure.Databases.DatabaseConnections.DatabasePartitionSqlConnection(databasePartitionName)); SqlCommand sqlCommand = Sahara.Core.Settings.Azure.Databases.DatabaseConnections.DatabasePartitionSqlConnection(databasePartitionName).CreateCommand(); sqlCommand.CommandText = "DestroySchema"; try { sqlCommand.CommandType = System.Data.CommandType.StoredProcedure; sqlCommand.Parameters.Add(new SqlParameter("@SchemaName", schemaName)); sqlCommand.Parameters.Add(new SqlParameter("@WorkTest", 'w')); sqlCommand.Connection.OpenWithRetry(); sqlCommand.ExecuteNonQueryWithRetry(); sqlCommand.Connection.Close(); response.isSuccess = true; response.SuccessMessage = "Schema '" + schemaName + "', and all associated object have been destroyed on '" + databasePartitionName + "'"; } catch (Exception e) { //Log exception and email platform admins PlatformExceptionsHelper.LogExceptionAndAlertAdmins( e, "attempting to destroy for: " + schemaName, System.Reflection.MethodBase.GetCurrentMethod() ); PlatformLogManager.LogActivity( CategoryType.ManualTask, ActivityType.ManualTask_SQL, "Stored Procedure 'DestroySchema' Failed on the '" + databasePartitionName + "' partition for schema '" + schemaName + "'", sqlCommand.ToString(), null, null, null, null, null, null, System.Reflection.MethodBase.GetCurrentMethod().ToString() ); response.isSuccess = false; response.ErrorMessage = e.Message; } return(response); }
public DataAccessResponseType UpdatePlatformUserPassword(string email, string currentPassword, string newPassword, string requesterId, RequesterType requesterType, string sharedClientKey) { // Ensure the clients are certified. if (sharedClientKey != Sahara.Core.Platform.Requests.RequestManager.SharedClientKey) { return(null); } #region Validate Request var requesterName = string.Empty; var requesterEmail = string.Empty; var requestResponseType = RequestManager.ValidateRequest(requesterId, requesterType, out requesterName, out requesterEmail, Sahara.Core.Settings.Platform.Users.Authorization.Roles.SuperAdmin, null); if (!requestResponseType.isApproved) { //Request is not approved, send results: return(new DataAccessResponseType { isSuccess = false, ErrorMessage = requestResponseType.requestMessage }); } #endregion var result = PlatformUserManager.ChangePassword(email, currentPassword, newPassword); #region Log Platform Activity if (result.isSuccess) { try { PlatformLogManager.LogActivity( CategoryType.PlatformUser, ActivityType.PlatformUser_Invited, "Password changed", requesterName + " has updated their password", null, null, requesterId, requesterName, requesterEmail ); } catch { } } #endregion return(result); }
public DataAccessResponseType CreatePlatformUser(string email, string firstName, string lastName, string password, string roleName, string requesterId, RequesterType requesterType, string sharedClientKey) { // Ensure the clients are certified. if (sharedClientKey != Sahara.Core.Platform.Requests.RequestManager.SharedClientKey) { return(null); } #region Validate Request var requesterName = string.Empty; var requesterEmail = string.Empty; var requestResponseType = RequestManager.ValidateRequest(requesterId, requesterType, out requesterName, out requesterEmail, Sahara.Core.Settings.Platform.Users.Authorization.Roles.SuperAdmin, null); if (!requestResponseType.isApproved) { //Request is not approved, send results: return(new DataAccessResponseType { isSuccess = false, ErrorMessage = requestResponseType.requestMessage }); } #endregion var result = PlatformUserManager.CreatePlatformUser(email, firstName, lastName, password, roleName); #region Log Platform Activity if (result.isSuccess) { try { PlatformLogManager.LogActivity( CategoryType.PlatformUser, ActivityType.PlatformUser_Created, "User created", requesterName + " created new user: '******'", null, null, requesterId, requesterName, requesterEmail ); } catch { } } #endregion return(result); }
/// <summary> /// Returns true if event has been logged in the past /// </summary> /// <returns></returns> internal static bool HasEventBeenLogged(string eventId) { var stripeWebhookEventsLog = GetWebhookEvent(eventId); if (stripeWebhookEventsLog != null) { //Event exists and has been run by our webhook API, increase retry count by 1 and return true: try { //Update retry count +1 stripeWebhookEventsLog.RetryCount = stripeWebhookEventsLog.RetryCount + 1; TableOperation operation = TableOperation.InsertOrReplace(stripeWebhookEventsLog); //Create the cloudtable instance and name for the entity operate against: var cloudTableClient = Sahara.Core.Settings.Azure.Storage.StorageConnections.PlatformStorage.CreateCloudTableClient(); //Create and set retry policy //IRetryPolicy exponentialRetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(1), 4); IRetryPolicy linearRetryPolicy = new LinearRetry(TimeSpan.FromSeconds(1), 5); cloudTableClient.DefaultRequestOptions.RetryPolicy = linearRetryPolicy; stripeWebhookEventsLog.cloudTable = cloudTableClient.GetTableReference(StripeWebhookEventsLogManager.StripeWebhookEventsLogTableName); stripeWebhookEventsLog.cloudTable.CreateIfNotExists(); stripeWebhookEventsLog.cloudTable.Execute(operation); } catch (Exception e) { PlatformLogManager.LogActivity( CategoryType.Error, ActivityType.Error_Exception, "An exception occurred while attempting to increment retry count on an existing stripe event log for idempotenancy", "Incrementing retry count on stripe idempotent log for: " + stripeWebhookEventsLog.EventID, null, null, null, null, null, null, null, JsonConvert.SerializeObject(e) ); } //return true: return(true); } else { //Event does not exists, return false; return(false); } }
/// <summary> /// Helper function to Logs exceptions AND send emails to alert platform admins /// </summary> /// <param name="error"></param> /// <param name="details"></param> /// <param name="codeLocation"></param> /// <param name="accountId"></param> /// <param name="accountName"></param> /// <param name="serializedObject"></param> /// <returns></returns> public static bool LogErrorAndAlertAdmins(string error, string attemptedAction, MethodBase methodBase, string accountId = null, string accountName = null) { attemptedAction = "An error occurred while " + attemptedAction; #region Log The Error PlatformLogManager.LogActivity( CategoryType.Error, ActivityType.Error_Other, error, attemptedAction, accountId, accountName, null, null, null, null, methodBase.ReflectedType.FullName + "." + methodBase.Name, null ); #endregion #region Email Platform Admins EmailManager.Send( Settings.Endpoints.Emails.PlatformEmailAddresses, Settings.Endpoints.Emails.FromExceptions, "Platform Error", "Error Alert!", "Error location: <b>" + methodBase.ReflectedType.FullName + "." + methodBase.Name + "</b>" + "<br/><br/>" + attemptedAction + "<br/><br/><b>" + error + "</b><br/><br/>" + accountId + "<br/><br/>" + accountName, true, true ); #endregion return(true); }
public static DataAccessResponseType ClearIntermediaryStorage() { var response = new DataAccessResponseType(); var daysAgo = (Sahara.Core.Settings.Platform.GarbageCollection.IntermediaryStorageContainerDaysToPurge * -1); try { //Clients that wish to save source files to intermediary blob storage mush use the following date format to name the container for custodial garbage collection to take place. var date = DateTime.UtcNow.AddDays(daysAgo); var containerName = date.ToShortDateString().Replace("/", "-"); //Delete Storage Containers on Intermediary Labeled from "X" days ago CloudBlobClient blobClient = Sahara.Core.Settings.Azure.Storage.StorageConnections.IntermediateStorage.CreateCloudBlobClient(); //Create and set retry policy IRetryPolicy exponentialRetryPolicy = new ExponentialRetry(TimeSpan.FromMilliseconds(500), 8); blobClient.DefaultRequestOptions.RetryPolicy = exponentialRetryPolicy; if (blobClient.GetContainerReference(containerName).Exists()) { blobClient.GetContainerReference(containerName).DeleteIfExists(); //Log Garbage Collection PlatformLogManager.LogActivity( CategoryType.GarbageCollection, ActivityType.GarbageCollection_IntermediaryStorage, "Purged the '" + containerName + "' intermediary storage container", "An intermediary storage container older than " + Sahara.Core.Settings.Platform.GarbageCollection.IntermediaryStorageContainerDaysToPurge + " days has been purged" ); } response.isSuccess = true; } catch (Exception e) { //Log exception and email platform admins PlatformExceptionsHelper.LogExceptionAndAlertAdmins( e, "attempting to purge intermediary data past " + Sahara.Core.Settings.Platform.GarbageCollection.IntermediaryStorageContainerDaysToPurge + " days old", System.Reflection.MethodBase.GetCurrentMethod() ); response.isSuccess = false; response.ErrorMessage = e.Message; } return(response); }
internal static DataAccessResponseType DestroySearchIndexes(Account account) { var response = new DataAccessResponseType { isSuccess = false }; try { // Create new stopwatch & begin timing tasks Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); #region Delete the search indexes for this account //SearchServiceClient searchServiceClient = Settings.Azure.Search.AccountsSearchServiceClient; //searchServiceClient.Indexes.Delete(account.ProductSearchIndex); //Using partition for this account: SearchServiceClient searchServiceClient = Settings.Azure.Search.GetSearchPartitionClient(account.SearchPartition); searchServiceClient.Indexes.Delete(account.ProductSearchIndex); #endregion } catch { #region Manual Task Instructions (if failure occurs) response.isSuccess = false; PlatformLogManager.LogActivity( CategoryType.ManualTask, ActivityType.ManualTask_DocumentDB, "Deletion of Search Indexes for closed account '" + account.AccountName + "' failed.", "Search Indexes for: '" + account.AccountNameKey + "' will need to be manually deleted in the Azure portal.", null, null, null, null, null, null, System.Reflection.MethodBase.GetCurrentMethod().ToString() ); #endregion } return(response); }
internal static DataAccessResponseType DestroyTableStorageData(Account account) { var response = new DataAccessResponseType { isSuccess = false }; //Loop through all tables named by schema for this account and delete //CloudTableClient cloudTableClient = Sahara.Core.Settings.Azure.Storage.StorageConnections.AccountsStorage.CreateCloudTableClient(); CloudTableClient cloudTableClient = Settings.Azure.Storage.GetStoragePartitionAccount(account.StoragePartition).CreateCloudTableClient(); //Create and set retry policy IRetryPolicy exponentialRetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(1), 16); //IRetryPolicy linearRetryPolicy = new LinearRetry(TimeSpan.FromSeconds(1), 3); cloudTableClient.DefaultRequestOptions.RetryPolicy = exponentialRetryPolicy; IEnumerable <CloudTable> tables = cloudTableClient.ListTables(Sahara.Core.Common.Methods.SchemaNames.AccountIdToTableStorageName(account.AccountID.ToString())); foreach (CloudTable table in tables) { try { table.Delete(); } catch { response.isSuccess = false; PlatformLogManager.LogActivity( CategoryType.ManualTask, ActivityType.ManualTask_TableStorage, "Table(s) Deletion Failed for schema" + Sahara.Core.Common.Methods.SchemaNames.AccountIdToTableStorageName(account.AccountID.ToString()), "Please delete all tables for schema '" + Sahara.Core.Common.Methods.SchemaNames.AccountIdToTableStorageName(account.AccountID.ToString()) + "' manually.", null, null, null, null, null, null, System.Reflection.MethodBase.GetCurrentMethod().ToString() ); } } return(response); }
internal static DataAccessResponseType DeleteTag(Account account, string tagName) { var response = new DataAccessResponseType(); //CloudTableClient cloudTableClient = Sahara.Core.Settings.Azure.Storage.StorageConnections.AccountsStorage.CreateCloudTableClient(); CloudTableClient cloudTableClient = Settings.Azure.Storage.GetStoragePartitionAccount(account.StoragePartition).CreateCloudTableClient(); //Create and set retry policy //IRetryPolicy exponentialRetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(1), 4); IRetryPolicy linearRetryPolicy = new LinearRetry(TimeSpan.FromSeconds(1), 4); cloudTableClient.DefaultRequestOptions.RetryPolicy = linearRetryPolicy; CloudTable cloudTable = cloudTableClient.GetTableReference(Sahara.Core.Common.Methods.SchemaNames.AccountIdToTableStorageName(account.AccountID.ToString()) + TagsTableName); cloudTable.CreateIfNotExists(); try { TagTableEntity tagEntity = cloudTable.CreateQuery <TagTableEntity>().Where(t => t.PartitionKey == tagName).FirstOrDefault(); TableResult deleteResult = cloudTable.Execute(TableOperation.Delete(tagEntity)); response.isSuccess = true; } catch (Exception e) { PlatformLogManager.LogActivity( CategoryType.Error, ActivityType.Error_Exception, e.Message, "Exception while attempting to delete tag '" + tagName + "'", account.AccountID.ToString(), account.AccountName, null, null, null, null, System.Reflection.MethodBase.GetCurrentMethod().ToString(), null ); } return(response); }
internal static DataAccessResponseType DestroyBlobStorageData(Account account) { var response = new DataAccessResponseType { isSuccess = true }; //CloudBlobClient blobClient = Sahara.Core.Settings.Azure.Storage.StorageConnections.AccountsStorage.CreateCloudBlobClient(); CloudBlobClient blobClient = Sahara.Core.Settings.Azure.Storage.GetStoragePartitionAccount(account.StoragePartition).CreateCloudBlobClient(); //Create and set retry policy IRetryPolicy exponentialRetryPolicy = new ExponentialRetry(TimeSpan.FromMilliseconds(500), 8); blobClient.DefaultRequestOptions.RetryPolicy = exponentialRetryPolicy; CloudBlobContainer blobContainer = blobClient.GetContainerReference(account.AccountID.ToString()); //CloudBlobContainer blobContainer = blobClient.GetContainerReference(account.AccountNameKey); try { blobContainer.DeleteIfExists(); } catch { response.isSuccess = false; PlatformLogManager.LogActivity( CategoryType.ManualTask, ActivityType.ManualTask_BlobStorage, "Blob Container Deletion Failed", "Please delete the top level container '" + account.AccountID.ToString() + "' manually.", null, null, null, null, null, null, System.Reflection.MethodBase.GetCurrentMethod().ToString() ); } return(response); }
/// <summary> /// Helper function to log when an account reaches a limitation AND send emails to alert platform admins for upsell opportunities /// </summary> /// <param name="limitationReached"></param> /// <param name="accountId"></param> /// <param name="accountName"></param> /// <returns></returns> public static bool LogLimitationAndAlertAdmins(string limitationObjectName, string accountId = null, string accountName = null) { #region Log The Limitation PlatformLogManager.LogActivity( CategoryType.Account, ActivityType.Account_LimitationReached, accountName + " has reached an account limitation", accountName + " has reached a limitation on their maximum allowed " + limitationObjectName, accountId, accountName, null, null, null, null, null, null ); #endregion #region Email Platform Admins EmailManager.Send( Settings.Endpoints.Emails.PlatformEmailAddresses, Settings.Endpoints.Emails.FromPlatform, "Account Limitations", "Account Limitation Reached!", "<a href='http://" + Sahara.Core.Settings.Endpoints.URLs.PlatformDomain + "/account/" + accountId + "'><strong>" + accountName + "</strong></a> has attempted to go past a plan limitation on their maximum allowed " + limitationObjectName, true, true ); #endregion return(true); }
/// <summary> /// Helper function to log when an account is closed AND send emails to alert platform admins for verification purposes /// </summary> /// <param name="accountId"></param> /// <param name="accountName"></param> /// <param name="accountNameKey"></param> /// <param name="userEmail"></param> /// <param name="userId"></param> /// <returns></returns> public static bool LogAccountClosureAndAlertAdmins(string accountId, string accountName, string accountNameKey, string userName, string userId, string userEmail, bool isPaidAccount) { #region Log The Limitation PlatformLogManager.LogActivity( CategoryType.Account, ActivityType.Account_ClosureRequested, accountName + " has requested closure", accountName + " has closure request initiated by " + userName + "(" + userId + " | " + userEmail + ")", accountId, accountName, null, null, null, null, null, null ); #endregion #region Email Platform Admins EmailManager.Send( Settings.Endpoints.Emails.PlatformEmailAddresses, Settings.Endpoints.Emails.FromPlatform, "Account Closure Request", accountName + " has requested account closure", "<a href='http://" + Sahara.Core.Settings.Endpoints.URLs.PlatformDomain + "/account/" + accountNameKey + "'><strong>" + accountName + "</strong></a> has been closed by " + userName + "(" + userId + " | " + userEmail + ")", true, true ); #endregion return(true); }
internal static bool ClearReminderEmailsLog(int amountOfDays) { CloudTableClient cloudTableClient = Sahara.Core.Settings.Azure.Storage.StorageConnections.PlatformStorage.CreateCloudTableClient(); //Create and set retry policy //IRetryPolicy exponentialRetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(1), 4); IRetryPolicy linearRetryPolicy = new LinearRetry(TimeSpan.FromSeconds(1), 3); cloudTableClient.DefaultRequestOptions.RetryPolicy = linearRetryPolicy; CloudTable cloudTable = cloudTableClient.GetTableReference(ReminderEmailsCardExpirationLogTableName); cloudTable.CreateIfNotExists(); TableQuery <CardExpirationEmailRemindersLogTableEntity> query = new TableQuery <CardExpirationEmailRemindersLogTableEntity>() .Where(TableQuery.GenerateFilterConditionForDate("DateTimeUTC", QueryComparisons.LessThanOrEqual, DateTimeOffset.UtcNow.AddDays(amountOfDays * -1))); var cardExirationReminderEmails = cloudTable.ExecuteQuery(query); int count = cardExirationReminderEmails.Count(); foreach (var log in cardExirationReminderEmails) { cloudTable.Execute(TableOperation.Delete(log)); } if (count > 0) { //Log Garbage Collection PlatformLogManager.LogActivity( CategoryType.GarbageCollection, ActivityType.GarbageCollection_CreditCardExpirationRemindersLog, "Purged " + count.ToString("#,##0") + " item(s) from the credit card expiration reminders logs", count.ToString("#,##0") + " credit card expiration reminder(s) past " + Sahara.Core.Settings.Platform.GarbageCollection.CreditCardExpirationReminderEmailsLogDaysToPurge + " days have been purged" ); } return(true); }
public static DataAccessResponseType DeprovisionAccount(Account account) { DataAccessResponseType response = new DataAccessResponseType(); if (account.AccountID == Guid.Empty) { response.isSuccess = false; response.ErrorMessage = "No account to deprovision"; return(response); } try { // 0. Get Account Users: account.Users = AccountUserManager.GetUsers(account.AccountID.ToString()); #region LOG ACTIVITY (Deprovisioning Started) if (account.Provisioned) { PlatformLogManager.LogActivity( CategoryType.Account, ActivityType.Account_Deprovisioning_Started, "Deprovisioning of '" + account.AccountName + "' has started", "AccountID: '" + account.AccountID + "' SqlPartition: '" + account.SqlPartition + "' DocumentPartition: '" + account.DocumentPartition + "' StripeCustomerID: '" + account.StripeCustomerID + "'" ); } else if (!account.Provisioned) { //Account has not been provisioned, only delete the account and user objects, This will be a simple purge and not a full deprovisioning PlatformLogManager.LogActivity(CategoryType.Account, ActivityType.Account_Purge_Started, "Purging of unprovisioned account '" + account.AccountName + "' has started", "AccountID: '" + account.AccountID + "' Account Owner: '" + account.Users[0].UserName + "'"); } #endregion // Owners of accounts that have been provisioned will get an email, create a list of owner emails before all users are delted var accountOwnerEmails = AccountManager.GetAccountOwnerEmails(account.AccountID.ToString()); string accountOwners = string.Empty; foreach (string ownerEmail in accountOwnerEmails) { accountOwners += ownerEmail + " "; } #region STEPS 1-3 DELETE ACCOUNT USERS AND ACCOUNT // 1. Delete All Account Users AccountDeprovisioning.DeleteAllAccountUsers(account); // 2. Delete Account AccountDeprovisioning.DeleteAccount(account); // 3. Delete Customer in Stripe if the account has a StripeCustomerID if (account.StripeCustomerID != null) { try { var stripeManager = new StripeManager(); stripeManager.DeleteCustomer(account.StripeCustomerID); } catch { } } #endregion if (!account.Provisioned) { #region Log closure if account is not provisioned //Account has never been provisioned, since we already deleted the account and all associated users, we are done. Log activity completion and return result: PlatformLogManager.LogActivity( CategoryType.Account, ActivityType.Account_Purged, "Purging of unprovisioned account '" + account.AccountName + "' has completed", "Account Owners: '" + accountOwners + "'", account.AccountID.ToString(), account.AccountName, null, null, null, null, null, JsonConvert.SerializeObject(account) ); //Log the closed account PlatformLogManager.LogActivity( CategoryType.Account, ActivityType.Account_Closed, "Unprovisioned", account.AccountNameKey, account.AccountID.ToString(), account.AccountName, null, null, null, null, null, JsonConvert.SerializeObject(account)); response.isSuccess = true; response.SuccessMessage = "Purging of account '" + account.AccountID + "' Complete!"; #endregion } else { // 4. Clear SQL Data Schema & AccountDeprovisioning.DestroySqlSchemaAndTables(account); // 5. Clear Table Storage Data AccountDeprovisioning.DestroyTableStorageData(account); // 6. Clear Blob Storage Data AccountDeprovisioning.DestroyBlobStorageData(account); // 7. Clear Document Data (Retired) AccountDeprovisioning.DestroyDocumentCollection(account); // 8. Clear Search Indexes AccountDeprovisioning.DestroySearchIndexes(account); // 9. Decriment both STORAGE & SEARCH Partitions Sql.Statements.UpdateStatements.UpdatePartitionsTenantCounts(account.StoragePartition, account.SearchPartition); // 10. Log Activity #region Logging PlatformLogManager.LogActivity( CategoryType.GarbageCollection, ActivityType.GarbageCollection_ClosedAccounts, "All resources for account '" + account.AccountName + "' have been destroyed", "Purged resources now available to new accounts", account.AccountID.ToString(), account.AccountName, null, null, null, null, null, JsonConvert.SerializeObject(account) ); PlatformLogManager.LogActivity( CategoryType.Account, ActivityType.Account_Deprovisioned, "Deprovisioning of '" + account.AccountName + "' has completed", "SqlPartition: '" + account.SqlPartition + "'", account.AccountID.ToString(), account.AccountName, null, null, null, null, null, JsonConvert.SerializeObject(account) ); //Log the closed account PlatformLogManager.LogActivity( CategoryType.Account, ActivityType.Account_Closed, "Deprovisioned", account.AccountNameKey + " | " + account.PaymentPlanName, account.AccountID.ToString(), account.AccountName, null, null, null, null, null, JsonConvert.SerializeObject(account)); #endregion // 11. Email all account users regarding closure: EmailManager.Send( accountOwnerEmails, Settings.Endpoints.Emails.FromAlerts, Settings.Copy.EmailMessages.DeprovisioningComplete.FromName, Settings.Copy.EmailMessages.DeprovisioningComplete.Subject, String.Format(Settings.Copy.EmailMessages.DeprovisioningComplete.Body, account.AccountName), true); // 12. Destroy ALL caches associated with an account AccountManager.DestroyAccountCaches(account.AccountID.ToString(), account.AccountNameKey, account.StripeCustomerID); // 13. Destroy subdomains try { var cloudFlareResult = CloudFlareManager.RemoveSubdomains(account.AccountNameKey); if (cloudFlareResult.isSuccess == false) { //Log exception and email platform admins PlatformExceptionsHelper.LogErrorAndAlertAdmins( cloudFlareResult.ErrorMessage, "attempting to remove cloudflare subdomains for the '" + account.AccountName + "' account during deprovisioning.", System.Reflection.MethodBase.GetCurrentMethod(), account.AccountID.ToString(), account.AccountName ); } } catch (Exception e) { //Log exception and email platform admins PlatformExceptionsHelper.LogExceptionAndAlertAdmins( e, "attempting to remove cloudflare subdomains for the '" + account.AccountName + "' account during deprovisioning.", System.Reflection.MethodBase.GetCurrentMethod(), account.AccountID.ToString(), account.AccountName ); } response.isSuccess = true; response.SuccessMessage = "Deprovisioning of account '" + account.AccountID + "' Complete!"; } //TODO: Log purged account into ClosedAccounts Table } catch (Exception e) { #region LOG ERROR (Deprovisioning Errors) //Log exception and email platform admins PlatformExceptionsHelper.LogExceptionAndAlertAdmins( e, "attempting to deprovision or purge account: " + account.AccountName, System.Reflection.MethodBase.GetCurrentMethod(), account.AccountID.ToString(), account.AccountName ); #endregion response.isSuccess = false; response.ErrorMessage = e.Message; } // Archive the closed account //ClosedAccountsStorageManager.ArchiveClosedAccount(account); return(response); }
/// <summary> /// This is the entry point of the service host process. /// </summary> private static void Main() { try { // The ServiceManifest.XML file defines one or more service type names. // Registering a service maps a service type name to a .NET type. // When Service Fabric creates an instance of this service type, // an instance of the class is created in this host process. #region Startup Tasks // 1.) ------ System.Net.ServicePointManager.DefaultConnectionLimit = 12 * Environment.ProcessorCount; //<-- Allows us to marshal up more SearchService/SearchIndex Clients to avoid exhausting sockets. #region Working w/ Service Fabric Enviornment Variables //Pull in enviornment variables: ----------------------------------------------------------- //var hostId = Environment.GetEnvironmentVariable("Fabric_ApplicationHostId"); //var appHostType = Environment.GetEnvironmentVariable("Fabric_ApplicationHostType"); //var tyoeEndpoint = Environment.GetEnvironmentVariable("Fabric_Endpoint_[YourServiceName]TypeEndpoint"); //var nodeName = Environment.GetEnvironmentVariable("Fabric_NodeName"); //Or print them all out (Fabric Only): /* * foreach (DictionaryEntry de in Environment.GetEnvironmentVariables()) * { * if (de.Key.ToString().StartsWith("Fabric")) * { * ServiceEventSource.Current.ServiceMessage(this.Context, " Environment variable {0} = {1}", de.Key, de.Value); * } * } */ //EVERY SINGLE ONE: /* * foreach (DictionaryEntry de in Environment.GetEnvironmentVariables()) * { * ServiceEventSource.Current.ServiceMessage(this.Context, " Environment variable {0} = {1}", de.Key, de.Value); * * }*/ #endregion // 2.) ------ var nodeName = Environment.GetEnvironmentVariable("Fabric_NodeName"); // 3.) ------ // string environment = "production"; //RoleEnvironment.GetConfigurationSettingValue("Environment"); string environment = Environment.GetEnvironmentVariable("Env").ToLower(); Sahara.Core.Settings.Startup.Initialize(environment); Sahara.Core.Settings.Azure.CurrentRoleInstance.Name = nodeName; // RoleEnvironment.CurrentRoleInstance.Role.Name; //Sahara.Core.Settings.Azure.CurrentRoleInstance.Id = nodeName; //instanceIndex; // TODO: Track down use of Sahara.Core.Settings.Azure.CurrentRoleInstance.Id and replace with nodeName or anotehr var type //Trace.TraceInformation("Sahara.CoreServices.WcfEndpoints node:" + nodeName + " entry point called on env: " + environment); //Log Activity: PlatformLogManager.LogActivity( CategoryType.Worker, ActivityType.Worker_Status_Update, "Platform Worker starting on node '" + nodeName + "' (env: " + environment + ")....", "WORKER.PlatformWorker entry point called on env: " + environment + " (node:" + nodeName + ") (env: " + environment + ")" ); #endregion ServiceRuntime.RegisterServiceAsync("PlatformWorkerType", context => new PlatformWorker(context)).GetAwaiter().GetResult(); ServiceEventSource.Current.ServiceTypeRegistered(Process.GetCurrentProcess().Id, typeof(PlatformWorker).Name); // Prevents this host process from terminating so services keep running. Thread.Sleep(Timeout.Infinite); } catch (Exception e) { ServiceEventSource.Current.ServiceHostInitializationFailed(e.ToString()); throw; } }
public static DataAccessResponseType ProvisionPlatform(string FirstName, string LastName, string Email, string password) { // Begin timing task Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); DataAccessResponseType response = new DataAccessResponseType(); if (!isPlatformInitialized()) { //Generate Databases & Schemas PlatformInitialization platformInitialization = new PlatformInitialization(); response = platformInitialization.InitializePlatform(); if (response.isSuccess) { try { //Create initial Platform User & Assign to SuperAdmin Role var createUserResult = PlatformUserManager.CreatePlatformUser(Email, FirstName, LastName, password, Sahara.Core.Settings.Platform.Users.Authorization.Roles.SuperAdmin); if (createUserResult.isSuccess) { //Replicate Payment Plans to Stripe Account: //StripeInitialization.SeedPaymentPlans(); var stripePlansResponse = PaymentPlanManager.DuplicatePlansToStripe(); if (!stripePlansResponse.isSuccess) { response.isSuccess = false; response.ErrorMessage = "An error occured when creating Stripe plans"; return(response); } /*====================================== * Create AccountPartition Document Database * ========================================*/ /* Retired ------------------*/ //var client = Sahara.Core.Settings.Azure.DocumentDB.DocumentClients.AccountDocumentClient; var databasename = Sahara.Core.Settings.Azure.DocumentDB.AccountPartitionDatabaseId; Database accountDatabase = Sahara.Core.Settings.Azure.DocumentDbClients.AccountDocumentClient.CreateDatabaseQuery().Where(db => db.Id == databasename).ToArray().FirstOrDefault(); if (accountDatabase == null) { //Create if not exists accountDatabase = Sahara.Core.Settings.Azure.DocumentDbClients.AccountDocumentClient.CreateDatabaseAsync(new Database { Id = databasename }).Result; } /*====================================== * Clear all logs () * ========================================*/ //PlatformLogManager.ClearLogs(); /*====================================== * Log Initilization of Platform * ========================================*/ stopwatch.Stop(); PlatformLogManager.LogActivity( CategoryType.Platform, ActivityType.Platform_Initialized, "Platform initilized by: " + FirstName + " " + LastName + " (" + Email + ")", "Initialization took " + String.Format("{0:0,0.00}", TimeSpan.FromMilliseconds(stopwatch.ElapsedMilliseconds).TotalMinutes) + " minute(s) to complete" ); response.isSuccess = true; response.SuccessMessage = "Platform has been successfully initialized and '" + Email + "' has been registered as the initial platform administrator."; } } catch (Exception e) { response.isSuccess = false; response.ErrorMessage = e.Message; try { response.ErrorMessages.Add(e.InnerException.Message); } catch { } } } return(response); } else { response.isSuccess = false; response.ErrorMessage = "Platform is already initialized."; response.ErrorMessages.Add("If you are attempting to create a new installation on this envionemnt: You must first clear all platfrom components manually."); return(response); } }
/// <summary> /// This is the main entry point for your service instance. /// </summary> /// <param name="cancellationToken">Canceled when Service Fabric needs to shut down this service instance.</param> protected override async Task RunAsync(CancellationToken cancellationToken) { #region Working w/ Service Fabric Enviornment Variables //Pull in enviornment variables: ----------------------------------------------------------- //var hostId = Environment.GetEnvironmentVariable("Fabric_ApplicationHostId"); //var appHostType = Environment.GetEnvironmentVariable("Fabric_ApplicationHostType"); //var tyoeEndpoint = Environment.GetEnvironmentVariable("Fabric_Endpoint_[YourServiceName]TypeEndpoint"); //var nodeName = Environment.GetEnvironmentVariable("Fabric_NodeName"); //Or print them all out (Fabric Only): /* * foreach (DictionaryEntry de in Environment.GetEnvironmentVariables()) * { * if (de.Key.ToString().StartsWith("Fabric")) * { * ServiceEventSource.Current.ServiceMessage(this.Context, " Environment variable {0} = {1}", de.Key, de.Value); * } * } */ //EVERY SINGLE ONE: /* * foreach (DictionaryEntry de in Environment.GetEnvironmentVariables()) * { * ServiceEventSource.Current.ServiceMessage(this.Context, " Environment variable {0} = {1}", de.Key, de.Value); * * } */ #endregion //Check if platform is initialized bool platformInitialized = PlatformInitializationManager.isPlatformInitialized(); //Tests/References ------ ConfigurationPackage configPackage = this.Context.CodePackageActivationContext.GetConfigurationPackageObject("config"); var configurationSetting = configPackage.Settings.Sections["CustodialConfigSection"].Parameters["MyConfigSetting"].Value; string environmentVariable = Environment.GetEnvironmentVariable("MyEnvVariable"); var nodeName = Environment.GetEnvironmentVariable("Fabric_NodeName"); ServiceEventSource.Current.ServiceMessage(this.Context, String.Format("{0} waking up on {1}", workerName, nodeName)); while (true) { cancellationToken.ThrowIfCancellationRequested(); if (platformInitialized) { #region RUN TASKS // Create new stopwatch Stopwatch stopwatch = new Stopwatch(); // Begin timing tasks stopwatch.Start(); #if DEBUG //Trace.TraceInformation("Custodian Working..."); #endif //Log //PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_Scheduled_Tasks_Started, //"Starting Scheduled Tasks"); //======================================================================== // TASK 1: Deprovision Closed Accounts: //======================================================================== var deprovisionClosedAccountsResponse = CustodianManager.DeprovisionClosedAccounts(); if (deprovisionClosedAccountsResponse.isSuccess) { //PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_Scheduled_Task, "Task # 4 Complete (Deprovision Closed Accounts)"); } else { PlatformLogManager.LogActivity(CategoryType.Error, ActivityType.Error_Custodian, "Task # 1 Had Errors (Deprovision Closed Accounts)", deprovisionClosedAccountsResponse.ErrorMessage); } //======================================================================== // TASK 2: Email Accounts Dunning Reminder(s) About Upcoming Credit Card Expiration Dtes: //======================================================================== var creditCardExpirationRemindersResponse = CustodianManager.SendCreditCardExpirationReminders(); if (creditCardExpirationRemindersResponse.isSuccess) { //PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_Scheduled_Task, "Task # 6 Complete (Credit Card Expiration Date Reminders)"); } else { PlatformLogManager.LogActivity(CategoryType.Error, ActivityType.Error_Custodian, "Task # 2 Had Errors (Credit Card Expiration Date Reminders)", creditCardExpirationRemindersResponse.ErrorMessage); } //======================================================================== // TASK 3: Clean Up Credit Card Expirations Email Log //======================================================================== var creditCardExpirationRemindersLogCleanupResponse = CustodianManager.ClearCreditCardExpirationRemindersLog(); if (creditCardExpirationRemindersLogCleanupResponse.isSuccess) { //PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_Scheduled_Task, "Task # 7 Complete (Cleaned Up Credit Card Expiration Date Reminders Log )"); } else { PlatformLogManager.LogActivity(CategoryType.Error, ActivityType.Error_Custodian, "Task # 3 Had Errors (Cleaned Up Credit Card Expiration Date Reminders Log )", creditCardExpirationRemindersLogCleanupResponse.ErrorMessage); } //======================================================================== // TASK 4: Clean up Intermediary Storage of Source Files //======================================================================== var intermediaryCleanupResponse = CustodianManager.ClearIntermediaryStorage(); if (intermediaryCleanupResponse.isSuccess) { //PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_Scheduled_Task, "Task # 8 Complete (Intermediary Storage Cleanup)"); } else { PlatformLogManager.LogActivity(CategoryType.Error, ActivityType.Error_Custodian, "Task # 4 Had Errors (Log Cleanup)", intermediaryCleanupResponse.ErrorMessage); } //======================================================================== // TASK 5: Clean up Intermediary Storage of Source Files //======================================================================== var stripeWebhookEventsCleanupResponse = CustodianManager.ClearStripeWebhooksLog(); if (stripeWebhookEventsCleanupResponse.isSuccess) { //PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_Scheduled_Task, "Task # 8 Complete (Intermediary Storage Cleanup)"); } else { PlatformLogManager.LogActivity(CategoryType.Error, ActivityType.Error_Custodian, "Task # 5 Had Errors (Log Cleanup)", stripeWebhookEventsCleanupResponse.ErrorMessage); } //======================================================================== // TASK 6: Ping sites to keep them awake for user traffic: //======================================================================== var pingSitesResponse = CustodianManager.PingSites(); /* * if (pingSitesResponse.isSuccess) * { * PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_Scheduled_Task, "Task # 6 Complete (Ping Sites)"); * } * else * { * PlatformLogManager.LogActivity(CategoryType.Error, ActivityType.Error_Custodian, "Task # 6 Had Errors (Ping sites)", pingSitesResponse.ErrorMessage); * } */ //======================================================================== // TASK 7: Load up subset of account data so it is cached and ready for API calls: //======================================================================== var cacheAccountsResponse = CustodianManager.CacheAccountData(); //======================================================================== // TASK 0: Cleanup Logs: //======================================================================== var logCleanupResponse = CustodianManager.ClearLogs(); if (logCleanupResponse.isSuccess) { //Not yet implemented - is it even necessary? //PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_Scheduled_Task, "Task # 0 Complete (Log Cleanup)"); } else { PlatformLogManager.LogActivity(CategoryType.Error, ActivityType.Error_Custodian, "Task # 0 Had Errors (Log Cleanup)", logCleanupResponse.ErrorMessage); } //======================================================================== // TASK 10: Cleanup Source Images: //======================================================================== #if DEBUG //Trace.TraceInformation("Tasks complete."); //Trace.TraceInformation("Custodian sleeping for: " + Sahara.Core.Settings.Platform.Custodian.Frequency.Description); #endif stopwatch.Stop(); //PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_Scheduled_Tasks_Complete, //"Scheduled Tasks Started & Completed in " + stopwatch.ElapsedMilliseconds.ToString("#,##0") + " milliseconds"); //Invalidate the accounts snapshot cache so platform admins see any account updates quicker: PlatformSnapshotsManager.DestroyAccountSnapshotCache(); //Sleep for 4 seconds to put next_run log activity at the top: //Thread.Sleep(4000); <-- No longer required since we are only logging one activity //Sleep for 4 seconds to put next_run log activity at the top: //Thread.Sleep(4000); <-- No longer required since we are only logging one activity //Log PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_Sleeping, "Scheduled tasks complete. Sleeping for " + Sahara.Core.Settings.Platform.Custodian.Frequency.Description, "Tasks completed in " + stopwatch.ElapsedMilliseconds.ToString("#,##0") + " milliseconds"); // PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_NextRun, //"Custodian next run in " + Sahara.Core.Settings.Platform.Custodian.Frequency.Description, //DateTime.UtcNow.AddMilliseconds(Sahara.Core.Settings.Platform.Custodian.Frequency.Length).ToString() //); #endregion } else { //Check if platform is initialized again platformInitialized = PlatformInitializationManager.isPlatformInitialized(); } //Sleep Thread.Sleep(Sahara.Core.Settings.Platform.Custodian.Frequency.Length); } }
public AuthenticationResponse Authenticate(string email, string password, string ipAddress, string origin, string sharedClientKey) { // Ensure the clients are certified. if (sharedClientKey != Sahara.Core.Platform.Requests.RequestManager.SharedClientKey) { return(null); } var authResponse = new AuthenticationResponse(); //From here you may log the fact that the user has authenticated at this time (if this is something you wish to track) //login.IP; <-- IP address for logging purposes var result = PlatformSecurityManager.AuthenticateUser(email, password); authResponse.isSuccess = result.isSuccess; authResponse.ErrorMessage = result.ErrorMessage; if (result.isSuccess) { //Get the IdentityUser from the ResponseObject: var platformUserIdentity = (PlatformUserIdentity)result.ResponseObject; //Convert to non Identity version & add to response object: authResponse.PlatformUser = PlatformUserManager.TransformPlatformUserIdentityToPlatformUser(platformUserIdentity); //Get Claims based identity for the user System.Security.Claims.ClaimsIdentity identity = PlatformUserManager.GetUserClaimsIdentity( platformUserIdentity, DefaultAuthenticationTypes.ApplicationCookie); //<-- Uses a cookie for the local web application // You can add to claims thusly: //identity.AddClaim(new Claim(ClaimTypes.Name, "Name")); authResponse.ClaimsIdentity = identity; #region Log Platform user Activity (AuthenticationPassed) try { PlatformLogManager.LogActivity( CategoryType.Authentication, ActivityType.Authentication_Passed, "Successfull log in.", authResponse.PlatformUser.FirstName + " successfully logged in.", null, null, authResponse.PlatformUser.Id, authResponse.PlatformUser.FirstName, authResponse.PlatformUser.Email, ipAddress, origin); } catch { } #endregion } else { #region Log Platform User Activity (AuthenticationFailed) try { PlatformLogManager.LogActivity( CategoryType.Authentication, ActivityType.Authentication_Failed, "An attempt to log into the platform admin with email '" + email + "' has failed.", result.ErrorMessage, null, null, "Unknown", "Unknown", email, ipAddress, origin); } catch { } #endregion } return(authResponse); }
public static DataAccessResponseType ProcessSendApplicationDataInjectionImageDocuments(string accountId, int documentInjectionCount) { var result = new DataAccessResponseType { isSuccess = false }; //Get the account var account = AccountManager.GetAccount(accountId); //Create base document var imageDocument = new ApplicationImageDocumentModel { AccountID = accountId, DocumentType = "ApplicationImage", Title = "Generic Application Image Document", Description = "Generic description for batch injected document. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." }; //Get the DocumentDB Client //var client = Sahara.Core.Settings.Azure.DocumentDB.DocumentClients.AccountDocumentClient; //var dbSelfLink = Sahara.Core.Settings.Azure.DocumentDB.AccountPartitionDatabaseSelfLink; //Sahara.Core.Settings.Azure.DocumentDbClients.AccountDocumentClient.OpenAsync(); //Build a collection Uri out of the known IDs //(These helpers allow you to properly generate the following URI format for Document DB: //"dbs/{xxx}/colls/{xxx}/docs/{xxx}" Uri collectionUri = UriFactory.CreateDocumentCollectionUri(Sahara.Core.Settings.Azure.DocumentDB.AccountPartitionDatabaseId, account.DocumentPartition); string triggerId = "IncrementApplicationImageCount"; var requestOptions = new RequestOptions { PostTriggerInclude = new List <string> { triggerId } }; int documentsInjected = 0; //int retryAttempts = 0; //int maxAttemptsPerRetry = 0; //<-- Used to track max retries per attempt // Create new stopwatch Stopwatch stopwatch = new Stopwatch(); // Begin timing tasks stopwatch.Start(); //var retryStrategy = new DocumentDbRetryStrategy{ FastFirstRetry = true }; //DocumentDbRetryStrategy.F do { imageDocument.Id = Guid.NewGuid().ToString(); var createDocumentResponse = Sahara.Core.Settings.Azure.DocumentDbClients.AccountDocumentClient.CreateDocumentAsync(collectionUri.ToString(), imageDocument, requestOptions).Result; documentsInjected++; //<--Increment amount of documents that have been injected try { AccountCapacityManager.InvalidateAccountCapacitiesCache(accountId); //<--Invalidate Account Capacities Cache } catch { } }while (documentsInjected != documentInjectionCount); if (documentsInjected == documentInjectionCount) { result.isSuccess = true; } stopwatch.Stop(); //Output timing into data injection log PlatformLogManager.LogActivity( CategoryType.DataInjection, ActivityType.DataInjection_ImageDocuments, "Batch Injection complete! " + documentsInjected + " of " + documentInjectionCount + " documents injected", "Time: " + stopwatch.ElapsedMilliseconds + " Milliseconds( " + String.Format("{0:0,0.00}", TimeSpan.FromMilliseconds(stopwatch.ElapsedMilliseconds).TotalMinutes) + " Minutes)", // | Retries: " + retryAttempts + " | Max Attempts Per Retry: " + maxAttemptsPerRetry, accountId ); return(result); }
/// <summary> /// Deletes all image records for an object in table storage /// </summary> /// <param name="accountId"></param> /// <param name="imageGroupTypeNameKey"></param> /// <param name="objectId"></param> /// <returns></returns> internal static DataAccessResponseType DeleteAllImageRecordsForObject(string accountId, string storagePartition, string imageFormatGroupTypeNameKey, string objectId) { var response = new DataAccessResponseType(); //CloudTableClient cloudTableClient = Sahara.Core.Settings.Azure.Storage.StorageConnections.AccountsStorage.CreateCloudTableClient(); CloudTableClient cloudTableClient = Settings.Azure.Storage.GetStoragePartitionAccount(storagePartition).CreateCloudTableClient(); //Create and set retry policy //IRetryPolicy exponentialRetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(1), 4); IRetryPolicy linearRetryPolicy = new LinearRetry(TimeSpan.FromSeconds(1), 4); cloudTableClient.DefaultRequestOptions.RetryPolicy = linearRetryPolicy; try { //Delete From MAIN table CloudTable cloudTable1 = cloudTableClient.GetTableReference(Sahara.Core.Common.Methods.SchemaNames.AccountIdToTableStorageName(accountId) + ImageRecordTableName(imageFormatGroupTypeNameKey)); //cloudTable1.CreateIfNotExists(); List <TableEntity> productImageEntities1 = cloudTable1.CreateQuery <TableEntity>().Where(p => p.PartitionKey == objectId).ToList(); foreach (TableEntity productImageEntity in productImageEntities1) { cloudTable1.Execute(TableOperation.Delete(productImageEntity)); } //Delete From LISTING table CloudTable cloudTable2 = cloudTableClient.GetTableReference(Sahara.Core.Common.Methods.SchemaNames.AccountIdToTableStorageName(accountId) + ImageRecordListingTableName(imageFormatGroupTypeNameKey)); //cloudTable2.CreateIfNotExists(); List <TableEntity> productImageEntities2 = cloudTable2.CreateQuery <TableEntity>().Where(p => p.PartitionKey == objectId).ToList(); foreach (TableEntity productImageEntity in productImageEntities2) { cloudTable2.Execute(TableOperation.Delete(productImageEntity)); } response.isSuccess = true; } catch (Exception e) { if (!e.Message.Contains("(404) Not Found")) { PlatformLogManager.LogActivity( CategoryType.Error, ActivityType.Error_Exception, e.Message, "Exception while attempting to delete all image records for " + imageFormatGroupTypeNameKey + " '" + objectId + "' in table storage", accountId, null, null, null, null, null, System.Reflection.MethodBase.GetCurrentMethod().ToString(), null ); } } return(response); }
public static DataAccessResponseType ProvisionAccount(Account account) { var response = new DataAccessResponseType(); #region Pre Provisioning Verification bool _documentPartitioning = true; //<-- If false will skip provisioning DocumentDB resources for accounts bool _searchPartitioning = true; //<-- If false will skip provisioning Search resources for accounts bool _storagePartitioning = true; //<-- If false will skip provisioning Search resources for accounts bool _sqlPartitioning = true; //<-- If false will skip provisioning a SQL Location and SchemeName for accounts StoragePartition storagePartition = null; //<-- Chosen partition for this account SearchPartition searchPartition = null; //<-- Chosen partition for this account //Make sure account isn't already provisioned if (account.Provisioned) { response.isSuccess = false; response.ErrorMessage = "Account is already provisioned!"; return(response); } if (account.StripeSubscriptionID == null || account.StripeCustomerID == null) { response.isSuccess = false; response.ErrorMessage = "This account has not been assigned a payment plan or a Stripe CustomerID"; return(response); } //If Account object is passed in without users get all/initial user(s): if (account.Users == null) { account.Users = AccountUserManager.GetUsers(account.AccountID.ToString()); } #region Ensure that there is a storage partition available and select next available spot if (_storagePartitioning) { var storagePartitions = StoragePartitioningManager.GetStoragePartitions(); //Sort with lowest tenant count at the top: storagePartitions = storagePartitions.OrderBy(o => o.TenantCount).ToList(); if (storagePartitions.Count > 0) { if (storagePartitions[0].TenantCount >= Settings.Platform.Partitioning.MaximumTenantsPerStorageAccount) { response.isSuccess = false; response.ErrorMessage = "There are no storage partitions available for this account! Please create one before attempting to provision."; //Reset account to inactive so you can restart partitioning sequence after partition hopper has additional partitions added AccountManager.UpdateAccountActiveState(account.AccountID.ToString(), false); return(response); } else { //Assign storage partition: storagePartition = storagePartitions[0]; } } else { response.isSuccess = false; response.ErrorMessage = "There are no storage partitions available on this platform! Cannot provision any accounts!"; //Reset account to inactive so you can restart partitioning sequence after partition hopper has additional partitions added AccountManager.UpdateAccountActiveState(account.AccountID.ToString(), false); return(response); } } #endregion #region Ensure that there is a search partition available and select next available spot if (_searchPartitioning) { //Get search plan type for this plan tier string searchPlan = account.PaymentPlan.SearchPlan; //Get list of search partitions available with this plan type var searchPartitions = SearchPartitioningManager.GetSearchPartitions(searchPlan); int maxTenantsAllowed = Int32.Parse((searchPlan.Substring(searchPlan.LastIndexOf("-") + 1))); /* MAx Tenatnts are now pulled from the SarchPlan name * * int maxTenantsAllowed = 0; * * if(searchPlan == "Basic") * { * maxTenantsAllowed = Settings.Platform.Partitioning.MaximumTenantsPerBasicSearchServiceShared; * } * else if (searchPlan == "Basic-Dedicated") * { * maxTenantsAllowed = Settings.Platform.Partitioning.MaximumTenantsPerBasicSearchServiceDedicated; * } * else if(searchPlan == "S1") * { * maxTenantsAllowed = Settings.Platform.Partitioning.MaximumTenantsPerS1SearchServiceShared; * } * else if (searchPlan == "S1-Dedicated") * { * maxTenantsAllowed = Settings.Platform.Partitioning.MaximumTenantsPerS1SearchServiceDedicated; * } * else if (searchPlan == "S2") * { * maxTenantsAllowed = Settings.Platform.Partitioning.MaximumTenantsPerS2SearchServiceShared; * } * else if (searchPlan == "S2-Dedicated") * { * maxTenantsAllowed = Settings.Platform.Partitioning.MaximumTenantsPerS2SearchServiceDedicated; * } * else if(searchPlan == "Free") * { * maxTenantsAllowed = Settings.Platform.Partitioning.MaximumTenantsPerFreeSearchService; * } */ //Sort with lowest tenant count at the top: searchPartitions = searchPartitions.OrderBy(o => o.TenantCount).ToList(); if (searchPartitions.Count > 0) { if (searchPartitions[0].TenantCount >= maxTenantsAllowed) { response.isSuccess = false; response.ErrorMessage = "There are no '" + searchPlan + "' search partitions available for this account! Please create one before attempting to provision."; //Reset account to inactive so you can restart partitioning sequence after partition hopper has additional partitions added AccountManager.UpdateAccountActiveState(account.AccountID.ToString(), false); return(response); } else { //Assign storage partition: searchPartition = searchPartitions[0]; } } else { response.isSuccess = false; response.ErrorMessage = "There are no '" + searchPlan + "' search partitions available on this platform! Cannot provision any accounts!"; //Reset account to inactive so you can restart partitioning sequence after partition hopper has additional partitions added AccountManager.UpdateAccountActiveState(account.AccountID.ToString(), false); return(response); } } #endregion #endregion #region Account Partitioning #region Document Database Partitioning (REMOVED) if (_documentPartitioning) { //Connect to the document client & get the database selfLink //var client = Sahara.Core.Settings.Azure.DocumentDbClients.AccountDocumentClient; //Sahara.Core.Settings.Azure.DocumentDbClients.AccountDocumentClient.OpenAsync().ConfigureAwait(false); //Sahara.Core.Settings.Azure.DocumentDbClients.AccountDocumentClient.OpenAsync(); //var dataBaseSelfLink = Sahara.Core.Settings.Azure.DocumentDB.AccountPartitionDatabaseSelfLink; //STEP 1: Get or create the next available document partition for the 'Free' tier var partitioningResult = DocumentPartitioningManager.CreateDocumentCollectionAccountPartition(account.AccountNameKey, Sahara.Core.Settings.Azure.DocumentDbClients.AccountDocumentClient, Sahara.Core.Settings.Azure.DocumentDB.AccountPartitionDatabaseId); if (partitioningResult.isSuccess == true) { DocumentCollection nextAvailablePartitionCollection = (DocumentCollection)partitioningResult.ResponseObject; #region STEP 4: Add Account Settings Document for this account on the collection var accountSettingsDocumentCreated = false; Exception accountSettingsException = null; try { var accountSettingsDocument = new AccountSettingsDocumentModel { Id = "AccountSettings" }; accountSettingsDocument.ContactSettings = new ContactSettingsModel(); accountSettingsDocument.ContactSettings.ContactInfo = new ContactInfoModel(); accountSettingsDocument.SalesSettings = new SalesSettingsModel(); //Default LeadLabels accountSettingsDocument.SalesSettings.LeadLabels = new List <string>(); accountSettingsDocument.SalesSettings.LeadLabels.Add("New"); accountSettingsDocument.SalesSettings.LeadLabels.Add("Archive"); accountSettingsDocument.SalesSettings.LeadLabels.Add("Deleted"); accountSettingsDocument.Theme = "Light"; //<-- Default Theme accountSettingsDocument.SalesSettings.ButtonCopy = "I'm interested!"; //<-- Default Theme accountSettingsDocument.SalesSettings.DescriptionCopy = "Fill out our contact form and a member of our team will contact you directly."; Sahara.Core.Settings.Azure.DocumentDbClients.AccountDocumentClient.CreateDocumentAsync(nextAvailablePartitionCollection.SelfLink, accountSettingsDocument).ConfigureAwait(false); accountSettingsDocumentCreated = true; } #region Manage Exception & Create Manual Instructions catch (DocumentClientException de) { accountSettingsException = de.GetBaseException(); } catch (Exception e) { accountSettingsException = e; } if (!accountSettingsDocumentCreated) { #region Log Exception if (accountSettingsException != null) { PlatformExceptionsHelper.LogExceptionAndAlertAdmins( accountSettingsException, "creating an account settings document into a partition during account provisioning", System.Reflection.MethodBase.GetCurrentMethod(), account.AccountID.ToString(), account.AccountName ); } #endregion #region Manual Instructions //Not successfull, All tasks within 'GetNextAvailableDocumentPartition' must be run manually PlatformLogManager.LogActivity( CategoryType.ManualTask, ActivityType.ManualTask_DocumentDB, "AccountSettingsDocumentModel file creation failed during account provisioning", "Please create the 'AccountSettingsDocumentModel' document for '" + account.AccountName + "' within the '" + nextAvailablePartitionCollection.Id + "' collection manually.", account.AccountID.ToString(), account.AccountName, null, null, null, null, System.Reflection.MethodBase.GetCurrentMethod().ToString() ); #endregion } #endregion #endregion } else { #region Manual Instructions //Not successfull, All tasks within 'GetNextAvailableDocumentPartition' must be run manually PlatformLogManager.LogActivity( CategoryType.ManualTask, ActivityType.ManualTask_Other, "Document partitioning failed during account provisioning", "Please run all tasks under 'DocumentPartitioningManager.GetNextAvailableDocumentPartition('Free', client, dataBaseSelfLink)' as Well as 'if (partitioningResult.isSuccess == true)' manually. This may include creating a new DocumentPartition, updating account DocumentPartitionId and creating an AccountPropertiesDocument for this account into the new partition.", account.AccountID.ToString(), account.AccountName, null, null, null, null, System.Reflection.MethodBase.GetCurrentMethod().ToString() ); #endregion } #region Depricated DocumentDB Code /* * try * { * DocumentClient client = Sahara.Core.Settings.Azure.DocumentDB.DocumentClients.AccountDocumentClient; * client.OpenAsync(); //<-- By default, the first request will have a higher latency because it has to fetch the address routing table. In order to avoid this startup latency on the first request, you should call OpenAsync() once during initialization as follows. * * * //Generate Account Database * Database accountDatabase = client.CreateDatabaseAsync(new Database { Id = account.AccountID.ToString() }).Result; * * * //Generate "AccountProperties" Collection on the database * DocumentCollection accountPropertiesCollection = client.CreateDocumentCollectionAsync(accountDatabase.SelfLink, new DocumentCollection { Id = "AccountProperties" }).Result; * * * //Generate "SelfLinkReferences" Document within AccountProperties" collection * Document selfLinkReferencesDocument = client.CreateDocumentAsync(accountPropertiesCollection.SelfLink, new SelfLinkReferencesDocumentModel { Id = "SelfLinkReferences" }).Result; * * * //Store all the SelfLinks * var documentUpdateResults = Sql.Statements.UpdateStatements.UpdateDocumentDatabaseLinks(account.AccountID.ToString(), accountDatabase.SelfLink, accountPropertiesCollection.SelfLink, selfLinkReferencesDocument.SelfLink); * if (documentUpdateResults) * { * * } * else * { * * var errorMessage = "DocumentDB Selflink insertion into the '" + account.AccountName + "' account has failed"; * var errorDetails = "AccountID: '" + account.AccountID + "' Error: 'DocumentDB resources have been provisioned, but an error occured when updating database columns for the account'"; * * //Log Errors * PlatformLogManager.LogActivity( * CategoryType.Error, * ActivityType.Error_Other, * errorMessage, * errorDetails, * account.AccountID.ToString(), * account.AccountName * ); * * return new DataAccessResponseType { isSuccess = false, ErrorMessage = errorMessage }; * } * } * catch (Exception e) * { #region Handle Exception * * //Log exception and email platform admins * PlatformExceptionsHelper.LogExceptionAndAlertAdmins( * e, * "attempting to partition DocumentDB resources for the '" + account.AccountName + "' account during provisioning.", * System.Reflection.MethodBase.GetCurrentMethod(), * account.AccountID.ToString(), * account.AccountName * ); * #endregion * } */ #endregion } #endregion #region Storage Partitioning if (_storagePartitioning) { /* No longer need to set anything up (Back to document db) * * //Create setings JSON doc in storage (DocumentDB is now OFF) * var accountSettingsDocument = new AccountSettingsDocumentModel { Id = "AccountSettings" }; * * accountSettingsDocument.ContactSettings = new ContactSettingsModel(); * accountSettingsDocument.ContactSettings.ContactInfo = new ContactInfoModel(); * accountSettingsDocument.SalesSettings = new SalesSettingsModel(); * * //Default LeadLabels * accountSettingsDocument.SalesSettings.LeadLabels = new List<string>(); * accountSettingsDocument.SalesSettings.LeadLabels.Add("New"); * accountSettingsDocument.SalesSettings.LeadLabels.Add("Archive"); * accountSettingsDocument.SalesSettings.LeadLabels.Add("Deleted"); * * accountSettingsDocument.Theme = "Light"; //<-- Default Theme * accountSettingsDocument.SalesSettings.ButtonCopy = "I'm interested!"; //<-- Default Theme * accountSettingsDocument.SalesSettings.DescriptionCopy = "Fill out our contact form and a member of our team will contact you directly."; * * //Save to designated storage account * CloudStorageAccount storageAccount; * StorageCredentials storageCredentials = new StorageCredentials(storagePartition.Name, storagePartition.Key); * storageAccount = new CloudStorageAccount(storageCredentials, false); * CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); * * //Create and set retry policy * IRetryPolicy exponentialRetryPolicy = new ExponentialRetry(TimeSpan.FromMilliseconds(400), 6); * blobClient.DefaultRequestOptions.RetryPolicy = exponentialRetryPolicy; * * //Creat/Connect to the Blob Container for this account * blobClient.GetContainerReference(account.AccountNameKey).CreateIfNotExists(BlobContainerPublicAccessType.Blob); //<-- Create and make public * * * CloudBlobContainer blobContainer = blobClient.GetContainerReference(account.AccountNameKey); * * //Get reference to the text blob or create if not exists. * CloudBlockBlob blockBlob = blobContainer.GetBlockBlobReference("settings/" + "accountSettings.json"); * * blockBlob.UploadText(JsonConvert.SerializeObject(accountSettingsDocument)); * * //Save to storage * //Convert final BMP to byteArray * //Byte[] finalByteArray; * * //finalByteArray = outStream.ToArray(); * * //blockBlob.UploadFromByteArray(finalByteArray, 0, finalByteArray.Length); * */ } #endregion #region SQL Partitioning if (_sqlPartitioning) { try { // 1. Get and assign the next available database partition for this account to be provisioned into: var getAndAssignPartitionResponse = SqlPartitioningManager.GetAndAssignNextAvailableAccountSqlPartition(account.AccountID.ToString()); if (getAndAssignPartitionResponse.isSuccess) { string DatabasePartitionName = getAndAssignPartitionResponse.SuccessMessage; // 2. Run creation scripts to provision accounts schema to the selected partition: var generateAccountSchemaResponse = AccountProvisioning.GenerateAccountSchema(account.AccountID.ToString(), DatabasePartitionName); if (generateAccountSchemaResponse.isSuccess) { generateAccountSchemaResponse.SuccessMessage = DatabasePartitionName; //<-- Return the name of the database partition name } else { return(generateAccountSchemaResponse); } } else { return(getAndAssignPartitionResponse); } } catch (Exception e) { #region Handle Exception //Log exception and email platform admins PlatformExceptionsHelper.LogExceptionAndAlertAdmins( e, "attempting to partition SQL for the '" + account.AccountName + "' account during provisioning.", System.Reflection.MethodBase.GetCurrentMethod(), account.AccountID.ToString(), account.AccountName ); #endregion } } #endregion #region Search Partitioning if (_searchPartitioning) { //Create an Product Search Index for this account on the selected search partition --------------------- var searchIndexCreated = ProductSearchManager.CreateProductSearchIndex(account.AccountNameKey, searchPartition.Name, searchPartition.Key); } #endregion #endregion #region Post Partitioning Tasks // 1. Mark the Account as Provisioned, Active and assign a ProvisioningDate: var result = Sql.Statements.UpdateStatements.UpdateProvisiongStatus(account.AccountID.ToString(), true, true, storagePartition.Name, searchPartition.Name); if (result) { // 1. Create a platform user account SO we can log into the account for management purposes: AccountUserManager.CreateAccountUser(account.AccountID.ToString(), "platformadmin@[Config_PlatformEmail]", "Platform", "Admin", "[Config_PlatformPassword_AzureKeyVault]", Settings.Accounts.Users.Authorization.Roles.PlatformAdmin, true, null, true); // 2. Invalidated/Update the cache for this account AccountManager.UpdateAccountDetailCache(account.AccountNameKey); // 3. Email the creator with sucessful provisioning message and login info: /* * EmailManager.Send( * account.Users[0].Email, //<-- Will only have the initial user * Settings.Endpoints.Emails.FromProvisioning, * Settings.Copy.EmailMessages.ProvisioningComplete.FromName, * Settings.Copy.EmailMessages.ProvisioningComplete.Subject, * String.Format(Settings.Copy.EmailMessages.ProvisioningComplete.Body, account.AccountNameKey), * true * );*/ // 4. Send an alert to the platform admin(s): EmailManager.Send( Settings.Endpoints.Emails.PlatformEmailAddresses, Settings.Endpoints.Emails.FromProvisioning, "Provisioning " + Settings.Application.Name, "Account Provisioned", "<b>'" + account.AccountName + "'</b> has just been provisioned.", true ); // 5. Log Successfull Provisioning Activity PlatformLogManager.LogActivity(CategoryType.Account, ActivityType.Account_Provisioned, "Provisioning of '" + account.AccountName + "' has completed", "AccountID: '" + account.AccountID + "'", account.AccountID.ToString(), account.AccountName); //Register subdomains try { var cloudFlareResult = CloudFlareManager.RegisterSubdomains(account.AccountNameKey); if (cloudFlareResult.isSuccess == false) { //Log exception and email platform admins PlatformExceptionsHelper.LogErrorAndAlertAdmins( cloudFlareResult.ErrorMessage, "attempting to add cloudflare subdomains for the '" + account.AccountName + "' account during provisioning.", System.Reflection.MethodBase.GetCurrentMethod(), account.AccountID.ToString(), account.AccountName ); } } catch (Exception e) { //Log exception and email platform admins PlatformExceptionsHelper.LogExceptionAndAlertAdmins( e, "attempting to register cloudflare subdomains for the '" + account.AccountName + "' account during provisioning.", System.Reflection.MethodBase.GetCurrentMethod(), account.AccountID.ToString(), account.AccountName ); } return(new DataAccessResponseType { isSuccess = true }); } else { var errorMessage = "Account has been fully provisioned, but an error occured when setting the Account table to Active and assigning a provisioning date"; PlatformLogManager.LogActivity(CategoryType.Error, ActivityType.Error_Other, "Provisioning of '" + account.AccountName + "' has failed", errorMessage, account.AccountID.ToString(), account.AccountName); return(new DataAccessResponseType { isSuccess = false, ErrorMessage = errorMessage }); } #endregion }
// Future performance update: have client upload image to intermediary storage, submit location with imag eid for WCF processing (similar to other imageing solutions) public DataAccessResponseType UpdatePlatformUserProfilePhoto(string userId, byte[] imageByteArray, string requesterId, RequesterType requesterType, string sharedClientKey) { // Ensure the clients are certified. if (sharedClientKey != Sahara.Core.Platform.Requests.RequestManager.SharedClientKey) { return(null); } #region Validate Request var requesterName = string.Empty; var requesterEmail = string.Empty; var requestResponseType = RequestManager.ValidateRequest(requesterId, requesterType, out requesterName, out requesterEmail, Sahara.Core.Settings.Platform.Users.Authorization.Roles.SuperAdmin, null); if (!requestResponseType.isApproved) { //Request is not approved, send results: return(new DataAccessResponseType { isSuccess = false, ErrorMessage = requestResponseType.requestMessage }); } #endregion var result = PlatformUserManager.UpdateProfilePhoto(userId, imageByteArray); #region Log Platoform Activity if (result.isSuccess) { try { var logDescription = string.Empty; if (userId == requesterId) { logDescription = requesterName + " has updated their profile photo"; } else { var user = PlatformUserManager.GetUser(userId); logDescription = requesterName + " updated " + user.FullName + "'s profile photo"; } PlatformLogManager.LogActivity( CategoryType.PlatformUser, ActivityType.PlatformUser_Edited, "Photo updated", logDescription, null, null, requesterId, requesterName, requesterEmail ); } catch { } } #endregion return(result); }
public static DataAccessResponseType CacheAccountData() { //Set up security channel to allow for SSL/TLS ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; ServicePointManager.ServerCertificateValidationCallback = delegate { return(true); }; var response = new DataAccessResponseType(); var accounts = AccountManager.GetAllAccountsByFilter("Provisioned", "1", 0, 2000, "AccountNameKey"); //Loop through each account and call public api to preload data foreach (var account in accounts) { #region Account Info try { string callName = "account"; string url = "https://" + account.AccountNameKey + "." + Settings.Endpoints.URLs.AccountServiceDomain + "/account"; HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest; //optional HttpWebResponse webRequestResponse = webRequest.GetResponse() as HttpWebResponse; try { Stream stream = webRequestResponse.GetResponseStream(); PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_RefreshCache_Status, "Refreshing " + callName + " api cache for '" + account.AccountName + "' at:" + url); } catch (Exception e) { PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing " + callName + " api cache for '" + account.AccountName + "': " + e.Message); } } catch (Exception e) { PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing account api cache for '" + account.AccountName + ": " + e.Message); } #endregion #region Category Tree try { string callName = "categories"; string url = "https://" + account.AccountNameKey + "." + Settings.Endpoints.URLs.AccountServiceDomain + "/categories/tree?includeImages=true"; HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest; //optional HttpWebResponse webRequestResponse = webRequest.GetResponse() as HttpWebResponse; try { Stream stream = webRequestResponse.GetResponseStream(); PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_RefreshCache_Status, "Refreshing " + callName + " api cache for '" + account.AccountName + "' at:" + url); } catch (Exception e) { PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing " + callName + " api cache for '" + account.AccountName + "': " + e.Message); } } catch (Exception e) { PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing categories api cache for '" + account.AccountName + ": " + e.Message); } #endregion #region Search Query try { string callName = "search"; string url = "https://" + account.AccountNameKey + "." + Settings.Endpoints.URLs.AccountServiceDomain + "/search/products?query=test?skip=0&take=2"; HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest; //optional HttpWebResponse webRequestResponse = webRequest.GetResponse() as HttpWebResponse; try { Stream stream = webRequestResponse.GetResponseStream(); PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_RefreshCache_Status, "Refreshing " + callName + " api cache for '" + account.AccountName + "' at:" + url); } catch (Exception e) { PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing " + callName + " api cache for '" + account.AccountName + "': " + e.Message); } } catch (Exception e) { PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing search api cache for '" + account.AccountName + ": " + e.Message); } #endregion #region Search Sortables try { string callName = "search-sortables"; string url = "https://" + account.AccountNameKey + "." + Settings.Endpoints.URLs.AccountServiceDomain + "/search/sortables"; HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest; //optional HttpWebResponse webRequestResponse = webRequest.GetResponse() as HttpWebResponse; try { Stream stream = webRequestResponse.GetResponseStream(); PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_RefreshCache_Status, "Refreshing " + callName + " api cache for '" + account.AccountName + "' at:" + url); } catch (Exception e) { PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing " + callName + " api cache for '" + account.AccountName + "': " + e.Message); } } catch (Exception e) { PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing search-sortables api cache for '" + account.AccountName + ": " + e.Message); } #endregion #region Search Facets try { string callName = "search-facets"; string url = "https://" + account.AccountNameKey + "." + Settings.Endpoints.URLs.AccountServiceDomain + "/search/facets"; HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest; //optional HttpWebResponse webRequestResponse = webRequest.GetResponse() as HttpWebResponse; try { Stream stream = webRequestResponse.GetResponseStream(); PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_RefreshCache_Status, "Refreshing " + callName + " api cache for '" + account.AccountName + "' at:" + url); } catch (Exception e) { PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing " + callName + " api cache for '" + account.AccountName + "': " + e.Message); } } catch (Exception e) { PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing search-facets api cache for '" + account.AccountName + ": " + e.Message); } #endregion #region Properties try { string callName = "properties"; string url = "https://" + account.AccountNameKey + "." + Settings.Endpoints.URLs.AccountServiceDomain + "/properties/product"; HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest; //optional HttpWebResponse webRequestResponse = webRequest.GetResponse() as HttpWebResponse; try { Stream stream = webRequestResponse.GetResponseStream(); PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_RefreshCache_Status, "Refreshing " + callName + " api cache for '" + account.AccountName + "' at:" + url); } catch (Exception e) { PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing " + callName + " api cache for '" + account.AccountName + "': " + e.Message); } } catch (Exception e) { PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing properties api cache for '" + account.AccountName + ": " + e.Message); } #endregion #region Tags try { string callName = "tags"; string url = "https://" + account.AccountNameKey + "." + Settings.Endpoints.URLs.AccountServiceDomain + "/tags"; HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest; //optional HttpWebResponse webRequestResponse = webRequest.GetResponse() as HttpWebResponse; try { Stream stream = webRequestResponse.GetResponseStream(); PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_RefreshCache_Status, "Refreshing " + callName + " api cache for '" + account.AccountName + "' at:" + url); } catch (Exception e) { PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing " + callName + " api cache for '" + account.AccountName + "': " + e.Message); } } catch (Exception e) { PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing tags api cache for '" + account.AccountName + ": " + e.Message); } #endregion } //Loop through each account and call public site to preload pages foreach (var account in accounts) { #region Public Site Search try { string callName = "account-search"; string url = "https://" + account.AccountNameKey + "." + Settings.Endpoints.URLs.AccountSiteDomain + "/search"; HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest; //optional HttpWebResponse webRequestResponse = webRequest.GetResponse() as HttpWebResponse; try { Stream stream = webRequestResponse.GetResponseStream(); PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_RefreshAccountSite_Status, "Refreshing " + callName + " site cache for '" + account.AccountName + "' at:" + url); } catch (Exception e) { PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing " + callName + " site cache for '" + account.AccountName + "': " + e.Message); } } catch (Exception e) { PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing account-search site cache for '" + account.AccountName + ": " + e.Message); } #endregion #region Public Site Search try { string callName = "account-home"; string url = "https://" + account.AccountNameKey + "." + Settings.Endpoints.URLs.AccountSiteDomain; HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest; //optional HttpWebResponse webRequestResponse = webRequest.GetResponse() as HttpWebResponse; try { Stream stream = webRequestResponse.GetResponseStream(); PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_RefreshAccountSite_Status, "Refreshing " + callName + " site cache for '" + account.AccountName + "' at:" + url); } catch (Exception e) { PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing " + callName + " site cache for '" + account.AccountName + "': " + e.Message); } } catch (Exception e) { PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing account-home site cache for '" + account.AccountName + ": " + e.Message); } #endregion } response.isSuccess = true; //response.ErrorMessage = "Not implemented."; return(response); }
public static DataAccessResponseType RegisterNewAccount(RegisterNewAccountModel model) { //trim the name of whitespaces (start & end): model.AccountName = model.AccountName.Trim(); #region Refactoring notes /* * * With some refactoring you can start them directly with a chosen payment plan by passing a planid parameter to the Registration site (and ultimatly into this method) along with C.C. info * * This method will then check for a MonthlyRate > 0 and attempt to process the C.C. * note: You would only add a Credit Card capture form to the Registration site if a plan with a MonthlyRate above 0 is selected --> * * * * -- Adding a new "AllowRegistration" bool to the PaymentPlan object will allow for validation of selected plans coming in from users on this method for scenarios where users can choose a plan while signing up to avoid passing in ID's for plans such as "Unlimited" which must be approved by a Platform Admin * */ #endregion var response = new DataAccessResponseType { isSuccess = true }; try { #region Validate Account Info //Validate Registration Data: #region Refactoring notes /* * * * -- Adding a new "AllowRegistration" bool to the PaymentPlan object will allow for validation of selected plans coming in from users on AccountRegistrationManager for scenarios where users can choose a plan while signing up to avoid passing in ID's for plans such as "Unlimited" which must be approved by a Platform Admin * * > response.ErrorMessages.Add("Not a valid payment plan for public registration"); * */ #endregion #region Validate Password(s) Match if (model.Password != model.ConfirmPassword) { response.isSuccess = false; response.ErrorMessages.Add("Password and password confirmation do not match"); } #endregion #region Validate Account Name: ValidationResponseType accountNameValidationResponse = ValidationManager.IsValidAccountName(model.AccountName); if (!accountNameValidationResponse.isValid) { response.isSuccess = false; response.ErrorMessages.Add(accountNameValidationResponse.validationMessage); //return response; } #endregion #region Validate User Name ValidationResponseType firstNameValidationResponse = ValidationManager.IsValidFirstName(model.FirstName); if (!firstNameValidationResponse.isValid) { response.isSuccess = false; response.ErrorMessages.Add(firstNameValidationResponse.validationMessage); //return response; } ValidationResponseType lastNameValidationResponse = ValidationManager.IsValidLastName(model.LastName); if (!lastNameValidationResponse.isValid) { response.isSuccess = false; response.ErrorMessages.Add(lastNameValidationResponse.validationMessage); //return response; } #endregion #region Validate Email Unique (Optional) /* * var userValidation = AccountUserManager.GetUserIdentity(model.Email); * if (userValidation != null) * { * response.isSuccess = false; * response.ErrorMessages.Add("Another account is associated with that email address, please provide another"); * } */ #endregion //If validation(s) fails, return the response: if (response.isSuccess == false) { //Log Platform Activity string errors = string.Empty; foreach (string error in response.ErrorMessages) { errors += error + "|"; } PlatformLogManager.LogActivity(CategoryType.Registration, ActivityType.Registration_Failed, String.Format("Registration failed for: '{0}' by: {1} from: {2}", model.AccountName, model.Email, model.Origin), String.Format("Errors:{0}", errors )); //Return the response response.ErrorMessage = "Could not register this account"; return(response); } #endregion // Generate AccountID ==================================== Guid accountId = Guid.NewGuid(); #region Register Initial AccountUser (AKA: AccountOwner) #region Validate & Create Account Owner User // Further validations and account owner creation: var registerUserResponse = AccountUserManager.RegisterAccountOwner( model.FirstName, model.LastName, accountId.ToString(), model.AccountName, model.Email, model.Password ); #endregion if (!registerUserResponse.isSuccess) { //Log Platform Activity string errors = string.Empty; foreach (string error in registerUserResponse.ErrorMessages) { errors += error + "|"; } PlatformLogManager.LogActivity(CategoryType.Registration, ActivityType.Registration_Failed, String.Format("Registration failed for: '{0}' by: {1} from: {2}", model.AccountName, model.Email, model.Origin), String.Format("Errors:{0}", errors )); //Return the response response.isSuccess = false; response.ErrorMessage = registerUserResponse.ErrorMessage; response.ErrorMessages = registerUserResponse.ErrorMessages; return(response); } //Get user back from result var user = (AccountUserIdentity)registerUserResponse.ResponseObject; #endregion #region Create Account try { // Create Accounts ============================================================= InsertStatements insertStatements = new InsertStatements(); var insertResult = insertStatements.InsertNewAccount(model, accountId); if (insertResult.isSuccess) { // (Optional) for certain scenrios //Add user to account, make them the owner, and assign them as SuperAdmin role: //AccountManager.AddUserToAccount(user.Id, AccountID.ToString(), true); // <-- Only for certain scenarios response.isSuccess = true; response.SuccessMessage = Sahara.Core.Settings.Copy.PlatformMessages.AccountRegistration.SuccessMessage; var origin = ""; if (model.Origin != null) { origin = "<br/><br/><b>Origin:</b> " + model.Origin; } var name = "<br/><br/><b>Name:</b> " + model.FirstName + " " + model.LastName; var email = "<br/><br/><b>Email:</b> " + model.Email; var phone = ""; if (model.PhoneNumber != null) { phone = "<br/><br/><b>Phone:</b> " + model.PhoneNumber; } try { //Send an alert to the platform admin(s): EmailManager.Send( Settings.Endpoints.Emails.PlatformEmailAddresses, Settings.Endpoints.Emails.FromRegistration, "Registration", "New Registrant", "A new account named <b>'" + model.AccountName + "'</b> has just been registered." + name + email + phone + origin, true ); } catch { } //Log The Activity ------------ : //PlatformLogManager.LogActivity(CategoryType.Registration, //ActivityType.Registration_Succeeded, //String.Format("Registration completed for: '{0}' by: {1} from: {2}", model.AccountName, model.Email, model.Origin), //String.Format("Name:'{0}', Email:'{1}', Origin:{2}", model.AccountName, model.Email, model.Origin)); PlatformLogManager.LogActivity(CategoryType.Account, ActivityType.Account_Registered, String.Format("Registration completed for: '{0}' by: {1} from: {2}", model.AccountName, model.Email, model.Origin), String.Format("Name:'{0}', Email:'{1}', Origin:{2}", model.AccountName, model.Email, model.Origin), accountId.ToString(), model.AccountName, null, null, null, null, model.Origin); return(response); } else { #region Error Handling string error = insertResult.ErrorMessage; AccountUser outUser = null; //rollback user creation: AccountUserManager.DeleteUser(user.Id, false, out outUser); //Log The Activity ------------ : PlatformLogManager.LogActivity(CategoryType.Registration, ActivityType.Registration_Failed, String.Format("Registration failed for: '{0}' by: {1} from: {2}", model.AccountName, model.Email, model.Origin), String.Format("Error:{0}", error)); //PlatformLogManager.LogActivity(ErrorLogActivity.PlatformError, //String.Format("Registration failed for: '{0}' by: {1} from: {2}", model.AccountName, model.Email, model.Origin), //String.Format("Error:{0}", error)); response.isSuccess = false; response.ErrorMessage = error; response.ErrorMessages.Add(error); return(response); #endregion } } catch (Exception e) { #region Error Handling string error = String.Empty; AccountUser outUser = null; //rollback user creation: AccountUserManager.DeleteUser(user.Id, false, out outUser); try { error = e.Message; } catch { error = "An error occured"; } //rollback user: //To Do: AccountUserManager.DeleteUser(model.Email); string errorDetails = String.Format("Registration failed for: '{0}' by: {1} from: {2}", model.AccountName, model.Email, model.Origin); //Log The Error(s) ------------ : PlatformLogManager.LogActivity(CategoryType.Registration, ActivityType.Registration_Error, errorDetails, String.Format("Error:{0}", error)); PlatformExceptionsHelper.LogExceptionAndAlertAdmins( e, "registering a new account for " + model.AccountName + " / " + model.Email + " / " + model.FirstName + " " + model.LastName + " from: " + model.Origin, System.Reflection.MethodBase.GetCurrentMethod()); response.isSuccess = false; response.ErrorMessage = error; response.ErrorMessages.Add(error); return(response); #endregion } #endregion } catch (Exception e) { //Log The Error(s) ------------ : PlatformLogManager.LogActivity(CategoryType.Registration, ActivityType.Registration_Error, String.Format("Registration failed for: '{0}' by: {1} from: {2}", model.AccountName, model.Email, model.Origin), String.Format("Error:{0}", e.Message)); PlatformExceptionsHelper.LogExceptionAndAlertAdmins( e, "registering a new account for " + model.AccountName + " / " + model.Email + " / " + model.FirstName + " " + model.LastName + " from: " + model.Origin, System.Reflection.MethodBase.GetCurrentMethod()); response.isSuccess = false; response.ErrorMessage = "An error occured when creating the account"; response.ErrorMessages.Add(e.Message); try { response.ErrorMessages.Add(e.InnerException.InnerException.Message); } catch { } return(response); } }