/// <summary>
        /// removes the order passed in from the persistent storage. Also the order detail rows belonging with this order will be
        /// removed. It is wise to refresh the gui after this action, since collections and other data elements have to refreshed to illustrate the
        /// change.
        /// </summary>
        /// <param name="orderToRemove">Order entity to remove from the persistent storage</param>
        /// <returns>true if the removal was succesful, false otherwise</returns>
        private bool RemoveOrder(OrderEntity orderToRemove)
        {
            DataAccessAdapter adapter = new DataAccessAdapter();
            bool toReturn             = false;

            adapter.StartTransaction(System.Data.IsolationLevel.ReadCommitted, "RemoveOrder");
            try
            {
                // first remove the orderdetail rows of this order
                adapter.DeleteEntityCollection(orderToRemove.OrderDetails);

                // remove the order itself
                toReturn = adapter.DeleteEntity(orderToRemove);

                // done
                adapter.Commit();
            }
            catch
            {
                adapter.Rollback();
                throw;
            }
            finally
            {
                adapter.Dispose();
            }

            return(toReturn);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Deletes the given forum from the system, including <b>all</b> threads in this forum and messages in those threads.
        /// </summary>
        /// <param name="forumId">Forum ID.</param>
        /// <returns>True if succeeded, false otherwise</returns>
        public static async Task <bool> DeleteForumAsync(int forumId)
        {
            // first all threads in this forum have to be removed, then this forum should be removed. Do this in one transaction.
            using (var adapter = new DataAccessAdapter())
            {
                await adapter.StartTransactionAsync(IsolationLevel.ReadCommitted, "DeleteForum").ConfigureAwait(false);

                try
                {
                    await ThreadManager.DeleteAllThreadsInForumAsync(forumId, adapter);

                    // remove all ForumRoleForumActionRight entities for this forum
                    await adapter.DeleteEntitiesDirectlyAsync(typeof(ForumRoleForumActionRightEntity),
                                                              new RelationPredicateBucket(ForumRoleForumActionRightFields.ForumID.Equal(forumId)))
                    .ConfigureAwait(false);

                    // remove the forum entity. do this by executing a direct delete statement on the database
                    await adapter.DeleteEntitiesDirectlyAsync(typeof(ForumEntity), new RelationPredicateBucket(ForumFields.ForumID.Equal(forumId))).ConfigureAwait(false);

                    adapter.Commit();
                    return(true);
                }
                catch
                {
                    // exception occured, rollback
                    adapter.Rollback();
                    throw;
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Removes the order and the order detail rows of this order from the database.
        /// </summary>
        /// <param name="toRemove">order to remove.</param>
        /// <returns>true if the remove was successful, false otherwise</returns>
        public bool RemoveOrder(OrderEntity toRemove)
        {
            Console.WriteLine("RemoveOrder called");
            bool toReturn = false;

            using (DataAccessAdapter adapter = new DataAccessAdapter())
            {
                adapter.StartTransaction(IsolationLevel.ReadCommitted, "order removal");
                try
                {
                    // LLBLGen Pro doesn't have cascading deletes, as those aren't always possible (multiple paths from A to B), plus
                    // deletes are always explicit in LLBLGen Pro so no surprises which aren't recoverable.
                    // first remove the orderdetail rows of this order
                    adapter.DeleteEntityCollection(toRemove.OrderDetails);

                    // remove the order itself
                    toReturn = adapter.DeleteEntity(toRemove);

                    // done. Commit the work.
                    adapter.Commit();
                    toReturn = true;
                }
                catch
                {
                    // exception occured. Rollback transaction
                    adapter.Rollback();
                    // simply rethrow the exception
                    throw;
                }
            }

            return(toReturn);
        }
Exemplo n.º 4
0
        private static async Task ConvertMessages()
        {
            // display total amount of messages to process
            int totalNumberOfMessages = await MessageGuiHelper.GetTotalNumberOfMessagesAsync();

            Console.WriteLine("Total # of messages to process: {0}. Using batch size: {1}", totalNumberOfMessages, BATCHSIZE);
            var numberOfBatches = (totalNumberOfMessages / BATCHSIZE) + 1;
            var qf = new QueryFactory();
            var q  = qf.Message.OrderBy(MessageFields.MessageID.Ascending())
                     .Exclude(MessageFields.MessageTextAsHTML);

            using (var adapter = new DataAccessAdapter())
            {
                await adapter.StartTransactionAsync(IsolationLevel.ReadCommitted, "Converting UBB to Markdown").ConfigureAwait(false);

                adapter.KeepTrackOfTransactionParticipants = false;
                try
                {
                    var messages = new EntityCollection <MessageEntity>();
                    for (int batchNo = 1; batchNo <= numberOfBatches; batchNo++)
                    {
                        messages.Clear();
                        Console.WriteLine("Batch {0} of {1}", batchNo, numberOfBatches);
                        q.Page(batchNo, BATCHSIZE);
                        Console.Write("\tFetching messages...");
                        adapter.FetchQuery(q, messages);
                        Console.WriteLine("DONE. Messages fetched: {0}", messages.Count);
                        Console.Write("\tParsing messages...");
                        foreach (var message in messages)
                        {
                            string parserLog;
                            string messageAsXml;
                            bool   errorsOccurred;
                            string convertedText = TextParser.TransformUBBMessageStringToHTML(message.MessageText, _parserData, out parserLog, out errorsOccurred, out messageAsXml);
                            if (errorsOccurred)
                            {
                                Console.WriteLine("\nERRORS: {0}", parserLog);
                                Console.WriteLine("MessageID: {0}\nMessage as text:\n{1}--------------\n", message.MessageID, message.MessageText);
                            }
                            else
                            {
                                // html decode, so any &lt; etc. are converted back to the regular characters.
                                message.MessageText = HttpUtility.HtmlDecode(convertedText);
                            }
                        }
                        Console.WriteLine("DONE");
                        Console.Write("\tPersisting batch...");
                        await adapter.SaveEntityCollectionAsync(messages).ConfigureAwait(false);

                        Console.WriteLine("DONE\n");
                    }
                    adapter.Commit();
                }
                catch
                {
                    adapter.Rollback();
                    throw;
                }
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Deletes the given role from the system.
        /// </summary>
        /// <param name="roleId">ID of role to delete</param>
        /// <returns>true if succeeded, false otherwise</returns>
        public static async Task <bool> DeleteRoleAsync(int roleId)
        {
            var toDelete = await SecurityGuiHelper.GetRoleAsync(roleId);

            if (toDelete == null)
            {
                // not found
                return(false);
            }

            using (var adapter = new DataAccessAdapter())
            {
                await adapter.StartTransactionAsync(IsolationLevel.ReadCommitted, "DeleteRole").ConfigureAwait(false);

                try
                {
                    // remove the role - forum - action right entities
                    await adapter.DeleteEntitiesDirectlyAsync(typeof(ForumRoleForumActionRightEntity),
                                                              new RelationPredicateBucket(ForumRoleForumActionRightFields.RoleID.Equal(roleId))).ConfigureAwait(false);

                    // Remove role-audit action entities
                    await adapter.DeleteEntitiesDirectlyAsync(typeof(RoleAuditActionEntity),
                                                              new RelationPredicateBucket(RoleAuditActionFields.RoleID.Equal(roleId))).ConfigureAwait(false);

                    ;

                    // remove Role - systemright entities
                    await adapter.DeleteEntitiesDirectlyAsync(typeof(RoleSystemActionRightEntity),
                                                              new RelationPredicateBucket(RoleSystemActionRightFields.RoleID.Equal(roleId))).ConfigureAwait(false);

                    ;

                    // remove Role - user entities
                    await adapter.DeleteEntitiesDirectlyAsync(typeof(RoleUserEntity),
                                                              new RelationPredicateBucket(RoleUserFields.RoleID.Equal(roleId))).ConfigureAwait(false);

                    ;

                    // delete the actual role
                    await adapter.DeleteEntityAsync(toDelete).ConfigureAwait(false);

                    ;
                    adapter.Commit();
                    return(true);
                }
                catch
                {
                    // error occured, rollback
                    adapter.Rollback();
                    throw;
                }
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Marks the thread as done.
        /// </summary>
        /// <param name="threadId">Thread ID.</param>
        /// <returns></returns>
        public static async Task <bool> MarkThreadAsDoneAsync(int threadId)
        {
            var thread = await ThreadGuiHelper.GetThreadAsync(threadId);

            if (thread == null)
            {
                // not found
                return(false);
            }

            var containingSupportQueue = await SupportQueueGuiHelper.GetQueueOfThreadAsync(threadId);

            thread.MarkedAsDone = true;
            using (var adapter = new DataAccessAdapter())
            {
                // if the thread is in a support queue, the thread has to be removed from that queue. This is a multi-entity action and therefore we've to start a
                // transaction if that's the case. If not, we can use the easy route and simply save the thread and be done with it.
                if (containingSupportQueue == null)
                {
                    // not in a queue, simply save the thread.
                    return(await adapter.SaveEntityAsync(thread).ConfigureAwait(false));
                }

                // in a queue, so remove from the queue and save the entity.
                await adapter.StartTransactionAsync(IsolationLevel.ReadCommitted, "MarkThreadDone").ConfigureAwait(false);

                try
                {
                    // save the thread
                    var result = await adapter.SaveEntityAsync(thread).ConfigureAwait(false);

                    if (result)
                    {
                        // save succeeded, so remove from queue, pass the current adapter to the method so the action takes place inside this transaction.
                        await SupportQueueManager.RemoveThreadFromQueueAsync(threadId, adapter);
                    }

                    adapter.Commit();
                    return(true);
                }
                catch
                {
                    // rollback transaction
                    adapter.Rollback();
                    throw;
                }
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Creates a new message in the given thread. Caller should validate input parameters. It potentially closes the thread if ordered to do so.
        /// </summary>
        /// <param name="threadId">Thread wherein the new message will be placed</param>
        /// <param name="userId">User who posted this message</param>
        /// <param name="messageText">Message text</param>
        /// <param name="messageAsHTML">Message text as HTML</param>
        /// <param name="userIdIPAddress">IP address of user calling this method</param>
        /// <param name="subscribeToThread">if set to <c>true</c> [subscribe to thread].</param>
        /// <param name="emailData">The email data.</param>
        /// <param name="sendReplyNotifications">Flag to signal to send reply notifications. If set to false no notifications are mailed,
        /// otherwise a notification is mailed to all subscribers to the thread the new message is posted in</param>
        /// <returns>
        /// MessageID if succeeded, 0 if not.
        /// </returns>
        private static async Task <int> CreateNewMessageInThreadAndPotentiallyCloseThread(int threadId, int userId, string messageText, string messageAsHTML,
                                                                                          string userIdIPAddress, bool subscribeToThread,
                                                                                          Dictionary <string, string> emailData, bool sendReplyNotifications)
        {
            var messageId = 0;

            using (var adapter = new DataAccessAdapter())
            {
                await adapter.StartTransactionAsync(IsolationLevel.ReadCommitted, "InsertNewMessage").ConfigureAwait(false);

                try
                {
                    var postingDate = DateTime.Now;
                    var message     = new MessageEntity
                    {
                        MessageText       = messageText,
                        MessageTextAsHTML = messageAsHTML,
                        PostedByUserID    = userId,
                        PostingDate       = postingDate,
                        ThreadID          = threadId,
                        PostedFromIP      = userIdIPAddress,
                    };
                    messageId = await adapter.SaveEntityAsync(message).ConfigureAwait(false) ? message.MessageID : 0;

                    if (messageId > 0)
                    {
                        await MessageManager.UpdateStatisticsAfterMessageInsert(threadId, userId, messageId, adapter, postingDate, true, subscribeToThread);
                    }

                    adapter.Commit();
                }
                catch
                {
                    adapter.Rollback();
                    throw;
                }
            }

            if (sendReplyNotifications)
            {
                // send notification email to all subscribers. Do this outside the transaction so a failed email send action doesn't terminate the save process
                // of the message.
                await ThreadManager.SendThreadReplyNotifications(threadId, userId, emailData).ConfigureAwait(false);
            }

            return(messageId);
        }
Exemplo n.º 8
0
        /// <summary>
        /// Saves the given set of actionrights as the set of forum action rights for the given forum / role combination.
        /// It first removes all current action rights for that combination.
        /// </summary>
        /// <param name="actionRightIDs">List of actionrights to set of this role</param>
        /// <param name="roleId">Role to use</param>
        /// <param name="forumId">Forum to use</param>
        /// <returns>true if succeeded, false otherwise</returns>
        public static async Task <bool> SaveForumActionRightsForForumRoleAsync(List <int> actionRightIDs, int roleId, int forumId)
        {
            var forumRightsPerRole = new EntityCollection <ForumRoleForumActionRightEntity>();

            foreach (var actionRightId in actionRightIDs)
            {
                var newForumRightPerRole = new ForumRoleForumActionRightEntity
                {
                    ActionRightID = actionRightId,
                    ForumID       = forumId,
                    RoleID        = roleId
                };
                forumRightsPerRole.Add(newForumRightPerRole);
            }

            using (var adapter = new DataAccessAdapter())
            {
                await adapter.StartTransactionAsync(IsolationLevel.ReadCommitted, "SaveForumActionRights").ConfigureAwait(false);

                try
                {
                    // first remove the existing rows for the role. Do this by a query directly on the database.
                    await adapter.DeleteEntitiesDirectlyAsync(typeof(ForumRoleForumActionRightEntity),
                                                              new RelationPredicateBucket((ForumRoleForumActionRightFields.RoleID.Equal(roleId))
                                                                                          .And(ForumRoleForumActionRightFields.ForumID.Equal(forumId))))
                    .ConfigureAwait(false);

                    // then save the new entities
                    await adapter.SaveEntityCollectionAsync(forumRightsPerRole).ConfigureAwait(false);

                    // all done, commit transaction
                    adapter.Commit();
                    return(true);
                }
                catch
                {
                    // failed, rollback transaction
                    adapter.Rollback();
                    throw;
                }
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Deletes the given message from the database and the complete logged history.
        /// </summary>
        /// <param name="messageId">The ID of the message to delete</param>
        /// <param name="threadId">The id of the thread the message is part of</param>
        /// <returns>True if succeeded, false otherwise</returns>
        public static async Task <bool> DeleteMessageAsync(int messageId, int threadId)
        {
            using (var adapter = new DataAccessAdapter())
            {
                // if the message was the last message in the thread, we have first to update the statistics entity with the message that's semi-last.
                // we do that by simply fetching the last two messages of the thread. if the last message of these 2 is the one to delete, we update
                // the statistics entity with the one that's semi-last.
                var qf = new QueryFactory();
                var q  = qf.Message
                         .Where(MessageFields.ThreadID.Equal(threadId))
                         .OrderBy(MessageFields.PostingDate.Descending())
                         .Limit(2)
                         .Select(() => MessageFields.MessageID.ToValue <int>());
                var lastTwoMessageIdsInThread = await adapter.FetchQueryAsync(q).ConfigureAwait(false);

                await adapter.StartTransactionAsync(IsolationLevel.ReadCommitted, "DeleteMessage").ConfigureAwait(false);

                try
                {
                    var threadStatisticsUpdater = new ThreadStatisticsEntity();
                    threadStatisticsUpdater.Fields[(int)ThreadStatisticsFieldIndex.NumberOfMessages].ExpressionToApply = (ThreadStatisticsFields.NumberOfMessages - 1);
                    if (lastTwoMessageIdsInThread.Count == 2 && lastTwoMessageIdsInThread[0] == messageId)
                    {
                        // message is the last one in the thread, update statistics row with the new last one
                        threadStatisticsUpdater.LastMessageID = lastTwoMessageIdsInThread[1];
                        await adapter.UpdateEntitiesDirectlyAsync(threadStatisticsUpdater, new RelationPredicateBucket(ThreadStatisticsFields.ThreadID.Equal(threadId)))
                        .ConfigureAwait(false);
                    }

                    await DeleteMessagesAsync(MessageFields.MessageID.Equal(messageId), adapter);

                    adapter.Commit();
                    return(true);
                }
                catch
                {
                    adapter.Rollback();
                    throw;
                }
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// Deletes the support queue with the ID specified.
        /// </summary>
        /// <param name="queueId">The queue ID of the queue to delete.</param>
        /// <returns>true if succeeded, false otherwise</returns>
        /// <remarks>All threads in the queue are automatically de-queued and not in a queue anymore. The Default support queue
        /// for forums which have this queue as the default support queue is reset to null.</remarks>
        public static async Task <bool> DeleteSupportQueueAsync(int queueId)
        {
            using (var adapter = new DataAccessAdapter())
            {
                // we'll do several actions in one atomic transaction, so start a transaction first.
                await adapter.StartTransactionAsync(IsolationLevel.ReadCommitted, "DeleteSupportQ").ConfigureAwait(false);

                try
                {
                    // first reset all the FKs in Forum to NULL if they point to this queue.
                    await adapter.UpdateEntitiesDirectlyAsync(new ForumEntity()
                    {
                        DefaultSupportQueueID = null
                    },
                                                              new RelationPredicateBucket(ForumFields.DefaultSupportQueueID.Equal(queueId))).ConfigureAwait(false);

                    ;

                    // delete all SupportQueueThread entities which refer to this queue. This will make all threads which are in this queue become queue-less.
                    await adapter.DeleteEntitiesDirectlyAsync(typeof(SupportQueueThreadEntity),
                                                              new RelationPredicateBucket(SupportQueueThreadFields.QueueID.Equal(queueId))).ConfigureAwait(false);

                    ;

                    // it's now time to delete the actual supportqueue entity.
                    var result = await adapter.DeleteEntitiesDirectlyAsync(typeof(SupportQueueEntity),
                                                                           new RelationPredicateBucket(SupportQueueFields.QueueID.Equal(queueId))).ConfigureAwait(false);

                    ;

                    // done so commit the transaction.
                    adapter.Commit();
                    return(result > 0);
                }
                catch
                {
                    adapter.Rollback();
                    throw;
                }
            }
        }
Exemplo n.º 11
0
        public async Task UpdateManagersAndEmployees(ManagerEntity manager, EmployeeEntity employee)
        {
            using (var adapter = new DataAccessAdapter()){
                adapter.StartTransaction(IsolationLevel.ReadCommitted, "FirstTransaction");

                try{
                    manager.IsNew  = false;
                    employee.IsNew = false;

                    await adapter.SaveEntityAsync(manager);

                    await adapter.SaveEntityAsync(employee);

                    adapter.Commit();
                }
                catch (Exception e) {
                    adapter.Rollback();
                    throw new Exception("Transaction rollbacked {0}", e);
                }
            }
        }
Exemplo n.º 12
0
        /// <summary>
        /// Deletes the given Thread from the system, including <b>all</b> messages and related data in this Thread.
        /// </summary>
        /// <param name="threadId">Thread to delete.</param>
        /// <returns>True if succeeded, false otherwise</returns>
        public static async Task <bool> DeleteThreadAsync(int threadId)
        {
            using (var adapter = new DataAccessAdapter())
            {
                // we'll use the delete threads feature as deleting a thread requires updating more data than just deleting a single thread object.
                await adapter.StartTransactionAsync(IsolationLevel.ReadCommitted, "DeleteThread").ConfigureAwait(false);

                try
                {
                    await ThreadManager.DeleteThreadsAsync(new PredicateExpression(ThreadFields.ThreadID.Equal(threadId)), adapter);

                    adapter.Commit();
                    return(true);
                }
                catch
                {
                    adapter.Rollback();
                    throw;
                }
            }
        }
Exemplo n.º 13
0
        /// <summary>
        /// Marks the thread as un-done, and add it to the default queue of the forum.
        /// </summary>
        /// <param name="threadId">Thread ID</param>
        /// <param name="userId">the user adding the thread to a queue by unmarking it as done </param>
        /// <returns></returns>
        public static async Task <bool> UnMarkThreadAsDoneAsync(int threadId, int userId)
        {
            var thread = await ThreadGuiHelper.GetThreadAsync(threadId);

            if (thread == null)
            {
                // not found
                return(false);
            }

            thread.MarkedAsDone = false;
            using (var adapter = new DataAccessAdapter())
            {
                // Save the thread and add it to the default queue of the forum.
                await adapter.StartTransactionAsync(IsolationLevel.ReadCommitted, "MarkThreadUnDone").ConfigureAwait(false);

                try
                {
                    await adapter.SaveEntityAsync(thread, true).ConfigureAwait(false);

                    var q     = new QueryFactory().Forum.Where(ForumFields.ForumID.Equal(thread.ForumID));
                    var forum = await adapter.FetchFirstAsync(q).ConfigureAwait(false);

                    if (forum?.DefaultSupportQueueID != null)
                    {
                        // not in a queue, and the forum has a default queue. Add the thread to the queue of the forum
                        await SupportQueueManager.AddThreadToQueueAsync(threadId, forum.DefaultSupportQueueID.Value, userId, adapter);
                    }

                    adapter.Commit();
                    return(true);
                }
                catch
                {
                    // rollback transaction
                    adapter.Rollback();
                    throw;
                }
            }
        }
Exemplo n.º 14
0
        /// <summary>
        /// Modifies the given properties of the given thread.
        /// </summary>
        /// <param name="threadId">The threadID of the thread which properties should be changed</param>
        /// <param name="subject">The new subject for this thread</param>
        /// <param name="isSticky">The new value for IsSticky</param>
        /// <param name="isClosed">The new value for IsClosed</param>
        public static async Task ModifyThreadPropertiesAsync(int threadId, string subject, bool isSticky, bool isClosed)
        {
            var thread = await ThreadGuiHelper.GetThreadAsync(threadId);

            if (thread == null)
            {
                // not found
                return;
            }

            // update the fields with new values
            thread.Subject  = subject;
            thread.IsSticky = isSticky;
            thread.IsClosed = isClosed;
            using (var adapter = new DataAccessAdapter())
            {
                await adapter.StartTransactionAsync(IsolationLevel.ReadCommitted, "ModifyThreadProperties");

                try
                {
                    var result = await adapter.SaveEntityAsync(thread).ConfigureAwait(false);

                    if (result)
                    {
                        // save succeeded, so remove from queue, pass the current transaction to the method so the action takes place inside this transaction.
                        await SupportQueueManager.RemoveThreadFromQueueAsync(threadId, adapter);
                    }

                    adapter.Commit();
                }
                catch
                {
                    adapter.Rollback();
                    throw;
                }
            }
        }
Exemplo n.º 15
0
        public int CreateWithIsolationLevel(EmployeeClassificationEntity classification, bool shouldRollBack, IsolationLevel isolationLevel)
        {
            if (classification == null)
            {
                throw new ArgumentNullException(nameof(classification), $"{nameof(classification)} is null.");
            }

            using (var adapter = new DataAccessAdapter())
            {
                adapter.StartTransaction(isolationLevel, null);
                adapter.SaveEntity(classification, true, recurse: false);
                var result = classification.EmployeeClassificationKey;

                if (shouldRollBack)
                {
                    adapter.Rollback();
                }
                else
                {
                    adapter.Commit();
                }
                return(result);
            }
        }
Exemplo n.º 16
0
        /// <summary>
        /// Handler of the Submit button
        /// Persists changes to the database
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSubmit_Click(object sender, EventArgs e)
        {
            int savedCount   = 0;
            int deletedCount = 0;

            // A using statement makes sure the Adapter is Dispose.
            using (DataAccessAdapter adapter = new DataAccessAdapter())
            {
                // Start a Transaction
                adapter.StartTransaction(IsolationLevel.ReadCommitted, "CustomersActions");
                try
                {
                    // Save changes of the bound collection to the database. (Inserts/Updates)
                    savedCount = adapter.SaveEntityCollection(_entities, true, false);

                    // Delete entities removed from the bound collection.
                    if (_entitiesToDelete.Count > 0)
                    {
                        deletedCount = adapter.DeleteEntityCollection(_entitiesToDelete);
                        _entitiesToDelete.Clear();
                    }

                    // Commit the Transaction
                    adapter.Commit();
                }
                catch
                {
                    // Rollback the Transaction.
                    adapter.Rollback();
                    throw;
                }
            }

            // Show a feedback message to the user.
            MessageBox.Show("Number of saved records = " + savedCount.ToString() + "\r\nNumber of deleted records = " + deletedCount.ToString());
        }
Exemplo n.º 17
0
        /// <summary>
        /// Deletes the user with the ID passed in. Will reset all posts made by the user to the userid 0.
        /// </summary>
        /// <param name="userId">The user ID.</param>
        /// <remarks>Can't delete user 0</remarks>
        /// <returns>true if succeeded, false otherwise</returns>
        public static async Task <bool> DeleteUserAsync(int userId)
        {
            if (userId <= 1)
            {
                // can't delete the Anonymous user nor the admin user
                return(false);
            }

            var toDelete = await UserGuiHelper.GetUserAsync(userId);

            if (toDelete == null)
            {
                // user doesn't exist
                return(false);
            }

            if (toDelete.NickName == "Admin")
            {
                // can't delete admin
                return(false);
            }

            using (var adapter = new DataAccessAdapter())
            {
                await adapter.StartTransactionAsync(IsolationLevel.ReadCommitted, "DeleteUser").ConfigureAwait(false);

                try
                {
                    // we'll first update all PostedByUserId fields of all messages which are posted by the user to delete.
                    var messageUpdater = new MessageEntity {
                        PostedByUserID = 0
                    };

                    // reset to AC.
                    await adapter.UpdateEntitiesDirectlyAsync(messageUpdater, new RelationPredicateBucket(MessageFields.PostedByUserID.Equal(userId)))
                    .ConfigureAwait(false);

                    // set the startuser of threads started by this user to 0
                    var threadUpdater = new ThreadEntity {
                        StartedByUserID = 0
                    };
                    await adapter.UpdateEntitiesDirectlyAsync(threadUpdater, new RelationPredicateBucket(ThreadFields.StartedByUserID.Equal(userId)))
                    .ConfigureAwait(false);

                    // remove the user from the UserRoles set, as the user shouldn't be in any roles.
                    await adapter.DeleteEntitiesDirectlyAsync(typeof(RoleUserEntity), new RelationPredicateBucket(RoleUserFields.UserID.Equal(userId)))
                    .ConfigureAwait(false);

                    // delete all bookmarks of user
                    await adapter.DeleteEntitiesDirectlyAsync(typeof(BookmarkEntity), new RelationPredicateBucket(BookmarkFields.UserID.Equal(userId)))
                    .ConfigureAwait(false);

                    // delete all audit data
                    // first fetch it, then delete all entities from the collection, as the audit data is in an inheritance hierarchy of TargetPerEntity which can't
                    // be deleted directly from the db.
                    var auditData = await adapter.FetchQueryAsync(new QueryFactory().User.Where(UserFields.UserID.Equal(userId))).ConfigureAwait(false);

                    await adapter.DeleteEntityCollectionAsync(auditData).ConfigureAwait(false);

                    // set IP bans set by this user to userid 0
                    var ipbanUpdater = new IPBanEntity {
                        IPBanSetByUserID = 0
                    };
                    await adapter.UpdateEntitiesDirectlyAsync(ipbanUpdater, new RelationPredicateBucket(IPBanFields.IPBanSetByUserID.Equal(userId)))
                    .ConfigureAwait(false);

                    // delete threadsubscriptions
                    await adapter.DeleteEntitiesDirectlyAsync(typeof(ThreadSubscriptionEntity), new RelationPredicateBucket(ThreadSubscriptionFields.UserID.Equal(userId)))
                    .ConfigureAwait(false);

                    // remove supportqueuethread claims
                    await adapter.DeleteEntitiesDirectlyAsync(typeof(SupportQueueThreadEntity),
                                                              new RelationPredicateBucket(SupportQueueThreadFields.ClaimedByUserID.Equal(userId)))
                    .ConfigureAwait(false);

                    // set all placed in queue references to userid 0, so the threads stay in the queues.
                    var supportQueueThreadUpdater = new SupportQueueThreadEntity {
                        PlacedInQueueByUserID = 0
                    };
                    await adapter.UpdateEntitiesDirectlyAsync(supportQueueThreadUpdater,
                                                              new RelationPredicateBucket(SupportQueueThreadFields.PlacedInQueueByUserID.Equal(userId)))
                    .ConfigureAwait(false);

                    // now delete the actual user entity
                    await adapter.DeleteEntityAsync(toDelete).ConfigureAwait(false);

                    adapter.Commit();
                    return(true);
                }
                catch
                {
                    adapter.Rollback();
                    throw;
                }
            }
        }
Exemplo n.º 18
0
        /// <summary>
        /// Updates the given user's profile data using the values of the properties of this class.
        /// </summary>
        /// <param name="userId">The user ID.</param>
        /// <param name="dateOfBirth">The date of birth.</param>
        /// <param name="emailAddress">The email address.</param>
        /// <param name="emailAddressIsPublic">flag to signal if the emailaddress is visible for everyone or not</param>
        /// <param name="iconUrl">The icon URL.</param>
        /// <param name="location">The location.</param>
        /// <param name="occupation">The occupation.</param>
        /// <param name="password">The password.</param>
        /// <param name="signature">The signature.</param>
        /// <param name="website">The website.</param>
        /// <param name="userTitleId">The user title ID.</param>
        /// <param name="autoSubscribeThreads">Default value when user creates new threads.</param>
        /// <param name="defaultMessagesPerPage">Messages per page to display</param>
        /// <param name="isBanned">flag whether the user is banned or not. Can be null, in which case the value is left untouched</param>
        /// <param name="roleIds">The RoleIDs of the roles the user is in. Can be null, in which case no roles are updated</param>
        /// <returns>true if succeeded, false otherwise</returns>
        public static async Task <bool> UpdateUserProfileAsync(int userId, DateTime?dateOfBirth, string emailAddress, bool emailAddressIsPublic, string iconUrl,
                                                               string location, string occupation, string password, string signature, string website, int userTitleId,
                                                               bool autoSubscribeThreads, short defaultMessagesPerPage, bool?isBanned = null, List <int> roleIds = null)
        {
            var user = await UserGuiHelper.GetUserAsync(userId);

            if (user == null)
            {
                // not found
                return(false);
            }

            user.DateOfBirth          = dateOfBirth;
            user.EmailAddress         = emailAddress;
            user.EmailAddressIsPublic = emailAddressIsPublic;
            user.IconURL     = iconUrl;
            user.Location    = location;
            user.Occupation  = occupation;
            user.UserTitleID = userTitleId;
            if (isBanned.HasValue)
            {
                user.IsBanned = isBanned.Value;
            }

            if (!string.IsNullOrWhiteSpace(password))
            {
                user.Password = HnDGeneralUtils.HashPassword(password, performPreMD5Hashing: true);
            }

            user.Signature = signature;
            user.Website   = website;

            //Preferences
            user.AutoSubscribeToThread          = autoSubscribeThreads;
            user.DefaultNumberOfMessagesPerPage = defaultMessagesPerPage;

            // first encode fields which could lead to cross-site-scripting attacks
            EncodeUserTextFields(user);

            if (roleIds != null)
            {
                // Add new entities for the user for all roleid's in the list specified. We'll first delete the ones the user is already in below directly
                foreach (var roleId in roleIds)
                {
                    user.RoleUser.Add(new RoleUserEntity()
                    {
                        RoleID = roleId
                    });
                }
            }

            using (var adapter = new DataAccessAdapter())
            {
                await adapter.StartTransactionAsync(IsolationLevel.ReadCommitted, "Update User Info").ConfigureAwait(false);

                try
                {
                    if (roleIds != null)
                    {
                        // first remove the user from all roles, we'll do that directly.
                        await adapter.DeleteEntitiesDirectlyAsync(typeof(RoleUserEntity),
                                                                  new RelationPredicateBucket(RoleUserFields.UserID.Equal(userId)))
                        .ConfigureAwait(false);
                    }

                    // then save everything in one go.
                    var toReturn = await adapter.SaveEntityAsync(user).ConfigureAwait(false);

                    adapter.Commit();
                    return(toReturn);
                }
                catch
                {
                    adapter.Rollback();
                    throw;
                }
            }
        }
Exemplo n.º 19
0
        /// <summary>
        /// Creates a new thread in the given forum and places the passed in message as the first message in the thread.
        /// Caller should validate input parameters.
        /// </summary>
        /// <param name="forumId">Forum wherein the new thread will be placed</param>
        /// <param name="userId">User who started this thread</param>
        /// <param name="subject">Subject of the thread</param>
        /// <param name="messageText">First message of the thread</param>
        /// <param name="messageAsHTML">Message text as HTML</param>
        /// <param name="isSticky">Flag if the thread is sticky / pinned (true) or not (false)</param>
        /// <param name="userIdIPAddress">IP address of user calling this method</param>
        /// <param name="defaultSupportQueueId">The ID of the default support queue for this forum. If not null, the thread created will be
        /// added to the support queue with the ID specified.</param>
        /// <param name="subscribeToThread">If true, the user with userid is automatically subscribed to the new thread created</param>
        /// <returns>tuple with ThreadID and messageid. ThreadId, if succeeded, is set to the threadid of the new thread, or 0 if failed.
        /// The message ID is the id of the new message, which is the start message in the thread.</returns>
        public static async Task <(int threadId, int messageId)> CreateNewThreadInForumAsync(int forumId, int userId, string subject, string messageText,
                                                                                             string messageAsHTML, bool isSticky, string userIdIPAddress,
                                                                                             int?defaultSupportQueueId, bool subscribeToThread)
        {
            var newThread = new ThreadEntity
            {
                ForumID         = forumId,
                IsClosed        = false,
                IsSticky        = isSticky,
                StartedByUserID = userId,
                Subject         = subject,
            };

            if (defaultSupportQueueId.HasValue)
            {
                // a support queue has been specified as the default support queue for this forum. Add the new thread to this support queue.
                newThread.SupportQueueThread = new SupportQueueThreadEntity
                {
                    QueueID = defaultSupportQueueId.Value,
                    PlacedInQueueByUserID = userId,
                    PlacedInQueueOn       = DateTime.Now,

                    // No need to set the Thread property, as it's auto-assigned due to the assignment of newThread.SupportQueueThread.
                };
            }

            var newMessage = new MessageEntity
            {
                MessageText       = messageText,
                MessageTextAsHTML = messageAsHTML,
                PostedByUserID    = userId,
                PostingDate       = DateTime.Now,
                PostedFromIP      = userIdIPAddress,
                Thread            = newThread
            };

            // Assign a new statistics entity so we can track what the last message is.
            newThread.Statistics = new ThreadStatisticsEntity()
            {
                LastMessage = newMessage, NumberOfMessages = 1, NumberOfViews = 1
            };

            using (var adapter = new DataAccessAdapter())
            {
                await adapter.StartTransactionAsync(IsolationLevel.ReadCommitted, "NewThread").ConfigureAwait(false);

                try
                {
                    // save the complete graph
                    await adapter.SaveEntityAsync(newMessage, true).ConfigureAwait(false);

                    var messageId = newMessage.MessageID;
                    var threadId  = newMessage.ThreadID;

                    // update thread statistics, this is the task for the message manager, and we pass the adapter so the actions will run in
                    // the same transaction. Pass -1 as newMessageId as we already have inserted this.
                    await MessageManager.UpdateStatisticsAfterMessageInsert(threadId, userId, -1, adapter, DateTime.Now, false, subscribeToThread);

                    adapter.Commit();

                    return(newThread.ThreadID, messageId);
                }
                catch
                {
                    adapter.Rollback();
                    throw;
                }
            }
        }
Exemplo n.º 20
0
        private static void ConvertThreadMemos()
        {
            Console.WriteLine("Converting thread memos. ");
            var qf = new QueryFactory();

            using (var adapter = new DataAccessAdapter())
            {
                var totalNumberOfThreads = adapter.FetchScalar <int>(qf.Thread.Select(Functions.CountRow()));
                var numberOfBatches      = (totalNumberOfThreads / BATCHSIZE) + 1;
                Console.WriteLine("Total # of threads to process: {0}. Using batch size: {1}", numberOfBatches, BATCHSIZE);
                var q = qf.Thread.OrderBy(ThreadFields.ThreadID.Ascending());
                adapter.StartTransaction(IsolationLevel.ReadCommitted, "Converting UBB to Markdown");
                adapter.KeepTrackOfTransactionParticipants = false;
                try
                {
                    var threads = new EntityCollection <ThreadEntity>();
                    for (int batchNo = 1; batchNo <= numberOfBatches; batchNo++)
                    {
                        threads.Clear();
                        Console.WriteLine("Batch {0} of {1}", batchNo, numberOfBatches);
                        q.Page(batchNo, BATCHSIZE);
                        Console.Write("\tFetching threads...");
                        adapter.FetchQuery(q, threads);
                        Console.WriteLine("DONE. Threads fetched: {0}", threads.Count);
                        Console.Write("\tParsing memos on threads...");
                        foreach (var thread in threads)
                        {
                            var toConvert = thread.Memo;
                            if (string.IsNullOrWhiteSpace(toConvert))
                            {
                                continue;
                            }
                            // replace CRLF with <space><space>CRLF, as the markdown parser will otherwise collide it with the previous lines which we don't want
                            toConvert = toConvert.Replace(Environment.NewLine, "  " + Environment.NewLine);
                            string parserLog;
                            string messageAsXml;
                            bool   errorsOccurred;
                            string convertedText = TextParser.TransformUBBMessageStringToHTML(toConvert, _parserData, out parserLog, out errorsOccurred, out messageAsXml);
                            if (errorsOccurred)
                            {
                                Console.WriteLine("\nERRORS: {0}", parserLog);
                                Console.WriteLine("ThreadID: {0}\nThread memo as text:\n{1}--------------\n", thread.ThreadID, thread.Memo);
                            }
                            else
                            {
                                // html decode, so any &lt; etc. are converted back to the regular characters.
                                thread.Memo = HttpUtility.HtmlDecode(convertedText);
                            }
                        }
                        Console.WriteLine("DONE");
                        Console.Write("\tPersisting batch...");
                        adapter.SaveEntityCollection(threads);
                        Console.WriteLine("DONE\n");
                    }
                    adapter.Commit();
                }
                catch
                {
                    adapter.Rollback();
                    throw;
                }
            }
        }
Exemplo n.º 21
0
        /// <summary>
        /// Updates the role entity with the id specified, with the role description and system action rights set
        /// It resets the system action rights for the given role to the given set of action rights and it modifies
        /// the role description for the given role. If the user specified a role description that is already available, false will be returned to signal
        /// that the save failed.
        /// </summary>
        /// <param name="roleId">the id of the role</param>
        /// <param name="roleDescription">the new description of the role</param>
        /// <param name="systemActionRightsSet">the system action rights to assign to the role</param>
        /// <param name="auditActionsSet">the ids of the audit actions set for the role</param>
        /// <returns></returns>
        public static async Task <bool> ModifyRoleAsync(int roleId, string roleDescription, List <int> systemActionRightsSet, List <int> auditActionsSet)
        {
            using (var adapter = new DataAccessAdapter())
            {
                var q    = new QueryFactory().Role.Where(RoleFields.RoleID.Equal(roleId));
                var role = await adapter.FetchFirstAsync(q).ConfigureAwait(false);

                if (role == null)
                {
                    return(false);
                }

                // check if the description is different. If so, we've to check if the new roledescription is already present. If so, we'll abort the save
                role.RoleDescription = roleDescription;
                if (role.Fields.GetIsChanged((int)RoleFieldIndex.RoleID))
                {
                    if (await CheckIfRoleDescriptionIsPresentAsync(roleDescription))
                    {
                        // new description, is already present, fail
                        return(false);
                    }
                }

                foreach (var actionRightId in systemActionRightsSet)
                {
                    role.RoleSystemActionRights.Add(new RoleSystemActionRightEntity {
                        ActionRightID = actionRightId
                    });
                }

                foreach (var auditActionId in auditActionsSet)
                {
                    role.RoleAuditAction.Add(new RoleAuditActionEntity()
                    {
                        AuditActionID = auditActionId
                    });
                }

                // all set. We're going to delete all Role - SystemAction Rights combinations first, as we're going to re-insert them later on.
                // We'll use a transaction to be able to roll back all our changes if something fails.
                await adapter.StartTransactionAsync(IsolationLevel.ReadCommitted, "ModifyRole").ConfigureAwait(false);

                try
                {
                    await adapter.DeleteEntitiesDirectlyAsync(typeof(RoleSystemActionRightEntity),
                                                              new RelationPredicateBucket(RoleSystemActionRightFields.RoleID.Equal(roleId)));

                    await adapter.DeleteEntitiesDirectlyAsync(typeof(RoleAuditActionEntity), new RelationPredicateBucket(RoleAuditActionFields.RoleID.Equal(roleId)));

                    await adapter.SaveEntityAsync(role).ConfigureAwait(false);

                    // all done, commit the transaction
                    adapter.Commit();
                    return(true);
                }
                catch
                {
                    // failed, roll back transaction.
                    adapter.Rollback();
                    throw;
                }
            }
        }