Пример #1
0
 public virtual PublishRequest RenderPayload <T>(EActionType type, EActionScope scope, Mutator mutator, T current, T source) where T : Data <T>
 {
     return(new PublishRequest
     {
         Message =
             new { type = type.ToString(), scope = scope.ToString(), payload = current ?? source }.ToJson(),
         Subject = $"{(current ?? source).GetFullIdentifier()}",
         TopicArn = Topic
     });
 }
Пример #2
0
        public IAction Build()
        {
            var elementType = typeof(IAction).GetTypeInfo().Assembly
                              .GetTypes()
                              .FirstOrDefault(type => type.Name == _type.ToString());

            var element = (Action)Activator.CreateInstance(elementType);

            element.Properties = _actionProperties;

            return(element);
        }
        public void UpdatePlayerAction(bool isAlive, int playerNum, EActionType act, int amount)
        {
            var         pos    = _playerPositions[playerNum];
            var         x      = pos.X;
            var         y      = pos.Y;
            var         action = act.ToString().Replace("Action", "") + "  ";
            var         bet    = amount + "    ";
            ConsoleLine playerAction;
            ConsoleLine betAmount;

            switch (pos.Type)
            {
            case PositionType.Top:
                playerAction = new ConsoleLine(x, y + 2, action);
                betAmount    = new ConsoleLine(x, y + 3, bet, ConsoleColor.Green);
                break;

            case PositionType.Right:
                playerAction = new ConsoleLine(x + 15, y + 2, action);
                betAmount    = new ConsoleLine(x + 15, y + 3, bet, ConsoleColor.Green);
                break;

            case PositionType.Bottom:
                playerAction = new ConsoleLine(x, y + 6, action);
                betAmount    = new ConsoleLine(x, y + 5, bet, ConsoleColor.Green);
                break;

            case PositionType.Left:
                playerAction = new ConsoleLine(x, y + 2, action);
                betAmount    = new ConsoleLine(x, y + 3, bet, ConsoleColor.Green);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
            DrawLines(new List <ConsoleLine> {
                playerAction, betAmount
            }, ConsoleColor.Black, isAlive ? ConsoleColor.Cyan : ConsoleColor.Red);
        }
Пример #4
0
        public T Process <T>(EActionType type, EActionScope scope, Mutator mutator, T current, T source) where T : Data <T>
        {
            // This is the main Moderation control flow. Let's start by setting up some helper classes:

            var moderationSetup          = ModerationHelper.Setup <T>();
            var customModerationPipeline = moderationSetup.CustomModerationPipeline;
            var allowedActions           = customModerationPipeline?.GetModerationActions(type, scope, mutator, current, source) ?? moderationSetup.ModerationActions;
            var currentPerson            = App.Current.Orchestrator.Person?.Locator;

            //Log.Info<T>($"MOD {type} | {currentPerson}");
            //Log.Info<T>($"MOD {type} | {allowedActions.ToJson()}");
            //Log.Info<T>($"MOD {type} | {current.ToReference()}");

            var currentKey = current.GetDataKey();

            // What can this user do?

            // Before anything, check if the target entry is marked as Imported. In that case the whole Moderation pipeline is sidestepped.

            var importModelMember = moderationSetup.Setup.ImportModelMember;

            if (importModelMember != null)
            {
                if (!current.HasMember(importModelMember))
                {
                    var msg = $"Moderation Pipeline: Invalid configuration - missing [{importModelMember}] ImportModelMember";
                    Base.Current.Log.Warn <T>(msg);
                    throw new InvalidOperationException(msg);
                }

                switch (type)
                {
                case EActionType.Insert:
                    var status = current.GetMemberValue <bool>(importModelMember);
                    if (status)
                    {
                        return(current);            // Imported record, nothing to be done here.
                    }
                    break;

                case EActionType.Update:
                    var newStatus = current.GetMemberValue <bool>(importModelMember);
                    var oldStatus = source.GetMemberValue <bool>(importModelMember);

                    if (source != null)
                    {
                        if (newStatus != oldStatus)
                        {
                            throw new ArgumentException($"Moderation Pipeline: Import flag [{importModelMember}] cannot be changed.");
                        }
                    }

                    if (newStatus)
                    {
                        return(current);
                    }
                    break;
                }
            }

            // Let's determine the Creator of this record.

            string creatorLocator = null;

            var creatorLocatorModelMember = moderationSetup.Setup.CreatorLocatorModelMember;

            if (creatorLocatorModelMember != null)
            {
                if (!current.HasMember(creatorLocatorModelMember))
                {
                    var msg = $"Moderation Pipeline: Invalid configuration - missing [{creatorLocatorModelMember}] CreatorLocatorModelMember";
                    Base.Current.Log.Warn <T>(msg);
                    throw new InvalidOperationException(msg);
                }

                creatorLocator = current.GetMemberValue <string>(creatorLocatorModelMember);
            }

            var    isCreator  = creatorLocator == currentPerson;
            string oRationale = null;

            // There are two kinds of Moderation action that this pipeline can handle. One is a Moderation Task....

            var controlPayload = ModerationHelper.GetModerationControlPayload();

            if (controlPayload != null)
            {
                // This is a Moderation Task operation - say, like an User trying to delete their own entry,
                // or a Mod changing things. We can use some extra data to help with the process.

                var oTaskId = controlPayload?.___ModerationTaskId;
                oRationale = controlPayload?.___ModerationRationale;

                if (oTaskId != null)
                {
                    var oTask = ModerationTask <T> .Get(oTaskId);

                    switch (type)
                    {
                    case EActionType.Insert:
                    case EActionType.Update:
                        // Let's change the payload to the new content.

                        var _os = oTask.Entry.ToJson();
                        var _ns = current.ToJson();

                        if (_ns != _os)
                        {
                            oTask.Entry = current;
                            oTask.Save();

                            new ModerationLog <T>
                            {
                                SourceId = currentKey,
                                Entry    = current,
                                Action   = type.ToString()
                            }.Save();

                            Base.Current.Log.Info <T>($"Moderation Pipeline: PATCH {oTaskId}");
                        }

                        // Moderator/Whitelisted? Accept it.

                        if (allowedActions.Moderate || allowedActions.Whitelisted || moderationSetup.Setup.CreatorCanWithdraw && isCreator)
                        {
                            ModerationTask <T> .Approve(oTaskId);
                        }

                        break;

                    case EActionType.Remove:
                        if (allowedActions.Moderate || allowedActions.Whitelisted)
                        {
                            ModerationTask <T> .Withdraw(oTaskId);
                        }
                        else
                        {
                            ModerationTask <T> .Reject(oTaskId);
                        }
                        break;
                    }
                }
            }

            // The second kind is regular models posted by users. Let's determine their fate:

            var mustCreateTask = false;
            var clearModel     = false;

            if (!(allowedActions.Author || allowedActions.Whitelisted))
            {
                throw new InvalidOperationException("Moderation Pipeline: Not authorized.");
            }

            switch (type)
            {
            case EActionType.Insert:
            case EActionType.Update:

                if (!(allowedActions.Moderate || allowedActions.Whitelisted))
                {
                    mustCreateTask = true;
                }

                if (allowedActions.Whitelisted)     // User is Whitelisted
                {
                    if (type == EActionType.Update) // If it's an update,
                    {
                        if (!isCreator)             // Whitelisted user isn't the creator
                        {
                            mustCreateTask = true;
                        }
                    }
                }

                break;

            case EActionType.Remove:
                if (allowedActions.Moderate)
                {
                    break;
                }
                if (allowedActions.Whitelisted && isCreator)
                {
                    break;
                }
                if (moderationSetup.Setup.CreatorCanWithdraw && isCreator)
                {
                    break;
                }

                mustCreateTask = true;

                break;

            default: throw new ArgumentOutOfRangeException(nameof(type), type, null);
            }

            if (mustCreateTask) //
            {
                var statusModelMember = moderationSetup.Setup.StatusModelMember;
                if (statusModelMember != null)
                {
                    if (current.HasMember(statusModelMember))
                    {
                        if (!current.SetMemberValue(statusModelMember, null)) // Mark as 'Waiting Moderation'.
                        {
                            Base.Current.Log.Warn <T>($"Could NOT change moderation status on [{statusModelMember}] | {type}, entry {{{currentKey}}}");
                        }
                    }
                }

                var moderationTask = new ModerationTask <T>
                {
                    SourceId      = currentKey,
                    Entry         = current,
                    Action        = type.ToString(),
                    AuthorLocator = currentPerson,
                    Rationale     = oRationale
                };

                moderationTask.Save();

                clearModel = true;
            }

            new ModerationLog <T>
            {
                SourceId      = currentKey,
                Entry         = current,
                Action        = type.ToString(),
                AuthorLocator = currentPerson,
                Result        = mustCreateTask ? States.EResult.TaskCreated : States.EResult.Approved
            }.Save();

            if (moderationSetup.Setup.NotifyChanges)
            {
                var ePer = new Email();

                var emailContent =
                    "A new entry has been submitted.<br/><br/>" +
                    "Entry: " + current.ToReference() + "<br/>" +
                    "Creator: " + App.Current.Orchestrator.Person + "<br/><br/>";

                ePer.AddTo(App.Current.Orchestrator.Application.GetGroup("CUR"));
                ePer.AddCc(App.Current.Orchestrator.Application.GetGroup("MOD"));

                ePer.Title = $"{currentPerson}: {type} {Info<T>.Settings.FriendlyName}";

                emailContent += !mustCreateTask
                    ? "User was whitelisted: Action was automatically approved."
                    : "Action was submitted for moderation.";

                ePer.Content = emailContent;
                ePer.Send();
            }

            if (clearModel)
            {
                current = null;
            }
            return(current);
        }