// post task
        private ActionResult PostTask(Covenant.Models.Grunts.GruntEncryptedMessage outputMessage)
        {
            string cookie = this.GetCookie();

            API.Models.Grunt gruntModel = this.CovenantClient.ApiGruntsGet().FirstOrDefault(G => G.CookieAuthKey == cookie);
            if (gruntModel == null || gruntModel.Status != GruntStatus.Active)
            {
                // Invalid CookieAuthKey. May not be legitimate Grunt request, respond NotFound
                return(NotFound());
            }

            string       TaskName     = outputMessage.Meta;
            GruntTasking gruntTasking = CovenantClient.ApiGruntsByIdTaskingsByTasknameGet(gruntModel.Id ?? default, TaskName);

            if (gruntTasking == null || gruntModel.Id != gruntTasking.GruntId)
            {
                // Invalid taskname. May not be legitimate Grunt request, respond NotFound
                return(NotFound());
            }

            var realGrunt = Covenant.Models.Grunts.Grunt.Create(gruntModel);

            if (realGrunt == null || realGrunt.Status != Covenant.Models.Grunts.Grunt.GruntStatus.Active)
            {
                // Invalid Grunt. May not be legitimate Grunt request, respond NotFound
                return(NotFound());
            }
            if (!outputMessage.VerifyHMAC(Convert.FromBase64String(realGrunt.GruntNegotiatedSessionKey)))
            {
                // Invalid signature. Almost certainly not a legitimate Grunt request, responsd NotFound
                return(NotFound());
            }
            string taskOutput = Common.CovenantEncoding.GetString(realGrunt.SessionDecrypt(outputMessage));

            gruntTasking.GruntTaskOutput = taskOutput;
            gruntTasking.Status          = GruntTaskingStatus.Completed;
            if (gruntTasking.Type == GruntTaskingType.Kill)
            {
                gruntModel.Status = GruntStatus.Killed;
                CovenantClient.ApiGruntsPut(gruntModel);
            }
            CovenantClient.ApiGruntsByIdTaskingsByTasknamePut(gruntTasking.GruntId ?? default, gruntTasking.Name, gruntTasking);

            GruntTask DownloadTask = CovenantClient.ApiGruntTasksGet().FirstOrDefault(GT => GT.Name == "Download");

            if (gruntTasking.TaskId == DownloadTask.Id)
            {
                CovenantClient.ApiEventsPost(new EventModel
                {
                    Message = "Grunt: " + realGrunt.Name + " has completed GruntTasking: " + gruntTasking.Name,
                    Level   = EventLevel.Highlight,
                    Context = realGrunt.Name
                });
                string FileName = Common.CovenantEncoding.GetString(Convert.FromBase64String(gruntTasking.GruntTaskingAssembly.Split(",")[1]));
                CovenantClient.ApiEventsDownloadPost(new DownloadEvent
                {
                    Message      = "Downloaded: " + FileName + "\r\n" + "Syncing to Elite...",
                    Level        = EventLevel.Info,
                    Context      = realGrunt.Name,
                    FileName     = FileName,
                    FileContents = gruntTasking.GruntTaskOutput,
                    Progress     = DownloadProgress.Complete
                });
            }
            else
            {
                CovenantClient.ApiEventsPost(new EventModel
                {
                    Message = "Grunt: " + realGrunt.Name + " has completed GruntTasking: " + gruntTasking.Name,
                    Level   = EventLevel.Highlight,
                    Context = realGrunt.Name
                });
                CovenantClient.ApiEventsPost(new EventModel
                {
                    Message = gruntTasking.GruntTaskOutput,
                    Level   = EventLevel.Info,
                    Context = realGrunt.Name
                });
            }
            return(Ok());
        }