Пример #1
0
        static async Task <Tuple <List <UpdateMessage>, List <CommunicateMessage> > > DeleteChildrenAsync(this Role role, RequestInfo requestInfo, Func <RequestInfo, CancellationToken, Task> serviceCaller = null, Action <RequestInfo, string, Exception> onServiceCallerGotError = null, CancellationToken cancellationToken = default)
        {
            var updateMessages      = new List <UpdateMessage>();
            var communicateMessages = new List <CommunicateMessage>();
            var objectName          = role.GetTypeName(true);

            var children = await role.FindChildrenAsync(cancellationToken).ConfigureAwait(false);

            await children.ForEachAsync(async child =>
            {
                var messages        = await child.DeleteChildrenAsync(requestInfo, serviceCaller, onServiceCallerGotError, cancellationToken).ConfigureAwait(false);
                updateMessages      = updateMessages.Concat(messages.Item1).ToList();
                communicateMessages = communicateMessages.Concat(messages.Item2).ToList();
            }, true, false).ConfigureAwait(false);

            await Role.DeleteAsync <Role>(role.ID, requestInfo.Session.User.ID, cancellationToken).ConfigureAwait(false);

            await role.ClearCacheAsync(cancellationToken, requestInfo.CorrelationID, true).ConfigureAwait(false);

            // send notification
            role.SendNotificationAsync("Delete", role.Organization.Notifications, ApprovalStatus.Published, ApprovalStatus.Published, requestInfo, ServiceBase.ServiceComponent.CancellationToken).Run();

            // update users
            var beRemovedUserIDs = role.UserIDs ?? new List <string>();
            var parentRole       = role.ParentRole;

            while (parentRole != null)
            {
                beRemovedUserIDs = beRemovedUserIDs.Concat(parentRole.UserIDs ?? new List <string>()).ToList();
                parentRole       = parentRole.ParentRole;
            }
            beRemovedUserIDs = beRemovedUserIDs.Distinct(StringComparer.OrdinalIgnoreCase).ToList();
            var requestUser = new RequestInfo(requestInfo)
            {
                ServiceName = "Users",
                ObjectName  = "Privileges",
                Verb        = "POST",
                Query       = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase)
                {
                    { "related-service", requestInfo.ServiceName },
                    { "related-object", "Role" },
                    { "related-system", role.SystemID },
                    { "related-entity", typeof(Role).GetTypeName() },
                    { "related-object-identity", role.ID }
                },
                Extra = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase)
                {
                    { "RemovedRoles", new[] { role.ID }.ToJArray().ToString(Formatting.None).Encrypt(Utility.EncryptionKey) }
                }
            };
            await beRemovedUserIDs.ForEachAsync(async userID =>
            {
                try
                {
                    requestUser.Query["object-identity"] = userID;
                    await(serviceCaller == null ? Task.CompletedTask : serviceCaller(requestUser, cancellationToken)).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    onServiceCallerGotError?.Invoke(requestUser, $"Error occurred while updating roles of an user account [{userID}] => {ex.Message}", ex);
                }
            }, true, false).ConfigureAwait(false);

            var json = role.ToJson();

            updateMessages.Add(new UpdateMessage
            {
                Type     = $"{requestInfo.ServiceName}#{objectName}#Delete",
                Data     = json,
                DeviceID = "*"
            });
            communicateMessages.Add(new CommunicateMessage(requestInfo.ServiceName)
            {
                Type           = $"{objectName}#Delete",
                Data           = json,
                ExcludedNodeID = Utility.NodeID
            });
            return(new Tuple <List <UpdateMessage>, List <CommunicateMessage> >(updateMessages, communicateMessages));
        }
Пример #2
0
        internal static async Task <JObject> DeleteRoleAsync(this RequestInfo requestInfo, bool isSystemAdministrator = false, Func <RequestInfo, CancellationToken, Task> serviceCaller = null, Action <RequestInfo, string, Exception> onServiceCallerGotError = null, CancellationToken cancellationToken = default)
        {
            // prepare
            var role = await(requestInfo.GetObjectIdentity() ?? "").GetRoleByIDAsync(cancellationToken).ConfigureAwait(false);

            if (role == null)
            {
                throw new InformationNotFoundException();
            }
            else if (role.Organization == null)
            {
                throw new InformationInvalidException("The organization is invalid");
            }

            // check permission
            var gotRights = isSystemAdministrator || requestInfo.Session.User.IsAdministrator(null, null, role.Organization, requestInfo.CorrelationID);

            if (!gotRights)
            {
                throw new AccessDeniedException();
            }

            var updateMessages      = new List <UpdateMessage>();
            var communicateMessages = new List <CommunicateMessage>();
            var objectName          = role.GetTypeName(true);
            var updateChildren      = requestInfo.Header.TryGetValue("x-children", out var childrenMode) && "set-null".IsEquals(childrenMode);

            // delete
            var children = await role.FindChildrenAsync(cancellationToken).ConfigureAwait(false);

            await children.ForEachAsync(async child =>
            {
                // update children to root
                if (updateChildren)
                {
                    child.ParentID       = null;
                    child.LastModified   = DateTime.Now;
                    child.LastModifiedID = requestInfo.Session.User.ID;
                    await Role.UpdateAsync(child, requestInfo.Session.User.ID, cancellationToken).ConfigureAwait(false);
                    child.Set().ClearRelatedCacheAsync(null, ServiceBase.ServiceComponent.CancellationToken, requestInfo.CorrelationID).Run();;
                    child.SendNotificationAsync("Update", child.Organization.Notifications, ApprovalStatus.Published, ApprovalStatus.Published, requestInfo, ServiceBase.ServiceComponent.CancellationToken).Run();

                    var json = child.ToJson(true, false);
                    updateMessages.Add(new UpdateMessage
                    {
                        Type     = $"{requestInfo.ServiceName}#{objectName}#Update",
                        Data     = json,
                        DeviceID = "*"
                    });
                    communicateMessages.Add(new CommunicateMessage(requestInfo.ServiceName)
                    {
                        ServiceName    = requestInfo.ServiceName,
                        Type           = $"{objectName}#Update",
                        Data           = json,
                        ExcludedNodeID = Utility.NodeID
                    });
                }

                // delete children
                else
                {
                    var messages        = await child.DeleteChildrenAsync(requestInfo, serviceCaller, onServiceCallerGotError, cancellationToken).ConfigureAwait(false);
                    updateMessages      = updateMessages.Concat(messages.Item1).ToList();
                    communicateMessages = communicateMessages.Concat(messages.Item2).ToList();
                }
            }, true, false).ConfigureAwait(false);

            await Role.DeleteAsync <Role>(role.ID, requestInfo.Session.User.ID, cancellationToken).ConfigureAwait(false);

            await role.ClearCacheAsync(cancellationToken, requestInfo.CorrelationID, true).ConfigureAwait(false);

            // update users
            var beRemovedUserIDs = role.UserIDs ?? new List <string>();
            var parentRole       = role.ParentRole;

            while (parentRole != null)
            {
                beRemovedUserIDs = beRemovedUserIDs.Concat(parentRole.UserIDs ?? new List <string>()).ToList();
                parentRole       = parentRole.ParentRole;
            }
            beRemovedUserIDs = beRemovedUserIDs.Distinct(StringComparer.OrdinalIgnoreCase).ToList();
            var requestUser = new RequestInfo(requestInfo)
            {
                ServiceName = "Users",
                ObjectName  = "Privileges",
                Verb        = "POST",
                Query       = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase)
                {
                    { "related-service", requestInfo.ServiceName },
                    { "related-object", "Role" },
                    { "related-system", role.SystemID },
                    { "related-entity", typeof(Role).GetTypeName() },
                    { "related-object-identity", role.ID }
                },
                Extra = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase)
                {
                    { "RemovedRoles", new[] { role.ID }.ToJArray().ToString(Formatting.None).Encrypt(Utility.EncryptionKey) }
                }
            };
            await beRemovedUserIDs.ForEachAsync(async userID =>
            {
                try
                {
                    requestUser.Query["object-identity"] = userID;
                    await(serviceCaller == null ? Task.CompletedTask : serviceCaller(requestUser, cancellationToken)).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    onServiceCallerGotError?.Invoke(requestUser, $"Error occurred while updating roles of an user account [{userID}] => {ex.Message}", ex);
                }
            }, true, false).ConfigureAwait(false);

            // message to update to all other connected clients
            var response = role.ToJson();

            updateMessages.Add(new UpdateMessage
            {
                Type     = $"{requestInfo.ServiceName}#{objectName}#Delete",
                DeviceID = "*",
                Data     = response
            });

            // message to update to all service instances (on all other nodes)
            communicateMessages.Add(new CommunicateMessage(requestInfo.ServiceName)
            {
                Type           = $"{objectName}#Delete",
                Data           = response,
                ExcludedNodeID = Utility.NodeID
            });

            // send update  messages
            await Task.WhenAll(
                updateMessages.ForEachAsync(message => Utility.RTUService.SendUpdateMessageAsync(message, cancellationToken), true, false),
                communicateMessages.ForEachAsync(message => Utility.RTUService.SendInterCommunicateMessageAsync(message, cancellationToken))
                ).ConfigureAwait(false);

            // send notification
            role.SendNotificationAsync("Delete", role.Organization.Notifications, ApprovalStatus.Published, ApprovalStatus.Published, requestInfo, ServiceBase.ServiceComponent.CancellationToken).Run();

            // response
            return(response);
        }