示例#1
0
        internal static async Task <JObject> SyncRoleAsync(this RequestInfo requestInfo, CancellationToken cancellationToken = default)
        {
            var data = requestInfo.GetBodyExpando();
            var role = await data.Get <string>("ID").GetRoleByIDAsync(cancellationToken).ConfigureAwait(false);

            if (role == null)
            {
                role = Role.CreateInstance(data);
                await Role.CreateAsync(role, cancellationToken).ConfigureAwait(false);
            }
            else
            {
                role.Fill(data);
                await Role.UpdateAsync(role, true, cancellationToken).ConfigureAwait(false);
            }

            // clear related cache
            if (requestInfo.GetHeaderParameter("x-converter") != null)
            {
                role.ClearRelatedCacheAsync(null, ServiceBase.ServiceComponent.CancellationToken, requestInfo.CorrelationID).Run();
            }
            else
            {
                await role.ClearCacheAsync(cancellationToken, requestInfo.CorrelationID).ConfigureAwait(false);
            }

            // send update messages
            var json       = role.Set().ToJson();
            var objectName = role.GetTypeName(true);
            await Task.WhenAll(
                Utility.RTUService.SendUpdateMessageAsync(new UpdateMessage
            {
                Type     = $"{requestInfo.ServiceName}#{objectName}#Update",
                Data     = json,
                DeviceID = "*"
            }, cancellationToken),
                Utility.RTUService.SendInterCommunicateMessageAsync(new CommunicateMessage(requestInfo.ServiceName)
            {
                Type           = $"{objectName}#Update",
                Data           = json,
                ExcludedNodeID = Utility.NodeID
            }, cancellationToken)
                ).ConfigureAwait(false);

            // return the response
            return(new JObject
            {
                { "Sync", "Success" },
                { "ID", role.ID },
                { "Type", objectName }
            });
        }
示例#2
0
        internal static async Task <JObject> CreateRoleAsync(this RequestInfo requestInfo, bool isSystemAdministrator = false, Func <RequestInfo, CancellationToken, Task> serviceCaller = null, Action <RequestInfo, string, Exception> onServiceCallerGotError = null, CancellationToken cancellationToken = default)
        {
            // prepare
            var request        = requestInfo.GetBodyExpando();
            var organizationID = request.Get <string>("SystemID") ?? requestInfo.GetParameter("x-system-id") ?? requestInfo.GetParameter("SystemID");
            var organization   = await(organizationID ?? "").GetOrganizationByIDAsync(cancellationToken).ConfigureAwait(false);

            if (organization == null)
            {
                throw new InformationInvalidException("The organization is invalid");
            }

            // check permission
            var gotRights = isSystemAdministrator || requestInfo.Session.User.IsModerator(null, null, organization, requestInfo.CorrelationID);

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

            // create new
            var role = request.CreateRoleInstance("SystemID,Privileges,OriginalPrivileges,Created,CreatedID,LastModified,LastModifiedID", obj =>
            {
                obj.ID           = string.IsNullOrWhiteSpace(obj.ID) || !obj.ID.IsValidUUID() ? UtilityService.NewUUID : obj.ID;
                obj.SystemID     = organization.ID;
                obj.ParentID     = obj.ParentRole != null ? obj.ParentID : null;
                obj.Created      = obj.LastModified = DateTime.Now;
                obj.CreatedID    = obj.LastModifiedID = requestInfo.Session.User.ID;
                obj._childrenIDs = new List <string>();
            });
            await Role.CreateAsync(role, cancellationToken).ConfigureAwait(false);

            role.Set().ClearRelatedCacheAsync(null, ServiceBase.ServiceComponent.CancellationToken, requestInfo.CorrelationID).Run();

            // update users
            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)
                {
                    { "AddedRoles", new[] { role.ID }.ToJArray().ToString(Formatting.None).Encrypt(Utility.EncryptionKey) }
                }
            };

            var userIDs    = role.UserIDs ?? new List <string>();
            var parentRole = role.ParentRole;

            while (parentRole != null)
            {
                userIDs    = userIDs.Concat(parentRole.UserIDs ?? new List <string>()).ToList();
                parentRole = parentRole.ParentRole;
            }

            await userIDs.Distinct(StringComparer.OrdinalIgnoreCase).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);

            // update parent
            var updateMessages      = new List <UpdateMessage>();
            var communicateMessages = new List <CommunicateMessage>();
            var objectName          = role.GetTypeName(true);

            if (role.ParentRole != null)
            {
                await role.ParentRole.FindChildrenAsync(cancellationToken).ConfigureAwait(false);

                role.ParentRole._childrenIDs.Add(role.ID);
                await role.ParentRole.SetAsync(true, cancellationToken).ConfigureAwait(false);

                // message to update to all connected clients
                var json = role.ParentRole.ToJson(true, false);
                updateMessages.Add(new UpdateMessage
                {
                    Type     = $"{requestInfo.ServiceName}#{objectName}#Update",
                    Data     = json,
                    DeviceID = "*"
                });

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

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

            if (role.ParentRole == null)
            {
                updateMessages.Add(new UpdateMessage
                {
                    Type     = $"{requestInfo.ServiceName}#{objectName}#Create",
                    Data     = response,
                    DeviceID = "*"
                });
            }

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

            // send the 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("Create", organization.Notifications, ApprovalStatus.Draft, ApprovalStatus.Published, requestInfo, ServiceBase.ServiceComponent.CancellationToken).Run();

            // response
            return(response);
        }